Initial commit
Change-Id: I6a4444e3c193dae437cd7929f4c39aba7b749efa
diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt
new file mode 100644
index 0000000..96a8334
--- /dev/null
+++ b/extensions/CMakeLists.txt
@@ -0,0 +1,162 @@
+PROJECT("freeDiameter extensions" C)
+
+# We want all resulting objects in the same folder
+SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
+
+# Use the macro FD_ADD_EXTENSION(name files...) to create an extension
+# It is equivalent to add_library with the appropriate parameters
+# and naming conventions (.fdx : FreeDiameter eXtension)
+MACRO(FD_ADD_EXTENSION EXTNAME)
+ ADD_LIBRARY(${EXTNAME} MODULE ${ARGN})
+ SET_TARGET_PROPERTIES(${EXTNAME} PROPERTIES PREFIX "" )
+ SET_TARGET_PROPERTIES(${EXTNAME} PROPERTIES SUFFIX ".fdx" )
+ENDMACRO(FD_ADD_EXTENSION)
+
+# Use the macro FD_EXTENSION_SUBDIR(extmacroname subdir descr default) to
+# add a new extension subdirectory.
+MACRO(FD_EXTENSION_SUBDIR EXTSUBDIR EXTDESCR EXTDEFAULT)
+ STRING(TOUPPER ${EXTSUBDIR} EXTMACRONAME)
+ IF (NOT ALL_EXTENSIONS)
+ OPTION(BUILD_${EXTMACRONAME} "Build ${EXTSUBDIR}.fdx? (${EXTDESCR})" ${EXTDEFAULT})
+ ENDIF (NOT ALL_EXTENSIONS)
+ IF (BUILD_${EXTMACRONAME} OR ALL_EXTENSIONS)
+ SUBDIRS(${EXTSUBDIR})
+ ENDIF (BUILD_${EXTMACRONAME} OR ALL_EXTENSIONS)
+ENDMACRO(FD_EXTENSION_SUBDIR)
+
+OPTION(ALL_EXTENSIONS "Build ALL available extensions? (disable to select individual components)" OFF)
+
+# The extensions include the headers of freeDiameter that contains gnutls objects
+INCLUDE_DIRECTORIES(${LFDCORE_INCLUDES})
+
+
+###########################
+# Extensions section
+
+####
+# Diameter applications dictionaries
+
+FD_EXTENSION_SUBDIR(dict_nasreq "NASREQ (RFC4005) Dictionary definitions" ON)
+FD_EXTENSION_SUBDIR(dict_eap "Diameter EAP (RFC4072) Dictionary definitions" ON)
+
+FD_EXTENSION_SUBDIR(dict_dcca "Diameter CC (RFC4006) Dictionary definitions [incomplete]" ON)
+FD_EXTENSION_SUBDIR(dict_dcca_3gpp "Diameter CC 3GPP Dictionary definitions [incomplete]" ON)
+FD_EXTENSION_SUBDIR(dict_dcca_starent "Diameter CC Starent Dictionary definitions" ON)
+
+FD_EXTENSION_SUBDIR(dict_sip "Diameter SIP (RFC4740) Dictionary definitions" ON)
+
+FD_EXTENSION_SUBDIR(dict_mip6a "Diameter Mobile IPv6 Auth Dictionary definitions" ON)
+FD_EXTENSION_SUBDIR(dict_mip6i "Diameter Mobile IPv6 IKE Dictionary definitions" ON)
+FD_EXTENSION_SUBDIR(dict_nas_mipv6 "Diameter NAS-to-HAAA Interaction Dictionary definitions" ON)
+
+FD_EXTENSION_SUBDIR(dict_legacy_xml "Load Diameter dictionary definitions from XML files." OFF)
+
+
+####
+# Diameter applications
+
+FD_EXTENSION_SUBDIR(app_acct "Simple accounting application that stores accounting records in flat database" OFF)
+FD_EXTENSION_SUBDIR(app_diameap "Diameter EAP Application server (RFC 4072)" OFF)
+FD_EXTENSION_SUBDIR(app_radgw "RADIUS/Diameter gateway translation - RADIUS client to Diameter server" OFF)
+FD_EXTENSION_SUBDIR(app_sip "Diameter SIP Authentication and Authorization server (RFC 4740)" OFF)
+
+FD_EXTENSION_SUBDIR(app_redirect "Diameter Redirect server: send configurable Redirect indications to other peers" OFF)
+
+
+####
+# Routing extensions
+
+FD_EXTENSION_SUBDIR(rt_busypeers "Handling of Diameter TOO_BUSY messages and relay timeouts" ON)
+FD_EXTENSION_SUBDIR(rt_default "Configurable routing rules for freeDiameter" ON)
+FD_EXTENSION_SUBDIR(rt_ereg "Configurable routing based on regexp matching of AVP values" OFF)
+FD_EXTENSION_SUBDIR(rt_ignore_dh "Stow Destination-Host in Proxy-Info, restore to Origin-Host for answers" ON)
+FD_EXTENSION_SUBDIR(rt_load_balance "Balance load over multiple equal hosts, based on outstanding requests" ON)
+FD_EXTENSION_SUBDIR(rt_randomize "Randomly choose one of the highest scored hosts and increase its score by one" ON)
+FD_EXTENSION_SUBDIR(rt_redirect "Handling of Diameter Redirect messages" ON)
+
+
+####
+# Peers security extensions
+
+FD_EXTENSION_SUBDIR(acl_wl "White-list based authorization of incoming connections" ON)
+
+
+####
+# Debug & test extensions
+
+FD_EXTENSION_SUBDIR(dbg_monitor "Outputs periodical status information" ON)
+FD_EXTENSION_SUBDIR(dbg_msg_timings "Show some timing information for messages" ON)
+FD_EXTENSION_SUBDIR(dbg_msg_dumps "Show human-readable content of the received & sent messages" ON)
+FD_EXTENSION_SUBDIR(dbg_rt "Routing extension for debugging the routing module" ON)
+FD_EXTENSION_SUBDIR(test_app "Testing application to send dummy message to another peer, like a Diameter 'ping'" OFF)
+FD_EXTENSION_SUBDIR(test_sip "Testing application to simulate Diameter-SIP client (RFC4740)" OFF)
+FD_EXTENSION_SUBDIR(dbg_interactive "Python-interpreter based module" OFF)
+FD_EXTENSION_SUBDIR(test_netemul "Simple Diameter network emulator proxy extension (latency, PDV, duplicates)" OFF)
+
+
+
+# The following extension have very little use except for specific tests, so we disable them except in Debug configurations.
+IF (CMAKE_BUILD_TYPE MATCHES "Debug")
+ FD_EXTENSION_SUBDIR(_sample "Simple extension to demonstrate extension mechanism, for developpers" OFF)
+ FD_EXTENSION_SUBDIR(test_acct "Receive Accounting-Requests and display the data, but no storage" OFF)
+ FD_EXTENSION_SUBDIR(test_rt_any "Routing extension randomly sending message to any peer available, for testing purpose" OFF)
+ENDIF (CMAKE_BUILD_TYPE MATCHES "Debug")
+
+
+FD_EXTENSION_SUBDIR(dict_3gpp2_avps "dict_3gpp2_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_CreditControl "dict_CreditControl extension library" ON)
+FD_EXTENSION_SUBDIR(dict_CxDx "dict_CxDx extension library" ON)
+FD_EXTENSION_SUBDIR(dict_Gx "dict_Gx extension library" ON)
+FD_EXTENSION_SUBDIR(dict_NAS "dict_NAS extension library" ON)
+FD_EXTENSION_SUBDIR(dict_Rf "dict_Rf extension library" ON)
+FD_EXTENSION_SUBDIR(dict_Ro "dict_Ro extension library" ON)
+FD_EXTENSION_SUBDIR(dict_Rx "dict_Rx extension library" ON)
+FD_EXTENSION_SUBDIR(dict_S6as6d "dict_S6as6d extension library" ON)
+FD_EXTENSION_SUBDIR(dict_S6mS6n "dict_S6mS6n extension library" ON)
+FD_EXTENSION_SUBDIR(dict_S6t "dict_S6t extension library" ON)
+FD_EXTENSION_SUBDIR(dict_SGd "dict_SGd extension library" ON)
+FD_EXTENSION_SUBDIR(dict_SLh "dict_SLh extension library" ON)
+FD_EXTENSION_SUBDIR(dict_Sd "dict_Sd extension library" ON)
+FD_EXTENSION_SUBDIR(dict_Sh "dict_Sh extension library" ON)
+FD_EXTENSION_SUBDIR(dict_T4 "dict_T4 extension library" ON)
+FD_EXTENSION_SUBDIR(dict_T6aT6bT7 "dict_T6aT6bT7 extension library" ON)
+FD_EXTENSION_SUBDIR(dict_Tsp "dict_Tsp extension library" ON)
+#FD_EXTENSION_SUBDIR(dict_base_rfc6733 "dict_base_rfc6733 extension library" ON)
+FD_EXTENSION_SUBDIR(dict_draftload_avps "dict_draftload_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_etsi283034_avps "dict_etsi283034_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc4004_avps "dict_rfc4004_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc4006bis_avps "dict_rfc4006bis_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc4072_avps "dict_rfc4072_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc4590_avps "dict_rfc4590_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc5447_avps "dict_rfc5447_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc5580_avps "dict_rfc5580_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc5777_avps "dict_rfc5777_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc5778_avps "dict_rfc5778_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc6734_avps "dict_rfc6734_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc6942_avps "dict_rfc6942_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc7155_avps "dict_rfc7155_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc7683_avps "dict_rfc7683_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_rfc7944_avps "dict_rfc7944_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29061_avps "dict_ts29061_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29128_avps "dict_ts29128_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29154_avps "dict_ts29154_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29173_avps "dict_ts29173_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29212_avps "dict_ts29212_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29214_avps "dict_ts29214_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29215_avps "dict_ts29215_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29217_avps "dict_ts29217_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29229_avps "dict_ts29229_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29272_avps "dict_ts29272_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29273_avps "dict_ts29273_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29329_avps "dict_ts29329_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29336_avps "dict_ts29336_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29337_avps "dict_ts29337_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29338_avps "dict_ts29338_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29343_avps "dict_ts29343_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29344_avps "dict_ts29344_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29345_avps "dict_ts29345_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29368_avps "dict_ts29368_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts29468_avps "dict_ts29468_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_ts32299_avps "dict_ts32299_avps extension library" ON)
+FD_EXTENSION_SUBDIR(dict_S6c "dict_S6c extension library" ON)
+FD_EXTENSION_SUBDIR(dict_S9 "dict_S9 extension library" ON)
diff --git a/extensions/_sample/CMakeLists.txt b/extensions/_sample/CMakeLists.txt
new file mode 100644
index 0000000..aad630a
--- /dev/null
+++ b/extensions/_sample/CMakeLists.txt
@@ -0,0 +1,14 @@
+# The sample extension
+PROJECT("Sample extension")
+
+# Compile as a module
+FD_ADD_EXTENSION(dbg_sample sample.c hello.cpp fini.c)
+
+
+####
+## INSTALL section ##
+
+# Uncomment the following lines to have the extension installed
+# INSTALL(TARGETS dbg_sample
+# LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+# COMPONENT freeDiameter-debug-tools)
diff --git a/extensions/_sample/fini.c b/extensions/_sample/fini.c
new file mode 100644
index 0000000..df7513c
--- /dev/null
+++ b/extensions/_sample/fini.c
@@ -0,0 +1,45 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 <freeDiameter/extension.h>
+
+/* The function MUST be called this */
+void fd_ext_fini(void)
+{
+ /* This code is executed when the daemon is exiting; cleanup management should be placed here */
+ TRACE_DEBUG(INFO, "Extension is terminated... Bye!");
+ return ;
+}
+
diff --git a/extensions/_sample/hello.cpp b/extensions/_sample/hello.cpp
new file mode 100644
index 0000000..05b340c
--- /dev/null
+++ b/extensions/_sample/hello.cpp
@@ -0,0 +1,48 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Sample file demonstrating how to write some C++ code */
+
+#include <iostream>
+
+#include <freeDiameter/extension.h>
+
+extern "C" void mycppfunc(); /* will be called from C code */
+
+
+void mycppfunc() {
+ std::cout << "Hello World!" << std::endl;
+ /* done */
+}
diff --git a/extensions/_sample/sample.c b/extensions/_sample/sample.c
new file mode 100644
index 0000000..9072684
--- /dev/null
+++ b/extensions/_sample/sample.c
@@ -0,0 +1,97 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Sample extension to test extensions mechanism in freeDiameter */
+#include <freeDiameter/extension.h>
+
+/* from sample.cpp */
+void mycppfunc();
+
+static int sample_main(char * conffile);
+
+/* Define the entry point. A convenience macro is provided */
+EXTENSION_ENTRY("sample", sample_main);
+
+/* The extension-specific initialization code */
+static int sample_main(char * conffile)
+{
+ /* The debug macro from main tree can be used the same way */
+ TRACE_ENTRY("%p", conffile);
+
+ /* This is how we access daemon's global vars */
+ fprintf(stdout, "I am extension " __FILE__ " running on host %s.", fd_g_config->cnf_diamid);
+
+ /* The configuration file name is received in the conffile var. It's up to extension to parse it */
+ if (conffile) {
+ fprintf(stdout, "I should parse my configuration file there: %s\n", conffile);
+ } else {
+ fprintf(stdout, "I received no configuration file to parse\n");
+ }
+
+ /* Functions from the libfreediameter can also be used as demonstrated here: */
+ TRACE_DEBUG(INFO, "Let's create that 'Example-AVP'...");
+ {
+ struct dict_object * origin_host_avp = NULL;
+ struct dict_object * session_id_avp = NULL;
+ struct dict_object * example_avp_avp = NULL;
+ struct dict_rule_data rule_data = { NULL, RULE_REQUIRED, 0, -1, 1 };
+ struct dict_avp_data example_avp_data = { 999999, 0, "Example-AVP", AVP_FLAG_VENDOR , 0, AVP_TYPE_GROUPED };
+
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &origin_host_avp, ENOENT));
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &session_id_avp, ENOENT));
+
+ CHECK_FCT( fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &example_avp_data , NULL, &example_avp_avp ));
+
+ rule_data.rule_avp = origin_host_avp;
+ rule_data.rule_min = 1;
+ rule_data.rule_max = 1;
+ CHECK_FCT( fd_dict_new ( fd_g_config->cnf_dict, DICT_RULE, &rule_data, example_avp_avp, NULL ));
+
+ rule_data.rule_avp = session_id_avp;
+ rule_data.rule_min = 1;
+ rule_data.rule_max = -1;
+ CHECK_FCT( fd_dict_new ( fd_g_config->cnf_dict, DICT_RULE, &rule_data, example_avp_avp, NULL ));
+
+ }
+ TRACE_DEBUG(INFO, "'Example-AVP' created without error");
+
+ /* Call the c++ function */
+ mycppfunc();
+
+ /* The initialization function returns an error code with the standard POSIX meaning (ENOMEM, and so on) */
+ return 0;
+}
+
+/* See file fini.c for an example of destructor */
diff --git a/extensions/acl_wl/CMakeLists.txt b/extensions/acl_wl/CMakeLists.txt
new file mode 100644
index 0000000..bd51150
--- /dev/null
+++ b/extensions/acl_wl/CMakeLists.txt
@@ -0,0 +1,29 @@
+# The acl_wl extension
+PROJECT("Access Control / White List" C)
+
+# Parser files
+BISON_FILE(aw_conf.y)
+FLEX_FILE(aw_conf.l)
+SET_SOURCE_FILES_PROPERTIES(lex.aw_conf.c aw_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( ACL_WL_SRC
+ acl_wl.h
+ acl_wl.c
+ aw_tree.c
+ lex.aw_conf.c
+ aw_conf.tab.c
+ aw_conf.tab.h
+)
+
+# Compile as a module
+FD_ADD_EXTENSION(acl_wl ${ACL_WL_SRC})
+
+
+####
+## INSTALL section ##
+
+# We install with the daemon component because it is a base feature.
+INSTALL(TARGETS acl_wl
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-daemon)
diff --git a/extensions/acl_wl/acl_wl.c b/extensions/acl_wl/acl_wl.c
new file mode 100644
index 0000000..c28ddd9
--- /dev/null
+++ b/extensions/acl_wl/acl_wl.c
@@ -0,0 +1,117 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * Whitelist extension for freeDiameter.
+ */
+
+#include "acl_wl.h"
+
+/* The validator function */
+static int aw_validate(struct peer_info * info, int * auth, int (**cb2)(struct peer_info *))
+{
+ int res;
+
+ TRACE_ENTRY("%p %p %p", info, auth, cb2);
+
+ CHECK_PARAMS(info && auth && cb2);
+
+ /* We don't use the second callback */
+ *cb2 = NULL;
+
+ /* Default to unknown result */
+ *auth = 0;
+
+ /* Now search the peer in our tree */
+ CHECK_FCT( aw_tree_lookup(info->pi_diamid, &res) );
+ if (res < 0) {
+ /* The peer is not whitelisted */
+ return 0;
+ }
+
+ /* We found the peer in the tree, now check the status */
+
+ /* First, if TLS is already in place, just accept */
+ if (info->runtime.pir_cert_list) {
+ *auth = 1;
+ return 0;
+ }
+
+ /* Now, if we did not specify any flag, reject */
+ if (res == 0) {
+ TRACE_DEBUG(INFO, "Peer '%s' rejected, only TLS-protected connection is whitelisted.", info->pi_diamid);
+ /* We don't actually set *auth = -1, leave space for a further extension to validate the peer */
+ return 0;
+ }
+
+ /* Otherwise, just set the configured flags for the peer, and authorize it */
+ *auth = 1;
+
+ /* Save information about the security mechanism to use after CER/CEA exchange */
+ if ((res & PI_SEC_NONE) && (res & PI_SEC_TLS_OLD))
+ res = PI_SEC_NONE; /* If we authorized it, we must have an IPsec tunnel setup, no need for TLS in this case */
+
+ info->config.pic_flags.sec = res;
+ return 0;
+}
+
+/* entry point */
+static int aw_entry(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ CHECK_PARAMS(conffile);
+
+ /* Parse configuration file */
+ CHECK_FCT( aw_conf_handle(conffile) );
+
+ TRACE_DEBUG(INFO, "Extension ACL_wl initialized with configuration: '%s'", conffile);
+ if (TRACE_BOOL(ANNOYING)) {
+ aw_tree_dump();
+ }
+
+ /* Register the validator function */
+ CHECK_FCT( fd_peer_validate_register ( aw_validate ) );
+
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ /* Destroy the tree */
+ aw_tree_destroy();
+}
+
+EXTENSION_ENTRY("acl_wl", aw_entry);
diff --git a/extensions/acl_wl/acl_wl.h b/extensions/acl_wl/acl_wl.h
new file mode 100644
index 0000000..8606c2a
--- /dev/null
+++ b/extensions/acl_wl/acl_wl.h
@@ -0,0 +1,60 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Header file for the acl_wl extension.
+ *
+ * This extension provides a simple mechanism to allow connections from remote peers
+ * without actively maintaining a connection to these peers.
+ *
+ * See the acl_wl.conf.sample file for the format of the configuration file.
+ */
+
+#include <freeDiameter/extension.h>
+
+/* Parse the configuration file */
+int aw_conf_handle(char * conffile);
+
+/* Add to the tree (name is \0 terminated) */
+int aw_tree_add(char * name, int flags);
+
+/* Search in the tree. On return, *result = -1: not found; >=0: found with PI_SEC_* flags */
+int aw_tree_lookup(char * name, int * result);
+
+/* Cleanup the tree */
+void aw_tree_destroy(void);
+
+/* For debug */
+void aw_tree_dump(void);
+
diff --git a/extensions/acl_wl/aw_conf.l b/extensions/acl_wl/aw_conf.l
new file mode 100644
index 0000000..d6b55c8
--- /dev/null
+++ b/extensions/acl_wl/aw_conf.l
@@ -0,0 +1,103 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Lex extension's configuration parser.
+ *
+ * The configuration file contains a default priority, and a list of peers with optional overwite priority.
+ * -- see the app_test.conf.sample file for more detail.
+ */
+
+%{
+#include "acl_wl.h"
+/* Include yacc tokens definitions */
+#include "aw_conf.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+static int curflag = 0;
+
+%}
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count, reset flag value */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ curflag = 0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+ /* Match the two allowed flags directly in LEX */
+ALLOW_IPSEC {
+ curflag |= PI_SEC_NONE;
+ }
+
+ALLOW_OLD_TLS {
+ curflag |= PI_SEC_TLS_OLD;
+ }
+
+ /* Any other string is considered a fqdn or partial fqdn with a star. The star can only be the first label. */
+(\*|[[:alnum:]][[:alnum:]-]*)(\.[[:alnum:]][[:alnum:]-]*)+ {
+ /* We matched a valid label, let's directly save it into the tree. The function will issue the appropriate warnings. */
+ CHECK_FCT_DO( aw_tree_add(yytext, curflag), return LEX_ERROR);
+ yylval->string = yytext;
+ return FQDN;
+ }
+
+ /* No match */
+<*>[[:alnum:]]+ | /* This rule is only useful to print a complete token in error messages */
+<*>. {
+ TRACE_ERROR("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/acl_wl/aw_conf.y b/extensions/acl_wl/aw_conf.y
new file mode 100644
index 0000000..4ace8e5
--- /dev/null
+++ b/extensions/acl_wl/aw_conf.y
@@ -0,0 +1,141 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ * See doc/acl_wl.conf.sample for configuration file format
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "acl_wl.h"
+#include "aw_conf.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+#include <string.h>
+#include <errno.h>
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+static int fqdn_added = 0;
+
+/* Parse the configuration file */
+int aw_conf_handle(char * conffile)
+{
+ extern FILE * aw_confin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ aw_confin = fopen(conffile, "r");
+ if (aw_confin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(aw_confin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ } else {
+ TRACE_DEBUG(FULL, "Read %d FQDN entries successfully.", fqdn_added);
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int aw_conflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ char *string;
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+/* Key words */
+%token <string> FQDN
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK */
+ | conffile FQDN
+ {
+ fqdn_added++;
+ TRACE_DEBUG(FULL, "Added FQDN: %s", $2);
+ }
+ | conffile LEX_ERROR
+ {
+ yyerror(&yylloc, conffile, "An error occurred while parsing the configuration file");
+ return EINVAL;
+ }
+ ;
+
diff --git a/extensions/acl_wl/aw_tree.c b/extensions/acl_wl/aw_tree.c
new file mode 100644
index 0000000..9b9cbd8
--- /dev/null
+++ b/extensions/acl_wl/aw_tree.c
@@ -0,0 +1,413 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "acl_wl.h"
+
+/* The configuration simply contains the allowed fqdn and/or domains (*.example.net)
+ * It is represented similarly to the DNS tree:
+ * (root)--___
+ * / \ \
+ * tld1 tld2 (tld3...)
+ * / |
+ * label1 label2
+ * / \
+ * lbl21 lbl22
+ * / \
+ * lbl211 *
+ *
+ * This tree would whitelist:
+ * - label1.tld1
+ * - lbl211.lbl21.label2.tld2
+ * - *.lbl22.label2.tld2
+ *
+ * The functions to add and search the tree are in aw_tree.c.
+ *
+ */
+
+/* Maximum depth of the tree. We set a static size to avoid dynamic allocations. We report an error if this is not sufficient. */
+#define AW_TREE_MAXDEPTH 10
+
+/* An element of the tree */
+struct tree_item {
+ struct fd_list chain; /* Link to elements at the same level. Ordered alphabetically. */
+ struct fd_list children; /* Sentinel for the subtree. */
+ char * str; /* the \0 terminated label, or NULL if it is a generic container ("*") */
+ int flags; /* PI_SEC_* flags */
+ int leaf; /* true if this item can be a leaf of the tree */
+};
+
+/* The root of the tree */
+static struct fd_list tree_root = FD_LIST_INITIALIZER(tree_root);
+
+/* Note: we don't need to lock, since we add only when parsing the conf, and then read only */
+
+
+/* The parsed name */
+struct split_name {
+ struct {
+ char * str; /* start of this label */
+ size_t len; /* length of this label. It does not include the final "." or "\0" */
+ } label[AW_TREE_MAXDEPTH];
+ int last_lbl; /* idx of last label defined */
+};
+
+/* The following function explodes a name into a split_name structure */
+static int parse_name(char * name, struct split_name * result)
+{
+ int i, l, prev_offset;
+
+ TRACE_ENTRY("%p %p", name, result);
+
+ /* First, initialize the result array */
+ memset(result, 0, sizeof(struct split_name));
+ result->label[0].str = name;
+ l = 0; prev_offset = 0;
+
+ for (i=0; name[i] != '\0'; i++) {
+ if (name[i]=='.') {
+ l++;
+ CHECK_PARAMS( l < AW_TREE_MAXDEPTH );
+
+ /* The previous label is complete, write its size */
+ result->label[l - 1].len = i - prev_offset;
+ prev_offset = i + 1;
+
+ /* Write the start of the new label */
+ result->label[l].str = name + i + 1;
+ }
+ }
+
+ /* Finally, write the size of the last label */
+ result->label[l].len = i - prev_offset;
+
+ result->last_lbl = l;
+
+#if 0
+ fd_log_debug("Parsed name %s as:", name);
+ for (i=0; i<=l; i++)
+ fd_log_debug(" str[%d] len: %d, v:%.*s", i, result->label[i].len, result->label[i].len, result->label[i].str);
+#endif /* 0 */
+ return 0;
+}
+
+/* Create a new tree_item structure */
+static struct tree_item * new_ti(char * str, size_t len, int flags, int leaf)
+{
+ struct tree_item * ti;
+ char * s = NULL;
+
+ TRACE_ENTRY("%p %zd %x", str, len, flags);
+
+ if (str) {
+ CHECK_MALLOC_DO(s = malloc(len + 1), return NULL);
+ memcpy(s, str, len);
+ s[len] = '\0';
+ }
+
+ CHECK_MALLOC_DO( ti = malloc(sizeof(struct tree_item)), {free(s); return NULL; } );
+ memset(ti, 0, sizeof(struct tree_item));
+
+ fd_list_init(&ti->chain, ti);
+ fd_list_init(&ti->children, ti);
+ ti->str = s;
+ ti->flags = flags;
+ ti->leaf = leaf;
+
+ return ti;
+}
+
+/* Recursively delete a subtree */
+static void delete_tree(struct fd_list * senti)
+{
+ while (!FD_IS_LIST_EMPTY(senti)) {
+ struct tree_item * ti = (struct tree_item *)(senti->next);
+
+ /* Delete recursively its children first */
+ delete_tree(&ti->children);
+
+ /* Now, unlink from the sentinel list */
+ fd_list_unlink(&ti->chain);
+
+ /* destroy this tree item */
+ free(ti->str);
+ free(ti);
+ }
+}
+
+/* Top-level destroy function */
+void aw_tree_destroy(void)
+{
+ delete_tree(&tree_root);
+}
+
+/* Display the content of a subtree */
+static void tree_dump(struct fd_list * sub, int indent)
+{
+ struct fd_list * li;
+ for (li = sub->next; li != sub; li = li->next) {
+ struct tree_item * ti = (struct tree_item *)li;
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "%*s%s", indent * 2, "", ti->str?:"*");
+ if (ti->leaf)
+ snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), " (flag:%x)", ti->flags);
+ fd_log_debug("%s", buf);
+ tree_dump(&ti->children, indent + 1);
+ }
+}
+
+/* Top-level function */
+void aw_tree_dump(void)
+{
+ fd_log_debug("[acl_wl] tree dump:");
+ fd_log_debug("(root)");
+ tree_dump(&tree_root, 1);
+ fd_log_debug("[acl_wl] end of dump");
+}
+
+/* Function to add a new entry in the tree */
+int aw_tree_add(char * name, int flags)
+{
+ struct split_name sn;
+ struct tree_item * ti;
+ struct fd_list * li, *senti;
+ int lbl, found;
+
+ TRACE_ENTRY("%p %x", name, flags);
+ CHECK_PARAMS(name && *name);
+
+ CHECK_FCT_DO( parse_name(name, &sn),
+ {
+ fd_log_debug("The name '%s' contains too many labels, try a generic (*) or recompile with bigger AW_TREE_MAXDEPTH value (cur: %d)", name, AW_TREE_MAXDEPTH);
+ return EINVAL;
+ } );
+
+ senti = &tree_root;
+
+ for (lbl = sn.last_lbl; lbl > 0; lbl--) {
+ /* Check if the list is empty, we can directly create the new entry */
+ if (FD_IS_LIST_EMPTY(senti)) {
+ CHECK_MALLOC( ti = new_ti(sn.label[lbl].str, sn.label[lbl].len, 0, 0 /* flags are only set in the terminals */) );
+ /* Insert this label in the sentinel sublist */
+ fd_list_insert_after(senti, &ti->chain);
+ /* Update the sentinel */
+ senti = &ti->children;
+ /* loop to the next label */
+ continue;
+ }
+
+ /* Check if we have a '*' element already that overlapses */
+ ti = (struct tree_item *)(senti->next);
+ if (ti->str == NULL) {
+ fd_log_debug("[acl_wl] Warning: entry '%s' is superseeded by a generic entry at label %d, ignoring.", name, lbl + 1);
+ return 0;
+ }
+
+ /* Search this label in the ordered list */
+ found = 0;
+ for (li = senti->next; li != senti; li=li->next) {
+ int cmp, len;
+ ti = (struct tree_item *)li;
+
+ cmp = strncasecmp(ti->str, sn.label[lbl].str, sn.label[lbl].len);
+ if (cmp > 0)
+ break; /* the new label must be inserted before li */
+ if (cmp < 0)
+ continue;
+
+ /* Check the lengths */
+ len = strlen(ti->str);
+ if (len > sn.label[lbl].len)
+ break; /* the new label must be inserted before li */
+ if (len < sn.label[lbl].len)
+ continue;
+
+ /* We already had this label */
+ found = 1;
+ senti = &ti->children;
+ break;
+ }
+
+ if (found)
+ continue;
+
+ /* Otherwise, we have to create a new ti, and add it before li */
+ CHECK_MALLOC( ti = new_ti(sn.label[lbl].str, sn.label[lbl].len, 0, 0 /* flags are only set in the terminals */) );
+ /* Insert this label in the sentinel sublist */
+ fd_list_insert_before(li, &ti->chain);
+ /* Update the sentinel */
+ senti = &ti->children;
+ }
+
+ ti = NULL;
+ li = senti;
+
+ /* At this point, senti points to the list where we are supposed to insert our last label. */
+ if (sn.label[0].str[0] == '*') {
+ if (!FD_IS_LIST_EMPTY(senti)) {
+ fd_log_debug("[acl_wl] Warning: entry '%s' overwrites previous more detailed entries, these are deleted.", name);
+ delete_tree(senti);
+ }
+
+ /* Create the new entry */
+ CHECK_MALLOC( ti = new_ti(NULL, 0, flags, 1) );
+ } else {
+ if (!FD_IS_LIST_EMPTY(senti)) {
+ /* Check we don't have a '*' entry already */
+ ti = (struct tree_item *)(senti->next);
+ if (ti->str == NULL) {
+ fd_log_debug("[acl_wl] Warning: entry '%s' is superseeded by a generic entry at label 1, ignoring.", name);
+ return 0;
+ }
+
+ /* Search the place for the new label */
+ for (li = senti->next; li != senti; li=li->next) {
+ int cmp, len;
+ ti = (struct tree_item *)li;
+
+ cmp = strncasecmp(ti->str, sn.label[0].str, sn.label[0].len);
+ if (cmp > 0)
+ break; /* the new label must be inserted before li */
+ if (cmp < 0)
+ continue;
+
+ /* Check the lengths */
+ len = strlen(ti->str);
+ if (len > sn.label[0].len)
+ break; /* the new label must be inserted before li */
+ if (len < sn.label[0].len)
+ continue;
+
+ /* We already had this label */
+ if (ti->leaf) {
+ fd_log_debug("[acl_wl] Warning: entry '%s' is duplicated, merging the flags.", name);
+ ti->flags |= flags;
+ return 0;
+ } else {
+ /* Just mark this entry as a valid leaf also */
+ ti->leaf = 1;
+ ti->flags = flags;
+ return 0;
+ }
+ }
+ }
+
+ /* Create the new entry */
+ CHECK_MALLOC( ti = new_ti(sn.label[0].str, sn.label[0].len, flags, 1) );
+ }
+
+ /* The new label is "ti", it is inserted before "li" */
+ fd_list_insert_before(li, &ti->chain);
+
+ /* Done! */
+ return 0;
+}
+
+/* Search in the tree. On return, *result = -1: not found; >=0: found with PI_SEC_* flags */
+int aw_tree_lookup(char * name, int * result)
+{
+ struct split_name sn;
+ int lbl, found;
+ struct tree_item * ti;
+ struct fd_list * senti, *li;
+
+ TRACE_ENTRY("%p %p", name, result);
+ CHECK_PARAMS(name && result);
+
+ /* Initialize */
+ *result = -1;
+
+ /* Parse the name into labels */
+ CHECK_FCT_DO( parse_name(name, &sn),
+ {
+ TRACE_DEBUG(INFO, "Too many labels in this name, it cannot be found in the tree, skipping.");
+ return 0;
+ } );
+
+ senti = &tree_root;
+
+ for (lbl = sn.last_lbl; lbl >= 0; lbl--) {
+ /* Check if the list is empty, we can directly return */
+ if (FD_IS_LIST_EMPTY(senti)) {
+ /* The item is not found */
+ return 0;
+ }
+
+ /* Check if we have a '*' element */
+ ti = (struct tree_item *)(senti->next);
+ if (ti->str == NULL) {
+ TRACE_DEBUG(ANNOYING, "[acl_wl] %s matched at label %d with a generic entry.", name, lbl + 1);
+ *result = ti->flags;
+ return 0;
+ }
+
+ /* Search this label in the ordered list */
+ found = 0;
+ for (li = senti->next; li != senti; li=li->next) {
+ int cmp, len;
+ ti = (struct tree_item *)li;
+
+ cmp = strncasecmp(ti->str, sn.label[lbl].str, sn.label[lbl].len);
+ if (cmp > 0)
+ return 0; /* the label was not found */
+ if (cmp < 0)
+ continue;
+
+ /* Check the lengths */
+ len = strlen(ti->str);
+ if (len > sn.label[lbl].len)
+ return 0; /* the label was not found */
+ if (len < sn.label[lbl].len)
+ continue;
+
+ /* We found the label */
+ found = 1;
+ senti = &ti->children;
+ break;
+ }
+
+ if (!found)
+ return 0; /* label not found */
+
+ /* otherwise, continue, sentinel has been updated */
+ }
+
+ /* At the end, ti points to the correct leaf */
+ if (!ti->leaf)
+ return 0;
+
+ TRACE_DEBUG(ANNOYING, "[acl_wl] %s matched exactly.", name);
+ *result = ti->flags;
+ return 0;
+}
diff --git a/extensions/app_acct/CMakeLists.txt b/extensions/app_acct/CMakeLists.txt
new file mode 100644
index 0000000..433ca5d
--- /dev/null
+++ b/extensions/app_acct/CMakeLists.txt
@@ -0,0 +1,38 @@
+# The app_acct extension
+PROJECT("Simple Accounting server" C)
+
+########################
+# Search for libpg (postgresql package)
+FIND_PACKAGE(PostgreSQL REQUIRED)
+INCLUDE_DIRECTORIES(${POSTGRESQL_INCLUDE_DIR})
+
+########################
+# Parser files
+BISON_FILE(acct_conf.y)
+FLEX_FILE(acct_conf.l)
+SET_SOURCE_FILES_PROPERTIES(lex.acct_conf.c acct_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( APP_ACCT_SRC
+ app_acct.h
+ app_acct.c
+ acct_db.c
+ acct_records.c
+)
+SET( APP_ACCT_SRC_GEN
+ lex.acct_conf.c
+ acct_conf.tab.c
+ acct_conf.tab.h
+)
+
+# Compile as a module
+FD_ADD_EXTENSION(app_acct ${APP_ACCT_SRC} ${APP_ACCT_SRC_GEN})
+TARGET_LINK_LIBRARIES(app_acct ${POSTGRESQL_LIBRARIES})
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS app_acct
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-accounting-server)
diff --git a/extensions/app_acct/acct_conf.l b/extensions/app_acct/acct_conf.l
new file mode 100644
index 0000000..c25de1a
--- /dev/null
+++ b/extensions/app_acct/acct_conf.l
@@ -0,0 +1,143 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Lex extension's configuration parser.
+ *
+ */
+
+%{
+#include "app_acct.h"
+#include "acct_conf.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+/* Quoted string. Multilines do not match. */
+qstring \"[^\"\n]*\"
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+ /* Recognize any integer */
+[-]?[[:digit:]]+ {
+ /* Convert this to an integer value */
+ int ret=0;
+ ret = sscanf(yytext, "%i", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+ /* Recognize quoted strings -- we do not support escaped \" in the string currently. */
+{qstring} {
+ /* Match a quoted string. Let's be very permissive. */
+ yylval->string = strdup(yytext+1);
+ if (!yylval->string) {
+ fd_log_debug("Unable to copy the string '%s': %s", yytext, strerror(errno));
+ TRACE_DEBUG(INFO, "strdup failed");
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+ yylval->string[strlen(yytext) - 2] = '\0';
+ return QSTRING;
+ }
+
+ /* Recognize the tokens */
+(?i:"ConnInfo") {
+ return CONNINFO;
+ }
+
+(?i:"Table") {
+ return TABLE;
+ }
+
+(?i:"Timestamp_field") {
+ return TSFIELD;
+ }
+
+(?i:"Server_name_field") {
+ return SRVNFIELD;
+ }
+
+(?i:"field") {
+ return FIELD;
+ }
+
+(?i:"required") {
+ return REQUIRED;
+ }
+
+(?i:"multi") {
+ return MULTI;
+ }
+
+
+
+ /* Valid single characters for yyparse */
+[=;{}] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]"*=>;\n]+ {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/app_acct/acct_conf.y b/extensions/app_acct/acct_conf.y
new file mode 100644
index 0000000..f79f1fa
--- /dev/null
+++ b/extensions/app_acct/acct_conf.y
@@ -0,0 +1,336 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2015, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ * See doc/app_acct.conf.sample for configuration file format
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "app_acct.h"
+#include "acct_conf.tab.h"
+
+#include <string.h>
+#include <errno.h>
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+/* The Lex parser prototype */
+int acct_conflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* the global configuration */
+struct acct_conf * acct_config = NULL;
+
+/* Initialize the blank configuration structure */
+int acct_conf_init(void)
+{
+ TRACE_ENTRY();
+
+ CHECK_MALLOC( acct_config = malloc(sizeof(struct acct_conf)) );
+ memset(acct_config, 0, sizeof(struct acct_conf) );
+ fd_list_init(&acct_config->avps, NULL);
+
+ return 0;
+}
+
+/* Validate and eventually display the content of the configuration file for debug */
+int acct_conf_check(char * conffile)
+{
+ CHECK_PARAMS(acct_config);
+
+ if ( ! acct_config->conninfo) {
+ fd_log_debug("[app_acct] ERROR: 'ConnInfo' is missing in file '%s'."
+ " You can specify 'ConnInfo=\"\";' to use default parameters.", conffile);
+ return EINVAL;
+ }
+ if ( ! acct_config->tablename) {
+ fd_log_debug("[app_acct] ERROR: 'Table' value is missing in file '%s'.", conffile);
+ return EINVAL;
+ }
+
+ if (!TRACE_BOOL(FULL))
+ return 0;
+
+ struct fd_list * li;
+
+ fd_log_debug("[app_acct] Configuration dump:");
+ fd_log_debug(" Database:");
+ fd_log_debug(" ConnInfo ...... : '%s'", acct_config->conninfo ?: "<null>");
+ fd_log_debug(" Table name .... : '%s'", acct_config->tablename ?: "<null>");
+ fd_log_debug(" Timestamp field : '%s'", acct_config->tsfield ?: "<null>");
+ fd_log_debug(" Server name fld : '%s'", acct_config->srvnfield ?: "<null>");
+ fd_log_debug(" AVPs that will be saved to the database:");
+ for (li = acct_config->avps.next; li != &acct_config->avps; li = li->next) {
+ struct acct_conf_avp * a = (struct acct_conf_avp *)li;
+ fd_log_debug(" %-*s AVP%s saved in ", 30, a->avpname, a->required ? " [required]":"" );
+ if (a->multi) {
+ fd_log_debug("fields '%s[1..%d]' ", a->field?:a->avpname, a->multi);
+ } else {
+ fd_log_debug("field '%s' ", a->field?:a->avpname);
+ }
+ fd_log_debug("as ::%s", diam2db_types_mapping[a->avptype]);
+ }
+ fd_log_debug("[app_acct] Complete.");
+ return 0;
+}
+
+void acct_conf_free(void)
+{
+ TRACE_ENTRY();
+
+ if (!acct_config)
+ return;
+
+ /* Destroy the list */
+ while (!FD_IS_LIST_EMPTY(&acct_config->avps)) {
+ struct acct_conf_avp * a = (struct acct_conf_avp *)(acct_config->avps.next);
+ fd_list_unlink(&a->chain);
+ free(a->avpname);
+ free(a->field);
+ free(a);
+ }
+
+ /* destroy other data */
+ free(acct_config->conninfo);
+ free(acct_config->tablename);
+ free(acct_config->tsfield);
+ free(acct_config->srvnfield);
+
+ /* Done */
+ free(acct_config);
+ acct_config = NULL;
+}
+
+/* Parse the configuration file */
+int acct_conf_parse(char * conffile)
+{
+ extern FILE * acct_confin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ acct_confin = fopen(conffile, "r");
+ if (acct_confin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(acct_confin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ LOG_E( "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ LOG_E("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ LOG_E("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ LOG_E("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+static struct acct_conf_avp avpdata;
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ char *string; /* The string is allocated by strdup in lex.*/
+ int integer; /* Store integer values */
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+/* Keywords */
+%token FIELD
+%token REQUIRED
+%token MULTI
+%token CONNINFO
+%token TABLE
+%token TSFIELD
+%token SRVNFIELD
+
+/* Tokens and types */
+/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */
+%token <string> QSTRING
+
+/* An integer value */
+%token <integer> INTEGER
+
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK for the parser (will be validated afterwards) */
+ | conffile avpline
+ | conffile conninfoline
+ | conffile tableline
+ | conffile tsfieldline
+ | conffile srvnfieldline
+ | conffile errors
+ {
+ yyerror(&yylloc, conffile, "An error occurred while parsing the configuration file.");
+ return EINVAL;
+ }
+ ;
+
+ /* Catch lexical and syntax errors */
+errors: LEX_ERROR
+ | error
+ ;
+
+ /* The tokens */
+avpline: {
+ memset(&avpdata, 0, sizeof(struct acct_conf_avp));
+ }
+ QSTRING avpcontents ';'
+ {
+ struct acct_conf_avp *new;
+ struct dict_object * dict;
+ struct dict_avp_data dictdata;
+
+ /* Validate the avp name first */
+ CHECK_FCT_DO( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS, $2, &dict, ENOENT),
+ { yyerror (&yylloc, conffile, "AVP definition not found in the dictionary. Was the appropriate dict_*.fdx extension loaded?"); YYERROR; } );
+ CHECK_FCT( fd_dict_getval( dict, &dictdata ));
+
+ /* Create a new entry */
+ CHECK_MALLOC_DO( new = malloc(sizeof(struct acct_conf_avp)),
+ { yyerror (&yylloc, conffile, "Out of memory"); YYERROR; } );
+
+ /* Retrieve all the data from avpcontents parsing (field, required, multi) */
+ memcpy(new, &avpdata, sizeof(struct acct_conf_avp));
+
+ /* Initialize the other data */
+ fd_list_init(&new->chain, NULL);
+ new->avpname = $2;
+ new->avpobj = dict;
+ new->avptype = dictdata.avp_basetype;
+
+ /* Add this new entry at the end of the list */
+ fd_list_insert_before( &acct_config->avps, &new->chain );
+ }
+ ;
+
+avpcontents: /* Empty content is fine */
+ | '=' '{' avpflagline '}'
+ ;
+
+avpflagline: /* Empty flags is also fine */
+ | avpflagline FIELD '=' QSTRING ';'
+ {
+ if (avpdata.field) {
+ yyerror (&yylloc, conffile, "Duplicate entry");
+ YYERROR;
+ }
+ avpdata.field = $4;
+ }
+ | avpflagline REQUIRED ';'
+ {
+ avpdata.required = 1;
+ }
+ | avpflagline MULTI '=' INTEGER ';'
+ {
+ avpdata.multi = (unsigned) $4;
+ }
+ ;
+
+conninfoline: CONNINFO '=' QSTRING ';'
+ {
+ if (acct_config->conninfo) {
+ yyerror (&yylloc, conffile, "Duplicate entry");
+ YYERROR;
+ }
+ acct_config->conninfo = $3;
+ }
+ ;
+
+tableline: TABLE '=' QSTRING ';'
+ {
+ if (acct_config->tablename) {
+ yyerror (&yylloc, conffile, "Duplicate entry");
+ YYERROR;
+ }
+ acct_config->tablename = $3;
+ }
+ ;
+
+tsfieldline: TSFIELD '=' QSTRING ';'
+ {
+ if (acct_config->tsfield) {
+ yyerror (&yylloc, conffile, "Duplicate entry");
+ YYERROR;
+ }
+ acct_config->tsfield = $3;
+ }
+ ;
+
+srvnfieldline: SRVNFIELD '=' QSTRING ';'
+ {
+ if (acct_config->srvnfield) {
+ yyerror (&yylloc, conffile, "Duplicate entry");
+ YYERROR;
+ }
+ acct_config->srvnfield = $3;
+ }
+ ;
diff --git a/extensions/app_acct/acct_db.c b/extensions/app_acct/acct_db.c
new file mode 100644
index 0000000..a444c94
--- /dev/null
+++ b/extensions/app_acct/acct_db.c
@@ -0,0 +1,341 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Database interface module */
+
+/* There is one connection to the db per thread.
+The connection is stored in the pthread_key_t variable */
+
+
+#include "app_acct.h"
+#include <libpq-fe.h>
+
+const char * diam2db_types_mapping[AVP_TYPE_MAX + 1] = {
+ "" /* AVP_TYPE_GROUPED */,
+ "bytea" /* AVP_TYPE_OCTETSTRING */,
+ "integer" /* AVP_TYPE_INTEGER32 */,
+ "bigint" /* AVP_TYPE_INTEGER64 */,
+ "integer" /* AVP_TYPE_UNSIGNED32 + cast */,
+ "bigint" /* AVP_TYPE_UNSIGNED64 + cast */,
+ "real" /* AVP_TYPE_FLOAT32 */,
+ "double precision" /* AVP_TYPE_FLOAT64 */
+};
+
+static const char * stmt = "acct_db_stmt";
+#ifndef TEST_DEBUG
+static
+#endif /* TEST_DEBUG */
+pthread_key_t connk;
+static char * sql = NULL; /* The buffer that will contain the SQL query */
+static int nbrecords = 0;
+
+
+/* Initialize the database context: connection to the DB, prepared statement to insert new records */
+int acct_db_init(void)
+{
+ struct acct_record_list emptyrecords;
+ struct fd_list * li;
+ size_t sql_allocd = 0; /* The malloc'd size of the buffer */
+ size_t sql_offset = 0; /* The actual data already written in this buffer */
+ int idx = 0;
+ PGresult * res;
+ PGconn *conn;
+ #define REALLOC_SIZE 1024 /* We extend the buffer by this amount */
+
+ TRACE_ENTRY();
+ CHECK_PARAMS( acct_config && acct_config->conninfo && acct_config->tablename );
+
+ CHECK_PARAMS_DO( PQisthreadsafe() == 1, {
+ fd_log_debug("You PostGreSQL installation is not thread-safe!");
+ return EINVAL;
+ } );
+
+ /* Use the information from acct_config to create the connection and prepare the query */
+ conn = PQconnectdb(acct_config->conninfo);
+
+ /* Check to see that the backend connection was successfully made */
+ if (PQstatus(conn) != CONNECTION_OK) {
+ fd_log_debug("Connection to database failed: %s", PQerrorMessage(conn));
+ acct_db_free();
+ return EINVAL;
+ }
+ if (PQprotocolVersion(conn) < 3) {
+ fd_log_debug("Database protocol version is too old, version 3 is required for prepared statements.");
+ acct_db_free();
+ return EINVAL;
+ }
+
+ TRACE_DEBUG(FULL, "Connection to database successful, server version %d.", PQserverVersion(conn));
+
+ /* Now, prepare the request object */
+
+ /* First, we build the list of AVP we will insert in the database */
+ CHECK_FCT( acct_rec_prepare(&emptyrecords) );
+
+ /* Now, prepare the text of the request */
+ CHECK_MALLOC(sql = malloc(REALLOC_SIZE));
+ sql_allocd = REALLOC_SIZE;
+
+ /* This macro hides the details of extending the buffer on each sprintf... */
+ #define ADD_EXTEND(args...) { \
+ size_t p; \
+ int loop = 0; \
+ do { \
+ p = snprintf(sql + sql_offset, sql_allocd - sql_offset, ##args); \
+ if (p >= sql_allocd - sql_offset) { \
+ /* Too short, extend the buffer and start again */ \
+ CHECK_MALLOC( sql = realloc(sql, sql_allocd + REALLOC_SIZE) ); \
+ sql_allocd += REALLOC_SIZE; \
+ loop++; \
+ ASSERT(loop < 100); /* detect infinite loops */ \
+ continue; \
+ } \
+ sql_offset += p; \
+ break; \
+ } while (1); \
+ }
+
+ /* This macro allows to add a value in the SQL buffer while escaping in properly */
+ #define ADD_ESCAPE(str) { \
+ char * __s = (char *)str; \
+ /* Check we have at least twice the size available +1 */ \
+ size_t p = strlen(__s); \
+ \
+ while (sql_allocd - sql_offset < 2 * p + 1) { \
+ /* Too short, extend the buffer */ \
+ CHECK_MALLOC( sql = realloc(sql, sql_allocd + REALLOC_SIZE) ); \
+ sql_allocd += REALLOC_SIZE; \
+ } \
+ \
+ /* Now add the escaped string */ \
+ p = PQescapeStringConn(conn, sql+sql_offset, __s, p, NULL); \
+ sql_offset += p; \
+ }
+
+ /* INSERT INTO table (tsfield, field1, field2, ...) VALUES (now, $1::bytea, $2::integer, ...) */
+ ADD_EXTEND("INSERT INTO %s (", acct_config->tablename);
+
+ if (acct_config->tsfield) {
+ ADD_EXTEND("\"");
+ ADD_ESCAPE(acct_config->tsfield);
+ ADD_EXTEND("\", ");
+ }
+
+ if (acct_config->srvnfield) {
+ ADD_EXTEND("\"");
+ ADD_ESCAPE(acct_config->srvnfield);
+ ADD_EXTEND("\", ");
+ }
+
+ for (li = emptyrecords.all.next; li != &emptyrecords.all; li = li->next) {
+ struct acct_record_item * i = (struct acct_record_item *)(li->o);
+ ADD_EXTEND("\"");
+ ADD_ESCAPE(i->param->field?:i->param->avpname);
+ if (i->index) {
+ ADD_EXTEND("%d", i->index);
+ }
+ if (li->next != &emptyrecords.all) {
+ ADD_EXTEND("\", ");
+ }
+ }
+
+ ADD_EXTEND("\") VALUES (");
+
+ if (acct_config->tsfield) {
+ ++idx;
+ ADD_EXTEND("$%d, ", idx);
+ }
+ if (acct_config->srvnfield) {
+ ADD_EXTEND("'");
+ ADD_ESCAPE(fd_g_config->cnf_diamid);
+ ADD_EXTEND("', ");
+ }
+
+ for (li = emptyrecords.all.next; li != &emptyrecords.all; li = li->next) {
+ struct acct_record_item * i = (struct acct_record_item *)(li->o);
+ ++idx;
+ ADD_EXTEND("$%d::%s", idx, diam2db_types_mapping[i->param->avptype]);
+
+ if (li->next != &emptyrecords.all) {
+ ADD_EXTEND(", ");
+ }
+ }
+
+ ADD_EXTEND(");");
+
+ TRACE_DEBUG(FULL, "Preparing the following SQL statement: '%s'", sql);
+ res = PQprepare(conn, stmt, sql, emptyrecords.nball, NULL);
+ if (PQresultStatus(res) != PGRES_COMMAND_OK) {
+ TRACE_DEBUG(INFO, "Preparing statement '%s' failed: %s",
+ sql, PQerrorMessage(conn));
+ PQclear(res);
+ return EINVAL;
+ }
+ PQclear(res);
+ nbrecords = emptyrecords.nball;
+
+ acct_rec_empty(&emptyrecords);
+
+ CHECK_POSIX( pthread_key_create(&connk, (void (*)(void*))PQfinish) );
+ CHECK_POSIX( pthread_setspecific(connk, conn) );
+
+ /* Ok, ready */
+ return 0;
+}
+
+/* Terminate the connection to the DB */
+void acct_db_free(void)
+{
+ CHECK_POSIX_DO(pthread_key_delete(connk) , );
+ free(sql);
+}
+
+/* When a new message has been received, insert the content of the parsed mapping into the DB (using prepared statement) */
+int acct_db_insert(struct acct_record_list * records)
+{
+ char **val;
+ int *val_len;
+ int *val_isbin;
+ int idx = 0;
+ int size = 0;
+ PGresult *res;
+ struct fd_list *li;
+ PGconn *conn;
+ int new = 0;
+
+ TRACE_ENTRY("%p", records);
+ CHECK_PARAMS( records );
+
+ conn = pthread_getspecific(connk);
+ if (!conn) {
+ conn = PQconnectdb(acct_config->conninfo);
+ CHECK_POSIX( pthread_setspecific(connk, conn) );
+
+ new = 1;
+ }
+
+ /* First, check if the connection with the DB has not staled, and eventually try to fix it */
+ if (PQstatus(conn) != CONNECTION_OK) {
+ /* Attempt a reset */
+ PQreset(conn);
+ if (PQstatus(conn) != CONNECTION_OK) {
+ TRACE_DEBUG(INFO, "Lost connection to the database server, and attempt to reestablish it failed");
+ TODO("Terminate the freeDiameter instance completely?");
+ return ENOTCONN;
+ }
+ }
+
+ if (new) {
+ /* Create the prepared statement for this ocnnection, it is not shared */
+ res = PQprepare(conn, stmt, sql, nbrecords, NULL);
+ if (PQresultStatus(res) != PGRES_COMMAND_OK) {
+ TRACE_DEBUG(INFO, "Preparing statement '%s' failed: %s",
+ sql, PQerrorMessage(conn));
+ PQclear(res);
+ return EINVAL;
+ }
+ PQclear(res);
+ }
+
+ size = acct_config->tsfield ? records->nball + 1 : records->nball;
+
+ /* Alloc the arrays of parameters */
+ CHECK_MALLOC( val = calloc(size, sizeof(const char *)) );
+ CHECK_MALLOC( val_len = calloc(size, sizeof(const int)) );
+ CHECK_MALLOC( val_isbin = calloc(size, sizeof(const int)) );
+
+ if (acct_config->tsfield) {
+ val[idx] = "now";
+ val_len[idx] = 3;
+ val_isbin[idx] = 0;
+ idx++;
+ }
+
+ /* Now write all the map'd records in these arrays */
+ for (li = records->all.next; li != &records->all; li = li->next) {
+ struct acct_record_item * r = (struct acct_record_item *)(li->o);
+ if (r->value) {
+ val_isbin[idx] = 1; /* We always pass binary parameters */
+ switch (r->param->avptype) {
+ case AVP_TYPE_OCTETSTRING:
+ val[idx] = (void *)(r->value->os.data);
+ val_len[idx] = r->value->os.len;
+ break;
+
+ case AVP_TYPE_INTEGER32:
+ case AVP_TYPE_UNSIGNED32:
+ case AVP_TYPE_FLOAT32:
+ r->scalar.v32 = htonl(r->value->u32);
+ val[idx] = &r->scalar.c;
+ val_len[idx] = sizeof(uint32_t);
+ break;
+
+ case AVP_TYPE_INTEGER64:
+ case AVP_TYPE_UNSIGNED64:
+ case AVP_TYPE_FLOAT64:
+ r->scalar.v64 = htonll(r->value->u64);
+ val[idx] = &r->scalar.c;
+ val_len[idx] = sizeof(uint64_t);
+ break;
+
+ default:
+ ASSERT(0); /* detect bugs */
+ }
+ }
+
+ idx++;
+ }
+
+ /* OK, now execute the SQL statement */
+ res = PQexecPrepared(conn, stmt, size, (const char * const *)val, val_len, val_isbin, 1 /* We actually don't care here */);
+
+ /* Done with the parameters */
+ free(val);
+ free(val_len);
+ free(val_isbin);
+
+ /* Now check the result code */
+ if (PQresultStatus(res) != PGRES_COMMAND_OK) {
+ TRACE_DEBUG(INFO, "An error occurred while INSERTing in the database: %s", PQerrorMessage(conn));
+ PQclear(res);
+ return EINVAL; /* It was probably a mistake in configuration file... */
+ }
+ PQclear(res);
+
+ /* Ok, we are done */
+ return 0;
+}
+
+
diff --git a/extensions/app_acct/acct_records.c b/extensions/app_acct/acct_records.c
new file mode 100644
index 0000000..4f1b340
--- /dev/null
+++ b/extensions/app_acct/acct_records.c
@@ -0,0 +1,161 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Functions to create a list of AVPs according to the configuration file */
+
+#include "app_acct.h"
+
+/* Prepare a list of acct_record entries from the configuration, without mapping any value at this time */
+int acct_rec_prepare(struct acct_record_list * records)
+{
+ struct fd_list * li;
+ TRACE_ENTRY("%p", records);
+ CHECK_PARAMS( records && acct_config );
+
+ /* Prepare the records structure */
+ memset(records, 0, sizeof(struct acct_record_list));
+ fd_list_init(&records->all, records);
+ fd_list_init(&records->unmaped, records);
+
+ /* for each entry in the configuration */
+ for (li = acct_config->avps.next; li != &acct_config->avps; li = li->next) {
+ struct acct_conf_avp * a = (struct acct_conf_avp *)li;
+ struct acct_record_item * new;
+ int i = a->multi ? 1 : 0;
+ /* Create as many records as the 'multi' parameter requires */
+ do {
+ CHECK_MALLOC( new = malloc(sizeof(struct acct_record_item)) );
+ memset(new, 0, sizeof(struct acct_record_item));
+ fd_list_init(&new->chain, new);
+ fd_list_init(&new->unmapd, new);
+ new->param = a;
+ new->index = i;
+ fd_list_insert_before(&records->all, &new->chain);
+ fd_list_insert_before(&records->unmaped, &new->unmapd);
+ records->nball++;
+ records->nbunmap++;
+ i++;
+ } while (i <= a->multi);
+ }
+
+ return 0;
+}
+
+/* Find the AVPs from configuration inside a received message */
+int acct_rec_map(struct acct_record_list * records, struct msg * msg)
+{
+ struct avp * avp;
+
+ TRACE_ENTRY("%p %p", records, msg);
+
+ /* For each AVP in the message, search if we have a corresponding unmap'd record */
+ CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) );
+ while (avp) {
+ struct fd_list * li;
+ struct dict_object * model;
+
+ CHECK_FCT( fd_msg_model(avp, &model) );
+ if (model != NULL) { /* we ignore the AVPs we don't recognize */
+
+ /* Search this model in the list */
+ for (li = records->unmaped.next; li != &records->unmaped; li = li->next) {
+ struct acct_record_item * r = (struct acct_record_item *)(li->o);
+ if (r->param->avpobj == model) {
+ /* It matches: save the AVP value and unlink this record from the unmap'd list */
+ struct avp_hdr * h;
+ CHECK_FCT( fd_msg_avp_hdr( avp, &h ) );
+ r->value = h->avp_value;
+ fd_list_unlink(&r->unmapd);
+ records->nbunmap -= 1;
+ break;
+ }
+ }
+
+ /* Continue only while there are some AVPs to map */
+ if (FD_IS_LIST_EMPTY(&records->unmaped))
+ break;
+ }
+
+ /* Go to next AVP in the message */
+ CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) );
+ }
+
+ /* Done */
+ return 0;
+}
+
+/* Check that a mapped list is not empty and no required AVP is missing. Free the record list in case of error */
+int acct_rec_validate(struct acct_record_list * records)
+{
+ struct fd_list * li;
+ TRACE_ENTRY("%p", records);
+ CHECK_PARAMS( records );
+
+ /* Check at least one AVP was mapped */
+ if (records->nball == records->nbunmap) {
+ fd_log_debug("The received ACR does not contain any AVP from the configuration file."
+ " This is an invalid situation. Please fix your configuration file."
+ " One way to ensure this does not happen is to include Session-Id in the database.");
+ acct_rec_empty(records);
+ return EINVAL;
+ }
+
+ /* Now, check there is no required AVP unmap'd */
+ for (li = records->unmaped.next; li != &records->unmaped; li = li->next) {
+ struct acct_record_item * r = (struct acct_record_item *)(li->o);
+ if (r->param->required && (r->index <= 1)) {
+ fd_log_debug("The received ACR does not contain the required AVP '%s'.", r->param->avpname);
+ acct_rec_empty(records);
+ return EINVAL;
+ }
+ }
+
+ /* The record list is OK */
+ return 0;
+}
+
+/* Free all the items in an acct_record_list returned by acct_rec_prepare */
+void acct_rec_empty(struct acct_record_list * records)
+{
+ TRACE_ENTRY("%p", records);
+ CHECK_PARAMS_DO( records, return );
+
+ while (!FD_IS_LIST_EMPTY(&records->all)) {
+ struct acct_record_item * r = (struct acct_record_item *)(records->all.next);
+ fd_list_unlink( &r->chain );
+ fd_list_unlink( &r->unmapd );
+ free(r);
+ }
+}
diff --git a/extensions/app_acct/app_acct.c b/extensions/app_acct/app_acct.c
new file mode 100644
index 0000000..9465b75
--- /dev/null
+++ b/extensions/app_acct/app_acct.c
@@ -0,0 +1,155 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+/* The simple Accounting server for freeDiameter */
+
+#include "app_acct.h"
+
+/* Mandatory AVPs for the Accounting-Answer (any value in adding all the other AVPs?) */
+static struct {
+ struct dict_object * Accounting_Record_Number;
+ struct dict_object * Accounting_Record_Type;
+} acct_dict;
+
+
+/* Callback for incoming Base Accounting Accounting-Request messages */
+static int acct_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ struct msg * m;
+ struct avp * a = NULL;
+ struct avp_hdr * art=NULL, *arn=NULL; /* We keep a pointer on the Accounting-Record-{Type, Number} AVPs from the query */
+ struct acct_record_list rl;
+
+ TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+ if (msg == NULL)
+ return EINVAL;
+
+ m = *msg;
+
+ /* Prepare a new record list */
+ CHECK_FCT( acct_rec_prepare( &rl ) );
+
+ /* Maps the AVPs from the query with this record list */
+ CHECK_FCT( acct_rec_map( &rl, m ) );
+
+ /* Check that at least one AVP was mapped */
+ CHECK_FCT( acct_rec_validate( &rl ) );
+
+ /* Now, save these mapped AVPs in the database */
+ CHECK_FCT( acct_db_insert( &rl ) );
+
+ acct_rec_empty( &rl );
+
+ /* OK, we can send a positive reply now */
+
+ /* Get Accounting-Record-{Number,Type} values */
+ CHECK_FCT( fd_msg_search_avp ( m, acct_dict.Accounting_Record_Type, &a) );
+ if (a) {
+ CHECK_FCT( fd_msg_avp_hdr( a, &art ) );
+ }
+ CHECK_FCT( fd_msg_search_avp ( m, acct_dict.Accounting_Record_Number, &a) );
+ if (a) {
+ CHECK_FCT( fd_msg_avp_hdr( a, &arn ) );
+ }
+
+ /* Create the answer message */
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ m = *msg;
+
+ /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */
+ CHECK_FCT( fd_msg_rescode_set( m, "DIAMETER_SUCCESS", NULL, NULL, 1 ) );
+
+ /* Add the mandatory AVPs in the ACA */
+ if (art) {
+ CHECK_FCT( fd_msg_avp_new ( acct_dict.Accounting_Record_Type, 0, &a ) );
+ CHECK_FCT( fd_msg_avp_setvalue( a, art->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( m, MSG_BRW_LAST_CHILD, a ) );
+ }
+ if (arn) {
+ CHECK_FCT( fd_msg_avp_new ( acct_dict.Accounting_Record_Number, 0, &a ) );
+ CHECK_FCT( fd_msg_avp_setvalue( a, arn->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( m, MSG_BRW_LAST_CHILD, a ) );
+ }
+
+ /* Send the answer */
+ *act = DISP_ACT_SEND;
+ return 0;
+}
+
+
+/* entry point */
+static int acct_entry(char * conffile)
+{
+ struct disp_when data;
+
+ TRACE_ENTRY("%p", conffile);
+
+#ifndef TEST_DEBUG /* We do this differently in the test scenario */
+ /* Initialize the configuration and parse the file */
+ CHECK_FCT( acct_conf_init() );
+ CHECK_FCT( acct_conf_parse(conffile) );
+ CHECK_FCT( acct_conf_check(conffile) );
+#endif /* TEST_DEBUG */
+
+ /* Now initialize the database module */
+ CHECK_FCT( acct_db_init() );
+
+ /* Search the AVPs we will need in this file */
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Number", &acct_dict.Accounting_Record_Number, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Type", &acct_dict.Accounting_Record_Type, ENOENT) );
+
+ /* Register the dispatch callbacks */
+ memset(&data, 0, sizeof(data));
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Base Accounting", &data.app, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Accounting-Request", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( acct_cb, DISP_HOW_CC, &data, NULL, NULL ) );
+
+ /* Advertise the support for the Diameter Base Accounting application in the peer */
+ CHECK_FCT( fd_disp_app_support ( data.app, NULL, 0, 1 ) );
+
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ /* Close the db connection */
+ acct_db_free();
+
+ /* Destroy the configuration */
+ acct_conf_free();
+}
+
+EXTENSION_ENTRY("app_acct", acct_entry);
diff --git a/extensions/app_acct/app_acct.h b/extensions/app_acct/app_acct.h
new file mode 100644
index 0000000..a98a335
--- /dev/null
+++ b/extensions/app_acct/app_acct.h
@@ -0,0 +1,121 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Header file for the app_acct extension.
+ *
+ * This extension is a simple Diameter Accounting server.
+ *
+ * It receives the Diameter Accounting-Request message, and sends its content in a
+ * "buffer" postgreSQL database (see configuration sample file app_acct.conf.sample).
+ *
+ * The intent is that another application will then pick the records from this "buffer" database
+ * and process it accordingly to the requirements of the end application.
+ */
+
+#include <freeDiameter/extension.h>
+
+/* The structure corresponding to an AVP entry in the configuration file */
+struct acct_conf_avp {
+ /* Chain */
+ struct fd_list chain; /* link in the global list */
+
+ /* Raw information from the configuration file */
+ char *avpname; /* the name of the AVP, as appear in the configuration file */
+ char *field; /* the field name in the database, or NULL if it is the same as avpname */
+ int required; /* set to true if this AVP has to be in the message */
+ unsigned multi; /* the number of occurrences of this AVP we convert, or 0 if it was not specified */
+
+ /* Parsed information */
+ struct dict_object *avpobj; /* the dictionary object corresponding to this AVP */
+ enum dict_avp_basetype avptype; /* this info is extracted from avpobj. GROUPED avps are not allowed yet */
+};
+
+/* This is described only inside acct_db.c */
+struct acct_db;
+
+/* The complete configuration */
+struct acct_conf {
+ /* AVPs */
+ struct fd_list avps; /* the list of acct_conf_avp entries */
+
+ /* Raw information */
+ char *conninfo; /* the connection string to the database, that is passed as is to the database library */
+ char *tablename; /* the name of the table we are working with */
+ char *tsfield; /* the name of the timestamp field, or NULL if not required */
+ char *srvnfield; /* the name of the server name field, or NULL if not required */
+};
+
+/* A successfully parsed Accounting-Request produces a list of these: */
+struct acct_record_item {
+ struct fd_list chain; /* link with all others */
+ struct fd_list unmapd;/* link with only unmap'd records */
+ struct acct_conf_avp *param; /* the AVP entry this refers to. */
+ unsigned index; /* in case of multi */
+ union avp_value *value; /* If the AVP was found in the message, this points to its value. Otherwise, NULL */
+ union {
+ uint32_t v32 /* Storage area for network byte-order copy of the AVP value */;
+ uint64_t v64;
+ char c; /* pointer that is passed to the database */
+ } scalar;/* for scalar AVP (all types except OCTETSTRING) we copy in this area the value in network byte order */
+};
+
+/* The sentinel for a list of acct_record_items */
+struct acct_record_list {
+ struct fd_list all; /* The list of records */
+ int nball; /* The number of records in all */
+ struct fd_list unmaped;/* Only the records without a value */
+ int nbunmap;/* The number of unmap'd records */
+};
+
+/* Mapping of the data types between Diameter AVP and PQ types: */
+extern const char * diam2db_types_mapping[];
+
+/* In acct_conf.y */
+extern struct acct_conf * acct_config; /* the global configuration */
+int acct_conf_init(void);
+int acct_conf_parse(char * conffile);
+int acct_conf_check(char * conffile);
+void acct_conf_free(void);
+
+/* In acct_db.c */
+int acct_db_init(void);
+int acct_db_insert(struct acct_record_list * records);
+void acct_db_free(void);
+
+/* In acct_records.c */
+int acct_rec_prepare(struct acct_record_list * records);
+int acct_rec_map(struct acct_record_list * records, struct msg * msg);
+int acct_rec_validate(struct acct_record_list * records);
+void acct_rec_empty(struct acct_record_list * records);
diff --git a/extensions/app_diameap/CMakeLists.txt b/extensions/app_diameap/CMakeLists.txt
new file mode 100644
index 0000000..f463022
--- /dev/null
+++ b/extensions/app_diameap/CMakeLists.txt
@@ -0,0 +1,56 @@
+# The Diameter EAP Application extension
+PROJECT("Diameter EAP Application extension" C)
+
+# Find MySQL
+FIND_PACKAGE(MySQL REQUIRED)
+FIND_PACKAGE(Gcrypt 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.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 ${GCRYPT_LIBRARY} ${GNUTLS_LIBRARIES} ${MySQL_LIBRARY} )
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS app_diameap
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-eap-server)
diff --git a/extensions/app_diameap/LICENSE b/extensions/app_diameap/LICENSE
new file mode 100644
index 0000000..cfe48d2
--- /dev/null
+++ b/extensions/app_diameap/LICENSE
@@ -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.
+
diff --git a/extensions/app_diameap/README b/extensions/app_diameap/README
new file mode 100644
index 0000000..fad85bd
--- /dev/null
+++ b/extensions/app_diameap/README
@@ -0,0 +1,119 @@
+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-Create a new MySQL database and add tables using the sql script 'diameap.sql'.
+
+3- 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.
+
+4- Enable DiamEAP by enabling BUILD_APP_DIAMEAP option with CMake:
+
+cmake -DBUILD_APP_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/eap_md5.emp":"";
+Load_plugin = "EAP TLS":13:0:"extensions/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
diff --git a/extensions/app_diameap/diameap.c b/extensions/app_diameap/diameap.c
new file mode 100644
index 0000000..ac399cb
--- /dev/null
+++ b/extensions/app_diameap/diameap.c
@@ -0,0 +1,87 @@
+/*****************************************************************************************************
+ * 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"
+
+
+
+/* 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));
+
+ LOG_D("%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;
+}
+
+/* Define the entry point */
+EXTENSION_ENTRY("DiamEAP", diameap_main, "dict_eap")
+;
diff --git a/extensions/app_diameap/diameap.h b/extensions/app_diameap/diameap.h
new file mode 100644
index 0000000..b55b280
--- /dev/null
+++ b/extensions/app_diameap/diameap.h
@@ -0,0 +1,80 @@
+/*****************************************************************************************************
+ * 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;
+
+/* Initialize the configuration of DiamEAP*/
+int diameap_init(char * conffile);
+
+/* parser */
+int diameapparse(struct diameap_conf * config);
+
+
+#endif /* DIAMEAP_H_ */
diff --git a/extensions/app_diameap/diameap.l b/extensions/app_diameap/diameap.l
new file mode 100644
index 0000000..1dcb470
--- /dev/null
+++ b/extensions/app_diameap/diameap.l
@@ -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.
+ *****************************************************************************************************/
+
+
+
+/*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; \
+ }
+
+#define YY_NO_INPUT
+%}
+
+
+
+%option noyywrap
+%option yylineno
+%option bison-bridge
+%option bison-locations
+%option nounput
+
+%%
+ /* 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;
+ }
+
+(?i:"Check_user_identity") {
+ return CHECK_USER_IDENTITY;
+ }
+
+"="|";"|":"|"," {
+ 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 */
+
+
diff --git a/extensions/app_diameap/diameap.sql b/extensions/app_diameap/diameap.sql
new file mode 100644
index 0000000..3d0a362
--- /dev/null
+++ b/extensions/app_diameap/diameap.sql
@@ -0,0 +1,82 @@
+#########################################################################
+# diameap.sql #
+# DiamEAP extension #
+# Users Information Database schema #
+# #
+# #
+# #
+# MySQL command to load the script: #
+# mysql> mysql -u username -p password diameap_ui < diameap.sql #
+# #
+#########################################################################
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `authe`
+--
+
+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`)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `authz`
+--
+
+CREATE TABLE IF NOT EXISTS `authz` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `grp` int(11) NOT NULL,
+ `attribute` set('NAS-IPv6-Address','NAS-Identifier','NAS-IP-Address','NAS-Port','NAS-Port-Id','NAS-Port-Type','Called-Station-Id','Calling-Station-Id','Connect-Info','Originating-Line-Info','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`)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `grp`
+--
+
+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`)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `users`
+--
+
+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`)
+);
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `user_grp`
+--
+
+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`)
+);
diff --git a/extensions/app_diameap/diameap.y b/extensions/app_diameap/diameap.y
new file mode 100644
index 0000000..543d404
--- /dev/null
+++ b/extensions/app_diameap/diameap.y
@@ -0,0 +1,194 @@
+/*****************************************************************************************************
+ * 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
+%token CHECK_USER_IDENTITY
+
+%%
+
+confparams : /* empty */
+ | confparams EAPmethod
+ | confparams Authorize
+ | confparams DiamEAP_MySQL
+ | confparams MAX_Invalid_EAP_Packet
+ | confparams Multi_Round_Timeout
+ | confparams Check_User_Identity
+ | 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", $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_CONF_PATH) + 2 ),
+ { yyerror (&yylloc, config, "Not enough memory"); YYERROR; } );
+ sprintf(cfile, DEFAULT_CONF_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;
+ };
+
+Check_User_Identity: CHECK_USER_IDENTITY '=' NUM ';'
+ {
+ if((int)$3){
+ check_user_identity = TRUE;
+ }else{
+ check_user_identity = FALSE;
+ }
+ };
+
+
+%%
+
+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);
+}
diff --git a/extensions/app_diameap/diameap_common.h b/extensions/app_diameap/diameap_common.h
new file mode 100644
index 0000000..82822c7
--- /dev/null
+++ b/extensions/app_diameap/diameap_common.h
@@ -0,0 +1,127 @@
+/*****************************************************************************************************
+ * 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_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_ */
diff --git a/extensions/app_diameap/diameap_defs.h b/extensions/app_diameap/diameap_defs.h
new file mode 100644
index 0000000..c095e86
--- /dev/null
+++ b/extensions/app_diameap/diameap_defs.h
@@ -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_*/
diff --git a/extensions/app_diameap/diameap_eap.c b/extensions/app_diameap/diameap_eap.c
new file mode 100644
index 0000000..72885ea
--- /dev/null
+++ b/extensions/app_diameap/diameap_eap.c
@@ -0,0 +1,604 @@
+/*****************************************************************************************************
+ * 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"
+
+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=*id+1;
+ }
+}
+
+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;
+ if (eap_sm == NULL)
+ {
+ return EINVAL;
+ }
+
+ eap_sm->selectedMethod = NULL;
+
+ 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=NULL;
+ }
+ 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("%d",type);
+ if (type == TYPE_IDENTITY)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+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->aaaEapMSKLength = 0;
+ eap_i->aaaEapEMSKLength = 0;
+ if (eap_sm->selectedMethod->eap_method_getKey)
+ {
+ if ((*eap_sm->selectedMethod->eap_method_getKey)(eap_sm,
+ &eap_i->aaaEapMSKData, &eap_i->aaaEapMSKLength,
+ &eap_i->aaaEapEMSKData, &eap_i->aaaEapEMSKLength))
+ {
+ TRACE_DEBUG(INFO,"%s[EAP Protocol] [%s plugin] Generating EAP Master Key failed.",DIAMEAP_EXTENSION,eap_sm->selectedMethod->methodname)
+ eap_i->aaaEapMSKLength = 0;
+ eap_i->aaaEapEMSKLength = 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] [%s plugin] 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->aaaEapMSKData != 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;
+
+ case EAP_IDLE:
+ break;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/extensions/app_diameap/diameap_eap.h b/extensions/app_diameap/diameap_eap.h
new file mode 100644
index 0000000..8fb6617
--- /dev/null
+++ b/extensions/app_diameap/diameap_eap.h
@@ -0,0 +1,73 @@
+/*****************************************************************************************************
+ * 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 *aaaEapMSKData;
+ int aaaEapMSKLength;
+ u8 *aaaEapEMSKData;
+ int aaaEapEMSKLength;
+ boolean aaaEapKeyAvailable;
+ int aaaMethodTimeout;
+
+};
+
+int diameap_eap_statemachine(struct eap_state_machine * sm, struct diameap_eap_interface * eap_i, boolean * error);
+
+
+#endif /* EAP_H_ */
diff --git a/extensions/app_diameap/diameap_eappacket.c b/extensions/app_diameap/diameap_eappacket.c
new file mode 100644
index 0000000..a696161
--- /dev/null
+++ b/extensions/app_diameap/diameap_eappacket.c
@@ -0,0 +1,310 @@
+/*****************************************************************************************************
+ * 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("%d",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)
+ {
+ CHECK_MALLOC( *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("%d %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-------------");
+ 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");
+ break;
+ case 2:
+ fd_log_debug("Response");
+ break;
+ case 3:
+ fd_log_debug("Success");
+ break;
+ case 4:
+ fd_log_debug("Failure");
+ break;
+ default:
+ fd_log_debug("Error (EAP Code value [%d] not allowed)",code);
+ break;
+ }
+ u8 id;
+ CHECK_FCT_DO(diameap_eap_get_identifier(eappacket,&id),return);
+ fd_log_debug("\t -Identifier : %x ", id);
+ u16 length;
+ CHECK_FCT_DO(diameap_eap_get_length(eappacket,&length),return);
+ fd_log_debug("\t -Length : %d ", (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 ", type);
+ }
+ if (eappacket->length > 5)
+ {
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "\t -Data : ");
+ for (i = 5; i < eappacket->length && i < 30; i++)
+ {
+ snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%02x ", G8(eappacket->data + i));
+ }
+ if(i+1<eappacket->length)
+ snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "[...] (len=%d)",(unsigned int) length);
+ fd_log_debug("%s", buf);
+ }
+ fd_log_debug("-------------End Dump EAP Packet-------------");
+}
+
+int diameap_eap_new(eap_code code, u8 id, eap_type type, u8 * data,
+ u16 dataLength, struct eap_packet *eappacket)
+{
+
+ TRACE_ENTRY("%d %hhu %d %p %hu %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;
+}
diff --git a/extensions/app_diameap/diameap_eappacket.h b/extensions/app_diameap/diameap_eappacket.h
new file mode 100644
index 0000000..1f0c069
--- /dev/null
+++ b/extensions/app_diameap/diameap_eappacket.h
@@ -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_ */
diff --git a/extensions/app_diameap/diameap_init.c b/extensions/app_diameap/diameap_init.c
new file mode 100644
index 0000000..e3b8cc9
--- /dev/null
+++ b/extensions/app_diameap/diameap_init.c
@@ -0,0 +1,424 @@
+/*****************************************************************************************************
+ * 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;
+
+
+
+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;
+ check_user_identity = TRUE;
+
+ 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);
+ const my_bool 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;
+}
+
+static void diameap_conf_dump(void)
+{
+
+ if (!TRACE_BOOL(INFO))
+ return;
+
+ fd_log_debug("-------- DiamEAP extension : Configuration parameters (Dump) -------------");
+ fd_log_debug("\t-Configuration file.....: %s", diameap_config->conffile);
+ fd_log_debug("\t-EAP Application Id.....: %u",
+ diameap_config->application_id);
+ fd_log_debug("\t-EAP Application Command: %u",
+ diameap_config->command_code);
+ fd_log_debug("\t-EAP Application Vendor.: %u", diameap_config->vendor_id);
+ fd_log_debug("\t-Max invalid EAP packets: %u", diameap_config->max_invalid_eap_packet);
+ fd_log_debug("\t-Multi-Round Timeout....: %u", diameap_config->multi_round_time_out);
+ if (diameap_config->db.user)
+ {
+ fd_log_debug("\t-MySQL Database Params..:");
+ fd_log_debug("\t\tUser .......:%s", diameap_config->db.user);
+ fd_log_debug("\t\tServer .....:%s", diameap_config->db.server);
+ fd_log_debug("\t\tDatabase....:%s", diameap_config->db.database);
+ }
+
+ fd_log_debug("\t-EAP Method Plugins.....: ");
+ diameap_plugin_dump();
+
+ fd_log_debug("-------- DiamEAP extension : Configuration parameters (End) ---------------");
+}
+
+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;
+}
diff --git a/extensions/app_diameap/diameap_mysql.c b/extensions/app_diameap/diameap_mysql.c
new file mode 100644
index 0000000..b7a09c5
--- /dev/null
+++ b/extensions/app_diameap/diameap_mysql.c
@@ -0,0 +1,234 @@
+/*****************************************************************************************************
+ * 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"
+
+static pthread_mutex_t db_cs_mutex =
+PTHREAD_MUTEX_INITIALIZER;
+
+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);
+
+ 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));
+ 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]);
+ CHECK_MALLOC(user->userid=malloc(strlen(row[1])+1));
+ memcpy(user->userid,row[1],strlen(row[1])+1);
+ user->useridLength = strlen(row[1]);
+ CHECK_MALLOC(user->password=malloc(strlen(row[2])+1));
+ memcpy(user->password, row[2],strlen(row[2])+1);
+ 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);
+
+ 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));
+ 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);
+
+ 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));
+ 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);
+}
diff --git a/extensions/app_diameap/diameap_mysql.h b/extensions/app_diameap/diameap_mysql.h
new file mode 100644
index 0000000..c217dc6
--- /dev/null
+++ b/extensions/app_diameap/diameap_mysql.h
@@ -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_MYSQL_H_
+#define DIAMEAP_MYSQL_H_
+
+#include "libdiameap.h"
+#include <mysql.h>
+
+/* MySQL Database connection */
+MYSQL *db_conn;
+
+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_ */
diff --git a/extensions/app_diameap/diameap_plugins.c b/extensions/app_diameap/diameap_plugins.c
new file mode 100644
index 0000000..836c686
--- /dev/null
+++ b/extensions/app_diameap/diameap_plugins.c
@@ -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 %d %d %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", plugin->methodname,
+ plugin->methodtype,plugin->vendor, plugin->handler ? "" : "not ");
+ }
+}
+
+int diameap_plugin_get(u32 vendor, eap_type type, struct plugin ** getplugin)
+{
+ TRACE_ENTRY("%d %d %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: %s.",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)(®isterplugin) != 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*,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("%d %d",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;
+}
diff --git a/extensions/app_diameap/diameap_plugins.h b/extensions/app_diameap/diameap_plugins.h
new file mode 100644
index 0000000..9a12c39
--- /dev/null
+++ b/extensions/app_diameap/diameap_plugins.h
@@ -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_ */
diff --git a/extensions/app_diameap/diameap_server.c b/extensions/app_diameap/diameap_server.c
new file mode 100644
index 0000000..b93f6bb
--- /dev/null
+++ b/extensions/app_diameap/diameap_server.c
@@ -0,0 +1,3419 @@
+/*****************************************************************************************************
+ * 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"
+
+/* 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;
+
+
+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 } };
+
+
+
+void diameap_cli_sess_cleanup(struct sess_state * diameap_sess_data, os0_t sid, void * opaque)
+{
+
+ 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 sess_state * 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+1));
+ U8COPY(diameap_sm->eap_sm.user.userid,0,diameap_sm->eap_sm.user.useridLength+1,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+1));
+ U8COPY(diameap_sm->eap_sm.user.password,0,diameap_sm->eap_sm.user.passwordLength+1, 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->aaaEapMSKData = NULL;
+ eap_i->aaaEapEMSKData = NULL;
+ eap_i->aaaEapKeyAvailable = FALSE;
+ eap_i->aaaMethodTimeout = 0;
+
+ 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)
+
+ 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;*/
+ }
+
+ if((eap_sm->respMethod == TYPE_IDENTITY) && (length < 6)){
+ TRACE_DEBUG(INFO,"%sUser Identity missing",DIAMEAP_EXTENSION);
+ return 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_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 = 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_sess_data_new(
+ struct sess_state *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+1));
+ U8COPY(diameap_sess_data->user.userid,0,diameap_sess_data->user.useridLength+1,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+1));
+ U8COPY(diameap_sess_data->user.password,0,diameap_sess_data->user.passwordLength+1,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 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)
+{
+ if(avp_attrib){
+ free(avp_attrib);
+ avp_attrib = NULL;
+ }
+}
+
+static void free_ans_attrib(struct avp_attribute * ans_attrib)
+{
+ if(ans_attrib){
+ if (ans_attrib->tofree == 1)
+ {
+ if(ans_attrib->value.os.data){
+ free(ans_attrib->value.os.data);
+ ans_attrib->value.os.data = NULL;
+ }
+ }
+ free(ans_attrib);
+ ans_attrib = 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 void diameap_free(struct diameap_state_machine * diameap_sm)
+{
+
+ if (diameap_sm != NULL)
+ {
+ 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), );
+
+ free(diameap_sm);
+ diameap_sm = NULL;
+ }
+
+}
+
+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 %d %p", avp_attributes, attribute, avp_attrib, unlink, 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 %d %p", auth_attributes, attribute, auth_attrib, unlink, 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 %d %p", ans_attributes, attribute, ans_attrib, unlink, 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_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("%d %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 %d",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 %d",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((char *)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, (char *)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((char *)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;
+ }
+ }
+ return FALSE;
+}
+
+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 %d %p",A,tofree,datatype,rval);
+ if (datatype == AVP_TYPE_OCTETSTRING)
+ {
+ CHECK_MALLOC(rval->os.data=malloc(A->os.len));
+ memcpy(rval->os.data,A->os.data,A->os.len);
+ 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 %d %p",B,tofree,datatype,rval);
+ if (datatype == AVP_TYPE_OCTETSTRING)
+ {
+ CHECK_MALLOC(rval->os.data=malloc(strlen(B)));
+ memcpy(rval->os.data,B,strlen(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_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->aaaEapMSKData;
+ avp_val.os.len = eap_i->aaaEapMSKLength;
+ 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 = NULL;//
+ avp_val.os.len = 0;//
+ 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));
+ CHECK_MALLOC(avp_val.os.data=malloc(avphdr->avp_value->os.len));
+ memcpy(avp_val.os.data,avphdr->avp_value->os.data,avphdr->avp_value->os.len);
+ 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;
+}
+
+
+
+
+static int diameap_server_callback(struct msg ** rmsg, struct avp * ravp,
+ struct session * sess, void * opaque, enum disp_action * action)
+{
+ TRACE_ENTRY("%p %p %p %p", rmsg, ravp, sess, action);
+
+ struct sess_state * 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,"%s 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 sess_state)))
+ ;
+ memset(diameap_sess_data, 0, sizeof(struct sess_state));
+ 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;})
+ ;
+
+ LOG_N("%s Auth FAIL: %.*s",DIAMEAP_EXTENSION, diameap_sm->eap_sm.user.useridLength, diameap_sm->eap_sm.user.userid);
+
+ 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;})
+ ;
+
+ LOG_N("%s Auth Success: %.*s",DIAMEAP_EXTENSION, diameap_sm->eap_sm.user.useridLength, diameap_sm->eap_sm.user.userid);
+
+ 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;
+
+ case DIAMEAP_IDLE:
+ break;
+ }
+ }
+
+ diameap_free(diameap_sm);
+
+ s_end: return 0;
+}
+
+int diameap_start_server(void)
+{
+ struct disp_when when;
+
+ /*create handler for sessions */
+ CHECK_FCT(fd_sess_handler_create(&diameap_server_reg, diameap_cli_sess_cleanup, NULL, NULL));
+
+ /* 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, NULL,
+ &handle));
+
+ if (handle == NULL)
+ {
+ TRACE_DEBUG(INFO, "%sCannot register the callback !!!",DIAMEAP_EXTENSION);
+ return 1;
+ }
+ return 0;
+}
+
+int diameap_stop_server(void)
+{
+ CHECK_FCT(fd_sess_handler_destroy(&diameap_server_reg, NULL));
+ CHECK_FCT(fd_disp_unregister(&handle, NULL));
+
+ return 0;
+}
diff --git a/extensions/app_diameap/diameap_server.h b/extensions/app_diameap/diameap_server.h
new file mode 100644
index 0000000..cef11c7
--- /dev/null
+++ b/extensions/app_diameap/diameap_server.h
@@ -0,0 +1,117 @@
+/*****************************************************************************************************
+ * 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_
+
+
+/* session data structure to store */
+struct sess_state
+{
+ 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);
+
+#endif /* DIAMEAP_SERVER_H_ */
diff --git a/extensions/app_diameap/diameap_tls.c b/extensions/app_diameap/diameap_tls.c
new file mode 100644
index 0000000..e77a65c
--- /dev/null
+++ b/extensions/app_diameap/diameap_tls.c
@@ -0,0 +1,492 @@
+/*****************************************************************************************************
+ * 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"
+
+//GCRY_THREAD_OPTION_PTHREAD_IMPL;
+
+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 = (u8 *) 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_t) data);
+
+ /* starting version 2.12, this call is not needed */
+ //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)
+{
+ struct tls_data * data = (struct tls_data *) ptr;
+ 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,
+ u32 * 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 EINVAL;
+ 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");
+
+ free(data);
+}
+
+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;
+}
+
diff --git a/extensions/app_diameap/diameap_tls.h b/extensions/app_diameap/diameap_tls.h
new file mode 100644
index 0000000..c5774e7
--- /dev/null
+++ b/extensions/app_diameap/diameap_tls.h
@@ -0,0 +1,141 @@
+/*****************************************************************************************************
+ * 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_
+
+#if defined(__GNUC__)
+# define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x)
+# define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x)
+# if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 /* 4.6.x */
+# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(push) \
+ GCC_DIAG_PRAGMA(ignored x)
+# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(pop)
+# else /* older */
+# define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(ignored x)
+# define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(warning x)
+# endif
+#else
+# define GCC_DIAG_OFF(x)
+# define GCC_DIAG_ON(x)
+#endif
+
+
+#include "diameap_defs.h"
+#include <gnutls/gnutls.h>
+GCC_DIAG_OFF("-Wdeprecated-declarations")
+#include <gcrypt.h>
+GCC_DIAG_ON("-Wdeprecated-declarations")
+#include <errno.h>
+#include <pthread.h>
+
+
+
+#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;
+
+ //configuration parameters
+ boolean check_cert_cn_username;
+
+ 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, u32 * 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_ */
diff --git a/extensions/app_diameap/diameap_user.c b/extensions/app_diameap/diameap_user.c
new file mode 100644
index 0000000..8e8de1b
--- /dev/null
+++ b/extensions/app_diameap/diameap_user.c
@@ -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 %hu",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 %hu",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 %d",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 %d %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 %d %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;
+}
diff --git a/extensions/app_diameap/diameap_user.h b/extensions/app_diameap/diameap_user.h
new file mode 100644
index 0000000..f798a88
--- /dev/null
+++ b/extensions/app_diameap/diameap_user.h
@@ -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 */
+};
+
+boolean check_user_identity;
+
+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_ */
diff --git a/extensions/app_diameap/libcrypt.c b/extensions/app_diameap/libcrypt.c
new file mode 100644
index 0000000..846d6c8
--- /dev/null
+++ b/extensions/app_diameap/libcrypt.c
@@ -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;
+}
diff --git a/extensions/app_diameap/libcrypt.h b/extensions/app_diameap/libcrypt.h
new file mode 100644
index 0000000..375234b
--- /dev/null
+++ b/extensions/app_diameap/libcrypt.h
@@ -0,0 +1,54 @@
+/*****************************************************************************************************
+ * 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_
+
+/* EAP-TLS*/
+#include "diameap_tls.h"
+
+GCC_DIAG_OFF("-Wdeprecated-declarations")
+#include <gcrypt.h>
+GCC_DIAG_ON("-Wdeprecated-declarations")
+#include <stdio.h>
+
+
+
+int md5hash(void * buffer, int length, void * digest);
+
+#endif /* LIBCRYPT_H_ */
diff --git a/extensions/app_diameap/libdiameap.h b/extensions/app_diameap/libdiameap.h
new file mode 100644
index 0000000..b459e29
--- /dev/null
+++ b/extensions/app_diameap/libdiameap.h
@@ -0,0 +1,187 @@
+/*****************************************************************************************************
+ * 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 ** msk,int *msklength,
+ u8 ** emsk,int *emsklength); /* 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_ */
diff --git a/extensions/app_diameap/plugins.h b/extensions/app_diameap/plugins.h
new file mode 100644
index 0000000..edf92e5
--- /dev/null
+++ b/extensions/app_diameap/plugins.h
@@ -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"
+
+
+
+
+/* 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 ) \
+static struct register_plugin *registerplugin = NULL; \
+static int isregistered = 0; \
+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*/
diff --git a/extensions/app_diameap/plugins/CMakeLists.txt b/extensions/app_diameap/plugins/CMakeLists.txt
new file mode 100644
index 0000000..5b36611
--- /dev/null
+++ b/extensions/app_diameap/plugins/CMakeLists.txt
@@ -0,0 +1,34 @@
+PROJECT("EAP Methods Plugins" C)
+
+MACRO(EAP_ADD_METHOD METHNAME)
+ ADD_LIBRARY(${METHNAME} MODULE ${ARGN})
+ SET_TARGET_PROPERTIES(${METHNAME} PROPERTIES PREFIX "" )
+ SET_TARGET_PROPERTIES(${METHNAME} PROPERTIES SUFFIX ".emp" )
+ INSTALL(TARGETS ${METHNAME}
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-eap-server)
+ENDMACRO(EAP_ADD_METHOD)
+
+# Use the macro FD_EAP_PLUGIN(extmacroname subdir descr default) to
+# add a new extension subdirectory.
+MACRO(FD_EAP_PLUGIN EXTSUBDIR EXTDESCR EXTDEFAULT)
+ STRING(TOUPPER ${EXTSUBDIR} EXTMACRONAME)
+ IF (NOT ALL_EXTENSIONS)
+ OPTION(BUILD_${EXTMACRONAME} ${EXTDESCR} ${EXTDEFAULT})
+ ENDIF (NOT ALL_EXTENSIONS)
+ IF (BUILD_${EXTMACRONAME} OR ALL_EXTENSIONS)
+ ADD_SUBDIRECTORY(${EXTSUBDIR})
+ ENDIF (BUILD_${EXTMACRONAME} OR ALL_EXTENSIONS)
+ENDMACRO(FD_EAP_PLUGIN)
+
+###########################
+# EAP Methods Plugins Section
+
+# EAP Identity plugin
+FD_EAP_PLUGIN(eap_identity "Build EAP Identity Plugin " ON)
+
+# EAP MD5 plugin
+FD_EAP_PLUGIN(eap_md5 "Build EAP-MD5 Plugin " OFF)
+
+# EAP TLS plugin
+FD_EAP_PLUGIN(eap_tls "Build EAP-TLS Plugin " OFF)
diff --git a/extensions/app_diameap/plugins/eap_identity/CMakeLists.txt b/extensions/app_diameap/plugins/eap_identity/CMakeLists.txt
new file mode 100644
index 0000000..45f469f
--- /dev/null
+++ b/extensions/app_diameap/plugins/eap_identity/CMakeLists.txt
@@ -0,0 +1,4 @@
+# EAP Identity plugin
+PROJECT("EAP Identity Plugin" C)
+
+EAP_ADD_METHOD(eap_identity eap_identity.c)
diff --git a/extensions/app_diameap/plugins/eap_identity/eap_identity.c b/extensions/app_diameap/plugins/eap_identity/eap_identity.c
new file mode 100644
index 0000000..e736f9d
--- /dev/null
+++ b/extensions/app_diameap/plugins/eap_identity/eap_identity.c
@@ -0,0 +1,177 @@
+/*****************************************************************************************************
+ * 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((u8 *)user,0,len,Respdata);
+ user[length-5]='\0';
+ if(check_user_identity == FALSE){
+ ret=diameap_get_eap_user(&(smd->user),"Default User");
+ CHECK_MALLOC_DO(smd->user.userid=realloc(smd->user.userid,strlen(user)+1),{ret = 1; goto next;});
+ memcpy(smd->user.userid,user,strlen(user)+1);
+ smd->user.useridLength = strlen(user);
+ } else {
+ ret=diameap_get_eap_user(&(smd->user),user);
+ }
+next:
+ 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;
+}
diff --git a/extensions/app_diameap/plugins/eap_md5/CMakeLists.txt b/extensions/app_diameap/plugins/eap_md5/CMakeLists.txt
new file mode 100644
index 0000000..1c0253b
--- /dev/null
+++ b/extensions/app_diameap/plugins/eap_md5/CMakeLists.txt
@@ -0,0 +1,4 @@
+# EAP MD5 Plugin
+PROJECT("EAP MD5 Plugin" C)
+
+EAP_ADD_METHOD(eap_md5 eap_md5.c)
diff --git a/extensions/app_diameap/plugins/eap_md5/eap_md5.c b/extensions/app_diameap/plugins/eap_md5/eap_md5.c
new file mode 100644
index 0000000..d21c9ce
--- /dev/null
+++ b/extensions/app_diameap/plugins/eap_md5/eap_md5.c
@@ -0,0 +1,200 @@
+/*****************************************************************************************************
+ * 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"
+GCC_DIAG_OFF("-Wdeprecated-declarations")
+#include <gcrypt.h>
+GCC_DIAG_ON("-Wdeprecated-declarations")
+
+#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;
+}
diff --git a/extensions/app_diameap/plugins/eap_tls/CMakeLists.txt b/extensions/app_diameap/plugins/eap_tls/CMakeLists.txt
new file mode 100644
index 0000000..023d134
--- /dev/null
+++ b/extensions/app_diameap/plugins/eap_tls/CMakeLists.txt
@@ -0,0 +1,18 @@
+# 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
+ )
+
+TARGET_LINK_LIBRARIES(eap_tls ${GNUTLS_LIBRARIES})
diff --git a/extensions/app_diameap/plugins/eap_tls/eap_tls.c b/extensions/app_diameap/plugins/eap_tls/eap_tls.c
new file mode 100644
index 0000000..6b812dd
--- /dev/null
+++ b/extensions/app_diameap/plugins/eap_tls/eap_tls.c
@@ -0,0 +1,426 @@
+/*****************************************************************************************************
+ * 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** msk, int * msklen, u8** emsk, int * emsklen);
+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;
+ tls_global_conf.check_cert_cn_username = FALSE;
+
+ /*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 = 64*1024 /* As per RFC 5216 recommendation */;
+
+ /* 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;
+
+ if(tls_global_conf.check_cert_cn_username == TRUE){
+ unsigned int list_size;
+ const gnutls_datum_t * list = gnutls_certificate_get_peers (data->session, &list_size);
+ if(list_size<1){
+ goto failure;
+ }
+
+ gnutls_x509_crt_t cert;
+
+ CHECK_GNUTLS_DO(gnutls_x509_crt_init(&cert),{
+ TRACE_DEBUG(NONE,"%s[EAP TLS plugin] [GnuTLS] error in initialization crt init",DIAMEAP_EXTENSION);
+ goto failure;});
+
+ CHECK_GNUTLS_DO(gnutls_x509_crt_import(cert, &list[0], GNUTLS_X509_FMT_DER), {
+ TRACE_DEBUG(NONE,"%s[EAP TLS plugin] [GnuTLS] error parsing certificate",DIAMEAP_EXTENSION);
+ goto failure;});
+
+ void * buff;
+ size_t size_buffer;
+ int ret;
+ ret = gnutls_x509_crt_get_dn_by_oid(cert,GNUTLS_OID_X520_COMMON_NAME,0,0,NULL,&size_buffer);
+ if( ret != GNUTLS_E_SHORT_MEMORY_BUFFER){
+ CHECK_GNUTLS_DO(ret,{
+ TRACE_DEBUG(NONE,"%s[EAP TLS plugin] [GnuTLS] error get dn by oid",DIAMEAP_EXTENSION);
+ goto failure;});
+ }
+
+ CHECK_MALLOC_DO(buff=malloc(size_buffer), goto failure);
+
+ CHECK_GNUTLS_DO(gnutls_x509_crt_get_dn_by_oid(cert,GNUTLS_OID_X520_COMMON_NAME,0,0,buff,&size_buffer),{
+ TRACE_DEBUG(NONE,"%s[EAP TLS plugin] [GnuTLS] error get dn by oid",DIAMEAP_EXTENSION);
+ goto failure;});
+
+ if(strncmp((char *)smd->user.userid,buff,smd->user.useridLength)!=0){
+ goto failure;
+ }
+
+ gnutls_x509_crt_deinit(cert);
+ goto next;
+
+ failure:
+ TRACE_DEBUG(NONE,"%s[EAP TLS plugin] Checking failed. certificate's CN does not match User_Name AVP value.",DIAMEAP_EXTENSION);
+ data->state = FAILURE;
+ smd->user.success = FALSE;
+ gnutls_x509_crt_deinit(cert);
+ }
+
+ next:
+ 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 ** msk, int *msklen, u8 ** emsk, int *emsklen)
+{
+ struct tls_data * data;
+ int len = emsk ? 128 : 64;
+ data = (struct tls_data *) smd->methodData;
+ *msk = malloc(len);
+ if (gnutls_prf(data->session, strlen("client EAP encryption"),
+ "client EAP encryption", 0, 0, NULL, len, (char *) *msk)
+ != GNUTLS_E_SUCCESS)
+ {
+ free(*msk);
+ *msk = NULL;
+ *msklen = 0;
+ return 1;
+ }
+ else
+ {
+ *msklen = 64;
+ }
+ if (emsk) {
+ *emsk = malloc(64);
+ memcpy(*emsk, (*msk)+64, 64);
+ memset((*msk)+64, 0, 64);
+ *emsklen = 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;
+}
diff --git a/extensions/app_diameap/plugins/eap_tls/eap_tls.h b/extensions/app_diameap/plugins/eap_tls/eap_tls.h
new file mode 100644
index 0000000..400f3d9
--- /dev/null
+++ b/extensions/app_diameap/plugins/eap_tls/eap_tls.h
@@ -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 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);
+int eaptlsparse(struct tls_config * conf);
+
+#endif /* EAP_TLS_H_ */
diff --git a/extensions/app_diameap/plugins/eap_tls/eaptls.l b/extensions/app_diameap/plugins/eap_tls/eaptls.l
new file mode 100644
index 0000000..7689333
--- /dev/null
+++ b/extensions/app_diameap/plugins/eap_tls/eaptls.l
@@ -0,0 +1,119 @@
+/*****************************************************************************************************
+ * 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 "eap_tls.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; \
+ }
+
+#define YY_NO_INPUT
+%}
+
+%option noyywrap
+%option yylineno
+%option bison-bridge
+%option bison-locations
+%option nounput
+%%
+ /* 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;
+ }
+
+(?i:"check_cert_cn_username") {
+ return CHECK_CN_USERNAME;
+ }
+
+
+
+"="|";"|":"|"," { /* 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 */
+
+
diff --git a/extensions/app_diameap/plugins/eap_tls/eaptls.y b/extensions/app_diameap/plugins/eap_tls/eaptls.y
new file mode 100644
index 0000000..31559eb
--- /dev/null
+++ b/extensions/app_diameap/plugins/eap_tls/eaptls.y
@@ -0,0 +1,243 @@
+/*****************************************************************************************************
+ * 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
+%token CHECK_CN_USERNAME
+
+%%
+
+confparams : /* empty */
+ | confparams CERTS_files
+ | confparams CA_file
+ | confparams CRL_file
+ | confparams CHECK_CN_USERNAME_param
+ | 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: %s",DIAMEAP_EXTENSION,certfile,strerror(ret));
+ 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: %s",DIAMEAP_EXTENSION,keyfile,strerror(ret));
+ 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: %s",DIAMEAP_EXTENSION,cafile,strerror(ret));
+ 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: %s",DIAMEAP_EXTENSION,crlfile,strerror(ret));
+ yyerror (&yylloc, config, "Error configuring CRL file for EAP-TLS");
+ YYERROR;
+ }
+ fclose(fl);
+ }
+ config->crlfile=$3;
+ }
+ ;
+
+CHECK_CN_USERNAME_param :
+ CHECK_CN_USERNAME '=' NUM ';'
+ {
+ if((int)$3 == 0){
+ config->check_cert_cn_username = FALSE;
+ }
+ else
+ {
+ config->check_cert_cn_username = TRUE;
+ }
+ }
+ ;
+
+%%
+
+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);
+}
diff --git a/extensions/app_radgw/CMakeLists.txt b/extensions/app_radgw/CMakeLists.txt
new file mode 100644
index 0000000..fb91c2b
--- /dev/null
+++ b/extensions/app_radgw/CMakeLists.txt
@@ -0,0 +1,118 @@
+# The app_radgw extension
+PROJECT("RADIUS/Diameter extensible gateway application for freeDiameter" C)
+
+
+########### Main app_radgw extension #############
+
+# Parser files
+BISON_FILE(rgw_conf.y)
+FLEX_FILE(rgw_conf.l)
+SET_SOURCE_FILES_PROPERTIES(lex.rgw_conf.c rgw_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( RGW_DEFAULT_SRC
+ radius.c
+ md5.c
+ rgw_msg_codes.c
+ rgw_msg_attrtype.c
+ rgw_main.c
+ lex.rgw_conf.c
+ rgw_conf.tab.c
+ rgw_conf.tab.h
+ rgw_clients.c
+ rgw_plugins.c
+ rgw_servers.c
+ rgw_worker.c
+)
+
+SET( RG_COMMON_HEADER
+ rgw_common.h
+ radius.h
+ md5.h
+ hostap_compat.h
+)
+
+# Compile these files as a freeDiameter extension.
+FD_ADD_EXTENSION(app_radgw ${RGW_DEFAULT_SRC} ${RG_COMMON_HEADER})
+
+
+########### RADIUS/Diameter translation agent plugins (support for RADIUS protocol) ############
+# Use the macro RGWX_ADD_PLUGIN(name files...) to create a plugin.
+# It is equivalent to add_library with the appropriate parameters
+# and naming conventions (.rgwx : Radius GateWay eXtension)
+MACRO(RGWX_ADD_PLUGIN PLGNAME)
+ ADD_LIBRARY(${PLGNAME} MODULE ${ARGN})
+ SET_TARGET_PROPERTIES(${PLGNAME} PROPERTIES PREFIX "" )
+ SET_TARGET_PROPERTIES(${PLGNAME} PROPERTIES SUFFIX ".rgwx" )
+ INSTALL(TARGETS ${PLGNAME}
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-radius-gateway)
+ENDMACRO(RGWX_ADD_PLUGIN)
+
+# Ask unless ALL_EXTENSIONS is set:
+MACRO(FD_OPTION_PLUGIN PLGVAR DESCR DEFLT)
+ IF (NOT ALL_EXTENSIONS)
+ OPTION(BUILD_${PLGVAR} ${DESCR} ${DEFLT})
+ ENDIF (NOT ALL_EXTENSIONS)
+ IF (BUILD_${PLGVAR} OR ALL_EXTENSIONS)
+ SET(${PLGVAR} TRUE)
+ ELSE (BUILD_${PLGVAR} OR ALL_EXTENSIONS)
+ SET(${PLGVAR} FALSE)
+ ENDIF (BUILD_${PLGVAR} OR ALL_EXTENSIONS)
+ENDMACRO(FD_OPTION_PLUGIN PLGVAR DESCR DEFLT)
+
+
+### Debug
+# Example of plugin:
+
+FD_OPTION_PLUGIN(RGWX_SAMPLE "Build sample plugin? (for developers only)" OFF)
+ IF (RGWX_SAMPLE)
+ RGWX_ADD_PLUGIN(sample ${RG_COMMON_HEADER} rgwx_sample.c)
+ ENDIF (RGWX_SAMPLE)
+
+# A plugin for debug: dumps RADIUS and Diameter messages state at the time the plugin is called.
+FD_OPTION_PLUGIN(RGWX_DEBUG "Build debug plugin? (display status of RADIUS and Diameter messages)" ON)
+ IF (RGWX_DEBUG)
+ RGWX_ADD_PLUGIN(debug ${RG_COMMON_HEADER} rgwx_debug.c)
+ ENDIF (RGWX_DEBUG)
+
+
+### Authentication, Authorization messages translation.
+FD_OPTION_PLUGIN(RGWX_AUTH "Build Authentication & Authorization RADIUS translation plugin? (RFC2865, RFC3579)" ON)
+ IF (RGWX_AUTH)
+ RGWX_ADD_PLUGIN(auth ${RG_COMMON_HEADER} rgwx_auth.c)
+ ENDIF (RGWX_AUTH)
+
+### SIP Authentication, Authorization messages translation.
+FD_OPTION_PLUGIN(RGWX_SIP "Build SIP RADIUS translation plugin? (RFC4740 or RFC5090)" OFF)
+ IF (RGWX_SIP)
+ RGWX_ADD_PLUGIN(sip ${RG_COMMON_HEADER} rgwx_sip.c)
+ ENDIF (RGWX_SIP)
+
+
+
+### Accounting messages translation.
+FD_OPTION_PLUGIN(RGWX_ACCT "Build Accounting RADIUS translation plugin? (RFC2866)" ON)
+ IF (RGWX_ACCT)
+ RGWX_ADD_PLUGIN(acct ${RG_COMMON_HEADER} rgwx_acct.c)
+ ENDIF (RGWX_ACCT)
+
+
+### Generic plugin to handle some attributes (either delete them or simply echo them in the answer)
+FD_OPTION_PLUGIN(RGWX_ECHODROP "Build 'echo/drop' plugin? (drop specific RADIUS attributes or echo them in RADIUS answer)" ON)
+ IF (RGWX_ECHODROP)
+ BISON_FILE(rgwx_echodrop.y)
+ FLEX_FILE(rgwx_echodrop.l)
+ SET_SOURCE_FILES_PROPERTIES(lex.rgwx_echodrop.c rgwx_echodrop.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+ RGWX_ADD_PLUGIN(echodrop ${RG_COMMON_HEADER} rgwx_echodrop.h rgwx_echodrop.c lex.rgwx_echodrop.c rgwx_echodrop.tab.c rgwx_echodrop.tab.h )
+ ENDIF (RGWX_ECHODROP)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS app_radgw
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-radius-gateway)
+
+# Note that all compiled plugins are added by the RGWX_ADD_PLUGIN macro in the component freeDiameter-radius-gateway as well.
diff --git a/extensions/app_radgw/hostap_compat.h b/extensions/app_radgw/hostap_compat.h
new file mode 100644
index 0000000..9bee2ac
--- /dev/null
+++ b/extensions/app_radgw/hostap_compat.h
@@ -0,0 +1,194 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* This file contains compatibility bindings for hostap files.
+ Most of the definitions here come from different files from the hostap project.
+
+ We don't care for OS-specific definitions since we are only compatible with POSIX systems.
+
+ */
+
+#ifndef _HOSTAP_COMPAT_H
+#define _HOSTAP_COMPAT_H
+
+#include <sys/time.h>
+
+typedef uint64_t u64;
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+typedef int64_t s64;
+typedef int32_t s32;
+typedef int16_t s16;
+typedef int8_t s8;
+
+/* md5.c uses a different macro name than freeDiameter for endianness */
+#ifdef HOST_BIG_ENDIAN
+# define WORDS_BIGENDIAN HOST_BIG_ENDIAN
+#else /* HOST_BIG_ENDIAN */
+# undef WORDS_BIGENDIAN
+#endif /* HOST_BIG_ENDIAN */
+
+/* freeDiameter uses the POSIX API, so we don't provide alternatives. This may be changed later as needed */
+#define os_malloc(s) malloc((s))
+#define os_realloc(p, s) realloc((p), (s))
+#define os_free(p) free((p))
+
+#define os_memcpy(d, s, n) memcpy((d), (s), (n))
+#define os_memmove(d, s, n) memmove((d), (s), (n))
+#define os_memset(s, c, n) memset(s, c, n)
+#define os_memcmp(s1, s2, n) memcmp((s1), (s2), (n))
+
+#define os_strdup(s) strdup(s)
+#define os_strlen(s) strlen(s)
+#define os_strcasecmp(s1, s2) strcasecmp((s1), (s2))
+#define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n))
+#define os_strchr(s, c) strchr((s), (c))
+#define os_strcmp(s1, s2) strcmp((s1), (s2))
+#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
+#define os_strncpy(d, s, n) strncpy((d), (s), (n))
+#define os_strrchr(s, c) strrchr((s), (c))
+#define os_strstr(h, n) strstr((h), (n))
+#define os_snprintf snprintf
+
+#define os_random() random()
+
+static __inline__ void * os_zalloc(size_t size)
+{
+ void *n = os_malloc(size);
+ if (n)
+ os_memset(n, 0, size);
+ return n;
+}
+
+typedef long os_time_t;
+struct os_time {
+ os_time_t sec;
+ os_time_t usec;
+};
+
+static __inline__ int os_get_time(struct os_time *t)
+{
+ int res;
+ struct timeval tv;
+ res = gettimeofday(&tv, NULL);
+ t->sec = tv.tv_sec;
+ t->usec = tv.tv_usec;
+ return res;
+}
+
+/* Macros for handling unaligned memory accesses */
+#define WPA_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
+#define WPA_PUT_BE16(a, val) \
+ do { \
+ (a)[0] = ((u16) (val)) >> 8; \
+ (a)[1] = ((u16) (val)) & 0xff; \
+ } while (0)
+
+#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
+#define WPA_PUT_LE16(a, val) \
+ do { \
+ (a)[1] = ((u16) (val)) >> 8; \
+ (a)[0] = ((u16) (val)) & 0xff; \
+ } while (0)
+
+#define WPA_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
+ ((u32) (a)[2]))
+#define WPA_PUT_BE24(a, val) \
+ do { \
+ (a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \
+ (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
+ (a)[2] = (u8) (((u32) (val)) & 0xff); \
+ } while (0)
+
+#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
+ (((u32) (a)[2]) << 8) | ((u32) (a)[3]))
+#define WPA_PUT_BE32(a, val) \
+ do { \
+ (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \
+ (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \
+ (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \
+ (a)[3] = (u8) (((u32) (val)) & 0xff); \
+ } while (0)
+
+#define WPA_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \
+ (((u32) (a)[1]) << 8) | ((u32) (a)[0]))
+#define WPA_PUT_LE32(a, val) \
+ do { \
+ (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \
+ (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \
+ (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
+ (a)[0] = (u8) (((u32) (val)) & 0xff); \
+ } while (0)
+
+#define WPA_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \
+ (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \
+ (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \
+ (((u64) (a)[6]) << 8) | ((u64) (a)[7]))
+#define WPA_PUT_BE64(a, val) \
+ do { \
+ (a)[0] = (u8) (((u64) (val)) >> 56); \
+ (a)[1] = (u8) (((u64) (val)) >> 48); \
+ (a)[2] = (u8) (((u64) (val)) >> 40); \
+ (a)[3] = (u8) (((u64) (val)) >> 32); \
+ (a)[4] = (u8) (((u64) (val)) >> 24); \
+ (a)[5] = (u8) (((u64) (val)) >> 16); \
+ (a)[6] = (u8) (((u64) (val)) >> 8); \
+ (a)[7] = (u8) (((u64) (val)) & 0xff); \
+ } while (0)
+
+#define WPA_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \
+ (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \
+ (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \
+ (((u64) (a)[1]) << 8) | ((u64) (a)[0]))
+
+
+/* Packing structures to avoid padding */
+#ifdef __GNUC__
+#define STRUCT_PACKED __attribute__ ((packed))
+#else
+#define STRUCT_PACKED
+#endif
+
+/* For md5.c file */
+#define INTERNAL_MD5
+#define CONFIG_CRYPTO_INTERNAL
+
+/* For radius.c file */
+#define CONFIG_IPV6
+#include <arpa/inet.h>
+
+
+#endif /* _HOSTAP_COMPAT_H */
diff --git a/extensions/app_radgw/md5.c b/extensions/app_radgw/md5.c
new file mode 100644
index 0000000..055fcf0
--- /dev/null
+++ b/extensions/app_radgw/md5.c
@@ -0,0 +1,399 @@
+/*********************************************************************************/
+/* freeDiameter author note:
+ * The content from this file comes directly from the hostap project.
+ * It is redistributed under the terms of the BSD license, as allowed
+ * by the original copyright reproduced below.
+ * In addition to this notice, only the #include directives have been modified.
+ */
+#include "rgw_common.h"
+/*********************************************************************************/
+
+
+/*
+ * MD5 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+
+/**
+ * hmac_md5_vector - HMAC-MD5 over data vector (RFC 2104)
+ * @key: Key for HMAC operations
+ * @key_len: Length of the key in bytes
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
+ * @mac: Buffer for the hash (16 bytes)
+ */
+void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac)
+{
+ u8 k_pad[64]; /* padding - key XORd with ipad/opad */
+ u8 tk[16];
+ const u8 *_addr[6];
+ size_t i, _len[6];
+
+ if (num_elem > 5) {
+ /*
+ * Fixed limit on the number of fragments to avoid having to
+ * allocate memory (which could fail).
+ */
+ return;
+ }
+
+ /* if key is longer than 64 bytes reset it to key = MD5(key) */
+ if (key_len > 64) {
+ md5_vector(1, &key, &key_len, tk);
+ key = tk;
+ key_len = 16;
+ }
+
+ /* the HMAC_MD5 transform looks like:
+ *
+ * MD5(K XOR opad, MD5(K XOR ipad, text))
+ *
+ * where K is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected */
+
+ /* start out by storing key in ipad */
+ os_memset(k_pad, 0, sizeof(k_pad));
+ os_memcpy(k_pad, key, key_len);
+
+ /* XOR key with ipad values */
+ for (i = 0; i < 64; i++)
+ k_pad[i] ^= 0x36;
+
+ /* perform inner MD5 */
+ _addr[0] = k_pad;
+ _len[0] = 64;
+ for (i = 0; i < num_elem; i++) {
+ _addr[i + 1] = addr[i];
+ _len[i + 1] = len[i];
+ }
+ md5_vector(1 + num_elem, _addr, _len, mac);
+
+ os_memset(k_pad, 0, sizeof(k_pad));
+ os_memcpy(k_pad, key, key_len);
+ /* XOR key with opad values */
+ for (i = 0; i < 64; i++)
+ k_pad[i] ^= 0x5c;
+
+ /* perform outer MD5 */
+ _addr[0] = k_pad;
+ _len[0] = 64;
+ _addr[1] = mac;
+ _len[1] = MD5_MAC_LEN;
+ md5_vector(2, _addr, _len, mac);
+}
+
+
+/**
+ * hmac_md5 - HMAC-MD5 over data buffer (RFC 2104)
+ * @key: Key for HMAC operations
+ * @key_len: Length of the key in bytes
+ * @data: Pointers to the data area
+ * @data_len: Length of the data area
+ * @mac: Buffer for the hash (16 bytes)
+ */
+void hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
+ u8 *mac)
+{
+ hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
+}
+
+
+#ifdef INTERNAL_MD5
+
+struct MD5Context {
+ u32 buf[4];
+ u32 bits[2];
+ u8 in[64];
+};
+
+#ifndef CONFIG_CRYPTO_INTERNAL
+static void MD5Init(struct MD5Context *context);
+static void MD5Update(struct MD5Context *context, unsigned char const *buf,
+ unsigned len);
+static void MD5Final(unsigned char digest[16], struct MD5Context *context);
+#endif /* CONFIG_CRYPTO_INTERNAL */
+static void MD5Transform(u32 buf[4], u32 const in[16]);
+
+
+typedef struct MD5Context MD5_CTX;
+
+
+/**
+ * md5_vector - MD5 hash for data vector
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
+ * @mac: Buffer for the hash
+ */
+void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+{
+ MD5_CTX ctx;
+ size_t i;
+
+ MD5Init(&ctx);
+ for (i = 0; i < num_elem; i++)
+ MD5Update(&ctx, addr[i], len[i]);
+ MD5Final(mac, &ctx);
+}
+
+
+/* ===== start - public domain MD5 implementation ===== */
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#ifndef WORDS_BIGENDIAN
+#define byteReverse(buf, len) /* Nothing */
+#else
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(unsigned char *buf, unsigned longs)
+{
+ u32 t;
+ do {
+ t = (u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(u32 *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
+{
+ u32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((u32) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ os_memcpy(p, buf, len);
+ return;
+ }
+ os_memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (u32 *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ os_memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (u32 *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ os_memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ os_memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (u32 *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ os_memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ os_memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((u32 *) ctx->in)[14] = ctx->bits[0];
+ ((u32 *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Transform(ctx->buf, (u32 *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ os_memcpy(digest, ctx->buf, 16);
+ os_memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+static void MD5Transform(u32 buf[4], u32 const in[16])
+{
+ register u32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+/* ===== end - public domain MD5 implementation ===== */
+
+#endif /* INTERNAL_MD5 */
diff --git a/extensions/app_radgw/md5.h b/extensions/app_radgw/md5.h
new file mode 100644
index 0000000..bcbfdc3
--- /dev/null
+++ b/extensions/app_radgw/md5.h
@@ -0,0 +1,46 @@
+/*********************************************************************************/
+/* freeDiameter author note:
+ * The content from this file comes directly from the hostap project.
+ * It is redistributed under the terms of the BSD license, as allowed
+ * by the original copyright reproduced below.
+ */
+
+/*********************************************************************************/
+
+/*
+ * MD5 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef MD5_H
+#define MD5_H
+
+#define MD5_MAC_LEN 16
+
+void hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac);
+void hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
+ u8 *mac);
+
+#ifdef CONFIG_CRYPTO_INTERNAL
+struct MD5Context;
+
+void MD5Init(struct MD5Context *context);
+void MD5Update(struct MD5Context *context, unsigned char const *buf,
+ unsigned len);
+void MD5Final(unsigned char digest[16], struct MD5Context *context);
+#endif /* CONFIG_CRYPTO_INTERNAL */
+
+ /* Forward declaration: */
+void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac);
+
+#endif /* MD5_H */
diff --git a/extensions/app_radgw/radius.c b/extensions/app_radgw/radius.c
new file mode 100644
index 0000000..44755eb
--- /dev/null
+++ b/extensions/app_radgw/radius.c
@@ -0,0 +1,1373 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* freeDiameter author note:
+ * The content from this file comes for the main part from the hostap project.
+ * It is redistributed under the terms of the BSD license, as allowed
+ * by the original copyright reproduced below.
+ * The modifications to this file are placed under the copyright of the freeDiameter project.
+ */
+
+/*
+ * hostapd / RADIUS message processing
+ * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+/*********************************************************************************/
+#include "rgw.h"
+
+static struct radius_attr_hdr *
+radius_get_attr_hdr(struct radius_msg *msg, int idx)
+{
+ return (struct radius_attr_hdr *) (msg->buf + msg->attr_pos[idx]);
+}
+
+
+struct radius_msg *radius_msg_new(u8 code, u8 identifier)
+{
+ struct radius_msg *msg;
+
+ msg = os_malloc(sizeof(*msg));
+ if (msg == NULL)
+ return NULL;
+
+ if (radius_msg_initialize(msg, RADIUS_DEFAULT_MSG_SIZE)) {
+ os_free(msg);
+ return NULL;
+ }
+
+ radius_msg_set_hdr(msg, code, identifier);
+
+ return msg;
+}
+
+
+int radius_msg_initialize(struct radius_msg *msg, size_t init_len)
+{
+ if (msg == NULL || init_len < sizeof(struct radius_hdr))
+ return -1;
+
+ os_memset(msg, 0, sizeof(*msg));
+ msg->buf = os_zalloc(init_len);
+ if (msg->buf == NULL)
+ return -1;
+
+ msg->buf_size = init_len;
+ msg->hdr = (struct radius_hdr *) msg->buf;
+ msg->buf_used = sizeof(*msg->hdr);
+
+ msg->attr_pos =
+ os_zalloc(RADIUS_DEFAULT_ATTR_COUNT * sizeof(*msg->attr_pos));
+ if (msg->attr_pos == NULL) {
+ os_free(msg->buf);
+ msg->buf = NULL;
+ msg->hdr = NULL;
+ return -1;
+ }
+
+ msg->attr_size = RADIUS_DEFAULT_ATTR_COUNT;
+ msg->attr_used = 0;
+
+ return 0;
+}
+
+
+void radius_msg_set_hdr(struct radius_msg *msg, u8 code, u8 identifier)
+{
+ msg->hdr->code = code;
+ msg->hdr->identifier = identifier;
+}
+
+
+void radius_msg_free(struct radius_msg *msg)
+{
+ os_free(msg->buf);
+ msg->buf = NULL;
+ msg->hdr = NULL;
+ msg->buf_size = msg->buf_used = 0;
+
+ os_free(msg->attr_pos);
+ msg->attr_pos = NULL;
+ msg->attr_size = msg->attr_used = 0;
+}
+
+/* Destroy a message */
+void rgw_msg_free(struct rgw_radius_msg_meta ** msg)
+{
+ if (!msg || !*msg)
+ return;
+
+ radius_msg_free(&(*msg)->radius);
+ free(*msg);
+ *msg = NULL;
+}
+
+
+
+struct radius_attr_type {
+ u8 type;
+ char *name;
+ enum {
+ RADIUS_ATTR_UNDIST, RADIUS_ATTR_TEXT, RADIUS_ATTR_IP,
+ RADIUS_ATTR_HEXDUMP, RADIUS_ATTR_INT32, RADIUS_ATTR_IPV6
+ } data_type;
+};
+
+static struct radius_attr_type radius_attrs[] =
+{
+ { RADIUS_ATTR_USER_NAME, "User-Name", RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_USER_PASSWORD, "User-Password", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_NAS_IP_ADDRESS, "NAS-IP-Address", RADIUS_ATTR_IP },
+ { RADIUS_ATTR_NAS_PORT, "NAS-Port", RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_FRAMED_MTU, "Framed-MTU", RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_REPLY_MESSAGE, "Reply-Message", RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_STATE, "State", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_CLASS, "Class", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_VENDOR_SPECIFIC, "Vendor-Specific", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_SESSION_TIMEOUT, "Session-Timeout", RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_IDLE_TIMEOUT, "Idle-Timeout", RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_TERMINATION_ACTION, "Termination-Action",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_CALLED_STATION_ID, "Called-Station-Id",
+ RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_CALLING_STATION_ID, "Calling-Station-Id",
+ RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_NAS_IDENTIFIER, "NAS-Identifier", RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_PROXY_STATE, "Proxy-State", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_ACCT_STATUS_TYPE, "Acct-Status-Type",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_DELAY_TIME, "Acct-Delay-Time", RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_INPUT_OCTETS, "Acct-Input-Octets",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_OUTPUT_OCTETS, "Acct-Output-Octets",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_SESSION_ID, "Acct-Session-Id", RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_ACCT_AUTHENTIC, "Acct-Authentic", RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_SESSION_TIME, "Acct-Session-Time",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_INPUT_PACKETS, "Acct-Input-Packets",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_OUTPUT_PACKETS, "Acct-Output-Packets",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_TERMINATE_CAUSE, "Acct-Terminate-Cause",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_MULTI_SESSION_ID, "Acct-Multi-Session-Id",
+ RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_ACCT_LINK_COUNT, "Acct-Link-Count", RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_INPUT_GIGAWORDS, "Acct-Input-Gigawords",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS, "Acct-Output-Gigawords",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_EVENT_TIMESTAMP, "Event-Timestamp",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_NAS_PORT_TYPE, "NAS-Port-Type", RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_TUNNEL_TYPE, "Tunnel-Type", RADIUS_ATTR_HEXDUMP },
+ { RADIUS_ATTR_TUNNEL_MEDIUM_TYPE, "Tunnel-Medium-Type",
+ RADIUS_ATTR_HEXDUMP },
+ { RADIUS_ATTR_CONNECT_INFO, "Connect-Info", RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_EAP_MESSAGE, "EAP-Message", RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_MESSAGE_AUTHENTICATOR, "Message-Authenticator",
+ RADIUS_ATTR_UNDIST },
+ { RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID, "Tunnel-Private-Group-Id",
+ RADIUS_ATTR_HEXDUMP },
+ { RADIUS_ATTR_ACCT_INTERIM_INTERVAL, "Acct-Interim-Interval",
+ RADIUS_ATTR_INT32 },
+ { RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, "Chargeable-User-Identity",
+ RADIUS_ATTR_TEXT },
+ { RADIUS_ATTR_NAS_IPV6_ADDRESS, "NAS-IPv6-Address", RADIUS_ATTR_IPV6 },
+};
+#define RADIUS_ATTRS (sizeof(radius_attrs) / sizeof(radius_attrs[0]))
+
+
+static struct radius_attr_type *radius_get_attr_type(u8 type)
+{
+ size_t i;
+
+ for (i = 0; i < RADIUS_ATTRS; i++) {
+ if (type == radius_attrs[i].type)
+ return &radius_attrs[i];
+ }
+
+ return NULL;
+}
+
+static char print_char_buf[5];
+
+static char * print_char(char c)
+{
+ if (c >= 32 && c < 127)
+ sprintf(print_char_buf, "%c", c);
+ else
+ sprintf(print_char_buf, "<%02x>", c);
+ return print_char_buf;
+}
+
+
+static char * radius_msg_dump_attr_val(struct radius_attr_hdr *hdr, char * outbuf, size_t buflen)
+{
+ struct radius_attr_type *attr;
+ int i, len;
+ unsigned char *pos;
+ u8 attrtype;
+
+ memset(outbuf, 0, buflen);
+
+ attr = radius_get_attr_type(hdr->type);
+
+ if (attr == NULL)
+ attrtype = RADIUS_ATTR_HEXDUMP;
+ else
+ attrtype = attr->data_type;
+
+ len = hdr->length - sizeof(struct radius_attr_hdr);
+ pos = (unsigned char *) (hdr + 1);
+
+ switch (attrtype) {
+ case RADIUS_ATTR_TEXT:
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " Value: '");
+ for (i = 0; i < len; i++)
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "%s", print_char(pos[i]));
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), "'");
+ break;
+
+ case RADIUS_ATTR_IP:
+ if (len == 4) {
+ struct in_addr addr;
+ os_memcpy(&addr, pos, 4);
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " Value: %s", inet_ntoa(addr));
+ } else
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " Invalid IP address length %d", len);
+ break;
+
+ case RADIUS_ATTR_IPV6:
+ if (len == 16) {
+ char buf[128];
+ const char *atxt;
+ struct in6_addr *addr = (struct in6_addr *) pos;
+ atxt = inet_ntop(AF_INET6, addr, buf, sizeof(buf));
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " Value: %s", atxt ? atxt : "?");
+ } else
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " Invalid IPv6 address length %d", len);
+ break;
+
+ case RADIUS_ATTR_INT32:
+ if (len == 4)
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " Value: %u", WPA_GET_BE32(pos));
+ else
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " Invalid INT32 length %d", len);
+ break;
+
+ case RADIUS_ATTR_HEXDUMP:
+ case RADIUS_ATTR_UNDIST:
+ default:
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " Value:");
+ for (i = 0; i < len; i++)
+ snprintf(outbuf + strlen(outbuf), buflen - strlen(outbuf), " %02x", pos[i]);
+ break;
+ }
+
+ return outbuf;
+}
+
+/* Dump a message */
+void rgw_msg_dump(struct rgw_radius_msg_meta * msg, int has_meta)
+{
+ unsigned char *auth;
+ char buf[256];
+ size_t i;
+ if (! TRACE_BOOL(FULL) )
+ return;
+
+ auth = &(msg->radius.hdr->authenticator[0]);
+
+ fd_log_debug("------ RADIUS msg dump -------");
+ fd_log_debug(" id : 0x%02hhx, code : %hhd (%s), length : %d", msg->radius.hdr->identifier, msg->radius.hdr->code, rgw_msg_code_str(msg->radius.hdr->code), ntohs(msg->radius.hdr->length));
+ fd_log_debug(" auth: %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx",
+ auth[0], auth[1], auth[2], auth[3], auth[4], auth[5], auth[6], auth[7]);
+ fd_log_debug(" %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx",
+ auth[8], auth[9], auth[10], auth[11], auth[12], auth[13], auth[14], auth[15]);
+ for (i = 0; i < msg->radius.attr_used; i++) {
+ struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[i]);
+ fd_log_debug(" - Type: 0x%02hhx (%s) Len: %-3hhu", attr->type, rgw_msg_attrtype_str(attr->type), attr->length);
+ fd_log_debug("%s", radius_msg_dump_attr_val(attr, buf, sizeof(buf)));
+ }
+ if (has_meta && msg->ps_nb) {
+ fd_log_debug("---- hidden attributes:");
+ for (i = msg->ps_first; i < msg->ps_first + msg->ps_nb; i++) {
+ struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[i]);
+ fd_log_debug(" - Type: 0x%02hhx (%s) Len: %-3hhu", attr->type, rgw_msg_attrtype_str(attr->type), attr->length);
+ fd_log_debug("%s", radius_msg_dump_attr_val(attr, buf, sizeof(buf)));
+ }
+ }
+ fd_log_debug("-----------------------------");
+}
+
+
+int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len)
+{
+ if (secret) {
+ u8 auth[MD5_MAC_LEN];
+ struct radius_attr_hdr *attr;
+
+ os_memset(auth, 0, MD5_MAC_LEN);
+ attr = radius_msg_add_attr(msg,
+ RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
+ auth, MD5_MAC_LEN);
+ if (attr == NULL) {
+ fd_log_debug("WARNING: Could not add Message-Authenticator");
+ return -1;
+ }
+ msg->hdr->length = htons(msg->buf_used);
+ hmac_md5(secret, secret_len, msg->buf, msg->buf_used,
+ (u8 *) (attr + 1));
+ } else
+ msg->hdr->length = htons(msg->buf_used);
+
+ if (msg->buf_used > 0xffff) {
+ fd_log_debug("WARNING: too long RADIUS message (%lu)",
+ (unsigned long) msg->buf_used);
+ return -1;
+ }
+ return 0;
+}
+
+
+int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len, const u8 *req_authenticator)
+{
+ u8 auth[MD5_MAC_LEN];
+ struct radius_attr_hdr *attr;
+ const u8 *addr[4];
+ size_t len[4];
+
+ if (msg->hdr->code != RADIUS_CODE_ACCOUNTING_RESPONSE) {
+ os_memset(auth, 0, MD5_MAC_LEN);
+ attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
+ auth, MD5_MAC_LEN);
+ if (attr == NULL) {
+ fd_log_debug("WARNING: Could not add Message-Authenticator");
+ return -1;
+ }
+ msg->hdr->length = htons(msg->buf_used);
+ os_memcpy(msg->hdr->authenticator, req_authenticator,
+ sizeof(msg->hdr->authenticator));
+ hmac_md5(secret, secret_len, msg->buf, msg->buf_used,
+ (u8 *) (attr + 1));
+ } else {
+ msg->hdr->length = htons(msg->buf_used);
+ }
+
+ /* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
+ addr[0] = (u8 *) msg->hdr;
+ len[0] = 1 + 1 + 2;
+ addr[1] = req_authenticator;
+ len[1] = MD5_MAC_LEN;
+ addr[2] = (u8 *) (msg->hdr + 1);
+ len[2] = msg->buf_used - sizeof(*msg->hdr);
+ addr[3] = secret;
+ len[3] = secret_len;
+ md5_vector(4, addr, len, msg->hdr->authenticator);
+
+ if (msg->buf_used > 0xffff) {
+ fd_log_debug("WARNING: too long RADIUS message (%lu)",
+ (unsigned long) msg->buf_used);
+ return -1;
+ }
+ return 0;
+}
+
+
+void radius_msg_finish_acct(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len)
+{
+ const u8 *addr[2];
+ size_t len[2];
+
+ msg->hdr->length = htons(msg->buf_used);
+ os_memset(msg->hdr->authenticator, 0, MD5_MAC_LEN);
+ addr[0] = msg->buf;
+ len[0] = msg->buf_used;
+ addr[1] = secret;
+ len[1] = secret_len;
+ md5_vector(2, addr, len, msg->hdr->authenticator);
+
+ if (msg->buf_used > 0xffff) {
+ fd_log_debug("WARNING: too long RADIUS messages (%lu)",
+ (unsigned long) msg->buf_used);
+ }
+}
+
+
+int radius_msg_add_attr_to_array(struct radius_msg *msg,
+ struct radius_attr_hdr *attr)
+{
+ if (msg->attr_used >= msg->attr_size) {
+ size_t *nattr_pos;
+ int nlen = msg->attr_size * 2;
+
+ nattr_pos = os_realloc(msg->attr_pos,
+ nlen * sizeof(*msg->attr_pos));
+ if (nattr_pos == NULL)
+ return -1;
+
+ msg->attr_pos = nattr_pos;
+ msg->attr_size = nlen;
+ }
+
+ msg->attr_pos[msg->attr_used++] = (unsigned char *) attr - msg->buf;
+
+ return 0;
+}
+
+
+struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
+ const u8 *data, size_t data_len)
+{
+ size_t buf_needed;
+ struct radius_attr_hdr *attr;
+
+ if (data_len > RADIUS_MAX_ATTR_LEN) {
+ fd_log_debug("radius_msg_add_attr: too long attribute (%lu bytes)",
+ (unsigned long) data_len);
+ return NULL;
+ }
+
+ buf_needed = msg->buf_used + sizeof(*attr) + data_len;
+
+ if (msg->buf_size < buf_needed) {
+ /* allocate more space for message buffer */
+ unsigned char *nbuf;
+ size_t nlen = msg->buf_size;
+
+ while (nlen < buf_needed)
+ nlen *= 2;
+ nbuf = os_realloc(msg->buf, nlen);
+ if (nbuf == NULL)
+ return NULL;
+ msg->buf = nbuf;
+ msg->hdr = (struct radius_hdr *) msg->buf;
+ os_memset(msg->buf + msg->buf_size, 0, nlen - msg->buf_size);
+ msg->buf_size = nlen;
+ }
+
+ attr = (struct radius_attr_hdr *) (msg->buf + msg->buf_used);
+ attr->type = type;
+ attr->length = sizeof(*attr) + data_len;
+ if (data_len > 0)
+ os_memcpy(attr + 1, data, data_len);
+
+ msg->buf_used += sizeof(*attr) + data_len;
+
+ if (radius_msg_add_attr_to_array(msg, attr))
+ return NULL;
+
+ return attr;
+}
+
+
+/* Modified version of radius_msg_parse */
+int rgw_msg_parse(unsigned char * buf, size_t len, struct rgw_radius_msg_meta ** msg)
+{
+ struct rgw_radius_msg_meta * temp_msg = NULL;
+ struct radius_hdr *hdr;
+ struct radius_attr_hdr *attr;
+ size_t msg_len;
+ unsigned char *pos, *end;
+ int ret = 0;
+
+ TRACE_ENTRY("%p %zd %p", buf, len, msg);
+
+ CHECK_PARAMS( buf && len >= sizeof(*hdr) && msg );
+
+ *msg = NULL;
+
+ /* Parse the RADIUS message */
+ hdr = (struct radius_hdr *) buf;
+ msg_len = ntohs(hdr->length);
+ if (msg_len < sizeof(*hdr) || msg_len > len) {
+ TRACE_DEBUG(INFO, "Invalid RADIUS message length");
+ return EINVAL;
+ }
+
+ if (msg_len < len) {
+ TRACE_DEBUG(INFO, "Ignored %lu extra bytes after RADIUS message",
+ (unsigned long) len - msg_len);
+ }
+
+ CHECK_MALLOC( temp_msg = malloc(sizeof(struct rgw_radius_msg_meta)) );
+ memset(temp_msg, 0, sizeof(struct rgw_radius_msg_meta));
+
+ if (radius_msg_initialize(&temp_msg->radius, msg_len)) {
+ TRACE_DEBUG(INFO, "Error in radius_msg_initialize, returning ENOMEM.");
+ free(temp_msg);
+ return ENOMEM;
+ }
+
+ /* Store the received data in the alloc'd buffer */
+ memcpy(temp_msg->radius.buf, buf, msg_len);
+ temp_msg->radius.buf_size = temp_msg->radius.buf_used = msg_len;
+
+ /* parse attributes */
+ pos = (unsigned char *) (temp_msg->radius.hdr + 1);
+ end = temp_msg->radius.buf + temp_msg->radius.buf_used;
+
+ while (pos < end) {
+ if ((size_t) (end - pos) < sizeof(*attr)) {
+ TRACE_DEBUG(INFO, "Trucated attribute found in RADIUS buffer, EINVAL.");
+ ret = EINVAL;
+ break;
+ }
+
+ attr = (struct radius_attr_hdr *) pos;
+
+ if (pos + attr->length > end || attr->length < sizeof(*attr)) {
+ TRACE_DEBUG(INFO, "Trucated attribute found in RADIUS buffer, EINVAL.");
+ ret = EINVAL;
+ break;
+ }
+
+ if (radius_msg_add_attr_to_array(&temp_msg->radius, attr)) {
+ TRACE_DEBUG(INFO, "Error in radius_msg_add_attr_to_array, ENOMEM");
+ ret = ENOMEM;
+ break;
+ }
+
+ if (attr->type == RADIUS_ATTR_PROXY_STATE)
+ temp_msg->ps_nb += 1;
+
+ pos += attr->length;
+ }
+
+ if (ret != 0) {
+ radius_msg_free(&temp_msg->radius);
+ free(temp_msg);
+ return ret;
+ }
+
+ /* Now move all the proxy-state attributes at the end of the attr_pos array */
+ if (temp_msg->ps_nb) {
+ size_t *temp_ps = NULL;
+ int n, new_n = 0, p = 0;
+
+ CHECK_MALLOC( temp_ps = calloc(temp_msg->ps_nb, sizeof(size_t)) );
+
+ /* Move all the Proxy-State attributes into the temp_ps array */
+ for (n=0; n < temp_msg->radius.attr_used; n++) {
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(temp_msg->radius.buf + temp_msg->radius.attr_pos[n]);
+
+ if (attr->type == RADIUS_ATTR_PROXY_STATE) {
+ temp_ps[p++] = temp_msg->radius.attr_pos[n];
+ } else {
+ temp_msg->radius.attr_pos[new_n++] = temp_msg->radius.attr_pos[n];
+ }
+ }
+ temp_msg->radius.attr_used = new_n; /* hide the proxy-state to other modules */
+ temp_msg->ps_first = new_n;
+
+ /* And back into the array */
+ memcpy(temp_msg->radius.attr_pos + new_n, temp_ps, p * sizeof(size_t));
+ free(temp_ps);
+ }
+
+ *msg = temp_msg;
+ return 0;
+}
+
+
+
+int radius_msg_add_eap(struct radius_msg *msg, const u8 *data, size_t data_len)
+{
+ const u8 *pos = data;
+ size_t left = data_len;
+
+ while (left > 0) {
+ int len;
+ if (left > RADIUS_MAX_ATTR_LEN)
+ len = RADIUS_MAX_ATTR_LEN;
+ else
+ len = left;
+
+ if (!radius_msg_add_attr(msg, RADIUS_ATTR_EAP_MESSAGE,
+ pos, len))
+ return 0;
+
+ pos += len;
+ left -= len;
+ }
+
+ return 1;
+}
+
+
+u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *eap_len)
+{
+ u8 *eap, *pos;
+ size_t len, i;
+ struct radius_attr_hdr *attr;
+
+ if (msg == NULL)
+ return NULL;
+
+ len = 0;
+ for (i = 0; i < msg->attr_used; i++) {
+ attr = radius_get_attr_hdr(msg, i);
+ if (attr->type == RADIUS_ATTR_EAP_MESSAGE)
+ len += attr->length - sizeof(struct radius_attr_hdr);
+ }
+
+ if (len == 0)
+ return NULL;
+
+ eap = os_malloc(len);
+ if (eap == NULL)
+ return NULL;
+
+ pos = eap;
+ for (i = 0; i < msg->attr_used; i++) {
+ attr = radius_get_attr_hdr(msg, i);
+ if (attr->type == RADIUS_ATTR_EAP_MESSAGE) {
+ int flen = attr->length - sizeof(*attr);
+ os_memcpy(pos, attr + 1, flen);
+ pos += flen;
+ }
+ }
+
+ if (eap_len)
+ *eap_len = len;
+
+ return eap;
+}
+
+
+int radius_msg_verify_msg_auth(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len, const u8 *req_auth)
+{
+ u8 auth[MD5_MAC_LEN], orig[MD5_MAC_LEN];
+ u8 orig_authenticator[16];
+ struct radius_attr_hdr *attr = NULL, *tmp;
+ size_t i;
+
+ for (i = 0; i < msg->attr_used; i++) {
+ tmp = radius_get_attr_hdr(msg, i);
+ if (tmp->type == RADIUS_ATTR_MESSAGE_AUTHENTICATOR) {
+ if (attr != NULL) {
+ fd_log_debug("Multiple Message-Authenticator attributes in RADIUS message");
+ return 1;
+ }
+ attr = tmp;
+ }
+ }
+
+ if (attr == NULL) {
+ fd_log_debug("No Message-Authenticator attribute found");
+ return 1;
+ }
+
+ os_memcpy(orig, attr + 1, MD5_MAC_LEN);
+ os_memset(attr + 1, 0, MD5_MAC_LEN);
+ if (req_auth) {
+ os_memcpy(orig_authenticator, msg->hdr->authenticator,
+ sizeof(orig_authenticator));
+ os_memcpy(msg->hdr->authenticator, req_auth,
+ sizeof(msg->hdr->authenticator));
+ }
+ hmac_md5(secret, secret_len, msg->buf, msg->buf_used, auth);
+ os_memcpy(attr + 1, orig, MD5_MAC_LEN);
+ if (req_auth) {
+ os_memcpy(msg->hdr->authenticator, orig_authenticator,
+ sizeof(orig_authenticator));
+ }
+
+ if (os_memcmp(orig, auth, MD5_MAC_LEN) != 0) {
+ fd_log_debug("Invalid Message-Authenticator!");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int radius_msg_verify(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len, struct radius_msg *sent_msg, int auth)
+{
+ const u8 *addr[4];
+ size_t len[4];
+ u8 hash[MD5_MAC_LEN];
+
+ if (sent_msg == NULL) {
+ fd_log_debug("No matching Access-Request message found");
+ return 1;
+ }
+
+ if (auth &&
+ radius_msg_verify_msg_auth(msg, secret, secret_len,
+ sent_msg->hdr->authenticator)) {
+ return 1;
+ }
+
+ /* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
+ addr[0] = (u8 *) msg->hdr;
+ len[0] = 1 + 1 + 2;
+ addr[1] = sent_msg->hdr->authenticator;
+ len[1] = MD5_MAC_LEN;
+ addr[2] = (u8 *) (msg->hdr + 1);
+ len[2] = msg->buf_used - sizeof(*msg->hdr);
+ addr[3] = secret;
+ len[3] = secret_len;
+ md5_vector(4, addr, len, hash);
+ if (os_memcmp(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) {
+ fd_log_debug("Response Authenticator invalid!");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int radius_msg_copy_attr(struct radius_msg *dst, struct radius_msg *src,
+ u8 type)
+{
+ struct radius_attr_hdr *attr;
+ size_t i;
+ int count = 0;
+
+ for (i = 0; i < src->attr_used; i++) {
+ attr = radius_get_attr_hdr(src, i);
+ if (attr->type == type) {
+ if (!radius_msg_add_attr(dst, type, (u8 *) (attr + 1),
+ attr->length - sizeof(*attr)))
+ return -1;
+ count++;
+ }
+ }
+
+ return count;
+}
+
+
+/* Create Request Authenticator. The value should be unique over the lifetime
+ * of the shared secret between authenticator and authentication server.
+ * Use one-way MD5 hash calculated from current timestamp and some data given
+ * by the caller. */
+void radius_msg_make_authenticator(struct radius_msg *msg,
+ const u8 *data, size_t len)
+{
+ struct os_time tv;
+ long int l;
+ const u8 *addr[3];
+ size_t elen[3];
+
+ os_get_time(&tv);
+ l = os_random();
+ addr[0] = (u8 *) &tv;
+ elen[0] = sizeof(tv);
+ addr[1] = data;
+ elen[1] = len;
+ addr[2] = (u8 *) &l;
+ elen[2] = sizeof(l);
+ md5_vector(3, addr, elen, msg->hdr->authenticator);
+}
+
+
+/* Get Vendor-specific RADIUS Attribute from a parsed RADIUS message.
+ * Returns the Attribute payload and sets alen to indicate the length of the
+ * payload if a vendor attribute with subtype is found, otherwise returns NULL.
+ * The returned payload is allocated with os_malloc() and caller must free it
+ * by calling os_free().
+ */
+static u8 *radius_msg_get_vendor_attr(struct radius_msg *msg, u32 vendor,
+ u8 subtype, size_t *alen)
+{
+ u8 *data, *pos;
+ size_t i, len;
+
+ if (msg == NULL)
+ return NULL;
+
+ for (i = 0; i < msg->attr_used; i++) {
+ struct radius_attr_hdr *attr = radius_get_attr_hdr(msg, i);
+ size_t left;
+ u32 vendor_id;
+ struct radius_attr_vendor *vhdr;
+
+ if (attr->type != RADIUS_ATTR_VENDOR_SPECIFIC)
+ continue;
+
+ left = attr->length - sizeof(*attr);
+ if (left < 4)
+ continue;
+
+ pos = (u8 *) (attr + 1);
+
+ os_memcpy(&vendor_id, pos, 4);
+ pos += 4;
+ left -= 4;
+
+ if (ntohl(vendor_id) != vendor)
+ continue;
+
+ while (left >= sizeof(*vhdr)) {
+ vhdr = (struct radius_attr_vendor *) pos;
+ if (vhdr->vendor_length > left ||
+ vhdr->vendor_length < sizeof(*vhdr)) {
+ left = 0;
+ break;
+ }
+ if (vhdr->vendor_type != subtype) {
+ pos += vhdr->vendor_length;
+ left -= vhdr->vendor_length;
+ continue;
+ }
+
+ len = vhdr->vendor_length - sizeof(*vhdr);
+ data = os_malloc(len);
+ if (data == NULL)
+ return NULL;
+ os_memcpy(data, pos + sizeof(*vhdr), len);
+ if (alen)
+ *alen = len;
+ return data;
+ }
+ }
+
+ return NULL;
+}
+
+
+static u8 * decrypt_ms_key(const u8 *key, size_t len,
+ const u8 *req_authenticator,
+ const u8 *secret, size_t secret_len, size_t *reslen)
+{
+ u8 *plain, *ppos, *res;
+ const u8 *pos;
+ size_t left, plen;
+ u8 hash[MD5_MAC_LEN];
+ int i, first = 1;
+ const u8 *addr[3];
+ size_t elen[3];
+
+ /* key: 16-bit salt followed by encrypted key info */
+
+ if (len < 2 + 16)
+ return NULL;
+
+ pos = key + 2;
+ left = len - 2;
+ if (left % 16) {
+ fd_log_debug("Invalid ms key len %lu", (unsigned long) left);
+ return NULL;
+ }
+
+ plen = left;
+ ppos = plain = os_malloc(plen);
+ if (plain == NULL)
+ return NULL;
+ plain[0] = 0;
+
+ while (left > 0) {
+ /* b(1) = MD5(Secret + Request-Authenticator + Salt)
+ * b(i) = MD5(Secret + c(i - 1)) for i > 1 */
+
+ addr[0] = secret;
+ elen[0] = secret_len;
+ if (first) {
+ addr[1] = req_authenticator;
+ elen[1] = MD5_MAC_LEN;
+ addr[2] = key;
+ elen[2] = 2; /* Salt */
+ } else {
+ addr[1] = pos - MD5_MAC_LEN;
+ elen[1] = MD5_MAC_LEN;
+ }
+ md5_vector(first ? 3 : 2, addr, elen, hash);
+ first = 0;
+
+ for (i = 0; i < MD5_MAC_LEN; i++)
+ *ppos++ = *pos++ ^ hash[i];
+ left -= MD5_MAC_LEN;
+ }
+
+ if (plain[0] == 0 || plain[0] > plen - 1) {
+ fd_log_debug("Failed to decrypt MPPE key");
+ os_free(plain);
+ return NULL;
+ }
+
+ res = os_malloc(plain[0]);
+ if (res == NULL) {
+ os_free(plain);
+ return NULL;
+ }
+ os_memcpy(res, plain + 1, plain[0]);
+ if (reslen)
+ *reslen = plain[0];
+ os_free(plain);
+ return res;
+}
+
+
+static void encrypt_ms_key(const u8 *key, size_t key_len, u16 salt,
+ const u8 *req_authenticator,
+ const u8 *secret, size_t secret_len,
+ u8 *ebuf, size_t *elen)
+{
+ int i, len, first = 1;
+ u8 hash[MD5_MAC_LEN], saltbuf[2], *pos;
+ const u8 *addr[3];
+ size_t _len[3];
+
+ WPA_PUT_BE16(saltbuf, salt);
+
+ len = 1 + key_len;
+ if (len & 0x0f) {
+ len = (len & 0xf0) + 16;
+ }
+ os_memset(ebuf, 0, len);
+ ebuf[0] = key_len;
+ os_memcpy(ebuf + 1, key, key_len);
+
+ *elen = len;
+
+ pos = ebuf;
+ while (len > 0) {
+ /* b(1) = MD5(Secret + Request-Authenticator + Salt)
+ * b(i) = MD5(Secret + c(i - 1)) for i > 1 */
+ addr[0] = secret;
+ _len[0] = secret_len;
+ if (first) {
+ addr[1] = req_authenticator;
+ _len[1] = MD5_MAC_LEN;
+ addr[2] = saltbuf;
+ _len[2] = sizeof(saltbuf);
+ } else {
+ addr[1] = pos - MD5_MAC_LEN;
+ _len[1] = MD5_MAC_LEN;
+ }
+ md5_vector(first ? 3 : 2, addr, _len, hash);
+ first = 0;
+
+ for (i = 0; i < MD5_MAC_LEN; i++)
+ *pos++ ^= hash[i];
+
+ len -= MD5_MAC_LEN;
+ }
+}
+
+
+struct radius_ms_mppe_keys *
+radius_msg_get_ms_keys(struct radius_msg *msg, struct radius_msg *sent_msg,
+ const u8 *secret, size_t secret_len)
+{
+ u8 *key;
+ size_t keylen;
+ struct radius_ms_mppe_keys *keys;
+
+ if (msg == NULL || sent_msg == NULL)
+ return NULL;
+
+ keys = os_zalloc(sizeof(*keys));
+ if (keys == NULL)
+ return NULL;
+
+ key = radius_msg_get_vendor_attr(msg, RADIUS_VENDOR_ID_MICROSOFT,
+ RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY,
+ &keylen);
+ if (key) {
+ keys->send = decrypt_ms_key(key, keylen,
+ sent_msg->hdr->authenticator,
+ secret, secret_len,
+ &keys->send_len);
+ os_free(key);
+ }
+
+ key = radius_msg_get_vendor_attr(msg, RADIUS_VENDOR_ID_MICROSOFT,
+ RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY,
+ &keylen);
+ if (key) {
+ keys->recv = decrypt_ms_key(key, keylen,
+ sent_msg->hdr->authenticator,
+ secret, secret_len,
+ &keys->recv_len);
+ os_free(key);
+ }
+
+ return keys;
+}
+
+
+struct radius_ms_mppe_keys *
+radius_msg_get_cisco_keys(struct radius_msg *msg, struct radius_msg *sent_msg,
+ const u8 *secret, size_t secret_len)
+{
+ u8 *key;
+ size_t keylen;
+ struct radius_ms_mppe_keys *keys;
+
+ if (msg == NULL || sent_msg == NULL)
+ return NULL;
+
+ keys = os_zalloc(sizeof(*keys));
+ if (keys == NULL)
+ return NULL;
+
+ key = radius_msg_get_vendor_attr(msg, RADIUS_VENDOR_ID_CISCO,
+ RADIUS_CISCO_AV_PAIR, &keylen);
+ if (key && keylen == 51 &&
+ os_memcmp(key, "leap:session-key=", 17) == 0) {
+ keys->recv = decrypt_ms_key(key + 17, keylen - 17,
+ sent_msg->hdr->authenticator,
+ secret, secret_len,
+ &keys->recv_len);
+ }
+ os_free(key);
+
+ return keys;
+}
+
+
+int radius_msg_add_mppe_keys(struct radius_msg *msg,
+ const u8 *req_authenticator,
+ const u8 *secret, size_t secret_len,
+ const u8 *send_key, size_t send_key_len,
+ const u8 *recv_key, size_t recv_key_len)
+{
+ struct radius_attr_hdr *attr;
+ u32 vendor_id = htonl(RADIUS_VENDOR_ID_MICROSOFT);
+ u8 *buf;
+ struct radius_attr_vendor *vhdr;
+ u8 *pos;
+ size_t elen;
+ int hlen;
+ u16 salt;
+
+ hlen = sizeof(vendor_id) + sizeof(*vhdr) + 2;
+
+ /* MS-MPPE-Send-Key */
+ buf = os_malloc(hlen + send_key_len + 16);
+ if (buf == NULL) {
+ return 0;
+ }
+ pos = buf;
+ os_memcpy(pos, &vendor_id, sizeof(vendor_id));
+ pos += sizeof(vendor_id);
+ vhdr = (struct radius_attr_vendor *) pos;
+ vhdr->vendor_type = RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY;
+ pos = (u8 *) (vhdr + 1);
+ salt = os_random() | 0x8000;
+ WPA_PUT_BE16(pos, salt);
+ pos += 2;
+ encrypt_ms_key(send_key, send_key_len, salt, req_authenticator, secret,
+ secret_len, pos, &elen);
+ vhdr->vendor_length = hlen + elen - sizeof(vendor_id);
+
+ attr = radius_msg_add_attr(msg, RADIUS_ATTR_VENDOR_SPECIFIC,
+ buf, hlen + elen);
+ os_free(buf);
+ if (attr == NULL) {
+ return 0;
+ }
+
+ /* MS-MPPE-Recv-Key */
+ buf = os_malloc(hlen + send_key_len + 16);
+ if (buf == NULL) {
+ return 0;
+ }
+ pos = buf;
+ os_memcpy(pos, &vendor_id, sizeof(vendor_id));
+ pos += sizeof(vendor_id);
+ vhdr = (struct radius_attr_vendor *) pos;
+ vhdr->vendor_type = RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY;
+ pos = (u8 *) (vhdr + 1);
+ salt ^= 1;
+ WPA_PUT_BE16(pos, salt);
+ pos += 2;
+ encrypt_ms_key(recv_key, recv_key_len, salt, req_authenticator, secret,
+ secret_len, pos, &elen);
+ vhdr->vendor_length = hlen + elen - sizeof(vendor_id);
+
+ attr = radius_msg_add_attr(msg, RADIUS_ATTR_VENDOR_SPECIFIC,
+ buf, hlen + elen);
+ os_free(buf);
+ if (attr == NULL) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* Add User-Password attribute to a RADIUS message and encrypt it as specified
+ * in RFC 2865, Chap. 5.2 */
+struct radius_attr_hdr *
+radius_msg_add_attr_user_password(struct radius_msg *msg,
+ const u8 *data, size_t data_len,
+ const u8 *secret, size_t secret_len)
+{
+ u8 buf[128];
+ int padlen, i;
+ size_t buf_len, pos;
+ const u8 *addr[2];
+ size_t len[2];
+ u8 hash[16];
+
+ if (data_len > 128)
+ return NULL;
+
+ os_memcpy(buf, data, data_len);
+ buf_len = data_len;
+
+ padlen = data_len % 16;
+ if (padlen) {
+ padlen = 16 - padlen;
+ os_memset(buf + data_len, 0, padlen);
+ buf_len += padlen;
+ }
+
+ addr[0] = secret;
+ len[0] = secret_len;
+ addr[1] = msg->hdr->authenticator;
+ len[1] = 16;
+ md5_vector(2, addr, len, hash);
+
+ for (i = 0; i < 16; i++)
+ buf[i] ^= hash[i];
+ pos = 16;
+
+ while (pos < buf_len) {
+ addr[0] = secret;
+ len[0] = secret_len;
+ addr[1] = &buf[pos - 16];
+ len[1] = 16;
+ md5_vector(2, addr, len, hash);
+
+ for (i = 0; i < 16; i++)
+ buf[pos + i] ^= hash[i];
+
+ pos += 16;
+ }
+
+ return radius_msg_add_attr(msg, RADIUS_ATTR_USER_PASSWORD,
+ buf, buf_len);
+}
+
+
+int radius_msg_get_attr(struct radius_msg *msg, u8 type, u8 *buf, size_t len)
+{
+ struct radius_attr_hdr *attr = NULL, *tmp;
+ size_t i, dlen;
+
+ for (i = 0; i < msg->attr_used; i++) {
+ tmp = radius_get_attr_hdr(msg, i);
+ if (tmp->type == type) {
+ attr = tmp;
+ break;
+ }
+ }
+
+ if (!attr)
+ return -1;
+
+ dlen = attr->length - sizeof(*attr);
+ if (buf)
+ os_memcpy(buf, (attr + 1), dlen > len ? len : dlen);
+ return dlen;
+}
+
+
+int radius_msg_get_attr_ptr(struct radius_msg *msg, u8 type, u8 **buf,
+ size_t *len, const u8 *start)
+{
+ size_t i;
+ struct radius_attr_hdr *attr = NULL, *tmp;
+
+ for (i = 0; i < msg->attr_used; i++) {
+ tmp = radius_get_attr_hdr(msg, i);
+ if (tmp->type == type &&
+ (start == NULL || (u8 *) tmp > start)) {
+ attr = tmp;
+ break;
+ }
+ }
+
+ if (!attr)
+ return -1;
+
+ *buf = (u8 *) (attr + 1);
+ *len = attr->length - sizeof(*attr);
+ return 0;
+}
+
+
+int radius_msg_count_attr(struct radius_msg *msg, u8 type, int min_len)
+{
+ size_t i;
+ int count;
+
+ for (count = 0, i = 0; i < msg->attr_used; i++) {
+ struct radius_attr_hdr *attr = radius_get_attr_hdr(msg, i);
+ if (attr->type == type &&
+ attr->length >= sizeof(struct radius_attr_hdr) + min_len)
+ count++;
+ }
+
+ return count;
+}
+
+
+struct radius_tunnel_attrs {
+ int tag_used;
+ int type; /* Tunnel-Type */
+ int medium_type; /* Tunnel-Medium-Type */
+ int vlanid;
+};
+
+
+/**
+ * radius_msg_get_vlanid - Parse RADIUS attributes for VLAN tunnel information
+ * @msg: RADIUS message
+ * Returns: VLAN ID for the first tunnel configuration of -1 if none is found
+ */
+int radius_msg_get_vlanid(struct radius_msg *msg)
+{
+ struct radius_tunnel_attrs tunnel[RADIUS_TUNNEL_TAGS], *tun;
+ size_t i;
+ struct radius_attr_hdr *attr = NULL;
+ const u8 *data;
+ char buf[10];
+ size_t dlen;
+
+ os_memset(&tunnel, 0, sizeof(tunnel));
+
+ for (i = 0; i < msg->attr_used; i++) {
+ attr = radius_get_attr_hdr(msg, i);
+ data = (const u8 *) (attr + 1);
+ dlen = attr->length - sizeof(*attr);
+ if (attr->length < 3)
+ continue;
+ if (data[0] >= RADIUS_TUNNEL_TAGS)
+ tun = &tunnel[0];
+ else
+ tun = &tunnel[data[0]];
+
+ switch (attr->type) {
+ case RADIUS_ATTR_TUNNEL_TYPE:
+ if (attr->length != 6)
+ break;
+ tun->tag_used++;
+ tun->type = WPA_GET_BE24(data + 1);
+ break;
+ case RADIUS_ATTR_TUNNEL_MEDIUM_TYPE:
+ if (attr->length != 6)
+ break;
+ tun->tag_used++;
+ tun->medium_type = WPA_GET_BE24(data + 1);
+ break;
+ case RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID:
+ if (data[0] < RADIUS_TUNNEL_TAGS) {
+ data++;
+ dlen--;
+ }
+ if (dlen >= sizeof(buf))
+ break;
+ os_memcpy(buf, data, dlen);
+ buf[dlen] = '\0';
+ tun->tag_used++;
+ tun->vlanid = atoi(buf);
+ break;
+ }
+ }
+
+ for (i = 0; i < RADIUS_TUNNEL_TAGS; i++) {
+ tun = &tunnel[i];
+ if (tun->tag_used &&
+ tun->type == RADIUS_TUNNEL_TYPE_VLAN &&
+ tun->medium_type == RADIUS_TUNNEL_MEDIUM_TYPE_802 &&
+ tun->vlanid > 0)
+ return tun->vlanid;
+ }
+
+ return -1;
+}
+
+
+void radius_free_class(struct radius_class_data *c)
+{
+ size_t i;
+ if (c == NULL)
+ return;
+ for (i = 0; i < c->count; i++)
+ os_free(c->attr[i].data);
+ os_free(c->attr);
+ c->attr = NULL;
+ c->count = 0;
+}
+
+
+int radius_copy_class(struct radius_class_data *dst,
+ const struct radius_class_data *src)
+{
+ size_t i;
+
+ if (src->attr == NULL)
+ return 0;
+
+ dst->attr = os_zalloc(src->count * sizeof(struct radius_attr_data));
+ if (dst->attr == NULL)
+ return -1;
+
+ dst->count = 0;
+
+ for (i = 0; i < src->count; i++) {
+ dst->attr[i].data = os_malloc(src->attr[i].len);
+ if (dst->attr[i].data == NULL)
+ break;
+ dst->count++;
+ os_memcpy(dst->attr[i].data, src->attr[i].data,
+ src->attr[i].len);
+ dst->attr[i].len = src->attr[i].len;
+ }
+
+ return 0;
+}
diff --git a/extensions/app_radgw/radius.h b/extensions/app_radgw/radius.h
new file mode 100644
index 0000000..c278472
--- /dev/null
+++ b/extensions/app_radgw/radius.h
@@ -0,0 +1,331 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*********************************************************************************/
+/* freeDiameter author note:
+ * The content from this file comes mostly from the hostap project.
+ * It is redistributed under the terms of the BSD license, as allowed
+ * by the original copyright reproduced below.
+ * The changes to this file are placed under the copyright of the freeDiameter project.
+ */
+
+/*
+ * hostapd / RADIUS message processing
+ * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+/*********************************************************************************/
+
+
+#ifndef RADIUS_H
+#define RADIUS_H
+
+/* RFC 2865 - RADIUS */
+
+#ifdef _MSC_VER
+#pragma pack(push, 1)
+#endif /* _MSC_VER */
+
+struct radius_hdr {
+ u8 code;
+ u8 identifier;
+ u16 length; /* including this header */
+ u8 authenticator[16];
+ /* followed by length-20 octets of attributes */
+} STRUCT_PACKED;
+
+enum { RADIUS_CODE_ACCESS_REQUEST = 1,
+ RADIUS_CODE_ACCESS_ACCEPT = 2,
+ RADIUS_CODE_ACCESS_REJECT = 3,
+ RADIUS_CODE_ACCOUNTING_REQUEST = 4,
+ RADIUS_CODE_ACCOUNTING_RESPONSE = 5,
+ RADIUS_CODE_ACCESS_CHALLENGE = 11,
+ RADIUS_CODE_STATUS_SERVER = 12,
+ RADIUS_CODE_STATUS_CLIENT = 13,
+ RADIUS_CODE_RESERVED = 255
+};
+
+struct radius_attr_hdr {
+ u8 type;
+ u8 length; /* including this header */
+ /* followed by length-2 octets of attribute value */
+} STRUCT_PACKED;
+
+#define RADIUS_MAX_ATTR_LEN (255 - sizeof(struct radius_attr_hdr))
+
+enum { RADIUS_ATTR_USER_NAME = 1,
+ RADIUS_ATTR_USER_PASSWORD = 2,
+ RADIUS_ATTR_NAS_IP_ADDRESS = 4,
+ RADIUS_ATTR_NAS_PORT = 5,
+ RADIUS_ATTR_FRAMED_MTU = 12,
+ RADIUS_ATTR_REPLY_MESSAGE = 18,
+ RADIUS_ATTR_STATE = 24,
+ RADIUS_ATTR_CLASS = 25,
+ RADIUS_ATTR_VENDOR_SPECIFIC = 26,
+ RADIUS_ATTR_SESSION_TIMEOUT = 27,
+ RADIUS_ATTR_IDLE_TIMEOUT = 28,
+ RADIUS_ATTR_TERMINATION_ACTION = 29,
+ RADIUS_ATTR_CALLED_STATION_ID = 30,
+ RADIUS_ATTR_CALLING_STATION_ID = 31,
+ RADIUS_ATTR_NAS_IDENTIFIER = 32,
+ RADIUS_ATTR_PROXY_STATE = 33,
+ RADIUS_ATTR_ACCT_STATUS_TYPE = 40,
+ RADIUS_ATTR_ACCT_DELAY_TIME = 41,
+ RADIUS_ATTR_ACCT_INPUT_OCTETS = 42,
+ RADIUS_ATTR_ACCT_OUTPUT_OCTETS = 43,
+ RADIUS_ATTR_ACCT_SESSION_ID = 44,
+ RADIUS_ATTR_ACCT_AUTHENTIC = 45,
+ RADIUS_ATTR_ACCT_SESSION_TIME = 46,
+ RADIUS_ATTR_ACCT_INPUT_PACKETS = 47,
+ RADIUS_ATTR_ACCT_OUTPUT_PACKETS = 48,
+ RADIUS_ATTR_ACCT_TERMINATE_CAUSE = 49,
+ RADIUS_ATTR_ACCT_MULTI_SESSION_ID = 50,
+ RADIUS_ATTR_ACCT_LINK_COUNT = 51,
+ RADIUS_ATTR_ACCT_INPUT_GIGAWORDS = 52,
+ RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS = 53,
+ RADIUS_ATTR_EVENT_TIMESTAMP = 55,
+ RADIUS_ATTR_NAS_PORT_TYPE = 61,
+ RADIUS_ATTR_TUNNEL_TYPE = 64,
+ RADIUS_ATTR_TUNNEL_MEDIUM_TYPE = 65,
+ RADIUS_ATTR_CONNECT_INFO = 77,
+ RADIUS_ATTR_EAP_MESSAGE = 79,
+ RADIUS_ATTR_MESSAGE_AUTHENTICATOR = 80,
+ RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID = 81,
+ RADIUS_ATTR_ACCT_INTERIM_INTERVAL = 85,
+ RADIUS_ATTR_CHARGEABLE_USER_IDENTITY = 89,
+ RADIUS_ATTR_NAS_IPV6_ADDRESS = 95
+};
+
+
+/* Termination-Action */
+#define RADIUS_TERMINATION_ACTION_DEFAULT 0
+#define RADIUS_TERMINATION_ACTION_RADIUS_REQUEST 1
+
+/* NAS-Port-Type */
+#define RADIUS_NAS_PORT_TYPE_IEEE_802_11 19
+
+/* Acct-Status-Type */
+#define RADIUS_ACCT_STATUS_TYPE_START 1
+#define RADIUS_ACCT_STATUS_TYPE_STOP 2
+#define RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE 3
+#define RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON 7
+#define RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF 8
+
+/* Acct-Authentic */
+#define RADIUS_ACCT_AUTHENTIC_RADIUS 1
+#define RADIUS_ACCT_AUTHENTIC_LOCAL 2
+#define RADIUS_ACCT_AUTHENTIC_REMOTE 3
+
+/* Acct-Terminate-Cause */
+#define RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST 1
+#define RADIUS_ACCT_TERMINATE_CAUSE_LOST_CARRIER 2
+#define RADIUS_ACCT_TERMINATE_CAUSE_LOST_SERVICE 3
+#define RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT 4
+#define RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT 5
+#define RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_RESET 6
+#define RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT 7
+#define RADIUS_ACCT_TERMINATE_CAUSE_PORT_ERROR 8
+#define RADIUS_ACCT_TERMINATE_CAUSE_NAS_ERROR 9
+#define RADIUS_ACCT_TERMINATE_CAUSE_NAS_REQUEST 10
+#define RADIUS_ACCT_TERMINATE_CAUSE_NAS_REBOOT 11
+#define RADIUS_ACCT_TERMINATE_CAUSE_PORT_UNNEEDED 12
+#define RADIUS_ACCT_TERMINATE_CAUSE_PORT_PREEMPTED 13
+#define RADIUS_ACCT_TERMINATE_CAUSE_PORT_SUSPENDED 14
+#define RADIUS_ACCT_TERMINATE_CAUSE_SERVICE_UNAVAILABLE 15
+#define RADIUS_ACCT_TERMINATE_CAUSE_CALLBACK 16
+#define RADIUS_ACCT_TERMINATE_CAUSE_USER_ERROR 17
+#define RADIUS_ACCT_TERMINATE_CAUSE_HOST_REQUEST 18
+
+#define RADIUS_TUNNEL_TAGS 32
+
+/* Tunnel-Type */
+#define RADIUS_TUNNEL_TYPE_PPTP 1
+#define RADIUS_TUNNEL_TYPE_L2TP 3
+#define RADIUS_TUNNEL_TYPE_IPIP 7
+#define RADIUS_TUNNEL_TYPE_GRE 10
+#define RADIUS_TUNNEL_TYPE_VLAN 13
+
+/* Tunnel-Medium-Type */
+#define RADIUS_TUNNEL_MEDIUM_TYPE_IPV4 1
+#define RADIUS_TUNNEL_MEDIUM_TYPE_IPV6 2
+#define RADIUS_TUNNEL_MEDIUM_TYPE_802 6
+
+
+struct radius_attr_vendor {
+ u8 vendor_type;
+ u8 vendor_length;
+} STRUCT_PACKED;
+
+#define RADIUS_VENDOR_ID_CISCO 9
+#define RADIUS_CISCO_AV_PAIR 1
+
+/* RFC 2548 - Microsoft Vendor-specific RADIUS Attributes */
+#define RADIUS_VENDOR_ID_MICROSOFT 311
+
+enum { RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY = 16,
+ RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY = 17
+};
+
+#ifdef _MSC_VER
+#pragma pack(pop)
+#endif /* _MSC_VER */
+
+struct radius_ms_mppe_keys {
+ u8 *send;
+ size_t send_len;
+ u8 *recv;
+ size_t recv_len;
+};
+
+
+/* RADIUS message structure for new and parsed messages */
+struct radius_msg {
+ unsigned char *buf;
+ size_t buf_size; /* total size allocated for buf */
+ size_t buf_used; /* bytes used in buf */
+
+ struct radius_hdr *hdr;
+
+ size_t *attr_pos; /* array of indexes to attributes (number of bytes
+ * from buf to the beginning of
+ * struct radius_attr_hdr). */
+ size_t attr_size; /* total size of the attribute pointer array */
+ size_t attr_used; /* total number of attributes in the array */
+};
+
+
+/* Default size to be allocated for new RADIUS messages */
+#define RADIUS_DEFAULT_MSG_SIZE 1024
+
+/* Default size to be allocated for attribute array */
+#define RADIUS_DEFAULT_ATTR_COUNT 16
+
+
+/* MAC address ASCII format for IEEE 802.1X use
+ * (draft-congdon-radius-8021x-20.txt) */
+#define RADIUS_802_1X_ADDR_FORMAT "%02X-%02X-%02X-%02X-%02X-%02X"
+/* MAC address ASCII format for non-802.1X use */
+#define RADIUS_ADDR_FORMAT "%02x%02x%02x%02x%02x%02x"
+
+struct radius_msg *radius_msg_new(u8 code, u8 identifier);
+int radius_msg_initialize(struct radius_msg *msg, size_t init_len);
+void radius_msg_set_hdr(struct radius_msg *msg, u8 code, u8 identifier);
+void radius_msg_free(struct radius_msg *msg);
+int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len);
+int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len, const u8 *req_authenticator);
+void radius_msg_finish_acct(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len);
+struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
+ const u8 *data, size_t data_len);
+int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
+ size_t data_len);
+u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *len);
+int radius_msg_verify(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len, struct radius_msg *sent_msg,
+ int auth);
+int radius_msg_verify_msg_auth(struct radius_msg *msg, const u8 *secret,
+ size_t secret_len, const u8 *req_auth);
+int radius_msg_copy_attr(struct radius_msg *dst, struct radius_msg *src,
+ u8 type);
+void radius_msg_make_authenticator(struct radius_msg *msg,
+ const u8 *data, size_t len);
+struct radius_ms_mppe_keys *
+radius_msg_get_ms_keys(struct radius_msg *msg, struct radius_msg *sent_msg,
+ const u8 *secret, size_t secret_len);
+struct radius_ms_mppe_keys *
+radius_msg_get_cisco_keys(struct radius_msg *msg, struct radius_msg *sent_msg,
+ const u8 *secret, size_t secret_len);
+int radius_msg_add_mppe_keys(struct radius_msg *msg,
+ const u8 *req_authenticator,
+ const u8 *secret, size_t secret_len,
+ const u8 *send_key, size_t send_key_len,
+ const u8 *recv_key, size_t recv_key_len);
+struct radius_attr_hdr *
+radius_msg_add_attr_user_password(struct radius_msg *msg,
+ const u8 *data, size_t data_len,
+ const u8 *secret, size_t secret_len);
+int radius_msg_get_attr(struct radius_msg *msg, u8 type, u8 *buf, size_t len);
+int radius_msg_get_vlanid(struct radius_msg *msg);
+
+static inline int radius_msg_add_attr_int32(struct radius_msg *msg, u8 type,
+ u32 value)
+{
+ u32 val = htonl(value);
+ return radius_msg_add_attr(msg, type, (u8 *) &val, 4) != NULL;
+}
+
+int radius_msg_add_attr_to_array(struct radius_msg *msg, struct radius_attr_hdr *attr);
+static inline int radius_msg_get_attr_int32(struct radius_msg *msg, u8 type,
+ u32 *value)
+{
+ u32 val;
+ int res;
+ res = radius_msg_get_attr(msg, type, (u8 *) &val, 4);
+ if (res != 4)
+ return -1;
+
+ *value = ntohl(val);
+ return 0;
+}
+int radius_msg_get_attr_ptr(struct radius_msg *msg, u8 type, u8 **buf,
+ size_t *len, const u8 *start);
+int radius_msg_count_attr(struct radius_msg *msg, u8 type, int min_len);
+
+
+struct radius_attr_data {
+ u8 *data;
+ size_t len;
+};
+
+struct radius_class_data {
+ struct radius_attr_data *attr;
+ size_t count;
+};
+
+void radius_free_class(struct radius_class_data *c);
+int radius_copy_class(struct radius_class_data *dst,
+ const struct radius_class_data *src);
+
+#endif /* RADIUS_H */
diff --git a/extensions/app_radgw/rgw.h b/extensions/app_radgw/rgw.h
new file mode 100644
index 0000000..b6c0911
--- /dev/null
+++ b/extensions/app_radgw/rgw.h
@@ -0,0 +1,134 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* This file contains the definitions for the app_radgw internal use. */
+
+#ifndef _RGW_H
+#define _RGW_H
+
+/* include the common definitions */
+#include "rgw_common.h"
+
+/* RADIUS messages + metadata */
+struct rgw_radius_msg_meta {
+
+ /* The RADIUS message */
+ struct radius_msg radius;
+
+ /* Metadata */
+ struct {
+ /* The port it was sent from, in network byte order */
+ unsigned port :16;
+
+ /* received on ACCT or AUTH port? */
+ unsigned serv_type :2;
+
+ /* The message has a valid Message-Authenticator attribute */
+ unsigned valid_mac :1;
+ };
+
+ /* For Proxy-State attributes: */
+ int ps_first; /* The index of the first Proxy-State attribute in radius.attr_pos. It is always >= radius.attr_used */
+ int ps_nb; /* The number of Proxy-State attributes. The real radius.attr_pos size is attr_used + ps_nb */
+};
+void rgw_msg_free(struct rgw_radius_msg_meta ** msg);
+int rgw_msg_parse(unsigned char * buf, size_t len, struct rgw_radius_msg_meta ** msg);
+void rgw_msg_dump(struct rgw_radius_msg_meta * msg, int has_meta);
+
+/* Local RADIUS server(s) configuration */
+struct rgw_serv {
+ unsigned disabled :1;
+ unsigned ip_disabled :1;
+ unsigned ip6_disabled :1;
+ unsigned :13; /* padding */
+
+ uint16_t port; /* stored in network byte order */
+
+ struct in_addr ip_endpoint;
+ struct in6_addr ip6_endpoint;
+};
+
+extern struct rgw_servs {
+ struct rgw_serv auth_serv;
+ struct rgw_serv acct_serv;
+} rgw_servers;
+
+int rgw_servers_init(void);
+int rgw_servers_start(void);
+void rgw_servers_dump(void);
+int rgw_servers_send(int type, unsigned char *buf, size_t buflen, struct sockaddr *to, uint16_t to_port);
+void rgw_servers_fini(void);
+
+
+/* Clients management */
+enum rgw_cli_type { RGW_CLI_NAS, RGW_CLI_PXY };
+int rgw_clients_auth_check(struct rgw_radius_msg_meta * msg, struct rgw_client * cli, uint8_t * req_auth);
+int rgw_clients_add( struct sockaddr * ip_port, unsigned char ** key, size_t keylen, enum rgw_cli_type type );
+int rgw_clients_getkey(struct rgw_client * cli, unsigned char **key, size_t *key_len);
+int rgw_clients_gettype(struct rgw_client * cli, enum rgw_cli_type *type);
+int rgw_clients_search(struct sockaddr * ip_port, struct rgw_client ** ref);
+int rgw_clients_check_dup(struct rgw_radius_msg_meta **msg, struct rgw_client *cli);
+int rgw_clients_create_origin(struct rgw_radius_msg_meta *msg, struct rgw_client * cli, struct msg ** diam);
+int rgw_client_finish_send(struct radius_msg ** msg, struct rgw_radius_msg_meta * req, struct rgw_client * cli);
+int rgw_client_finish_nosend(struct rgw_radius_msg_meta * req, struct rgw_client * cli);
+void rgw_clients_dispose(struct rgw_client ** ref);
+void rgw_clients_dump(void);
+int rgw_clients_init(void);
+void rgw_clients_fini(void);
+int rgw_client_session_add(struct rgw_client * cli, struct session *sess, char * dest_realm, char * dest_host, application_id_t appid);
+int rgw_client_session_stop(struct rgw_client * cli, struct session * sess, int32_t reason);
+
+
+/* Management of plugins */
+int rgw_plg_add( char * plgfile, char * conffile, int port, unsigned char ** codes_array, size_t codes_sz );
+void rgw_plg_dump(void);
+void rgw_plg_start_cache(void);
+int rgw_plg_loop_req(struct rgw_radius_msg_meta **rad, struct msg **diam_msg, struct rgw_client * cli);
+int rgw_plg_loop_ans(struct rgw_radius_msg_meta *req, struct msg **diam_ans, struct radius_msg ** rad_ans, struct rgw_client * cli);
+void rgw_plg_fini(void);
+
+
+/* Parse configuration file */
+int rgw_conf_handle(char * conffile);
+
+
+/* Worker module, process incoming RADIUS messages (in separated threads) */
+int rgw_work_start(void);
+int rgw_work_add(struct rgw_radius_msg_meta * msg, struct rgw_client * client);
+void rgw_work_fini(void);
+
+
+#endif /* _RGW_H */
+
diff --git a/extensions/app_radgw/rgw_clients.c b/extensions/app_radgw/rgw_clients.c
new file mode 100644
index 0000000..10922ce
--- /dev/null
+++ b/extensions/app_radgw/rgw_clients.c
@@ -0,0 +1,1181 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Manage the list of RADIUS clients, along with their shared secrets. */
+
+/* Probably some changes are needed to support RADIUS Proxies */
+
+#include "rgw.h"
+
+#define REVERSE_DNS_SIZE_MAX 512 /* length of our buffer for reverse DNS */
+#define DUPLICATE_CHECK_LIFETIME 60 /* number of seconds that the received RADIUS records are kept for duplicate checking . TODO: make it configurable if needed */
+
+/* Ordered lists of clients. The order relationship is a memcmp on the address zone.
+ For same addresses, the port is compared.
+ The same address cannot be added twice, once with a 0-port and once with another port value.
+ */
+static struct fd_list cli_ip = FD_LIST_INITIALIZER(cli_ip);
+static struct fd_list cli_ip6 = FD_LIST_INITIALIZER(cli_ip6);
+
+/* Lock to protect the previous lists. We use a rwlock because this list is mostly static, to allow parallel reading */
+static pthread_rwlock_t cli_rwl = PTHREAD_RWLOCK_INITIALIZER;
+
+/* Structure describing one received RADIUS message, for duplicate checks purpose. */
+struct req_info {
+ uint16_t port; /* UDP source port of the request */
+ uint8_t id; /* The identifier in the request header */
+ uint8_t auth[16]; /* Request authenticator, since some RADIUS clients do not implement the id mechanism properly. */
+ struct radius_msg *ans; /* The replied answer if any, in case the previous answer got lost. */
+
+ int nbdup; /* Number of times this request was received as a duplicate */
+ struct fd_list by_id; /* The list of requests ordered by their id, port, and auth */
+ time_t received; /* When was the last duplicate received? */
+ struct fd_list by_time; /* The list of requests ordered by the 'received' value . */
+};
+
+static pthread_t dbt_expire = (pthread_t)NULL; /* The thread that will remove old requests information from all clients (one thread for all) */
+
+/* Structure describing one client */
+struct rgw_client {
+ /* Link information in global list (cli_ip or cli_ip6) */
+ struct fd_list chain;
+
+ /* Reference count */
+ int refcount;
+
+ /* The address and optional port (alloc'd during configuration file parsing). */
+ union {
+ struct sockaddr *sa; /* generic pointer */
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+ };
+
+ /* The FQDN, realm, and optional aliases */
+ int is_local; /* true if the RADIUS client runs on the same host -- we use Diameter Identity in that case */
+ enum rgw_cli_type type; /* is it a proxy ? */
+ DiamId_t fqdn; /* malloc'd here */
+ size_t fqdn_len;
+ DiamId_t realm; /* references another string, do not free */
+ size_t realm_len;
+ struct {
+ os0_t name;
+ size_t len;
+ } *aliases; /* Received aliases */
+ size_t aliases_nb;
+
+ /* The secret key data. */
+ struct {
+ unsigned char * data;
+ size_t len;
+ } key;
+
+ /* information of previous msg received, for duplicate checks. */
+ struct {
+ pthread_mutex_t dupl_lock; /* The mutex protecting the following lists */
+ struct fd_list dupl_by_id; /* The list of req_info structures ordered by their id, port, and auth */
+ struct fd_list dupl_by_time; /* The list of req_info structures ordered by their time (approximative) */
+ } dupl_info[2]; /*[0] for auth, [1] for acct. */
+};
+
+
+/* Create a new req_info structure and initialize its data from a RADIUS request message */
+static struct req_info * dupl_new_req_info(struct rgw_radius_msg_meta *msg) {
+ struct req_info * ret = NULL;
+ CHECK_MALLOC_DO( ret = malloc(sizeof(struct req_info)), return NULL );
+ memset(ret, 0, sizeof(struct req_info));
+ ret->port = msg->port;
+ ret->id = msg->radius.hdr->identifier;
+ memcpy(&ret->auth[0], &msg->radius.hdr->authenticator[0], 16);
+ fd_list_init(&ret->by_id, ret);
+ fd_list_init(&ret->by_time, ret);
+ ret->received = time(NULL);
+ return ret;
+}
+
+/* Destroy a req_info structure, after it has been unlinked */
+static void dupl_free_req_info(struct req_info * r) {
+ CHECK_PARAMS_DO( r && FD_IS_LIST_EMPTY(&r->by_id) && FD_IS_LIST_EMPTY(&r->by_time), return );
+ if (r->ans) {
+ /* Free this RADIUS message */
+ radius_msg_free(r->ans);
+ free(r->ans);
+ }
+
+ /* Use r->nbdup for some purpose? */
+
+ free(r);
+}
+
+/* The core of the purge thread */
+static int dupl_purge_list(struct fd_list * clients) {
+
+ struct fd_list *li = NULL;
+
+ for (li = clients->next; li != clients; li = li->next) {
+ struct rgw_client * client = (struct rgw_client *)li;
+ int p;
+
+ for (p=0; p<=1; p++) {
+
+ /* Lock this list */
+ time_t now;
+ CHECK_POSIX( pthread_mutex_lock(&client->dupl_info[p].dupl_lock) );
+
+ now = time(NULL);
+
+ while (!FD_IS_LIST_EMPTY(&client->dupl_info[p].dupl_by_time)) {
+
+ /* Check the first item in the list */
+ struct req_info * r = (struct req_info *)(client->dupl_info[p].dupl_by_time.next->o);
+
+ if (now - r->received > DUPLICATE_CHECK_LIFETIME) {
+
+ TRACE_DEBUG(ANNOYING + 1, "Purging RADIUS request (id: %02hhx, port: %hu, dup #%d, age %ld secs)", r->id, ntohs(r->port), r->nbdup, (long)(now - r->received));
+
+ /* Remove this record */
+ fd_list_unlink(&r->by_time);
+ fd_list_unlink(&r->by_id);
+ dupl_free_req_info(r);
+ } else {
+ /* We are done for this list */
+ break;
+ }
+ }
+
+ CHECK_POSIX( pthread_mutex_unlock(&client->dupl_info[p].dupl_lock) );
+ }
+ }
+ return 0;
+}
+
+/* Thread that purges old RADIUS requests */
+static void * dupl_th(void * arg) {
+ /* Set the thread name */
+ fd_log_threadname ( "app_radgw:duplicate_purge" );
+
+ /* The thread will be canceled */
+ while (1) {
+
+ /* We don't use a cond var, we simply wake up every 5 seconds. If the size of the duplicate cache is critical, it might be changed */
+ sleep(5);
+
+ /* When we wake up, we will check all clients duplicate lists one by one */
+ CHECK_POSIX_DO( pthread_rwlock_rdlock(&cli_rwl), break );
+
+ CHECK_FCT_DO( dupl_purge_list(&cli_ip), break );
+ CHECK_FCT_DO( dupl_purge_list(&cli_ip6), break );
+
+ CHECK_POSIX_DO( pthread_rwlock_unlock(&cli_rwl), break );
+
+ /* Loop */
+ }
+
+ /* If we reach this part, some fatal error was encountered */
+ CHECK_FCT_DO(fd_core_shutdown(), );
+ TRACE_DEBUG(FULL, "Thread terminated");
+ return NULL;
+}
+
+
+/* create a new rgw_client. the arguments are MOVED into the structure (to limit malloc & free calls). */
+static int client_create(struct rgw_client ** res, struct sockaddr ** ip_port, unsigned char ** key, size_t keylen, enum rgw_cli_type type )
+{
+ struct rgw_client *tmp = NULL;
+ DiamId_t fqdn;
+ size_t fqdn_len = 0;
+ int ret, i;
+ int loc = 0;
+
+ /* Check if the IP address is local */
+ if ( ( ((*ip_port)->sa_family == AF_INET ) && ( IN_IS_ADDR_LOOPBACK( &((struct sockaddr_in *)(*ip_port))->sin_addr ) ) )
+ ||( ((*ip_port)->sa_family == AF_INET6) && ( IN6_IS_ADDR_LOOPBACK( &((struct sockaddr_in6 *)(*ip_port))->sin6_addr) ) )) {
+ /* The client is local */
+ loc = 1;
+ } else {
+ char buf[255];
+
+ /* Search FQDN for the client */
+ ret = getnameinfo( *ip_port, sizeof(struct sockaddr_storage), &buf[0], sizeof(buf), NULL, 0, 0 );
+ if (ret) {
+ TRACE_DEBUG(INFO, "Unable to resolve peer name: %s", gai_strerror(ret));
+ return EINVAL;
+ }
+ fqdn = &buf[0];
+ CHECK_FCT_DO( ret = fd_os_validate_DiameterIdentity(&fqdn, &fqdn_len, 1),
+ {
+ TRACE_DEBUG(INFO, "Unable to use resolved peer name '%s' as DiameterIdentity: %s", buf, strerror(ret));
+ return ret;
+ } );
+ }
+
+ /* Create the new object */
+ CHECK_MALLOC( tmp = malloc(sizeof (struct rgw_client)) );
+ memset(tmp, 0, sizeof(struct rgw_client));
+ fd_list_init(&tmp->chain, NULL);
+
+ /* Initialize the duplicate list info */
+ for (i=0; i<=1; i++) {
+ CHECK_POSIX( pthread_mutex_init(&tmp->dupl_info[i].dupl_lock, NULL) );
+ fd_list_init(&tmp->dupl_info[i].dupl_by_id, NULL);
+ fd_list_init(&tmp->dupl_info[i].dupl_by_time, NULL);
+ }
+ tmp->type = type;
+
+ if (loc) {
+ tmp->is_local = 1;
+ } else {
+ /* Copy the fqdn */
+ tmp->fqdn = fqdn;
+ tmp->fqdn_len = fqdn_len;
+
+ /* Find an appropriate realm */
+ tmp->realm = strchr(fqdn, '.');
+ if (tmp->realm) {
+ tmp->realm += 1;
+ tmp->realm_len = tmp->fqdn_len - (tmp->realm - fqdn);
+ }
+ if ((!tmp->realm) || (*tmp->realm == '\0')) { /* in case the fqdn was "localhost." for example, if it is possible... */
+ tmp->realm = fd_g_config->cnf_diamrlm;
+ tmp->realm_len = fd_g_config->cnf_diamrlm_len;
+ }
+ }
+
+ /* move the sa info reference */
+ tmp->sa = *ip_port;
+ *ip_port = NULL;
+
+ /* move the key material */
+ tmp->key.data = *key;
+ tmp->key.len = keylen;
+ *key = NULL;
+
+ /* Done! */
+ *res = tmp;
+ return 0;
+}
+
+/* Decrease refcount on a client; the lock must be held when this function is called. */
+static void client_unlink(struct rgw_client * client)
+{
+ client->refcount -= 1;
+
+ if (client->refcount <= 0) {
+ int idx;
+ /* to be sure: the refcount should be 0 only when client_fini is called */
+ ASSERT( FD_IS_LIST_EMPTY(&client->chain) );
+
+ /* Free the data */
+ for (idx = 0; idx < client->aliases_nb; idx++)
+ free(client->aliases[idx].name);
+ free(client->aliases);
+ free(client->fqdn);
+ free(client->sa);
+ free(client->key.data);
+
+ /* Free the duplicate info */
+ for (idx=0; idx <= 1; idx++){
+ CHECK_POSIX_DO( pthread_mutex_lock( &client->dupl_info[idx].dupl_lock ), /* continue */ );
+
+ while (!FD_IS_LIST_EMPTY(&client->dupl_info[idx].dupl_by_id)) {
+ struct req_info * r = (struct req_info *)(client->dupl_info[idx].dupl_by_id.next->o);
+ fd_list_unlink( &r->by_id );
+ fd_list_unlink( &r->by_time );
+ dupl_free_req_info(r);
+ }
+
+ CHECK_POSIX_DO( pthread_mutex_unlock( &client->dupl_info[idx].dupl_lock ), /* continue */ );
+
+ }
+
+ free(client);
+ }
+}
+
+
+/* Macro to avoid duplicating the code in the next function */
+#define client_search_family( _family_ ) \
+ case AF_INET##_family_: { \
+ struct sockaddr_in##_family_ * sin##_family_ = (struct sockaddr_in##_family_ *)ip_port; \
+ for (ref = cli_ip##_family_.next; ref != &cli_ip##_family_; ref = ref->next) { \
+ cmp = memcmp(&sin##_family_->sin##_family_##_addr, \
+ &((struct rgw_client *)ref)->sin##_family_->sin##_family_##_addr, \
+ sizeof(struct in##_family_##_addr)); \
+ if (cmp > 0) continue; /* search further in the list */ \
+ if (cmp < 0) break; /* this IP is not in the list */ \
+ /* Now compare the ports as follow: */ \
+ /* If the ip_port we are searching does not contain a port, just return the first match result */ \
+ if ( (sin##_family_->sin##_family_##_port == 0) \
+ /* If the entry in the list does not contain a port, return it as a match */ \
+ || (((struct rgw_client *)ref)->sin##_family_->sin##_family_##_port == 0) \
+ /* If both ports are equal, it is a match */ \
+ || (sin##_family_->sin##_family_##_port == \
+ ((struct rgw_client *)ref)->sin##_family_->sin##_family_##_port)) { \
+ *res = (struct rgw_client *)ref; \
+ return EEXIST; \
+ } \
+ /* Otherwise, the list is ordered by port value (byte order does not matter */ \
+ if (sin##_family_->sin##_family_##_port \
+ > ((struct rgw_client *)ref)->sin##_family_->sin##_family_##_port) continue; \
+ else break; \
+ } \
+ *res = (struct rgw_client *)(ref->prev); \
+ return ENOENT; \
+ }
+/* Function to look for an existing rgw_client, or the previous element.
+ The cli_rwl must be held for reading (at least) when calling this function.
+ Returns ENOENT if the matching client does not exist, and res points to the previous element in the list.
+ Returns EEXIST if the matching client is found, and res points to this element.
+ Returns other error code on other error. */
+static int client_search(struct rgw_client ** res, struct sockaddr * ip_port )
+{
+ int cmp;
+ struct fd_list *ref = NULL;
+
+ CHECK_PARAMS(res && ip_port);
+
+ switch (ip_port->sa_family) {
+ client_search_family()
+ break;
+
+ client_search_family( 6 )
+ break;
+ }
+
+ /* We're never supposed to reach this point */
+ ASSERT(0);
+ return EINVAL;
+}
+
+int rgw_clients_getkey(struct rgw_client * cli, unsigned char **key, size_t *key_len)
+{
+ CHECK_PARAMS( cli && key && key_len );
+ *key = cli->key.data;
+ *key_len = cli->key.len;
+ return 0;
+}
+
+int rgw_clients_gettype(struct rgw_client * cli, enum rgw_cli_type *type)
+{
+ CHECK_PARAMS( cli && type );
+ *type = cli->type;
+ return 0;
+}
+
+
+int rgw_clients_search(struct sockaddr * ip_port, struct rgw_client ** ref)
+{
+ int ret = 0;
+
+ TRACE_ENTRY("%p %p", ip_port, ref);
+
+ CHECK_PARAMS(ip_port && ref);
+
+ CHECK_POSIX( pthread_rwlock_rdlock(&cli_rwl) );
+
+ ret = client_search(ref, ip_port);
+ if (ret == EEXIST) {
+ (*ref)->refcount ++;
+ ret = 0;
+ } else {
+ *ref = NULL;
+ }
+
+ CHECK_POSIX( pthread_rwlock_unlock(&cli_rwl) );
+
+ return ret;
+}
+
+int rgw_clients_check_dup(struct rgw_radius_msg_meta **msg, struct rgw_client *cli)
+{
+ int p, dup = 0;
+ struct fd_list * li;
+ struct req_info * r;
+
+ TRACE_ENTRY("%p %p", msg, cli);
+
+ CHECK_PARAMS( msg && cli );
+
+ if ((*msg)->serv_type == RGW_PLG_TYPE_AUTH)
+ p = 0;
+ else
+ p = 1;
+
+ CHECK_POSIX( pthread_mutex_lock( &cli->dupl_info[p].dupl_lock ) );
+
+ /* Search if we have this message in our list */
+ for (li = cli->dupl_info[p].dupl_by_id.next; li != &cli->dupl_info[p].dupl_by_id; li = li->next) {
+ int cmp = 0;
+ r = (struct req_info *)(li->o);
+ if (r->id < (*msg)->radius.hdr->identifier)
+ continue;
+ if (r->id > (*msg)->radius.hdr->identifier)
+ break;
+ if (r->port < (*msg)->port)
+ continue;
+ if (r->port > (*msg)->port)
+ break;
+ cmp = memcmp(&r->auth[0], &(*msg)->radius.hdr->authenticator[0], 16);
+ if (cmp < 0)
+ continue;
+ if (cmp > 0)
+ break;
+ dup = 1;
+ break;
+ }
+
+ if (dup) {
+ time_t now = time(NULL);
+ r->nbdup += 1;
+ TRACE_DEBUG(INFO, "Received duplicated RADIUS message (id: %02hhx, port: %hu, dup #%d, previously seen %ld secs ago).",
+ r->id, ntohs(r->port), r->nbdup, (long)(now - r->received));
+
+ if (r->ans) {
+ /* Resend the answer */
+ CHECK_FCT_DO( rgw_servers_send((*msg)->serv_type, r->ans->buf, r->ans->buf_used, cli->sa, r->port), );
+
+ /* Should we delete 'r' so that a further duplicate will again be converted to Diameter? */
+ }
+
+ /* Update the timestamp */
+ r->received = now;
+ fd_list_unlink(&r->by_time);
+ fd_list_insert_before(&cli->dupl_info[p].dupl_by_time, &r->by_time); /* Move as last entry, since it is the most recent */
+
+ /* Delete the request message */
+ rgw_msg_free(msg);
+
+ } else {
+ /* The message was not a duplicate, we save it */
+ /* li currently points the the next entry in list_by_id */
+ CHECK_MALLOC_DO( r= dupl_new_req_info(*msg), { CHECK_POSIX_DO(pthread_mutex_unlock( &cli->dupl_info[p].dupl_lock ), ); return ENOMEM; } );
+ fd_list_insert_before(li, &r->by_id);
+ fd_list_insert_before(&cli->dupl_info[p].dupl_by_time, &r->by_time); /* it is the most recent */
+ }
+
+ CHECK_POSIX( pthread_mutex_unlock( &cli->dupl_info[p].dupl_lock ) );
+
+ return 0;
+}
+
+/* Check if the message has a valid authenticator, and update the meta-data accordingly */
+int rgw_clients_auth_check(struct rgw_radius_msg_meta * msg, struct rgw_client * cli, uint8_t * req_auth)
+{
+ unsigned char * key;
+ size_t keylen;
+ int count;
+
+ TRACE_ENTRY("%p %p %p", msg, cli, req_auth);
+
+ CHECK_PARAMS(msg && cli);
+
+ CHECK_FCT(rgw_clients_getkey(cli, &key, &keylen));
+
+ count = radius_msg_count_attr(&msg->radius, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, 0);
+ if (count > 1) {
+ TRACE_DEBUG(INFO, "Too many Message-Authenticator attributes (%d), discarding message.", count);
+ return EINVAL;
+ }
+ if (count == 0) {
+ TRACE_DEBUG(FULL, "Message does not contain a Message-Authenticator attributes.");
+ msg->valid_mac = 0;
+ } else {
+ if (radius_msg_verify_msg_auth( &msg->radius, key, keylen, req_auth )) {
+ TRACE_DEBUG(INFO, "Invalid Message-Authenticator received, discarding message.");
+ return EINVAL;
+ }
+ msg->valid_mac = 1;
+ }
+
+ return 0;
+}
+
+static struct dict_object * cache_orig_host = NULL;
+static struct dict_object * cache_orig_realm = NULL;
+static struct dict_object * cache_route_record = NULL;
+
+int rgw_clients_init(void)
+{
+ TRACE_ENTRY();
+ CHECK_FCT( fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &cache_orig_host, ENOENT) );
+ CHECK_FCT( fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &cache_orig_realm, ENOENT) );
+ CHECK_FCT( fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Route-Record", &cache_route_record, ENOENT) );
+
+ /* Create the thread that will purge old RADIUS duplicates */
+ CHECK_POSIX( pthread_create( &dbt_expire, NULL, dupl_th, NULL) );
+
+ return 0;
+}
+
+
+/* The following function checks if a RADIUS message contains a valid NAS identifier, and initializes an empty Diameter
+ message with the appropriate routing information */
+/* Check that the NAS-IP-Adress or NAS-Identifier is coherent with the IP the packet was received from */
+/* Also update the client list of aliases if needed */
+int rgw_clients_create_origin(struct rgw_radius_msg_meta *msg, struct rgw_client * cli, struct msg ** diam)
+{
+ int idx;
+ int valid_nas_info = 0;
+ struct radius_attr_hdr *nas_ip = NULL, *nas_ip6 = NULL, *nas_id = NULL;
+ size_t nas_id_len;
+ char * oh_str = NULL; size_t oh_strlen = 0; int oh_free = 0;
+ char * or_str = NULL; size_t or_strlen = 0;
+ char * rr_str = NULL; size_t rr_strlen = 0;
+ char buf[REVERSE_DNS_SIZE_MAX]; /* to store DNS lookups results */
+
+ struct avp *avp = NULL;
+ union avp_value avp_val;
+
+ TRACE_ENTRY("%p %p %p", msg, cli, diam);
+ CHECK_PARAMS(msg && cli && diam && (*diam == NULL));
+
+ /* Find the relevant attributes, if any */
+ for (idx = 0; idx < msg->radius.attr_used; idx++) {
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[idx]);
+ size_t attr_len = attr->length - sizeof(struct radius_attr_hdr);
+
+ if ((attr->type == RADIUS_ATTR_NAS_IP_ADDRESS) && (attr_len = 4)) {
+ nas_ip = attr;
+ continue;
+ }
+
+ if ((attr->type == RADIUS_ATTR_NAS_IDENTIFIER) && (attr_len > 0)) {
+ nas_id = attr;
+ nas_id_len = attr_len;
+ continue;
+ }
+
+ if ((attr->type == RADIUS_ATTR_NAS_IPV6_ADDRESS) && (attr_len = 16)) {
+ nas_ip6 = attr;
+ continue;
+ }
+ }
+
+ if (!nas_ip && !nas_ip6 && !nas_id) {
+ TRACE_DEBUG(FULL, "The message does not contain any NAS identification attribute.");
+
+ /* Get information on this peer */
+ CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
+
+ goto diameter;
+ }
+
+ /* Check if the message was received from the IP in NAS-IP-Address attribute */
+ if (nas_ip && (cli->sa->sa_family == AF_INET) && !memcmp(nas_ip+1, &cli->sin->sin_addr, sizeof(struct in_addr))) {
+ TRACE_DEBUG(FULL, "NAS-IP-Address contains the same address as the message was received from.");
+ valid_nas_info |= 1;
+ }
+ if (nas_ip6 && (cli->sa->sa_family == AF_INET6) && !memcmp(nas_ip6+1, &cli->sin6->sin6_addr, sizeof(struct in6_addr))) {
+ TRACE_DEBUG(FULL, "NAS-IPv6-Address contains the same address as the message was received from.");
+ valid_nas_info |= 2;
+ }
+
+
+ /*
+ In RADIUS it would be possible for a rogue NAS to forge the NAS-IP-
+ Address attribute value. Diameter/RADIUS translation agents MUST
+ check a received NAS-IP-Address or NAS-IPv6-Address attribute against
+ the source address of the RADIUS packet. If they do not match and
+ the Diameter/RADIUS translation agent does not know whether the
+ packet was sent by a RADIUS proxy or NAS (e.g., no Proxy-State
+ attribute), then by default it is assumed that the source address
+ corresponds to a RADIUS proxy, and that the NAS Address is behind
+ that proxy, potentially with some additional RADIUS proxies in
+ between. The Diameter/RADIUS translation agent MUST insert entries
+ in the Route-Record AVP corresponding to the apparent route. This
+ implies doing a reverse lookup on the source address and NAS-IP-
+ Address or NAS-IPv6-Address attributes to determine the corresponding
+ FQDNs.
+
+ If the source address and the NAS-IP-Address or NAS-IPv6-Address do
+ not match, and the Diameter/RADIUS translation agent knows that it is
+ talking directly to the NAS (e.g., there are no RADIUS proxies
+ between it and the NAS), then the error should be logged, and the
+ packet MUST be discarded.
+
+ Diameter agents and servers MUST check whether the NAS-IP-Address AVP
+ corresponds to an entry in the Route-Record AVP. This is done by
+ doing a reverse lookup (PTR RR) for the NAS-IP-Address to retrieve
+ the corresponding FQDN, and by checking for a match with the Route-
+ Record AVP. If no match is found, then an error is logged, but no
+ other action is taken.
+ */
+ if (nas_ip || nas_ip6) {
+ if (!valid_nas_info) {
+ if ((!cli->is_local) && (cli->type == RGW_CLI_NAS)) {
+ TRACE_DEBUG(INFO, "Message received with a NAS-IP-Address or NAS-IPv6-Address different from the sender's. Please configure as Proxy if this is expected. Message discarded.");
+ return EINVAL;
+ } else {
+ int ret;
+ sSS ss;
+ /* the peer is configured as a proxy, or running on localhost, so accept the message */
+
+ /* In that case, the cli will be stored as Route-Record and the NAS-IP-Address as origin */
+ if (!cli->is_local) {
+ rr_str = cli->fqdn;
+ rr_strlen = cli->fqdn_len;
+ }
+
+ /* We must DNS-reverse the NAS-IP*-Address */
+ memset(&ss, 0 , sizeof(sSS));
+ if (nas_ip) {
+ sSA4 * sin = (sSA4 *)&ss;
+ sin->sin_family = AF_INET;
+ memcpy(&sin->sin_addr, nas_ip + 1, sizeof(struct in_addr));
+ } else {
+ sSA6 * sin6 = (sSA6 *)&ss;
+ sin6->sin6_family = AF_INET6;
+ memcpy(&sin6->sin6_addr, nas_ip6 + 1, sizeof(struct in6_addr));
+ }
+ CHECK_SYS_DO( getnameinfo( (sSA *)&ss, sSAlen(&ss), &buf[0], sizeof(buf), NULL, 0, NI_NAMEREQD),
+ {
+ if (cli->is_local) {
+ CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
+ goto diameter;
+ }
+
+ TRACE_DEBUG(INFO, "The NAS-IP*-Address cannot be DNS reversed in order to create the Origin-Host AVP; rejecting the message (translation is impossible).");
+ return EINVAL;
+ } );
+
+ oh_str = &buf[0];
+ CHECK_FCT_DO( ret = fd_os_validate_DiameterIdentity(&oh_str, &oh_strlen, 1),
+ {
+ if (cli->is_local) {
+ CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
+ goto diameter;
+ }
+
+ TRACE_DEBUG(INFO, "Unable to use resolved client name '%s' as DiameterIdentity: %s", buf, strerror(ret));
+ return ret;
+ } );
+ oh_free = 1;
+
+ or_str = strchr(oh_str, '.');
+ if (or_str) {
+ or_str ++; /* move after the first dot */
+ if (*or_str == '\0')
+ or_str = NULL; /* Discard this realm, we will use the local realm later */
+ else
+ or_strlen = oh_strlen - (or_str - oh_str);
+ }
+ }
+ } else {
+ /* The attribute matches the source address, just use this in origin-host */
+ CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
+ }
+
+ goto diameter; /* we ignore the nas_id in that case */
+ }
+
+ /* We don't have a NAS-IP*-Address attribute if we are here */
+ if (cli->is_local) {
+ /* Simple: we use our own configuration */
+ CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
+ goto diameter;
+ }
+
+ /* At this point, we only have nas_id, and the client is not local */
+ ASSERT(nas_id);
+
+ {
+ int found, ret;
+ struct addrinfo hint, *res, *ptr;
+
+ /*
+ In RADIUS it would be possible for a rogue NAS to forge the NAS-
+ Identifier attribute. Diameter/RADIUS translation agents SHOULD
+ attempt to check a received NAS-Identifier attribute against the
+ source address of the RADIUS packet, by doing an A/AAAA RR query. If
+ the NAS-Identifier attribute contains an FQDN, then such a query
+ would resolve to an IP address matching the source address. However,
+ the NAS-Identifier attribute is not required to contain an FQDN, so
+ such a query could fail. If it fails, an error should be logged, but
+ no action should be taken, other than a reverse lookup on the source
+ address and insert the resulting FQDN into the Route-Record AVP.
+
+ Diameter agents and servers SHOULD check whether a NAS-Identifier AVP
+ corresponds to an entry in the Route-Record AVP. If no match is
+ found, then an error is logged, but no other action is taken.
+ */
+
+ /* first, check if the nas_id is the fqdn of the peer or a known alias */
+ if (!fd_os_almostcasesrch(nas_id + 1, nas_id_len,
+ cli->fqdn, cli->fqdn_len, NULL)) {
+ TRACE_DEBUG(FULL, "NAS-Identifier contains the fqdn of the client");
+ found = 1;
+ } else {
+ for (idx = 0; idx < cli->aliases_nb; idx++) {
+ if (!fd_os_cmp(nas_id + 1, nas_id_len,
+ cli->aliases[idx].name, cli->aliases[idx].len)) {
+ TRACE_DEBUG(FULL, "NAS-Identifier valid value found in the cache");
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ /* The NAS-Identifier matches the source IP */
+ CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
+
+ goto diameter;
+ }
+
+ /* Attempt DNS resolution of the identifier */
+ ASSERT( nas_id_len < sizeof(buf) );
+ memcpy(buf, nas_id + 1, nas_id_len);
+ buf[nas_id->length - sizeof(struct radius_attr_hdr)] = '\0';
+
+ /* Now check if this alias is valid for this peer */
+ memset(&hint, 0, sizeof(hint));
+ hint.ai_flags = AI_CANONNAME;
+ ret = getaddrinfo(buf, NULL, &hint, &res);
+ if (ret == 0) {
+ strncpy(buf, res->ai_canonname, sizeof(buf));
+ /* The name was resolved correctly, does it match the IP of the client? */
+ for (ptr = res; ptr != NULL; ptr = ptr->ai_next) {
+ if (cli->sa->sa_family != ptr->ai_family)
+ continue;
+ if (memcmp(cli->sa, ptr->ai_addr, sSAlen(cli->sa)))
+ continue;
+
+ found = 1;
+ break;
+ }
+ freeaddrinfo(res);
+
+ if (!found) {
+ if (cli->type == RGW_CLI_NAS) {
+ TRACE_DEBUG(INFO, "The NAS-Identifier value '%.*s' resolves to a different IP than the client's, discarding the message. Configure this client as a Proxy if this message should be valid.",
+ (int)nas_id_len, (char *)(nas_id + 1));
+ return EINVAL;
+ } else {
+ /* This identifier matches a different IP, assume it is a proxied message */
+ if (!cli->is_local) {
+ rr_str = cli->fqdn;
+ rr_strlen = cli->fqdn_len;
+ }
+ oh_str = &buf[0]; /* The canonname resolved */
+ oh_strlen = 0;
+ CHECK_FCT_DO( ret = fd_os_validate_DiameterIdentity(&oh_str, &oh_strlen, 1),
+ {
+ TRACE_DEBUG(INFO, "Unable to use resolved client name '%s' as DiameterIdentity: %s", buf, strerror(ret));
+ return ret;
+ } );
+ oh_free = 1;
+ or_str = strchr(oh_str, '.');
+ if (or_str) {
+ or_str ++; /* move after the first dot */
+ if (*or_str == '\0')
+ or_str = NULL; /* Discard this realm, we will use the local realm later */
+ else
+ or_strlen = oh_strlen - (or_str - oh_str);
+ }
+ }
+ } else {
+ /* It is a valid alias, save it */
+ CHECK_MALLOC( cli->aliases = realloc(cli->aliases, (cli->aliases_nb + 1) * sizeof(cli->aliases[0])) );
+
+ CHECK_MALLOC( cli->aliases[cli->aliases_nb + 1].name = os0dup(nas_id + 1, nas_id_len ) );
+ cli->aliases[cli->aliases_nb + 1].len = nas_id_len;
+
+ cli->aliases_nb ++;
+ TRACE_DEBUG(FULL, "Saved valid alias for client: '%.*s' -> '%s'", (int)nas_id_len, (char *)(nas_id + 1), cli->fqdn);
+ CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
+ }
+ } else {
+ /* Error resolving the name */
+ TRACE_DEBUG(INFO, "NAS-Identifier '%s' cannot be resolved: %s. Ignoring...", buf, gai_strerror(ret));
+ /* Assume this is a valid identifier for the client */
+ CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
+ }
+ }
+
+ /* Now, let's create the empty Diameter message with Origin-Host, -Realm, and Route-Record if needed. */
+diameter:
+ ASSERT(oh_str); /* If it is not defined here, there is a bug... */
+ if (!or_str) {
+ or_str = fd_g_config->cnf_diamrlm; /* Use local realm in that case */
+ or_strlen = fd_g_config->cnf_diamrlm_len;
+ }
+
+ /* Create an empty Diameter message so that extensions can store their AVPs */
+ CHECK_FCT( fd_msg_new ( NULL, MSGFL_ALLOC_ETEID, diam ) );
+
+ /* Add the Origin-Host as next AVP */
+ CHECK_FCT( fd_msg_avp_new ( cache_orig_host, 0, &avp ) );
+ memset(&avp_val, 0, sizeof(avp_val));
+ avp_val.os.data = (unsigned char *)oh_str;
+ avp_val.os.len = oh_strlen;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) );
+
+ /* Add the Origin-Realm as next AVP */
+ CHECK_FCT( fd_msg_avp_new ( cache_orig_realm, 0, &avp ) );
+ memset(&avp_val, 0, sizeof(avp_val));
+ avp_val.os.data = (unsigned char *)or_str;
+ avp_val.os.len = or_strlen;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) );
+
+ if (rr_str) {
+ CHECK_FCT( fd_msg_avp_new ( cache_route_record, 0, &avp ) );
+ memset(&avp_val, 0, sizeof(avp_val));
+ avp_val.os.data = (unsigned char *)rr_str;
+ avp_val.os.len = rr_strlen;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ if (oh_free)
+ free(oh_str);
+
+ /* Done! */
+ return 0;
+}
+
+int rgw_clients_get_origin(struct rgw_client *cli, DiamId_t *fqdn, size_t *fqdnlen, DiamId_t *realm, size_t *realmlen)
+{
+ TRACE_ENTRY("%p %p %p %p %p", cli, fqdn, fqdnlen, realm, realmlen);
+ CHECK_PARAMS(cli && fqdn && fqdnlen);
+
+ if (cli->is_local) {
+ *fqdn = fd_g_config->cnf_diamid;
+ *fqdnlen = fd_g_config->cnf_diamid_len;
+ if (realm)
+ *realm= fd_g_config->cnf_diamrlm;
+ if (realmlen)
+ *realmlen= fd_g_config->cnf_diamrlm_len;
+ } else {
+ *fqdn = cli->fqdn;
+ *fqdnlen = cli->fqdn_len;
+ if (realm)
+ *realm= cli->realm;
+ if (realmlen)
+ *realmlen= cli->realm_len;
+ }
+
+ return 0;
+}
+
+char * rgw_clients_id(struct rgw_client *cli)
+{
+ return cli->is_local ? "(local)" : cli->fqdn;
+}
+
+
+void rgw_clients_dispose(struct rgw_client ** ref)
+{
+ TRACE_ENTRY("%p", ref);
+ CHECK_PARAMS_DO(ref, return);
+
+ CHECK_POSIX_DO( pthread_rwlock_wrlock(&cli_rwl), );
+ client_unlink(*ref);
+ *ref = NULL;
+ CHECK_POSIX_DO( pthread_rwlock_unlock(&cli_rwl), );
+}
+
+int rgw_clients_add( struct sockaddr * ip_port, unsigned char ** key, size_t keylen, enum rgw_cli_type type )
+{
+ struct rgw_client * prev = NULL, *new = NULL;
+ int ret;
+
+ TRACE_ENTRY("%p %p %zu", ip_port, key, keylen);
+
+ CHECK_PARAMS( ip_port && key && *key && keylen );
+ CHECK_PARAMS( (ip_port->sa_family == AF_INET) || (ip_port->sa_family == AF_INET6) );
+ CHECK_PARAMS( (type == RGW_CLI_NAS) || (type == RGW_CLI_PXY) );
+
+ /* Dump the entry in debug mode */
+ if (TRACE_BOOL(FULL + 1 )) {
+ char sa_buf[sSA_DUMP_STRLEN];
+ fd_sa_sdump_numeric(sa_buf, ip_port);
+ TRACE_DEBUG(FULL, "Adding %s:", (type == RGW_CLI_NAS) ? "NAS" : "PROXY" );
+ TRACE_DEBUG(FULL, "\tIP : %s", sa_buf );
+ TRACE_BUFFER(FD_LOG_DEBUG, FULL, "\tKey: [", *key, keylen, "]" );
+ }
+
+ /* Lock the lists */
+ CHECK_POSIX( pthread_rwlock_wrlock(&cli_rwl) );
+
+ /* Check if the same entry does not already exist */
+ ret = client_search(&prev, ip_port );
+ if (ret == ENOENT) {
+ /* No duplicate found, Ok to add */
+ CHECK_FCT_DO( ret = client_create( &new, &ip_port, key, keylen, type ), goto end );
+ fd_list_insert_after(&prev->chain, &new->chain);
+ new->refcount++;
+ ret = 0;
+ goto end;
+ }
+
+ if (ret == EEXIST) {
+ char sa_buf[sSA_DUMP_STRLEN];
+ /* Check if the key is the same, then skip or return an error */
+ if ((keylen == prev->key.len ) && ( ! memcmp(*key, prev->key.data, keylen) ) && (type == prev->type)) {
+ TRACE_DEBUG(INFO, "Skipping duplicate client description");
+ ret = 0;
+ goto end;
+ }
+
+ fd_log_error("ERROR: Conflicting RADIUS clients descriptions!");
+ TRACE_ERROR("Previous entry: %s", (prev->type == RGW_CLI_NAS) ? "NAS" : "PROXY");
+ fd_sa_sdump_numeric(sa_buf, prev->sa);
+ TRACE_ERROR("\tIP : %s", sa_buf);
+ TRACE_BUFFER(FD_LOG_ERROR, NONE, "\tKey: [", prev->key.data, prev->key.len, "]" );
+ TRACE_ERROR("Conflicting entry: %s", (type == RGW_CLI_NAS) ? "NAS" : "PROXY");
+ fd_sa_sdump_numeric(sa_buf, ip_port);
+ TRACE_ERROR("\tIP : %s", sa_buf);
+ TRACE_BUFFER(FD_LOG_ERROR, NONE, "\tKey: [", *key, keylen, "]" );
+ }
+end:
+ /* release the lists */
+ CHECK_POSIX( pthread_rwlock_unlock(&cli_rwl) );
+
+ return ret;
+}
+
+static void dump_cli_list(struct fd_list *senti)
+{
+ struct rgw_client * client = NULL;
+ struct fd_list *ref = NULL;
+
+ for (ref = senti->next; ref != senti; ref = ref->next) {
+ char sa_buf[sSA_DUMP_STRLEN];
+ client = (struct rgw_client *)ref;
+ fd_sa_sdump_numeric(sa_buf, client->sa);
+ LOG_D(" - %s%s", sa_buf, (client->type == RGW_CLI_NAS) ? "" : " [PROXY]" );
+ }
+}
+
+void rgw_clients_dump(void)
+{
+ if ( ! TRACE_BOOL(FULL) )
+ return;
+
+ CHECK_POSIX_DO( pthread_rwlock_rdlock(&cli_rwl), /* ignore error */ );
+
+ if (!FD_IS_LIST_EMPTY(&cli_ip))
+ fd_log_debug(" RADIUS IP clients list:");
+ dump_cli_list(&cli_ip);
+
+ if (!FD_IS_LIST_EMPTY(&cli_ip6))
+ fd_log_debug(" RADIUS IPv6 clients list:");
+ dump_cli_list(&cli_ip6);
+
+ CHECK_POSIX_DO( pthread_rwlock_unlock(&cli_rwl), /* ignore error */ );
+}
+
+void rgw_clients_fini(void)
+{
+ struct fd_list * client;
+
+ TRACE_ENTRY();
+
+ CHECK_POSIX_DO( pthread_rwlock_wrlock(&cli_rwl), /* ignore error */ );
+
+ CHECK_FCT_DO( fd_thr_term(&dbt_expire), /* continue */ );
+
+ /* empty the lists */
+ while ( ! FD_IS_LIST_EMPTY(&cli_ip) ) {
+ client = cli_ip.next;
+ fd_list_unlink(client);
+ client_unlink((struct rgw_client *)client);
+ }
+ while (! FD_IS_LIST_EMPTY(&cli_ip6)) {
+ client = cli_ip6.next;
+ fd_list_unlink(client);
+ client_unlink((struct rgw_client *)client);
+ }
+
+ CHECK_POSIX_DO( pthread_rwlock_unlock(&cli_rwl), /* ignore error */ );
+
+}
+
+int rgw_client_finish_send(struct radius_msg ** msg, struct rgw_radius_msg_meta * req, struct rgw_client * cli)
+{
+ int p;
+ struct fd_list * li;
+
+ TRACE_ENTRY("%p %p %p", msg, req, cli);
+ CHECK_PARAMS( msg && *msg && cli );
+
+ if (!req) {
+ /* We don't support this case yet */
+ ASSERT(0);
+ return ENOTSUP;
+ }
+
+ /* Add all the Proxy-States back in the message */
+ for (p = 0; p < req->ps_nb; p++) {
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(req->radius.buf + req->radius.attr_pos[req->ps_first + p]);
+
+ if (radius_msg_add_attr_to_array(*msg, attr)) {
+ TRACE_DEBUG(INFO, "Error in radius_msg_add_attr_to_array, ENOMEM");
+ radius_msg_free(*msg);
+ free(*msg);
+ *msg = NULL;
+ return ENOMEM;
+ }
+ }
+
+ /* Add the Message-Authenticator if needed, and other final tasks */
+ if (radius_msg_finish_srv(*msg, cli->key.data, cli->key.len, req->radius.hdr->authenticator)) {
+ TRACE_DEBUG(INFO, "An error occurred while preparing the RADIUS answer");
+ radius_msg_free(*msg);
+ free(*msg);
+ *msg = NULL;
+ return EINVAL;
+ }
+
+ /* Debug */
+ TRACE_DEBUG(FULL, "RADIUS message ready for sending:");
+ rgw_msg_dump((struct rgw_radius_msg_meta *)*msg, 0);
+
+ /* Send the message */
+ CHECK_FCT( rgw_servers_send(req->serv_type, (*msg)->buf, (*msg)->buf_used, cli->sa, req->port) );
+
+ /* update the duplicate cache */
+ if (req->serv_type == RGW_PLG_TYPE_AUTH)
+ p = 0;
+ else
+ p = 1;
+
+ CHECK_POSIX( pthread_mutex_lock( &cli->dupl_info[p].dupl_lock ) );
+
+ /* Search this message in our list */
+ for (li = cli->dupl_info[p].dupl_by_id.next; li != &cli->dupl_info[p].dupl_by_id; li = li->next) {
+ int cmp = 0;
+ struct req_info * r = (struct req_info *)(li->o);
+ if (r->id < req->radius.hdr->identifier)
+ continue;
+ if (r->id > req->radius.hdr->identifier)
+ break;
+ if (r->port < req->port)
+ continue;
+ if (r->port > req->port)
+ break;
+ cmp = memcmp(&r->auth[0], &req->radius.hdr->authenticator[0], 16);
+ if (cmp < 0)
+ continue;
+ if (cmp > 0)
+ break;
+
+ /* We have the request in our duplicate cache */
+ /* This should not happen, but just in case... */
+ if (r->ans) {
+ radius_msg_free(r->ans);
+ free(r->ans);
+ }
+
+ /* Now save the message */
+ r->ans = *msg;
+ *msg = NULL;
+
+ /* Update the timestamp */
+ {
+ time_t now = time(NULL);
+ r->received = now;
+ fd_list_unlink(&r->by_time); /* Move as last entry, since it is the most recent */
+ fd_list_insert_before(&cli->dupl_info[p].dupl_by_time, &r->by_time);
+ }
+ break;
+ }
+
+ CHECK_POSIX( pthread_mutex_unlock( &cli->dupl_info[p].dupl_lock ) );
+
+ /* If we have not found the request in our list, the purge time is probably too small */
+ if (*msg) {
+ TODO("Augment the purge time...");
+ /* If we receive the duplicate request again, it will be converted to Diameter... */
+ radius_msg_free(*msg);
+ free(*msg);
+ *msg = NULL;
+ }
+
+ /* Finished */
+ return 0;
+}
+
+/* Call this function when a RADIUS request has explicitely no answer (mainly accounting) so
+that we purge the duplicate cache and allow further message to be translated again.
+This is useful for example when a temporary error occurred in Diameter (like UNABLE_TO_DELIVER) */
+int rgw_client_finish_nosend(struct rgw_radius_msg_meta * req, struct rgw_client * cli)
+{
+ int p;
+ struct fd_list * li;
+
+ TRACE_ENTRY("%p %p", req, cli);
+ CHECK_PARAMS( req && cli );
+
+ /* update the duplicate cache */
+ if (req->serv_type == RGW_PLG_TYPE_AUTH)
+ p = 0;
+ else
+ p = 1;
+
+ CHECK_POSIX( pthread_mutex_lock( &cli->dupl_info[p].dupl_lock ) );
+
+ /* Search this message in our list */
+ for (li = cli->dupl_info[p].dupl_by_id.next; li != &cli->dupl_info[p].dupl_by_id; li = li->next) {
+ int cmp = 0;
+ struct req_info * r = (struct req_info *)(li->o);
+ if (r->id < req->radius.hdr->identifier)
+ continue;
+ if (r->id > req->radius.hdr->identifier)
+ break;
+ if (r->port < req->port)
+ continue;
+ if (r->port > req->port)
+ break;
+ cmp = memcmp(&r->auth[0], &req->radius.hdr->authenticator[0], 16);
+ if (cmp < 0)
+ continue;
+ if (cmp > 0)
+ break;
+
+ /* We have the request in our duplicate cache, remove it */
+ fd_list_unlink(&r->by_id);
+ fd_list_unlink(&r->by_time);
+ dupl_free_req_info(r);
+ break;
+ }
+
+ CHECK_POSIX( pthread_mutex_unlock( &cli->dupl_info[p].dupl_lock ) );
+
+ /* Finished */
+ return 0;
+}
+
diff --git a/extensions/app_radgw/rgw_common.h b/extensions/app_radgw/rgw_common.h
new file mode 100644
index 0000000..bfb700a
--- /dev/null
+++ b/extensions/app_radgw/rgw_common.h
@@ -0,0 +1,287 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* This file contains definitions for both app_radgw extension and its plugins. */
+
+#ifndef _RGW_COMMON_H
+#define _RGW_COMMON_H
+
+/* Include definitions from the freeDiameter framework */
+#include <freeDiameter/extension.h>
+
+/* Include hostap files for RADIUS processings */
+#include "hostap_compat.h"
+#include "md5.h"
+#include "radius.h"
+
+
+/**************************************************************/
+/* Interface with gateway's plug-ins */
+/**************************************************************/
+/* This structure is private for each plugin */
+struct rgwp_config;
+
+/* This structure points to a RADIUS client description, the definition is not known to plugins */
+struct rgw_client;
+
+int rgw_clients_getkey(struct rgw_client * cli, unsigned char **key, size_t *key_len);
+char * rgw_clients_id(struct rgw_client *cli);
+int rgw_clients_get_origin(struct rgw_client *cli, DiamId_t *fqdn, size_t *fqdnlen, DiamId_t *realm, size_t *realmlen);
+
+/* Each plugin must provide the following structure. */
+extern struct rgw_api {
+ /* The name of the plugin */
+ const char * rgwp_name;
+
+ /* Parse the configuration file. It may be called several times with different configurations.
+ Called even if no configuration file is passed (with NULL conf_file parameter then) */
+ int (*rgwp_conf_parse) ( char * conf_file, struct rgwp_config ** state );
+
+ /* Cleanup the configuration state when the daemon is exiting (called even if state is NULL). */
+ void (*rgwp_conf_free) (struct rgwp_config * state);
+
+ /* handle an incoming RADIUS message */
+ int (*rgwp_rad_req) ( struct rgwp_config * conf, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli );
+ /* ret >0: critical error (errno), log and exit.
+ ret 0: continue;
+ ret -1: stop processing this message
+ ret -2: reply the content of rad_ans to the RADIUS client immediatly
+ */
+
+ /* handle the corresponding Diameter answer */
+ int (*rgwp_diam_ans) ( struct rgwp_config * conf, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli );
+ /* ret 0: continue; ret >0: error; ret: -1 ... (tbd) */
+
+} rgwp_descriptor;
+
+
+
+/**************************************************************/
+/* Additional definitions */
+/**************************************************************/
+/* Type of message / server */
+#define RGW_PLG_TYPE_AUTH 1
+#define RGW_PLG_TYPE_ACCT 2
+
+/* Class attribute prefix to store the Auth Application Id (required to send STR) */
+#define CLASS_AAI_PREFIX "fD/rgwx/aai:"
+
+/* Attributes missing from radius.h (not used in EAP) */
+enum { RADIUS_ATTR_CHAP_PASSWORD = 3,
+ RADIUS_ATTR_SERVICE_TYPE = 6,
+ RADIUS_ATTR_FRAMED_PROTOCOL = 7,
+ RADIUS_ATTR_FRAMED_IP_ADDRESS = 8,
+ RADIUS_ATTR_FRAMED_IP_NETMASK = 9,
+ RADIUS_ATTR_FRAMED_ROUTING = 10,
+ RADIUS_ATTR_FILTER_ID = 11,
+ RADIUS_ATTR_FRAMED_COMPRESSION = 13,
+ RADIUS_ATTR_LOGIN_IP_HOST = 14,
+ RADIUS_ATTR_LOGIN_SERVICE = 15,
+ RADIUS_ATTR_LOGIN_TCP_PORT = 16,
+ RADIUS_ATTR_CALLBACK_NUMBER = 19,
+ RADIUS_ATTR_CALLBACK_ID = 20,
+ RADIUS_ATTR_FRAMED_ROUTE = 22,
+ RADIUS_ATTR_FRAMED_IPX_NETWORK = 23,
+ RADIUS_ATTR_LOGIN_LAT_SERVICE = 34,
+ RADIUS_ATTR_LOGIN_LAT_NODE = 35,
+ RADIUS_ATTR_LOGIN_LAT_GROUP = 36,
+ RADIUS_ATTR_FRAMED_APPLETALK_LINK = 37,
+ RADIUS_ATTR_FRAMED_APPLETALK_NETWORK = 38,
+ RADIUS_ATTR_FRAMED_APPLETALK_ZONE = 39,
+ RADIUS_ATTR_CHAP_CHALLENGE = 60,
+ RADIUS_ATTR_PORT_LIMIT = 62,
+ RADIUS_ATTR_LOGIN_LAT_PORT = 63,
+ RADIUS_ATTR_TUNNEL_CLIENT_ENDPOINT = 66,
+ RADIUS_ATTR_TUNNEL_SERVER_ENDPOINT = 67,
+ RADIUS_ATTR_TUNNEL_PASSWORD = 69,
+ RADIUS_ATTR_ARAP_PASSWORD = 70,
+ RADIUS_ATTR_ARAP_FEATURES = 71,
+ RADIUS_ATTR_ARAP_ZONE_ACCESS = 72,
+ RADIUS_ATTR_ARAP_SECURITY = 73,
+ RADIUS_ATTR_ARAP_SECURITY_DATA = 74,
+ RADIUS_ATTR_PASSWORD_RETRY = 75,
+ RADIUS_ATTR_PROMPT = 76,
+ RADIUS_ATTR_CONFIGURATION_TOKEN = 78,
+ RADIUS_ATTR_TUNNEL_ASSIGNMENT_ID = 82,
+ RADIUS_ATTR_TUNNEL_PREFERENCE = 83,
+ RADIUS_ATTR_ARAP_CHALLENGE_RESPONSE = 84,
+ RADIUS_ATTR_NAS_PORT_ID = 87,
+ RADIUS_ATTR_FRAMED_POOL = 88,
+ RADIUS_ATTR_TUNNEL_CLIENT_AUTH_ID = 90,
+ RADIUS_ATTR_TUNNEL_SERVER_AUTH_ID = 91,
+ RADIUS_ATTR_ORIGINATING_LINE_INFO = 94,
+ RADIUS_ATTR_FRAMED_INTERFACE_ID = 96,
+ RADIUS_ATTR_FRAMED_IPV6_PREFIX = 97,
+ RADIUS_ATTR_LOGIN_IPV6_HOST = 98,
+ RADIUS_ATTR_FRAMED_IPV6_ROUTE = 99,
+ RADIUS_ATTR_FRAMED_IPV6_POOL = 100,
+ RADIUS_ATTR_ERROR_CAUSE = 101,
+ RADIUS_ATTR_EAP_KEY_NAME = 102,
+ RADIUS_ATTR_DIGEST_RESPONSE = 103,
+ RADIUS_ATTR_DIGEST_REALM = 104,
+ RADIUS_ATTR_DIGEST_NONCE = 105,
+ RADIUS_ATTR_DIGEST_RESPONSE_AUTH=106,
+ RADIUS_ATTR_DIGEST_NEXTNONCE = 107,
+ RADIUS_ATTR_DIGEST_METHOD = 108,
+ RADIUS_ATTR_DIGEST_URI = 109,
+ RADIUS_ATTR_DIGEST_QOP = 110,
+ RADIUS_ATTR_DIGEST_ALGORITHM = 111,
+ RADIUS_ATTR_DIGEST_ENTITY_BODY_HASH=112,
+ RADIUS_ATTR_DIGEST_CNONCE = 113,
+ RADIUS_ATTR_DIGEST_NONCE_COUNT = 114,
+ RADIUS_ATTR_DIGEST_USERNAME = 115,
+ RADIUS_ATTR_DIGEST_HA1 = 121,
+ RADIUS_ATTR_SIP_AOR = 122
+};
+
+enum { DIAM_ATTR_USER_NAME = 1,
+ DIAM_ATTR_USER_PASSWORD = 2,
+ DIAM_ATTR_NAS_IP_ADDRESS = 4,
+ DIAM_ATTR_NAS_PORT = 5,
+ DIAM_ATTR_SERVICE_TYPE = 6,
+ DIAM_ATTR_FRAMED_PROTOCOL = 7,
+ DIAM_ATTR_FRAMED_IP_ADDRESS = 8,
+ DIAM_ATTR_FRAMED_IP_NETMASK = 9,
+ DIAM_ATTR_FRAMED_ROUTING = 10,
+ DIAM_ATTR_FILTER_ID = 11,
+ DIAM_ATTR_FRAMED_MTU = 12,
+ DIAM_ATTR_FRAMED_COMPRESSION = 13,
+ DIAM_ATTR_LOGIN_IP_HOST = 14,
+ DIAM_ATTR_LOGIN_SERVICE = 15,
+ DIAM_ATTR_LOGIN_TCP_PORT = 16,
+ DIAM_ATTR_REPLY_MESSAGE = 18,
+ DIAM_ATTR_CALLBACK_NUMBER = 19,
+ DIAM_ATTR_CALLBACK_ID = 20,
+ DIAM_ATTR_FRAMED_ROUTE = 22,
+ DIAM_ATTR_FRAMED_IPX_NETWORK = 23,
+ DIAM_ATTR_STATE = 24,
+ DIAM_ATTR_CLASS = 25,
+ DIAM_ATTR_IDLE_TIMEOUT = 28,
+ DIAM_ATTR_NAS_IDENTIFIER = 32,
+ DIAM_ATTR_LOGIN_LAT_SERVICE = 34,
+ DIAM_ATTR_LOGIN_LAT_NODE = 35,
+ DIAM_ATTR_LOGIN_LAT_GROUP = 36,
+ DIAM_ATTR_FRAMED_APPLETALK_LINK = 37,
+ DIAM_ATTR_FRAMED_APPLETALK_NETWORK = 38,
+ DIAM_ATTR_FRAMED_APPLETALK_ZONE = 39,
+ DIAM_ATTR_ACCT_SESSION_ID = 44,
+ DIAM_ATTR_ACCT_MULTI_SESSION_ID = 50,
+ DIAM_ATTR_EVENT_TIMESTAMP = 55,
+ DIAM_ATTR_NAS_PORT_TYPE = 61,
+ DIAM_ATTR_PORT_LIMIT = 62,
+ DIAM_ATTR_LOGIN_LAT_PORT = 63,
+ DIAM_ATTR_TUNNEL_TYPE = 64,
+ DIAM_ATTR_TUNNEL_MEDIUM_TYPE = 65,
+ DIAM_ATTR_TUNNEL_CLIENT_ENDPOINT = 66,
+ DIAM_ATTR_TUNNEL_SERVER_ENDPOINT = 67,
+ DIAM_ATTR_TUNNEL_PASSWORD = 69,
+ DIAM_ATTR_ARAP_FEATURES = 71,
+ DIAM_ATTR_ARAP_ZONE_ACCESS = 72,
+ DIAM_ATTR_ARAP_SECURITY = 73,
+ DIAM_ATTR_ARAP_SECURITY_DATA = 74,
+ DIAM_ATTR_PASSWORD_RETRY = 75,
+ DIAM_ATTR_PROMPT = 76,
+ DIAM_ATTR_CONFIGURATION_TOKEN = 78,
+ DIAM_ATTR_TUNNEL_PRIVATE_GROUP_ID = 81,
+ DIAM_ATTR_TUNNEL_ASSIGNMENT_ID = 82,
+ DIAM_ATTR_TUNNEL_PREFERENCE = 83,
+ DIAM_ATTR_ARAP_CHALLENGE_RESPONSE = 84,
+ DIAM_ATTR_ACCT_INTERIM_INTERVAL = 85,
+ DIAM_ATTR_NAS_PORT_ID = 87,
+ DIAM_ATTR_FRAMED_POOL = 88,
+ DIAM_ATTR_TUNNEL_CLIENT_AUTH_ID = 90,
+ DIAM_ATTR_TUNNEL_SERVER_AUTH_ID = 91,
+ DIAM_ATTR_NAS_IPV6_ADDRESS = 95,
+ DIAM_ATTR_FRAMED_INTERFACE_ID = 96,
+ DIAM_ATTR_FRAMED_IPV6_PREFIX = 97,
+ DIAM_ATTR_LOGIN_IPV6_HOST = 98,
+ DIAM_ATTR_FRAMED_IPV6_ROUTE = 99,
+ DIAM_ATTR_FRAMED_IPV6_POOL = 100,
+ DIAM_ATTR_EAP_KEY_NAME = 102,
+ DIAM_ATTR_DIGEST_RESPONSE = 103,
+ DIAM_ATTR_DIGEST_REALM = 104,
+ DIAM_ATTR_DIGEST_NONCE = 105,
+ DIAM_ATTR_DIGEST_RESPONSE_AUTH=106,
+ DIAM_ATTR_DIGEST_NEXTNONCE = 107,
+ DIAM_ATTR_DIGEST_METHOD = 108,
+ DIAM_ATTR_DIGEST_URI = 109,
+ DIAM_ATTR_DIGEST_QOP = 110,
+ DIAM_ATTR_DIGEST_ALGORITHM = 111,
+ DIAM_ATTR_DIGEST_ENTITY_BODY_HASH=112,
+ DIAM_ATTR_DIGEST_CNONCE = 113,
+ DIAM_ATTR_DIGEST_NONCE_COUNT = 114,
+ DIAM_ATTR_DIGEST_USERNAME = 115,
+ DIAM_ATTR_DIGEST_HA1 = 121,
+ DIAM_ATTR_SIP_AOR = 122,
+ DIAM_ATTR_AUTH_APPLICATION_ID = 258,
+ DIAM_ATTR_ACCT_APPLICATION_ID = 259,
+ DIAM_ATTR_VENDOR_SPECIFIC_APPLICATION_ID = 260,
+ DIAM_ATTR_SESSION_ID = 263,
+ DIAM_ATTR_ORIGIN_HOST = 264,
+ DIAM_ATTR_MULTI_ROUND_TIMEOUT = 272,
+ DIAM_ATTR_AUTH_REQUEST_TYPE = 274,
+ DIAM_ATTR_AUTH_GRACE_PERIOD = 276,
+ DIAM_ATTR_AUTH_SESSION_STATE = 277,
+ DIAM_ATTR_ORIGIN_STATE_ID = 278,
+ DIAM_ATTR_FAILED_AVP = 279,
+ DIAM_ATTR_ERROR_MESSAGE = 281,
+ DIAM_ATTR_ROUTE_RECORD = 282,
+ DIAM_ATTR_PROXY_INFO = 284,
+ DIAM_ATTR_ACCOUNTING_SUB_SESSION_ID = 287,
+ DIAM_ATTR_ERROR_REPORTING_HOST = 294,
+ DIAM_ATTR_TERMINATION_CAUSE = 295,
+ DIAM_ATTR_ORIGIN_REALM = 296,
+ DIAM_ATTR_SIP_AUTH_DATA_ITEM = 376,
+ DIAM_ATTR_SIP_AUTHENTICATION_SCHEME = 377,
+ DIAM_ATTR_SIP_AUTHENTICATE = 379,
+ DIAM_ATTR_SIP_NUMBER_AUTH_ITEMS = 382,
+ DIAM_ATTR_NAS_FILTER_RULE = 400,
+ DIAM_ATTR_TUNNELING = 401,
+ DIAM_ATTR_QOS_FILTER_RULE = 407,
+ DIAM_ATTR_ORIGIN_AAA_PROTOCOL = 408,
+ DIAM_ATTR_EAP_PAYLOAD = 462,
+ DIAM_ATTR_EAP_REISSUED_PAYLOAD = 463,
+ DIAM_ATTR_EAP_MASTER_SESSION_KEY = 464,
+ DIAM_ATTR_ACCOUNTING_EAP_AUTH_METHOD = 465,
+ DIAM_ATTR_ACCOUNTING_RECORD_TYPE = 480,
+ DIAM_ATTR_ACCOUNTING_REALTIME_REQUIRED = 483,
+ DIAM_ATTR_ACCOUNTING_RECORD_NUMBER = 485
+};
+
+const char * rgw_msg_attrtype_str(unsigned char c);
+const char * rgw_msg_code_str(unsigned char c);
+
+#endif /* _RGW_COMMON_H */
+
diff --git a/extensions/app_radgw/rgw_conf.l b/extensions/app_radgw/rgw_conf.l
new file mode 100644
index 0000000..8afd779
--- /dev/null
+++ b/extensions/app_radgw/rgw_conf.l
@@ -0,0 +1,277 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+/* Lex configuration parser for radius_gw extension.
+ *
+ */
+
+%{
+#include "rgw.h"
+#include "rgw_conf.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* %option noinput ? */
+#define YY_NO_INPUT
+%}
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+/* Use the following start condition to parse an URI */
+%x IN_PLG
+%x IN_CLI1
+%x IN_CLI2
+%x EXPECT_IP4
+%x EXPECT_IP6
+%x EXPECT_DECINT
+
+/* Quoted string. Multilines do not match. */
+qstring \"[^\"\n]*\"
+
+/* Used to match IP, IP6, and port */
+IP4 [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
+IP6 [[:xdigit:]]*:[[:xdigit:]]*:[[:xdigit:].:]*
+BR_PORT [[][0-9]+[]]
+
+
+%%
+
+ /* All sections */
+<*>\n {
+ /* Update the line count */
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+<*>([[:space:]]{-}[\n])+ ; /* Eat all spaces, not new lines */
+<*>#.*$ ; /* Eat all comments */
+
+<*>{qstring} {
+ /* First copy the string without the quotes for use in the yacc parser */
+ yylval->string = strdup(yytext+1);
+ if (yylval->string == NULL) {
+ fd_log_debug("Unable to allocate memory: %s", strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+
+ yylval->string[yyleng-2] = '\0';
+
+ /* the yacc parser will check the string is valid */
+ return QSTRING;
+ }
+
+
+ /* Extension section */
+(?i:"RGWX") { BEGIN(IN_PLG); return PLG_PREFIX; }
+
+<IN_PLG>(?i:"auth") { return AUTH; }
+<IN_PLG>(?i:"acct") { return ACCT; }
+
+<IN_PLG,IN_CLI2>[[:xdigit:]]+ {
+ /* Convert this to an integer value */
+ int ret = sscanf(yytext, "%x", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+<IN_PLG>[:] { return yytext[0]; }
+
+
+ /* Client section */
+(?i:"nas"|"cli") { BEGIN(IN_CLI1); yylval->integer=RGW_CLI_NAS; return NAS_OR_PXY; }
+(?i:"pxy") { BEGIN(IN_CLI1); yylval->integer=RGW_CLI_PXY; return NAS_OR_PXY; }
+
+ /* Match an IP (4 or 6) and optional port */
+<IN_CLI1>({IP4}|{IP6}){BR_PORT}? {
+ char * work;
+ char * port;
+ unsigned short p = 0;
+
+ work = strdup(yytext);
+ if ( work == NULL ) {
+ fd_log_debug("Unable to allocate memory: %s", strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+
+ if ((port = strchr(work, '[')) != NULL) {
+ *port = '\0';
+ port++;
+ if (sscanf(port, "%hu]", &p) != 1) {
+ fd_log_debug("'%s' is not a valid port: %s", port, strerror(errno));
+ free(work);
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+ }
+
+ /* Do we have an IP or IPv6? Let's check if we have ':' char somewhere in the beginning */
+ if (memchr(work, ':', 5) != NULL) {
+ struct sockaddr_in6 * sin6 = NULL;
+
+ sin6 = malloc(sizeof(struct sockaddr_in6));
+ if (sin6 == NULL) {
+ fd_log_debug("Unable to allocate memory: %s", strerror(errno));
+ free(work);
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+
+ memset(sin6, 0, sizeof(struct sockaddr_in6));
+ sin6->sin6_family = AF_INET6;
+ if (inet_pton(AF_INET6, work, &sin6->sin6_addr) != 1) {
+ fd_log_debug("'%s' is not a valid IPv6 address: %s", work, strerror(errno));
+ free(work);
+ free(sin6);
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+ sin6->sin6_port = htons(p);
+ yylval->ss = (struct sockaddr *)sin6;
+ } else {
+ struct sockaddr_in * sin = NULL;
+
+ sin = malloc(sizeof(struct sockaddr_in));
+ if (sin == NULL) {
+ fd_log_debug("Unable to allocate memory: %s", strerror(errno));
+ free(work);
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+
+ memset(sin, 0, sizeof(struct sockaddr_in));
+ sin->sin_family = AF_INET;
+ if (inet_pton(AF_INET, work, &sin->sin_addr) != 1) {
+ fd_log_debug("'%s' is not a valid IP address: %s", work, strerror(errno));
+ free(work);
+ free(sin);
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+
+ sin->sin_port = htons(p);
+ yylval->ss = (struct sockaddr *)sin;
+ }
+ free(work);
+ return IP;
+ }
+
+
+<IN_CLI1>"/" { BEGIN(IN_CLI2); return '/'; }
+
+
+ /* Servers section */
+(?i:"auth_server_enable") { BEGIN(EXPECT_DECINT); return AUTH_ENABLE; }
+(?i:"auth_server_port") { BEGIN(EXPECT_DECINT); return AUTH_PORT; }
+(?i:"auth_server_ip4") { BEGIN(EXPECT_IP4); return AUTH_IP4; }
+(?i:"auth_server_ip6") { BEGIN(EXPECT_IP6); return AUTH_IP6; }
+(?i:"acct_server_enable") { BEGIN(EXPECT_DECINT); return ACCT_ENABLE; }
+(?i:"acct_server_port") { BEGIN(EXPECT_DECINT); return ACCT_PORT; }
+(?i:"acct_server_ip4") { BEGIN(EXPECT_IP4); return ACCT_IP4; }
+(?i:"acct_server_ip6") { BEGIN(EXPECT_IP6); return ACCT_IP6; }
+
+<EXPECT_DECINT>[[:digit:]]+ {
+ /* Match an integer (not hexa) */
+ int ret = sscanf(yytext, "%d", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+<EXPECT_IP4,EXPECT_IP6>(?i:"disable") { return DISABLED; }
+
+<EXPECT_IP4>{IP4} {
+ struct sockaddr_in * sin = NULL;
+
+ sin = malloc(sizeof(struct sockaddr_in));
+ if (sin == NULL) {
+ fd_log_debug("Unable to allocate memory: %s", strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+
+ memset(sin, 0, sizeof(struct sockaddr_in));
+ sin->sin_family = AF_INET;
+ if (inet_pton(AF_INET, yytext, &sin->sin_addr) != 1) {
+ fd_log_debug("'%s' is not a valid IP address: %s", yytext, strerror(errno));
+ free(sin);
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+ yylval->ss = (struct sockaddr *)sin;
+ return IP;
+ }
+
+<EXPECT_IP6>{IP6} {
+ struct sockaddr_in6 * sin6 = NULL;
+
+ sin6 = malloc(sizeof(struct sockaddr_in6));
+ if (sin6 == NULL) {
+ fd_log_debug("Unable to allocate memory: %s", strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+
+ memset(sin6, 0, sizeof(struct sockaddr_in6));
+ sin6->sin6_family = AF_INET6;
+ if (inet_pton(AF_INET6, yytext, &sin6->sin6_addr) != 1) {
+ fd_log_debug("'%s' is not a valid IPv6 address: %s", yytext, strerror(errno));
+ free(sin6);
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+ yylval->ss = (struct sockaddr *)sin6;
+ return IP;
+ }
+
+
+ /* Valid single characters for yyparse in all contexts */
+<*>[=] { return yytext[0]; }
+<*>[;] { BEGIN(INITIAL); return yytext[0]; }
+
+ /* Unrecognized token */
+<*>[[:alnum:]]+ | /* This rule is only useful to print a complete token in error messages */
+ /* Unrecognized character */
+<*>. {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/app_radgw/rgw_conf.y b/extensions/app_radgw/rgw_conf.y
new file mode 100644
index 0000000..53ab746
--- /dev/null
+++ b/extensions/app_radgw/rgw_conf.y
@@ -0,0 +1,404 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ * See doc/app_radgw.conf.sample for configuration file format
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "rgw.h"
+#include "rgw_conf.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+/* Parse the configuration file */
+int rgw_conf_handle(char * conffile)
+{
+ extern FILE * rgw_confin;
+ int ret;
+
+ rgw_confin = fopen(conffile, "r");
+ if (rgw_confin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ return ret;
+ }
+
+ ret = rgw_confparse(conffile);
+
+ fclose(rgw_confin);
+
+ if (ret != 0) {
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int rgw_conflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+/* Very simple byte stack management */
+static unsigned char * buf = NULL;
+static size_t buf_sz = 0;
+static size_t buf_rsz = 0;
+static inline int buf_add(unsigned char val) /* add a value in the array */
+{
+ buf_sz++;
+
+ if (buf_sz > buf_rsz) {
+ void * rez=NULL;
+ buf_rsz += 256;
+ rez = realloc(buf, buf_rsz);
+ if (rez == NULL) {
+ fd_log_debug("Error on memory allocation: %s", strerror(errno));
+ return 0;
+ }
+ buf = (unsigned char *)rez;
+ }
+ buf[buf_sz - 1] = val;
+ return 1;
+}
+static inline void buf_reinit(void)
+{
+ free(buf);
+ buf = NULL;
+ buf_sz = 0;
+ buf_rsz = 0;
+}
+
+static int port = 0;
+static char * plgconffile = NULL;
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ char *string; /* The string is allocated by strdup in lex.*/
+ int integer; /* Store integer values */
+ struct sockaddr *ss; /* sockaddr to free after use (alloc in lex) */
+}
+
+/* typed data */
+%token <string> QSTRING
+%token <integer> INTEGER
+%token <ss> IP
+
+%type <string> FINDFILEEXT
+
+%token <integer> NAS_OR_PXY
+
+/* simple tokens */
+%token DISABLED
+%token AUTH
+%token ACCT
+
+%token PLG_PREFIX
+
+%token AUTH_ENABLE
+%token AUTH_PORT
+%token AUTH_IP4
+%token AUTH_IP6
+%token ACCT_ENABLE
+%token ACCT_PORT
+%token ACCT_IP4
+%token ACCT_IP6
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK */
+ | conffile plugin
+ | conffile clientdef
+ | conffile authserv
+ | conffile acctserv
+ ;
+
+
+/* -------------------------------------- */
+FINDFILEEXT: QSTRING
+ {
+ char * fname = $1;
+ FILE * fd;
+
+ /* First, check if the file exists */
+ fd = fopen(fname, "r");
+ if ((fd == NULL) && (*fname != '/')) {
+ char * bkp = fname;
+ CHECK_MALLOC_DO( fname = malloc( strlen(bkp) + strlen(DEFAULT_EXTENSIONS_PATH) + 2 ),
+ { yyerror (&yylloc, conffile, "Not enough memory"); YYERROR; } );
+ sprintf(fname, DEFAULT_EXTENSIONS_PATH "/%s", bkp);
+ free(bkp);
+ fd = fopen(fname, "r");
+ }
+ if (fd == NULL) {
+ int ret = errno;
+ TRACE_DEBUG(INFO, "Unable to open file %s for reading: %s", fname, strerror(ret));
+ yyerror (&yylloc, conffile, "Error adding plugin");
+ YYERROR;
+ }
+ fclose(fd);
+
+ $$ = fname;
+ }
+ ;
+/* -------------------------------------- */
+plugin: {
+ /* Reset the parameters */
+ buf_reinit();
+ port = RGW_PLG_TYPE_AUTH | RGW_PLG_TYPE_ACCT ;
+ free(plgconffile); plgconffile = NULL;
+ }
+ PLG_PREFIX '=' FINDFILEEXT plg_attributes ';'
+ {
+ /* Add this extension in the list */
+ if ( rgw_plg_add( $4, plgconffile, port, &buf, buf_sz ) ) {
+ yyerror (&yylloc, conffile, "Error parsing / adding extension !");
+ YYERROR;
+ }
+
+ /* Free the array */
+ buf_reinit();
+
+ /* stop conffile from being freed here */
+ plgconffile = NULL;
+ }
+ ;
+
+plg_attributes: /* empty */
+ | plg_attributes ':' QSTRING
+ {
+ plgconffile = $3;
+ }
+ | plg_attributes ':' AUTH
+ {
+ port = RGW_PLG_TYPE_AUTH;
+ }
+ | plg_attributes ':' ACCT
+ {
+ port = RGW_PLG_TYPE_ACCT;
+ }
+ | plg_attributes ':' extcodes_list
+ ;
+
+extcodes_list: /* empty */
+ | extcodes_list INTEGER
+ {
+ if ($2 < 0 || $2 > 255) {
+ yyerror (&yylloc, conffile, "Invalid command code value!");
+ YYERROR;
+ }
+ if ( ! buf_add((unsigned char)$2) ) {
+ yyerror (&yylloc, conffile, "Error allocating memory!");
+ YYERROR;
+ }
+ }
+ ;
+
+/* -------------------------------------- */
+
+clientdef: {
+ buf_reinit();
+ }
+ NAS_OR_PXY '=' IP '/' clisecret_key ';'
+ {
+ /* Add this client */
+ if ( rgw_clients_add( $4, &buf, buf_sz, $2 ) ) {
+ yyerror (&yylloc, conffile, "Error parsing / adding client !");
+ YYERROR;
+ }
+
+ /* reinit the buffer */
+ buf_reinit();
+ }
+ ;
+
+clisecret_key: /* empty */
+ | clisecret_key QSTRING
+ {
+ int i;
+ size_t len = strlen($2);
+ for (i = 0; i < len; i++) {
+ if ( ! buf_add( $2 [i] ) ) {
+ yyerror (&yylloc, conffile, "Memory allocation error.");
+ YYERROR;
+ }
+ }
+
+ free($2);
+ }
+ | clisecret_key INTEGER
+ {
+ if ( $2 < 0 || $2 > 255 ) {
+ yyerror (&yylloc, conffile, "Invalid value in key.");
+ YYERROR;
+ }
+
+ if ( ! buf_add( $2 ) ) {
+ yyerror (&yylloc, conffile, "Memory allocation error.");
+ YYERROR;
+ }
+ }
+ ;
+
+/* -------------------------------------- */
+
+authserv: AUTH_ENABLE '=' INTEGER ';'
+ {
+ if ($3 == 0) {
+ rgw_servers.auth_serv.disabled = 1;
+ } else {
+ rgw_servers.auth_serv.disabled = 0;
+ }
+ }
+ | AUTH_PORT '=' INTEGER ';'
+ {
+ if ($3 <= 0 || $3 > 65535) {
+ yyerror (&yylloc, conffile, "Invalid port number !");
+ YYERROR;
+ }
+
+ rgw_servers.auth_serv.port = htons($3);
+ }
+ | AUTH_IP4 '=' DISABLED ';'
+ {
+ rgw_servers.auth_serv.ip_disabled = 1;
+ }
+ | AUTH_IP4 '=' IP ';'
+ {
+ if (((struct sockaddr *)($3))->sa_family != AF_INET) {
+ yyerror (&yylloc, conffile, "Invalid address specification !");
+ YYERROR;
+ }
+ memcpy( & rgw_servers.auth_serv.ip_endpoint, &((struct sockaddr_in *)($3))->sin_addr, sizeof(struct in_addr) );
+ free($3);
+ rgw_servers.auth_serv.ip_disabled = 0;
+ }
+ | AUTH_IP6 '=' DISABLED ';'
+ {
+ rgw_servers.auth_serv.ip6_disabled = 1;
+ }
+ | AUTH_IP6 '=' IP ';'
+ {
+ if (((struct sockaddr *)($3)) -> sa_family != AF_INET6) {
+ yyerror (&yylloc, conffile, "Invalid address specification !");
+ YYERROR;
+ }
+ memcpy( & rgw_servers.auth_serv.ip6_endpoint, &((struct sockaddr_in6 *)($3))->sin6_addr, sizeof(struct in6_addr) );
+ free($3);
+ rgw_servers.auth_serv.ip6_disabled = 0;
+ }
+ ;
+
+/* -------------------------------------- */
+
+acctserv: ACCT_ENABLE '=' INTEGER ';'
+ {
+ if ($3 == 0) {
+ rgw_servers.acct_serv.disabled = 1;
+ } else {
+ rgw_servers.acct_serv.disabled = 0;
+ }
+ }
+ | ACCT_PORT '=' INTEGER ';'
+ {
+ if ($3 <= 0 || $3 > 65535) {
+ yyerror (&yylloc, conffile, "Invalid port number !");
+ YYERROR;
+ }
+
+ rgw_servers.acct_serv.port = htons($3);
+ }
+ | ACCT_IP4 '=' DISABLED ';'
+ {
+ rgw_servers.acct_serv.ip_disabled = 1;
+ }
+ | ACCT_IP4 '=' IP ';'
+ {
+ if (((struct sockaddr *)($3)) -> sa_family != AF_INET) {
+ yyerror (&yylloc, conffile, "Invalid address specification !");
+ YYERROR;
+ }
+ memcpy( & rgw_servers.auth_serv.ip_endpoint, &((struct sockaddr_in *)($3))->sin_addr, sizeof(struct in_addr) );
+ free($3);
+ rgw_servers.acct_serv.ip_disabled = 0;
+ }
+ | ACCT_IP6 '=' DISABLED ';'
+ {
+ rgw_servers.acct_serv.ip6_disabled = 1;
+ }
+ | ACCT_IP6 '=' IP ';'
+ {
+ if (((struct sockaddr *)($3)) -> sa_family != AF_INET6) {
+ yyerror (&yylloc, conffile, "Invalid address specification !");
+ YYERROR;
+ }
+ memcpy( & rgw_servers.auth_serv.ip6_endpoint, &((struct sockaddr_in6 *)($3))->sin6_addr, sizeof(struct in6_addr) );
+ free($3);
+ rgw_servers.acct_serv.ip6_disabled = 0;
+ }
+ ;
diff --git a/extensions/app_radgw/rgw_main.c b/extensions/app_radgw/rgw_main.c
new file mode 100644
index 0000000..9276ef1
--- /dev/null
+++ b/extensions/app_radgw/rgw_main.c
@@ -0,0 +1,76 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+/*
+ * Main file of the app_radgw extension.
+ */
+
+#include "rgw.h"
+
+/* Extension entry point called by freeDiameter */
+static int rgw_main(char * conffile)
+{
+ CHECK_FCT( rgw_clients_init() );
+
+ CHECK_FCT( rgw_servers_init() );
+
+ CHECK_FCT( rgw_conf_handle(conffile) );
+
+ LOG_D( "Extension RADIUS Gateway initialized with configuration: '%s'", conffile);
+ rgw_servers_dump();
+ rgw_clients_dump();
+ rgw_plg_dump();
+
+ /* Start making extension list accelerators */
+ rgw_plg_start_cache();
+
+ /* Start the worker threads */
+ CHECK_FCT( rgw_work_start() );
+
+ /* Start the servers */
+ CHECK_FCT( rgw_servers_start() );
+
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ rgw_servers_fini();
+ rgw_work_fini();
+ rgw_plg_fini();
+ rgw_clients_fini();
+}
+
+EXTENSION_ENTRY("app_radgw", rgw_main);
diff --git a/extensions/app_radgw/rgw_msg_attrtype.c b/extensions/app_radgw/rgw_msg_attrtype.c
new file mode 100644
index 0000000..b14e54c
--- /dev/null
+++ b/extensions/app_radgw/rgw_msg_attrtype.c
@@ -0,0 +1,300 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "rgw_common.h"
+
+/* The content of this file was semi-automatically generated from the IANA registry. */
+
+/* Name of RADIUS attribute from its code */
+const char * rgw_msg_attrtype_str(unsigned char c) {
+ /* 1 User-Name */
+ if ( c == 1) return "User-Name ";
+ /* 2 User-Password */
+ if ( c == 2) return "User-Password ";
+ /* 3 CHAP-Password */
+ if ( c == 3) return "CHAP-Password ";
+ /* 4 NAS-IP-Address */
+ if ( c == 4) return "NAS-IP-Address ";
+ /* 5 NAS-Port */
+ if ( c == 5) return "NAS-Port ";
+ /* 6 Service-Type */
+ if ( c == 6) return "Service-Type ";
+ /* 7 Framed-Protocol */
+ if ( c == 7) return "Framed-Protocol ";
+ /* 8 Framed-IP-Address */
+ if ( c == 8) return "Framed-IP-Address ";
+ /* 9 Framed-IP-Netmask */
+ if ( c == 9) return "Framed-IP-Netmask ";
+ /* 10 Framed-Routing */
+ if ( c == 10) return "Framed-Routing ";
+ /* 11 Filter-Id */
+ if ( c == 11) return "Filter-Id ";
+ /* 12 Framed-MTU */
+ if ( c == 12) return "Framed-MTU ";
+ /* 13 Framed-Compression */
+ if ( c == 13) return "Framed-Compression ";
+ /* 14 Login-IP-Host */
+ if ( c == 14) return "Login-IP-Host ";
+ /* 15 Login-Service */
+ if ( c == 15) return "Login-Service ";
+ /* 16 Login-TCP-Port */
+ if ( c == 16) return "Login-TCP-Port ";
+ /* 17 Unassigned */
+ if ( c == 17) return "Unassigned ";
+ /* 18 Reply-Message */
+ if ( c == 18) return "Reply-Message ";
+ /* 19 Callback-Number */
+ if ( c == 19) return "Callback-Number ";
+ /* 20 Callback-Id */
+ if ( c == 20) return "Callback-Id ";
+ /* 21 Unassigned */
+ if ( c == 21) return "Unassigned ";
+ /* 22 Framed-Route */
+ if ( c == 22) return "Framed-Route ";
+ /* 23 Framed-IPX-Network */
+ if ( c == 23) return "Framed-IPX-Network ";
+ /* 24 State */
+ if ( c == 24) return "State ";
+ /* 25 Class */
+ if ( c == 25) return "Class ";
+ /* 26 Vendor-Specific */
+ if ( c == 26) return "Vendor-Specific ";
+ /* 27 Session-Timeout */
+ if ( c == 27) return "Session-Timeout ";
+ /* 28 Idle-Timeout */
+ if ( c == 28) return "Idle-Timeout ";
+ /* 29 Termination-Action */
+ if ( c == 29) return "Termination-Action ";
+ /* 30 Called-Station-Id */
+ if ( c == 30) return "Called-Station-Id ";
+ /* 31 Calling-Station-Id */
+ if ( c == 31) return "Calling-Station-Id ";
+ /* 32 NAS-Identifier */
+ if ( c == 32) return "NAS-Identifier ";
+ /* 33 Proxy-State */
+ if ( c == 33) return "Proxy-State ";
+ /* 34 Login-LAT-Service */
+ if ( c == 34) return "Login-LAT-Service ";
+ /* 35 Login-LAT-Node */
+ if ( c == 35) return "Login-LAT-Node ";
+ /* 36 Login-LAT-Group */
+ if ( c == 36) return "Login-LAT-Group ";
+ /* 37 Framed-AppleTalk-Link */
+ if ( c == 37) return "Framed-AppleTalk-Link ";
+ /* 38 Framed-AppleTalk-Network */
+ if ( c == 38) return "Framed-AppleTalk-Network ";
+ /* 39 Framed-AppleTalk-Zone */
+ if ( c == 39) return "Framed-AppleTalk-Zone ";
+ /* 40 Acct-Status-Type [RFC2866] */
+ if ( c == 40) return "Acct-Status-Type [RFC2866]";
+ /* 41 Acct-Delay-Time [RFC2866] */
+ if ( c == 41) return "Acct-Delay-Time [RFC2866]";
+ /* 42 Acct-Input-Octets [RFC2866] */
+ if ( c == 42) return "Acct-Input-Octets [RFC2866]";
+ /* 43 Acct-Output-Octets [RFC2866] */
+ if ( c == 43) return "Acct-Output-Octets [RFC2866]";
+ /* 44 Acct-Session-Id [RFC2866] */
+ if ( c == 44) return "Acct-Session-Id [RFC2866]";
+ /* 45 Acct-Authentic [RFC2866] */
+ if ( c == 45) return "Acct-Authentic [RFC2866]";
+ /* 46 Acct-Session-Time [RFC2866] */
+ if ( c == 46) return "Acct-Session-Time [RFC2866]";
+ /* 47 Acct-Input-Packets [RFC2866] */
+ if ( c == 47) return "Acct-Input-Packets [RFC2866]";
+ /* 48 Acct-Output-Packets [RFC2866] */
+ if ( c == 48) return "Acct-Output-Packets [RFC2866]";
+ /* 49 Acct-Terminate-Cause [RFC2866] */
+ if ( c == 49) return "Acct-Terminate-Cause [RFC2866]";
+ /* 50 Acct-Multi-Session-Id [RFC2866] */
+ if ( c == 50) return "Acct-Multi-Session-Id [RFC2866]";
+ /* 51 Acct-Link-Count [RFC2866] */
+ if ( c == 51) return "Acct-Link-Count [RFC2866]";
+ /* 52 Acct-Input-Gigawords [RFC2869] */
+ if ( c == 52) return "Acct-Input-Gigawords [RFC2869]";
+ /* 53 Acct-Output-Gigawords [RFC2869] */
+ if ( c == 53) return "Acct-Output-Gigawords [RFC2869]";
+ /* 54 Unassigned */
+ if ( c == 54) return "Unassigned ";
+ /* 55 Event-Timestamp [RFC2869] */
+ if ( c == 55) return "Event-Timestamp [RFC2869]";
+ /* 56 Egress-VLANID [RFC4675] */
+ if ( c == 56) return "Egress-VLANID [RFC4675]";
+ /* 57 Ingress-Filters [RFC4675] */
+ if ( c == 57) return "Ingress-Filters [RFC4675]";
+ /* 58 Egress-VLAN-Name [RFC4675] */
+ if ( c == 58) return "Egress-VLAN-Name [RFC4675]";
+ /* 59 User-Priority-Table [RFC4675] */
+ if ( c == 59) return "User-Priority-Table [RFC4675]";
+ /* 60 CHAP-Challenge */
+ if ( c == 60) return "CHAP-Challenge ";
+ /* 61 NAS-Port-Type */
+ if ( c == 61) return "NAS-Port-Type ";
+ /* 62 Port-Limit */
+ if ( c == 62) return "Port-Limit ";
+ /* 63 Login-LAT-Port */
+ if ( c == 63) return "Login-LAT-Port ";
+ /* 64 Tunnel-Type [RFC2868] */
+ if ( c == 64) return "Tunnel-Type [RFC2868]";
+ /* 65 Tunnel-Medium-Type [RFC2868] */
+ if ( c == 65) return "Tunnel-Medium-Type [RFC2868]";
+ /* 66 Tunnel-Client-Endpoint [RFC2868] */
+ if ( c == 66) return "Tunnel-Client-Endpoint [RFC2868]";
+ /* 67 Tunnel-Server-Endpoint [RFC2868] */
+ if ( c == 67) return "Tunnel-Server-Endpoint [RFC2868]";
+ /* 68 Acct-Tunnel-Connection [RFC2867] */
+ if ( c == 68) return "Acct-Tunnel-Connection [RFC2867]";
+ /* 69 Tunnel-Password [RFC2868] */
+ if ( c == 69) return "Tunnel-Password [RFC2868]";
+ /* 70 ARAP-Password [RFC2869] */
+ if ( c == 70) return "ARAP-Password [RFC2869]";
+ /* 71 ARAP-Features [RFC2869] */
+ if ( c == 71) return "ARAP-Features [RFC2869]";
+ /* 72 ARAP-Zone-Access [RFC2869] */
+ if ( c == 72) return "ARAP-Zone-Access [RFC2869]";
+ /* 73 ARAP-Security [RFC2869] */
+ if ( c == 73) return "ARAP-Security [RFC2869]";
+ /* 74 ARAP-Security-Data [RFC2869] */
+ if ( c == 74) return "ARAP-Security-Data [RFC2869]";
+ /* 75 Password-Retry [RFC2869] */
+ if ( c == 75) return "Password-Retry [RFC2869]";
+ /* 76 Prompt [RFC2869] */
+ if ( c == 76) return "Prompt [RFC2869]";
+ /* 77 Connect-Info [RFC2869] */
+ if ( c == 77) return "Connect-Info [RFC2869]";
+ /* 78 Configuration-Token [RFC2869] */
+ if ( c == 78) return "Configuration-Token [RFC2869]";
+ /* 79 EAP-Message [RFC2869] */
+ if ( c == 79) return "EAP-Message [RFC2869]";
+ /* 80 Message-Authenticator [RFC2869] */
+ if ( c == 80) return "Message-Authenticator [RFC2869]";
+ /* 81 Tunnel-Private-Group-ID [RFC2868] */
+ if ( c == 81) return "Tunnel-Private-Group-ID [RFC2868]";
+ /* 82 Tunnel-Assignment-ID [RFC2868] */
+ if ( c == 82) return "Tunnel-Assignment-ID [RFC2868]";
+ /* 83 Tunnel-Preference [RFC2868] */
+ if ( c == 83) return "Tunnel-Preference [RFC2868]";
+ /* 84 ARAP-Challenge-Response [RFC2869] */
+ if ( c == 84) return "ARAP-Challenge-Response [RFC2869]";
+ /* 85 Acct-Interim-Interval [RFC2869] */
+ if ( c == 85) return "Acct-Interim-Interval [RFC2869]";
+ /* 86 Acct-Tunnel-Packets-Lost [RFC2867] */
+ if ( c == 86) return "Acct-Tunnel-Packets-Lost [RFC2867]";
+ /* 87 NAS-Port-Id [RFC2869] */
+ if ( c == 87) return "NAS-Port-Id [RFC2869]";
+ /* 88 Framed-Pool [RFC2869] */
+ if ( c == 88) return "Framed-Pool [RFC2869]";
+ /* 89 CUI [RFC4372] */
+ if ( c == 89) return "CUI [RFC4372]";
+ /* 90 Tunnel-Client-Auth-ID [RFC2868] */
+ if ( c == 90) return "Tunnel-Client-Auth-ID [RFC2868]";
+ /* 91 Tunnel-Server-Auth-ID [RFC2868] */
+ if ( c == 91) return "Tunnel-Server-Auth-ID [RFC2868]";
+ /* 92 NAS-Filter-Rule [RFC4849] */
+ if ( c == 92) return "NAS-Filter-Rule [RFC4849]";
+ /* 93 Unassigned */
+ if ( c == 93) return "Unassigned ";
+ /* 94 Originating-Line-Info [RFC4005] */
+ if ( c == 94) return "Originating-Line-Info [RFC4005]";
+ /* 95 NAS-IPv6-Address [RFC3162] */
+ if ( c == 95) return "NAS-IPv6-Address [RFC3162]";
+ /* 96 Framed-Interface-Id [RFC3162] */
+ if ( c == 96) return "Framed-Interface-Id [RFC3162]";
+ /* 97 Framed-IPv6-Prefix [RFC3162] */
+ if ( c == 97) return "Framed-IPv6-Prefix [RFC3162]";
+ /* 98 Login-IPv6-Host [RFC3162] */
+ if ( c == 98) return "Login-IPv6-Host [RFC3162]";
+ /* 99 Framed-IPv6-Route [RFC3162] */
+ if ( c == 99) return "Framed-IPv6-Route [RFC3162]";
+ /* 100 Framed-IPv6-Pool [RFC3162] */
+ if ( c == 100) return "Framed-IPv6-Pool [RFC3162]";
+ /* 101 Error-Cause Attribute [RFC3576] */
+ if ( c == 101) return "Error-Cause Attribute[RFC3576]";
+ /* 102 EAP-Key-Name [RFC4072] */
+ if ( c == 102) return "EAP-Key-Name [RFC4072]";
+ /* 103 Digest-Response [RFC5090] */
+ if ( c == 103) return "Digest-Response [RFC5090]";
+ /* 104 Digest-Realm [RFC5090] */
+ if ( c == 104) return "Digest-Realm [RFC5090]";
+ /* 105 Digest-Nonce [RFC5090] */
+ if ( c == 105) return "Digest-Nonce [RFC5090]";
+ /* 106 Digest-Response-Auth [RFC5090] */
+ if ( c == 106) return "Digest-Response-Auth [RFC5090]";
+ /* 107 Digest-Nextnonce [RFC5090] */
+ if ( c == 107) return "Digest-Nextnonce [RFC5090]";
+ /* 108 Digest-Method [RFC5090] */
+ if ( c == 108) return "Digest-Method [RFC5090]";
+ /* 109 Digest-URI [RFC5090] */
+ if ( c == 109) return "Digest-URI [RFC5090]";
+ /* 110 Digest-Qop [RFC5090] */
+ if ( c == 110) return "Digest-Qop [RFC5090]";
+ /* 111 Digest-Algorithm [RFC5090] */
+ if ( c == 111) return "Digest-Algorithm [RFC5090]";
+ /* 112 Digest-Entity-Body-Hash [RFC5090] */
+ if ( c == 112) return "Digest-Entity-Body-Hash [RFC5090]";
+ /* 113 Digest-CNonce [RFC5090] */
+ if ( c == 113) return "Digest-CNonce [RFC5090]";
+ /* 114 Digest-Nonce-Count [RFC5090] */
+ if ( c == 114) return "Digest-Nonce-Count [RFC5090]";
+ /* 115 Digest-Username [RFC5090] */
+ if ( c == 115) return "Digest-Username [RFC5090]";
+ /* 116 Digest-Opaque [RFC5090] */
+ if ( c == 116) return "Digest-Opaque [RFC5090]";
+ /* 117 Digest-Auth-Param [RFC5090] */
+ if ( c == 117) return "Digest-Auth-Param [RFC5090]";
+ /* 118 Digest-AKA-Auts [RFC5090] */
+ if ( c == 118) return "Digest-AKA-Auts [RFC5090]";
+ /* 119 Digest-Domain [RFC5090] */
+ if ( c == 119) return "Digest-Domain [RFC5090]";
+ /* 120 Digest-Stale [RFC5090] */
+ if ( c == 120) return "Digest-Stale [RFC5090]";
+ /* 121 Digest-HA1 [RFC5090] */
+ if ( c == 121) return "Digest-HA1 [RFC5090]";
+ /* 122 SIP-AOR [RFC5090] */
+ if ( c == 122) return "SIP-AOR [RFC5090]";
+ /* 123 Delegated-IPv6-Prefix [RFC4818] */
+ if ( c == 123) return "Delegated-IPv6-Prefix [RFC4818]";
+ /* 124 MIP6-Feature-Vector [RFC5447] */
+ if ( c == 124) return "MIP6-Feature-Vector [RFC5447]";
+ /* 125 MIP6-Home-Link-Prefix [RFC5447] */
+ if ( c == 125) return "MIP6-Home-Link-Prefix [RFC5447]";
+ /* 126-191 Unassigned */
+ if ((c >= 126) && (c <= 191)) return "Unassigned ";
+ /* 192-223 Experimental Use [RFC3575] */
+ if ((c >= 192) && (c <= 223)) return "Experimental Use[RFC3575]";
+ /* 224-240 Implementation Specific [RFC3575] */
+ if ((c >= 224) && (c <= 240)) return "Implementation Specific[RFC3575]";
+ /* 241-255 Reserved [RFC3575] */
+ if ((c >= 241)) return "Reserved [RFC3575]";
+ /* fallback */ return "[Unknown]";
+}
diff --git a/extensions/app_radgw/rgw_msg_codes.c b/extensions/app_radgw/rgw_msg_codes.c
new file mode 100644
index 0000000..19b3e72
--- /dev/null
+++ b/extensions/app_radgw/rgw_msg_codes.c
@@ -0,0 +1,120 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "rgw_common.h"
+
+/* The content of this file was semi-automatically generated from the IANA registry. */
+
+/* Name of RADIUS command from its command code */
+const char * rgw_msg_code_str(unsigned char c) {
+ /* 1 Access-Request [RFC2865] */
+ if ( c == 1) return "Access-Request [RFC2865]";
+ /* 2 Access-Accept [RFC2865] */
+ if ( c == 2) return "Access-Accept [RFC2865]";
+ /* 3 Access-Reject [RFC2865] */
+ if ( c == 3) return "Access-Reject [RFC2865]";
+ /* 4 Accounting-Request [RFC2865] */
+ if ( c == 4) return "Accounting-Request [RFC2865]";
+ /* 5 Accounting-Response [RFC2865] */
+ if ( c == 5) return "Accounting-Response [RFC2865]";
+ /* 6 Accounting-Status [RFC3575] */
+ if ( c == 6) return "Accounting-Status [RFC3575]";
+ /* 7 Password-Request [RFC3575] */
+ if ( c == 7) return "Password-Request [RFC3575]";
+ /* 8 Password-Ack [RFC3575] */
+ if ( c == 8) return "Password-Ack [RFC3575]";
+ /* 9 Password-Reject [RFC3575] */
+ if ( c == 9) return "Password-Reject [RFC3575]";
+ /* 10 Accounting-Message [RFC3575] */
+ if ( c == 10) return "Accounting-Message [RFC3575]";
+ /* 11 Access-Challenge [RFC2865] */
+ if ( c == 11) return "Access-Challenge [RFC2865]";
+ /* 12 Status-Server (experimental) [RFC2865] */
+ if ( c == 12) return "Status-Server (experimental)[RFC2865]";
+ /* 13 Status-Client (experimental) [RFC2865] */
+ if ( c == 13) return "Status-Client (experimental)[RFC2865]";
+ /* 21 Resource-Free-Request [RFC3575] */
+ if ( c == 21) return "Resource-Free-Request [RFC3575]";
+ /* 22 Resource-Free-Response [RFC3575] */
+ if ( c == 22) return "Resource-Free-Response [RFC3575]";
+ /* 23 Resource-Query-Request [RFC3575] */
+ if ( c == 23) return "Resource-Query-Request [RFC3575]";
+ /* 24 Resource-Query-Response [RFC3575] */
+ if ( c == 24) return "Resource-Query-Response [RFC3575]";
+ /* 25 Alternate-Resource-Reclaim-Request [RFC3575] */
+ if ( c == 25) return "Alternate-Resource-Reclaim-Request [RFC3575]";
+ /* 26 NAS-Reboot-Request [RFC3575] */
+ if ( c == 26) return "NAS-Reboot-Request [RFC3575]";
+ /* 27 NAS-Reboot-Response [RFC3575] */
+ if ( c == 27) return "NAS-Reboot-Response [RFC3575]";
+ /* 28 Reserved */
+ if ( c == 28) return "Reserved ";
+ /* 29 Next-Passcode [RFC3575] */
+ if ( c == 29) return "Next-Passcode [RFC3575]";
+ /* 30 New-Pin [RFC3575] */
+ if ( c == 30) return "New-Pin [RFC3575]";
+ /* 31 Terminate-Session [RFC3575] */
+ if ( c == 31) return "Terminate-Session [RFC3575]";
+ /* 32 Password-Expired [RFC3575] */
+ if ( c == 32) return "Password-Expired [RFC3575]";
+ /* 33 Event-Request [RFC3575] */
+ if ( c == 33) return "Event-Request [RFC3575]";
+ /* 34 Event-Response [RFC3575] */
+ if ( c == 34) return "Event-Response [RFC3575]";
+ /* 40 Disconnect-Request [RFC3575][RFC5176] */
+ if ( c == 40) return "Disconnect-Request [RFC3575][RFC5176]";
+ /* 41 Disconnect-ACK [RFC3575][RFC5176] */
+ if ( c == 41) return "Disconnect-ACK [RFC3575][RFC5176]";
+ /* 42 Disconnect-NAK [RFC3575][RFC5176] */
+ if ( c == 42) return "Disconnect-NAK [RFC3575][RFC5176]";
+ /* 43 CoA-Request [RFC3575][RFC5176] */
+ if ( c == 43) return "CoA-Request [RFC3575][RFC5176]";
+ /* 44 CoA-ACK [RFC3575][RFC5176] */
+ if ( c == 44) return "CoA-ACK [RFC3575][RFC5176]";
+ /* 45 CoA-NAK [RFC3575][RFC5176] */
+ if ( c == 45) return "CoA-NAK [RFC3575][RFC5176]";
+ /* 50 IP-Address-Allocate [RFC3575] */
+ if ( c == 50) return "IP-Address-Allocate [RFC3575]";
+ /* 51 IP-Address-Release [RFC3575] */
+ if ( c == 51) return "IP-Address-Release [RFC3575]";
+ /* 52-249 Unassigned */
+ if ((c >= 52) && (c <= 249)) return "Unassigned ";
+ /* 250-253 Experimental Use [RFC3575] */
+ if ((c >= 250) && (c <= 253)) return "Experimental Use[RFC3575]";
+ /* 254 Reserved [RFC3575] */
+ if ( c == 254) return "Reserved [RFC3575]";
+ /* 255 Reserved [RFC3575] */
+ if ( c == 255) return "Reserved [RFC3575]";
+ /* fallback */ return "[Unknown]";
+}
diff --git a/extensions/app_radgw/rgw_plugins.c b/extensions/app_radgw/rgw_plugins.c
new file mode 100644
index 0000000..3bd4526
--- /dev/null
+++ b/extensions/app_radgw/rgw_plugins.c
@@ -0,0 +1,491 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Manage the list of plugins that provide handlers for RADIUS messages and attributes */
+
+#include "rgw.h"
+#include <dlfcn.h>
+#include <libgen.h>
+
+/* List of plugins, in the order they appear in the configuration file. */
+static struct fd_list plg_list = FD_LIST_INITIALIZER(plg_list);
+
+/* A plugin entry */
+struct plg_descr {
+ struct fd_list chain; /* chaining in plg_list */
+
+ void *dlo; /* pointer returned by dlopen for the extension, to use with dlclose later */
+ struct rgw_api *descriptor; /* Points to the resolved plugin's rgwp_descriptor */
+ struct rgwp_config *cs; /* the (private) state returned by rgwp_conf_parse */
+
+ int type; /* this extension is called for messages received on this(these) server port(s) only */
+ unsigned char *cc; /* array of command codes, or NULL for all cc */
+ size_t cc_len; /* size of the previous array */
+};
+
+/* Accelerators for each command code (one for each port). These accelerators are built on-demand, as a cache, after start_cache function has been called. */
+static struct fd_list plg_accel_auth = FD_LIST_INITIALIZER(plg_accel_auth);
+static struct fd_list plg_accel_acct = FD_LIST_INITIALIZER(plg_accel_acct);
+
+/* Accelerator list item, one per command code value (only the ones actually used) */
+struct plg_accel {
+ struct fd_list chain; /* link in the plg_accel_* list. List ordered by ccode. */
+ unsigned char ccode; /* the command code for this accelerator. We don't handle extended CC yet */
+ struct fd_list plugins;/* head for the list of plg_accel_item, corresponding to the extensions to be called for this command code. */
+};
+
+/* Accelerator item */
+struct plg_accel_item {
+ struct fd_list chain; /* link in the plg_accel "plugins" list */
+ struct plg_descr * plg; /* pointer to the plugin */
+ /* Note: we can further optimize by caching the location of plg->descriptor->rgwp_rad_req etc... at this level. */
+};
+
+/* RWlock to protect all the previous lists */
+static pthread_rwlock_t plg_lock = PTHREAD_RWLOCK_INITIALIZER;
+
+/* Has start_cache been called? */
+static int cache_started = 0;
+
+
+/* The read lock must be held before calling this function */
+static int get_accelerator(struct fd_list ** list, unsigned char ccode, int type)
+{
+ struct fd_list *refer, *search;
+ struct plg_accel * accel = NULL;
+ struct plg_accel_item * item = NULL;
+ int upgraded = 0;
+
+ TRACE_ENTRY("%p %hhu %i", list, ccode, type);
+
+ CHECK_PARAMS( cache_started && list && ((type == RGW_PLG_TYPE_AUTH) || (type == RGW_PLG_TYPE_ACCT)) );
+
+ if (type == RGW_PLG_TYPE_AUTH)
+ refer = &plg_accel_auth;
+ else
+ refer = &plg_accel_acct;
+restart:
+ /* Check if we have already an accelerator for this ccode */
+ for (search = refer->next; search != refer; search = search->next) {
+ struct plg_accel * loc = (struct plg_accel *)search;
+
+ if (loc->ccode < ccode)
+ continue;
+
+ if (loc->ccode > ccode)
+ break; /* we don't have an accelerator for this value yet */
+
+ /* We found the matching accelerator, just return this list */
+ *list = &loc->plugins;
+ return 0;
+ }
+
+ /* We must create the accelerator list, then save it just before "search" */
+
+ /* First , upgrade the lock to write lock, and restart the search. This is the only robust solution to avoid deadlocks */
+ if (! upgraded) {
+ CHECK_POSIX( pthread_rwlock_unlock(&plg_lock) );
+ CHECK_POSIX( pthread_rwlock_wrlock(&plg_lock) );
+ upgraded = 1;
+ goto restart;
+ }
+
+ /* Now create the new element */
+ CHECK_MALLOC( accel = malloc(sizeof(struct plg_accel)) );
+ memset(accel, 0, sizeof(struct plg_accel) );
+ fd_list_init(&accel->chain, NULL);
+ fd_list_init(&accel->plugins, accel);
+ accel->ccode = ccode;
+
+ /* Check each extension from the global list for this port and ccode */
+ for (refer = plg_list.next; refer != &plg_list; refer = refer->next) {
+ struct plg_descr * loc = (struct plg_descr *)refer;
+
+ /* Skip if this extension is not registered for this port */
+ if (! (loc->type & type) )
+ continue;
+
+ /* Check if the ccode is there */
+ if (loc->cc) {
+ int i;
+ int match = 0;
+ for (i=0; i< loc->cc_len; i++) {
+ if (loc->cc[i] < ccode)
+ continue;
+ if (loc->cc[i] == ccode)
+ match = 1;
+ break;
+ }
+ if (!match)
+ continue;
+ }
+
+ /* Ok, this extension must be called for this port / ccode, add to the accelerator */
+ CHECK_MALLOC( item = malloc(sizeof(struct plg_accel_item)) );
+ memset(item, 0, sizeof(struct plg_accel_item));
+ fd_list_init(&item->chain, NULL);
+ item->plg = loc;
+ /* Add as last element of the accelerator */
+ fd_list_insert_before(&accel->plugins, &item->chain);
+ }
+
+ /* Now, save this accelerator entry in the global list */
+ fd_list_insert_before(search, &accel->chain);
+ *list = &accel->plugins;
+
+ return 0;
+}
+
+
+int rgw_plg_add( char * plgfile, char * conffile, int type, unsigned char ** codes_array, size_t codes_sz )
+{
+ struct plg_descr * new;
+
+ TRACE_ENTRY("%p %p %d %p %zi", plgfile, conffile, type, codes_array, codes_sz);
+
+ CHECK_PARAMS( plgfile && type && codes_array && (cache_started == 0) );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct plg_descr)) );
+ memset(new, 0, sizeof(struct plg_descr));
+
+ fd_list_init(&new->chain, new);
+
+ /* Try and load the plugin */
+ TRACE_DEBUG(FULL, "Loading plugin: %s", plgfile);
+ new->dlo = dlopen(plgfile, RTLD_NOW | RTLD_GLOBAL);
+ if (new->dlo == NULL) {
+ /* An error occured */
+ fd_log_debug("Loading of plugin '%s' failed: %s", plgfile, dlerror());
+ goto error;
+ }
+
+ /* Resolve the descriptor */
+ new->descriptor = dlsym( new->dlo, "rgwp_descriptor" );
+ if (new->descriptor == NULL) {
+ /* An error occured */
+ fd_log_debug("Unable to resolve 'rgwp_descriptor' in plugin '%s': %s", plgfile, dlerror());
+ goto error;
+ }
+
+ TRACE_DEBUG(FULL, "Plugin '%s' found in file '%s'", new->descriptor->rgwp_name, plgfile);
+
+ /* Now parse the configuration file, this will initialize all plugin states and store it in the "cs" pointer (the plugin must be re-entrant, so no global state) */
+ if (new->descriptor->rgwp_conf_parse) {
+ CHECK_FCT_DO( (*(new->descriptor->rgwp_conf_parse))(conffile, &new->cs),
+ {
+ fd_log_debug("An error occurred while parsing configuration file '%s' in plugin '%s', aborting...", conffile, plgfile);
+ goto error;
+ } );
+ }
+
+ /* Now sort the array (very simple algorithm, but this list is usually small) of command codes and save */
+ if (*codes_array && codes_sz) {
+ int i;
+
+ new->cc = *codes_array;
+ *codes_array = NULL;
+
+ for (i = 0; i < codes_sz - 1; i++) {
+ int j, idx = i, min = new->cc[i];
+
+ /* find the smallest remaining element */
+ for (j = i + 1; j < codes_sz; j++) {
+ if (min > new->cc[j]) {
+ min = new->cc[j];
+ idx = j;
+ }
+ }
+
+ /* swap if needed */
+ if (idx != i) {
+ int tmp = new->cc[i];
+ new->cc[i] = new->cc[idx];
+ new->cc[idx] = tmp;
+ }
+ }
+ new->cc_len = codes_sz;
+ }
+
+ new->type = type;
+
+ /* And save this new extension in the list. We don't need to lock at this point because we are single threaded. */
+ fd_list_insert_before(&plg_list, &new->chain);
+
+ return 0;
+
+
+error:
+ if (new && new->dlo)
+ dlclose(new->dlo);
+ if (new)
+ free(new);
+ return EINVAL;
+}
+
+void rgw_plg_dump(void)
+{
+ struct plg_descr * plg;
+ struct fd_list * ptr, *ptraccel;
+
+ if ( ! TRACE_BOOL(FULL) )
+ return;
+
+ CHECK_POSIX_DO( pthread_rwlock_rdlock(&plg_lock), );
+
+ if ( ! FD_IS_LIST_EMPTY( &plg_list ) )
+ fd_log_debug("[app_radgw] --- List of registered plugins:");
+ for (ptr = plg_list.next; ptr != &plg_list; ptr = ptr->next) {
+ char buf[1024];
+ plg = (struct plg_descr *)ptr;
+
+ snprintf(buf, sizeof(buf), " %-25s ( %p ) - types: %s%s, codes: ",
+ plg->descriptor->rgwp_name,
+ plg->cs,
+ plg->type & RGW_PLG_TYPE_AUTH ? "Au" : " ",
+ plg->type & RGW_PLG_TYPE_ACCT ? "Ac" : " ");
+
+ if (plg->cc) {
+ int i;
+
+ for (i = 0; i < plg->cc_len; i++) {
+ snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%02hhx ", plg->cc[i]);
+ }
+ fd_log_debug("%s", buf);
+ } else {
+ fd_log_debug("%s*", buf);
+ }
+ }
+
+ CHECK_POSIX_DO( pthread_rwlock_unlock(&plg_lock), );
+
+ /* Dump the list of accelerators */
+ if ( ! TRACE_BOOL(FULL + 1) )
+ return;
+
+ CHECK_POSIX_DO( pthread_rwlock_rdlock(&plg_lock), );
+ if ( !FD_IS_LIST_EMPTY( &plg_accel_auth ) || !FD_IS_LIST_EMPTY( &plg_accel_acct ))
+ fd_log_debug(" --- Accelerators:");
+
+ for (ptraccel = plg_accel_auth.next; ptraccel != &plg_accel_auth; ptraccel = ptraccel->next) {
+ struct plg_accel * accel = (struct plg_accel *)ptraccel;
+ fd_log_debug(" auth, code %02hhu:", accel->ccode);
+
+ for (ptr = accel->plugins.next; ptr != &accel->plugins; ptr = ptr->next) {
+ struct plg_accel_item * item = (struct plg_accel_item *)ptr;
+ fd_log_debug(" %-15s (%p)", item->plg->descriptor->rgwp_name, item->plg->cs);
+ }
+ }
+ for (ptraccel = plg_accel_acct.next; ptraccel != &plg_accel_acct; ptraccel = ptraccel->next) {
+ struct plg_accel * accel = (struct plg_accel *)ptraccel;
+ fd_log_debug(" acct, code %02hhu:", accel->ccode);
+
+ for (ptr = accel->plugins.next; ptr != &accel->plugins; ptr = ptr->next) {
+ struct plg_accel_item * item = (struct plg_accel_item *)ptr;
+ fd_log_debug(" %-15s (%p)", item->plg->descriptor->rgwp_name, item->plg->cs);
+ }
+ }
+
+
+ CHECK_POSIX_DO( pthread_rwlock_unlock(&plg_lock), );
+
+}
+
+void rgw_plg_start_cache(void)
+{
+ cache_started++;
+}
+
+int rgw_plg_loop_req(struct rgw_radius_msg_meta **rad, struct msg **diam_msg, struct rgw_client * cli)
+{
+ int ret = 0;
+ struct fd_list * head = NULL, *li;
+ struct radius_msg * rad_ans = NULL;
+
+ TRACE_ENTRY("%p %p %p", rad, diam_msg, cli);
+ CHECK_PARAMS( rad && *rad && diam_msg && *diam_msg && cli);
+
+ /* First, get the list of extensions for this message */
+ CHECK_POSIX( pthread_rwlock_rdlock( &plg_lock) );
+ CHECK_FCT_DO( ret = get_accelerator(&head, (*rad)->radius.hdr->code, (*rad)->serv_type),
+ { CHECK_POSIX( pthread_rwlock_unlock( &plg_lock) ); return ret; } );
+
+ /* Loop in the list of extensions */
+ for (li = head->next; li != head; li = li->next) {
+ struct plg_descr * plg = ((struct plg_accel_item *) li)->plg;
+
+ if (plg->descriptor->rgwp_rad_req) {
+ TRACE_DEBUG(ANNOYING, "Calling next plugin: %s", plg->descriptor->rgwp_name);
+ ret = (*plg->descriptor->rgwp_rad_req)(plg->cs, &(*rad)->radius, &rad_ans, diam_msg, cli);
+ if (ret)
+ break;
+ } else {
+ TRACE_DEBUG(ANNOYING, "Skipping extension '%s' (NULL callback)", plg->descriptor->rgwp_name);
+ }
+ }
+
+ CHECK_POSIX( pthread_rwlock_unlock( &plg_lock) );
+
+ /* If no error encountered, we're done here */
+ if (ret == 0)
+ return 0;
+
+ /* Destroy the Diameter temp message, if any */
+ if (*diam_msg) {
+ CHECK_FCT_DO( fd_msg_free(*diam_msg), );
+ *diam_msg = NULL;
+ }
+
+ /* Send the radius message back if required */
+ if ((ret == -2) && rad_ans && rad) {
+ CHECK_FCT_DO( rgw_client_finish_send(&rad_ans, *rad, cli), /* It failed, it can't be helped... */);
+ }
+
+ if (ret > 0) {
+ /* Critical error, log and exit */
+ TRACE_DEBUG(NONE, "An error occurred while handling a RADIUS message from '%s': %s", rgw_clients_id(cli), strerror(ret));
+ return ret;
+ }
+
+ /* Now, discard the message and return */
+ rgw_msg_free(rad);
+ return 0;
+}
+
+/* Loop in the extension list (same as req) to convert data from diam_ans to rad_ans */
+int rgw_plg_loop_ans(struct rgw_radius_msg_meta *req, struct msg **diam_ans, struct radius_msg ** rad_ans, struct rgw_client * cli)
+{
+ int ret = 0;
+ struct fd_list * head = NULL, *li;
+
+ TRACE_ENTRY("%p %p %p %p", req, diam_ans, rad_ans, cli);
+ CHECK_PARAMS( req && diam_ans && *diam_ans && rad_ans && *rad_ans && cli);
+
+ /* Get the list of extensions of the RADIUS request */
+ CHECK_POSIX( pthread_rwlock_rdlock( &plg_lock) );
+ CHECK_FCT_DO( ret = get_accelerator(&head, req->radius.hdr->code, req->serv_type),
+ { CHECK_POSIX( pthread_rwlock_unlock( &plg_lock) ); return ret; } );
+
+ /* Loop in the list of extensions */
+ for (li = head->next; li != head; li = li->next) {
+ struct plg_descr * plg = ((struct plg_accel_item *) li)->plg;
+
+ if (plg->descriptor->rgwp_diam_ans) {
+ TRACE_DEBUG(ANNOYING, "Calling next plugin: %s", plg->descriptor->rgwp_name);
+ ret = (*plg->descriptor->rgwp_diam_ans)(plg->cs, diam_ans, rad_ans, (void *)cli);
+ if (ret)
+ break;
+ } else {
+ TRACE_DEBUG(ANNOYING, "Skipping extension '%s' (NULL callback)", plg->descriptor->rgwp_name);
+ }
+ }
+
+ CHECK_POSIX( pthread_rwlock_unlock( &plg_lock) );
+
+ /* If no error encountered, we're done here */
+ if (ret == 0)
+ return 0;
+
+ /* Destroy the temporary RADIUS answer */
+ if (*rad_ans) {
+ radius_msg_free(*rad_ans);
+ free(*rad_ans);
+ *rad_ans = NULL;
+ }
+
+ if (ret > 0) {
+ /* Critical error, log and exit */
+ fd_log_debug("[app_radgw] An error occurred while handling a DIAMETER answer to a converted RADIUS request, turn on DEBUG for details: %s", strerror(ret));
+ return ret;
+ }
+
+ /* We might define other return values with special meaning here (ret == -1, ...) for example create a new Diameter request */
+
+ /* -1: just abord the translation with no more processing. */
+
+ return 0;
+}
+
+void rgw_plg_fini(void)
+{
+ struct fd_list * item, *subitem;
+
+ TRACE_ENTRY();
+
+ CHECK_POSIX_DO( pthread_rwlock_rdlock( &plg_lock), /* continue anyway */ );
+
+ /* Remove all elements from all accelerators */
+ while ( ! FD_IS_LIST_EMPTY(&plg_accel_auth) ) {
+ item = plg_accel_auth.next;
+ fd_list_unlink(item);
+ {
+ struct plg_accel * accel = (struct plg_accel *)item;
+ while ( ! FD_IS_LIST_EMPTY(&accel->plugins) ) {
+ subitem = accel->plugins.next;
+ fd_list_unlink(subitem);
+ free(subitem);
+ }
+ }
+ free(item);
+ }
+ while ( ! FD_IS_LIST_EMPTY(&plg_accel_acct) ) {
+ item = plg_accel_acct.next;
+ fd_list_unlink(item);
+ {
+ struct plg_accel * accel = (struct plg_accel *)item;
+ while ( ! FD_IS_LIST_EMPTY(&accel->plugins) ) {
+ subitem = accel->plugins.next;
+ fd_list_unlink(subitem);
+ free(subitem);
+ }
+ }
+ free(item);
+ }
+
+ /* Now destroy all plugins information */
+ while ( ! FD_IS_LIST_EMPTY(&plg_list) ) {
+ struct plg_descr * plg = (struct plg_descr *) plg_list.next;
+ fd_list_unlink(&plg->chain);
+ free(plg->cc);
+ if (plg->descriptor && plg->descriptor->rgwp_conf_free ) {
+ TRACE_DEBUG(INFO, "RADIUS/Diameter gateway plugin '%s' cleaning up...", plg->descriptor->rgwp_name);
+ (*plg->descriptor->rgwp_conf_free)(plg->cs);
+ }
+ if (plg->dlo)
+ dlclose(plg->dlo);
+ free(plg);
+ }
+
+ CHECK_POSIX_DO( pthread_rwlock_unlock( &plg_lock), );
+}
diff --git a/extensions/app_radgw/rgw_servers.c b/extensions/app_radgw/rgw_servers.c
new file mode 100644
index 0000000..d524f20
--- /dev/null
+++ b/extensions/app_radgw/rgw_servers.c
@@ -0,0 +1,304 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Manage the RADIUS server(s): opening sockets, receiving messages, ... */
+
+#include "rgw.h"
+
+#define RADIUS_MAX_MSG_LEN 3000
+#define RADIUS_AUTH_PORT 1812
+#define RADIUS_ACCT_PORT 1813
+
+/* Declare the rgw_servers */
+struct rgw_servs rgw_servers;
+
+void rgw_servers_dump(void)
+{
+ char ipstr[INET6_ADDRSTRLEN];
+
+ LOG_D(" auth server:");
+ LOG_D(" disabled..... : %s", rgw_servers.auth_serv.disabled ? "TRUE":"false");
+ LOG_D(" IP disabled.. : %s", rgw_servers.auth_serv.ip_disabled ? "TRUE":"false");
+ LOG_D(" IPv6 disabled : %s", rgw_servers.auth_serv.ip6_disabled ? "TRUE":"false");
+ LOG_D(" port......... : %hu", ntohs(rgw_servers.auth_serv.port));
+ inet_ntop(AF_INET, &rgw_servers.auth_serv.ip_endpoint,ipstr,sizeof(ipstr));
+ LOG_D(" IP bind...... : %s", ipstr);
+ inet_ntop(AF_INET6, &rgw_servers.auth_serv.ip6_endpoint,ipstr,sizeof(ipstr));
+ LOG_D(" IPv6 bind.... : %s", ipstr);
+
+ LOG_D(" acct server:");
+ LOG_D(" disabled..... : %s", rgw_servers.acct_serv.disabled ? "TRUE":"false");
+ LOG_D(" IP disabled.. : %s", rgw_servers.acct_serv.ip_disabled ? "TRUE":"false");
+ LOG_D(" IPv6 disabled : %s", rgw_servers.acct_serv.ip6_disabled ? "TRUE":"false");
+ LOG_D(" port......... : %hu", ntohs(rgw_servers.acct_serv.port));
+ inet_ntop(AF_INET, &rgw_servers.acct_serv.ip_endpoint,ipstr,sizeof(ipstr));
+ LOG_D(" IP bind...... : %s", ipstr);
+ inet_ntop(AF_INET6, &rgw_servers.acct_serv.ip6_endpoint,ipstr,sizeof(ipstr));
+ LOG_D(" IPv6 bind.... : %s", ipstr);
+
+}
+
+static struct servers_data {
+ int type; /* auth or acct */
+ int family; /* AF_INET or AF_INET6 */
+ int sock; /* the socket number */
+ pthread_t th; /* the running server thread, or NULL */
+ char name[10];
+} SERVERS[4];
+
+int rgw_servers_init(void)
+{
+ memset(&rgw_servers, 0, sizeof(rgw_servers));
+ memset(&SERVERS[0], 0, sizeof(SERVERS));
+
+ rgw_servers.auth_serv.port = htons(RADIUS_AUTH_PORT);
+ rgw_servers.acct_serv.port = htons(RADIUS_ACCT_PORT);
+
+ return 0;
+}
+
+static void * server_thread(void * param)
+{
+ struct servers_data * me = (struct servers_data *)param;
+
+ TRACE_ENTRY("%p", param);
+
+ CHECK_PARAMS_DO(param, return NULL);
+
+ /* Set the thread name */
+ {
+ char buf[48];
+ snprintf(buf, sizeof(buf), "radgw/%s serv", me->name);
+ fd_log_threadname ( buf );
+ }
+
+ /* Now loop on this socket, parse and queue each message received, until thread is cancelled. */
+ while (1) {
+ struct sockaddr_storage from;
+ char sa_buf[sSA_DUMP_STRLEN];
+ socklen_t fromlen = sizeof(from);
+ int len;
+ struct rgw_client * nas_info = NULL;
+ uint16_t port = 0;
+ unsigned char buf[RADIUS_MAX_MSG_LEN];
+ struct rgw_radius_msg_meta *msg = NULL;
+
+ pthread_testcancel();
+
+ /* receive the next message */
+ CHECK_SYS_DO( len = recvfrom( me->sock, &buf[0], sizeof(buf), 0, (struct sockaddr *) &from, &fromlen), break );
+
+ /* Get the port */
+ port = sSAport(&from);
+ if (!port) {
+ LOG_E("Invalid port (family: %d), discarding received %d bytes...", from.ss_family, len);
+ continue;
+ }
+
+ fd_sa_sdump_numeric(sa_buf, (sSA*)&from);
+ LOG_D("RADIUS: RCV %dB from %s", len, sa_buf);
+
+ /* Search the associated client definition, if any */
+ CHECK_FCT_DO( rgw_clients_search((struct sockaddr *) &from, &nas_info),
+ {
+ LOG_E("Discarding %d bytes received from unknown IP: %s", len, sa_buf);
+ continue;
+ } );
+
+
+ /* parse the message, loop if message is invalid */
+ CHECK_FCT_DO( rgw_msg_parse(&buf[0], len, &msg),
+ {
+ DiamId_t cliname = NULL;
+ size_t clisz;
+ CHECK_FCT_DO( rgw_clients_get_origin(nas_info, &cliname, &clisz, NULL, NULL), );
+ LOG_E( "Discarding invalid RADIUS message from '%s'", cliname);
+ rgw_clients_dispose(&nas_info);
+ continue;
+ } );
+
+ msg->serv_type = me->type;
+ msg->port = port;
+
+ rgw_msg_dump(msg, 1);
+
+ /* queue the message for a worker thread */
+ CHECK_FCT_DO( rgw_work_add(msg, nas_info), break );
+
+ /* Then wait for next incoming message */
+ }
+
+ TRACE_DEBUG(INFO, "Server thread terminated.");
+ return NULL;
+}
+
+/* Set the socket options for UDP sockets, before bind is called */
+static int _udp_setsockopt(int family, int sk)
+{
+ int ret = 0;
+ int opt;
+
+ /* In case of v6 address, force the v6only option, we use a different socket for v4 */
+ #ifdef IPV6_V6ONLY
+ if (family == AF_INET6) {
+ opt = 1;
+ ret = setsockopt(sk, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
+ if (ret != 0) {
+ ret = errno;
+ TRACE_DEBUG(INFO, "Unable to set the socket IPV6_V6ONLY option: %s", strerror(ret));
+ return ret;
+ }
+ }
+ #endif /* IPV6_V6ONLY */
+
+ return 0;
+}
+
+/* We reuse the same logic for all 4 possible servers (IP / IPv6, Auth / Acct ports) */
+#define UDPSERV( _type_, _portval_, _family_ ) { \
+ /* Check that this type / family are not disabled by configuration */ \
+ if ( (! rgw_servers. _type_ ## _serv.disabled) \
+ && ( ! rgw_servers. _type_ ## _serv.ip ## _family_ ## _disabled ) ) { \
+ struct sockaddr_in ## _family_ sin ## _family_ ; \
+ /* Create the socket */ \
+ CHECK_SYS( SERVERS[idx].sock = socket(AF_INET ## _family_, SOCK_DGRAM, 0) ); \
+ /* Set the parameters for bind into "sin" or "sin6" */ \
+ memset(& sin ## _family_, 0, sizeof(struct sockaddr_in ## _family_)); \
+ sin ## _family_ . sin ## _family_ ## _family = AF_INET ## _family_; \
+ sin ## _family_ . sin ## _family_ ## _port = rgw_servers. _type_ ## _serv . port; \
+ memcpy( &sin ## _family_ .sin ## _family_ ## _addr, \
+ &rgw_servers. _type_ ## _serv . ip ## _family_ ## _endpoint, \
+ sizeof(struct in ## _family_ ## _addr) ); \
+ /* This sockopt must be set before binding */ \
+ TRACE_DEBUG(ANNOYING, "Setting socket options..."); \
+ CHECK_FCT( _udp_setsockopt(AF_INET ## _family_, SERVERS[idx].sock) ); \
+ /* OK, now, bind */ \
+ TRACE_DEBUG(ANNOYING, "Binding " #_type_ " ip" #_family_ " server..."); \
+ CHECK_SYS( bind( SERVERS[idx].sock, \
+ (struct sockaddr *)&sin ## _family_, \
+ sizeof(struct sockaddr_in ## _family_) ) ); \
+ /* Save the server information in SERVERS structure */ \
+ SERVERS[idx].type = _portval_; \
+ SERVERS[idx].family = AF_INET ## _family_; \
+ snprintf(&SERVERS[idx].name[0], sizeof(SERVERS[idx].name), # _type_ "/ip" #_family_); \
+ /* Create the server thread */ \
+ CHECK_POSIX( pthread_create(&SERVERS[idx].th, NULL, server_thread, &SERVERS[idx]) ); \
+ idx++; \
+ } \
+}
+
+int rgw_servers_start(void)
+{
+ int idx = 0;
+
+ TRACE_ENTRY();
+
+ UDPSERV( auth, RGW_PLG_TYPE_AUTH, );
+ UDPSERV( auth, RGW_PLG_TYPE_AUTH, 6 );
+ UDPSERV( acct, RGW_PLG_TYPE_ACCT, );
+ UDPSERV( acct, RGW_PLG_TYPE_ACCT, 6 );
+
+ TRACE_DEBUG(FULL, "%d UDP servers started succesfully.", idx);
+ return 0;
+}
+
+/* Send a RADIUS message */
+int rgw_servers_send(int type, unsigned char *buf, size_t buflen, struct sockaddr *to, uint16_t to_port)
+{
+ int idx = 0;
+ int ret = 0;
+ struct sockaddr_storage sto;
+ char sa_buf[sSA_DUMP_STRLEN];
+
+ /* Find the appropriate socket to use (not sure if it is important) */
+ for (idx = 0; idx < sizeof(SERVERS) / sizeof(SERVERS[0]); idx++) {
+ if ( SERVERS[idx].sock && (type == SERVERS[idx].type) && (to->sa_family == SERVERS[idx].family) ) {
+ ret = 1;
+ break;
+ }
+ }
+
+ if (!ret) {
+ LOG_E( "Trying to send a message from a disabled server: %s / %s",
+ (type == RGW_PLG_TYPE_AUTH) ? "Auth" : "Acct",
+ (to->sa_family == AF_INET) ? "IP (v4)" : "IPv6");
+ return EINVAL;
+ }
+
+ /* Prepare the destination info */
+ memset(&sto, 0, sizeof(sto));
+ if (to->sa_family == AF_INET) {
+ memcpy(&sto, to, sizeof(struct sockaddr_in));
+ ((struct sockaddr_in *)&sto)->sin_port = to_port;
+ } else {
+ memcpy(&sto, to, sizeof(struct sockaddr_in6));
+ ((struct sockaddr_in6 *)&sto)->sin6_port = to_port;
+ }
+
+ fd_sa_sdump_numeric(sa_buf, (sSA*)&sto);
+ LOG_D("RADIUS: SND %zdB to %s", buflen, sa_buf);
+
+ /* Send */
+ ret = sendto(SERVERS[idx].sock, buf, buflen, 0, (struct sockaddr *)&sto, sSAlen(&sto));
+ if (ret < 0) {
+ ret = errno;
+ TRACE_DEBUG(INFO, "An error prevented sending of a RADIUS message: %s", strerror(ret));
+ return ret;
+ }
+ if (ret != buflen) {
+ TRACE_DEBUG(INFO, "Incomplete send: %d bytes / %zd", ret, buflen);
+ return EAGAIN;
+ }
+
+ /* Done :) */
+ return 0;
+}
+
+void rgw_servers_fini(void)
+{
+ int idx = 0;
+
+ for (idx = 0; idx < sizeof(SERVERS) / sizeof(SERVERS[0]); idx++) {
+ if (SERVERS[idx].sock == 0)
+ break;
+
+ CHECK_FCT_DO( fd_thr_term(&SERVERS[idx].th), /* continue */ );
+ close(SERVERS[idx].sock);
+ SERVERS[idx].sock = 0;
+ }
+
+}
+
+
diff --git a/extensions/app_radgw/rgw_worker.c b/extensions/app_radgw/rgw_worker.c
new file mode 100644
index 0000000..25cb146
--- /dev/null
+++ b/extensions/app_radgw/rgw_worker.c
@@ -0,0 +1,346 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Manage incoming RADIUS messages. */
+
+#include "rgw.h"
+
+/* How many threads to handle messages in parallel ? */
+#define NB_WORKERS 2
+
+static pthread_t workers[NB_WORKERS];
+static struct fifo * work_stack = NULL;
+
+/* Data that is stacked */
+struct work_item {
+ struct rgw_radius_msg_meta * msg;
+ struct rgw_client * cli;
+};
+
+/* Data stored in freeDiameter while pending Diameter answer */
+struct pending_answer {
+ struct rgw_radius_msg_meta * rad; /* the RADIUS message that was received and translated */
+ struct rgw_client * cli; /* the client it was received from */
+};
+
+/* Callback when a Diameter answer is received */
+static void receive_diam_answer(void * paback, struct msg **ans);
+
+/* Worker thread, processing incoming RADIUS messages (after parsing) */
+static void * work_th(void * arg)
+{
+ TRACE_ENTRY("%p", arg);
+
+ /* Set the thread name */
+ {
+ char buf[48];
+ snprintf(buf, sizeof(buf), "radgw/worker #%ld", (long)arg);
+ fd_log_threadname ( buf );
+ }
+
+ while (1) { /* The thread will be cancelled */
+
+ struct rgw_radius_msg_meta * msg;
+ struct rgw_client * cli;
+ struct msg * diam_msg;
+ int pb, a;
+ struct pending_answer * pa;
+
+ /* Get the next incoming RADIUS message */
+ {
+ struct work_item * wi = NULL;
+
+ CHECK_FCT_DO( fd_fifo_get(work_stack, &wi), break );
+
+ msg = wi->msg;
+ cli = wi->cli;
+ free(wi);
+ }
+
+ TRACE_DEBUG(ANNOYING, "Processing next RADIUS message: %p received on client: %p", msg, cli);
+
+ /* process the data */
+
+ /* Check authenticator, if any */
+ CHECK_FCT_DO( rgw_clients_auth_check(msg, cli, NULL),
+ {
+ /* An error occurred, discard message */
+ rgw_msg_free(&msg);
+ rgw_clients_dispose(&cli);
+ continue;
+ } );
+
+ /* Check duplicate */
+ CHECK_FCT_DO( rgw_clients_check_dup(&msg, cli),
+ {
+ /* An error occurred, discard message */
+ rgw_msg_free(&msg);
+ rgw_clients_dispose(&cli);
+ continue;
+ } );
+ if (msg == NULL) {
+ rgw_clients_dispose(&cli);
+ continue; /* the message was a duplicate */
+ }
+
+ diam_msg = NULL;
+ /* Note: after this point, the radius message buffer may not be consistent with the array of attributes anymore. */
+
+ /* Check that IP is coherent with the identity in the message, and create an empty message with only Origin information */
+ CHECK_FCT_DO( rgw_clients_create_origin(msg, cli, &diam_msg),
+ {
+ /* An error occurred, discard message */
+ if (diam_msg) {
+ CHECK_FCT_DO( fd_msg_free(diam_msg), );
+ }
+ rgw_msg_free(&msg);
+ rgw_clients_dispose(&cli);
+ continue;
+ } );
+
+ /* Pass the message to the list of registered plugins */
+ CHECK_FCT_DO( rgw_plg_loop_req(&msg, &diam_msg, cli),
+ {
+ /* An error occurred, discard message */
+ if (diam_msg) {
+ CHECK_FCT_DO( fd_msg_free(diam_msg), );
+ diam_msg = NULL;
+ }
+ rgw_msg_free(&msg);
+ rgw_clients_dispose(&cli);
+ continue;
+ } );
+ if (msg == NULL) { /* Error or RADIUS answer locally generated */
+ rgw_clients_dispose(&cli);
+ if (diam_msg) {
+ CHECK_FCT_DO( fd_msg_free(diam_msg), );
+ diam_msg = NULL;
+ }
+ continue; /* the message was handled already */
+ }
+
+ pb = 0;
+
+ /* Check the created Diameter message -- it will be invalid if no callback has handled the RADIUS message */
+ if ((diam_msg == NULL) || ( fd_msg_parse_rules(diam_msg, fd_g_config->cnf_dict, NULL) ) ) {
+ fd_log_debug("[radgw] No or invalid Diameter message was generated after processing the RADIUS command %hhd (%s)."
+ " It may indicate a gateway configuration problem, or implementation issue in a plugin.",
+ msg->radius.hdr->code, rgw_msg_code_str(msg->radius.hdr->code));
+ /* We should also dump the conflicting rule here to help debug? */
+ pb++;
+ }
+
+ /* Check if the full content of the RADIUS message was handled */
+ for (a = 0; a < msg->radius.attr_used; a++) {
+ struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->radius.buf + msg->radius.attr_pos[a]);
+ pb++;
+ fd_log_debug("[radgw] No plugin available to handle attribute %hhd (%s) in command %hhd (%s)! Translation aborted.",
+ attr->type, rgw_msg_attrtype_str(attr->type),
+ msg->radius.hdr->code, rgw_msg_code_str(msg->radius.hdr->code));
+ }
+
+ if (pb) {
+ /* Something went wrong during the conversion */
+ if (diam_msg) {
+ CHECK_FCT_DO( fd_msg_free(diam_msg), );
+ diam_msg = NULL;
+ }
+
+ rgw_msg_free(&msg);
+ rgw_clients_dispose(&cli);
+
+ TRACE_DEBUG(INFO, "%d problem(s) occurred while translating a RADIUS message, data discarded.", pb);
+ continue;
+ }
+
+ /* Send the Diameter message and register for receiving the answer */
+ CHECK_MALLOC_DO( pa = malloc(sizeof(struct pending_answer)), break );
+ memset(pa, 0, sizeof(*pa));
+ pa->rad = msg;
+ pa->cli = cli;
+
+ CHECK_FCT_DO( fd_msg_send( &diam_msg, receive_diam_answer, pa),
+ {
+ /* If an error occurs, log and destroy the data */
+ fd_log_debug("An error occurred while sending Diameter message, please turn Debug on for detail.");
+
+ if (diam_msg) {
+ CHECK_FCT_DO( fd_msg_free(diam_msg), );
+ diam_msg = NULL;
+ }
+
+ rgw_msg_free(&msg);
+ rgw_clients_dispose(&cli);
+
+ free(pa);
+
+ continue;
+ } );
+
+ /* Done! */
+ }
+
+ TRACE_DEBUG(INFO, "Thread terminated!");
+ return NULL;
+}
+
+static void receive_diam_answer(void * paback, struct msg **ans)
+{
+ struct pending_answer * pa = (struct pending_answer *)paback;
+ struct radius_msg * rad_ans;
+ struct avp *avp;
+ struct avp_hdr *ahdr;
+ int pb = 0;
+
+ TRACE_ENTRY("%p %p", pa, ans);
+ CHECK_PARAMS_DO( pa && ans, return );
+
+ /* Create an empty RADIUS answer message */
+ CHECK_MALLOC_DO( rad_ans = radius_msg_new(0, pa->rad->radius.hdr->identifier), goto out );
+
+ /* Pass the Diameter answer to the same extensions as the request */
+ CHECK_FCT_DO( rgw_plg_loop_ans(pa->rad, ans, &rad_ans, pa->cli), goto out );
+
+ if (*ans != NULL) {
+
+ /* Now check what AVPs remain in the diameter answer. If AVPs with the 'M' flag are here, we have a problem... */
+ CHECK_FCT_DO( fd_msg_browse(*ans, MSG_BRW_FIRST_CHILD, &avp, NULL), { avp = NULL; pb++; } );
+ while (avp) {
+ CHECK_FCT_DO( fd_msg_avp_hdr ( avp, &ahdr ), { pb++; continue; } );
+ if (ahdr->avp_flags & AVP_FLAG_MANDATORY) {
+ if (ahdr->avp_flags & AVP_FLAG_VENDOR) {
+ TRACE_DEBUG(FULL, "Remaining Mandatory Vendor AVP, code %d", ahdr->avp_code);
+ pb++;
+ } else {
+ switch (ahdr->avp_code) {
+ /* A few AVPs can be safely ignored here: */
+ case DIAM_ATTR_SESSION_ID:
+ case DIAM_ATTR_ROUTE_RECORD:
+ case DIAM_ATTR_PROXY_INFO:
+
+
+ /* just ignore */
+ break;
+
+ default:
+ LOG_D("Remaining Mandatory AVP, code %d", ahdr->avp_code);
+ pb++;
+ }
+ }
+ }
+ CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), { pb++; break; } );
+ }
+
+ if (pb) {
+ TRACE_DEBUG(INFO, "[radgw] WARNING: %d mandatory AVP in the Diameter answer have not been translated to RADIUS! Please use debug.rgwx for more information.", pb);
+ }
+ }
+
+
+out:
+ /* Now try and send the RADIUS answer */
+ if (rad_ans) {
+ CHECK_FCT_DO( rgw_client_finish_send(&rad_ans, pa->rad, pa->cli), );
+ } else {
+ /* Remove the request from the duplicate cache */
+ CHECK_FCT_DO( rgw_client_finish_nosend(pa->rad, pa->cli), );
+ }
+
+ /* Clear the Diameter message */
+ if (*ans) {
+ CHECK_FCT_DO( fd_msg_free(*ans), );
+ *ans = NULL;
+ }
+
+ /* Clear the RADIUS request */
+ if (pa->rad) {
+ rgw_msg_free(&pa->rad);
+ }
+
+ /* Release reference on the client */
+ rgw_clients_dispose(&pa->cli);
+
+ /* Clear the answer data */
+ free(pa);
+
+ /* Finished */
+ return;
+}
+
+int rgw_work_start(void)
+{
+ long i;
+ TRACE_ENTRY();
+
+ memset(workers, 0, sizeof(workers));
+
+ CHECK_FCT( fd_fifo_new ( &work_stack, 30 ) );
+
+ /* Create the worker thread(s) */
+ for (i = 0; i < NB_WORKERS; i++) {
+ CHECK_POSIX( pthread_create(&workers[i], NULL, work_th, (void *)i) );
+ }
+
+ return 0;
+}
+
+int rgw_work_add(struct rgw_radius_msg_meta * msg, struct rgw_client * client)
+{
+ struct work_item * new;
+
+ CHECK_MALLOC( new = malloc(sizeof(struct work_item)) );
+ memset(new, 0, sizeof(struct work_item));
+
+ new->msg = msg;
+ new->cli = client;
+
+ CHECK_FCT( fd_fifo_post(work_stack, &new) );
+
+ return 0;
+}
+
+void rgw_work_fini(void)
+{
+ int i;
+ TRACE_ENTRY();
+
+ for (i = 0; i < NB_WORKERS; i++) {
+ fd_thr_term(&workers[i]);
+ }
+
+ TODO("Empty the stack, what to do about the RADIUS messages?");
+
+ return;
+}
diff --git a/extensions/app_radgw/rgwx_acct.c b/extensions/app_radgw/rgwx_acct.c
new file mode 100644
index 0000000..f9f1480
--- /dev/null
+++ b/extensions/app_radgw/rgwx_acct.c
@@ -0,0 +1,1463 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* RADIUS Accounting-Request messages translation plugin */
+
+#include "rgw_common.h"
+
+
+/* Other constants we use */
+#define AI_ACCT 3 /* Diameter Base Accounting application */
+#define CC_AC 271 /* ACR/ACA */
+#define ACV_ART_START_RECORD 2 /* START_RECORD */
+#define ACV_ART_INTERIM_RECORD 3 /* INTERIM_RECORD */
+#define ACV_ART_STOP_RECORD 4 /* STOP_RECORD */
+#define ACV_ART_AUTHORIZE_AUTHENTICATE 3 /* AUTHORIZE_AUTHENTICATE */
+
+
+/* The state we keep for this plugin */
+struct rgwp_config {
+ struct {
+ struct dict_object * Accounting_Record_Number; /* Accounting-Record-Number */
+ struct dict_object * Accounting_Record_Type; /* Accounting-Record-Type */
+ struct dict_object * Acct_Application_Id; /* Acct-Application-Id */
+ struct dict_object * Acct_Delay_Time; /* Acct-Delay-Time */
+ struct dict_object * Accounting_Input_Octets; /* Accounting-Input-Octets */
+ struct dict_object * Accounting_Output_Octets; /* Accounting-Output-Octets */
+ struct dict_object * Accounting_Input_Packets; /* Accounting-Input-Packets */
+ struct dict_object * Accounting_Output_Packets; /* Accounting-Output-Packets */
+ struct dict_object * Acct_Link_Count; /* Acct-Link-Count */
+ struct dict_object * Acct_Authentic; /* Acct-Authentic */
+ struct dict_object * Acct_Multi_Session_Id; /* Acct-Multi-Session-Id */
+ struct dict_object * Acct_Session_Id; /* Acct-Session-Id */
+ struct dict_object * Acct_Session_Time; /* Acct-Session-Time */
+
+ struct dict_object * ARAP_Password; /* ARAP-Password */
+ struct dict_object * ARAP_Security; /* ARAP-Security */
+ struct dict_object * ARAP_Security_Data; /* ARAP-Security-Data */
+ struct dict_object * Auth_Application_Id; /* Auth-Application-Id */
+ struct dict_object * Auth_Request_Type; /* Auth-Request-Type */
+ struct dict_object * Authorization_Lifetime; /* Authorization-Lifetime */
+ struct dict_object * Callback_Number; /* Callback-Number */
+ struct dict_object * Callback_Id; /* Callback-Id */
+ struct dict_object * Called_Station_Id; /* Called-Station-Id */
+ struct dict_object * Calling_Station_Id; /* Calling-Station-Id */
+ struct dict_object * Class; /* Class */
+ struct dict_object * CHAP_Algorithm; /* CHAP-Algorithm */
+ struct dict_object * CHAP_Auth; /* CHAP-Auth */
+ struct dict_object * CHAP_Challenge; /* CHAP-Challenge */
+ struct dict_object * CHAP_Ident; /* CHAP-Ident */
+ struct dict_object * CHAP_Response; /* CHAP-Response */
+ struct dict_object * Connect_Info; /* Connect-Info */
+ struct dict_object * Destination_Host; /* Destination-Host */
+ struct dict_object * Destination_Realm; /* Destination-Realm */
+ struct dict_object * EAP_Payload; /* EAP-Payload */
+ struct dict_object * Error_Message; /* Error-Message */
+ struct dict_object * Error_Reporting_Host; /* Error-Reporting-Host */
+ struct dict_object * Event_Timestamp; /* Event-Timestamp */
+ struct dict_object * Failed_AVP; /* Failed-AVP */
+ struct dict_object * Framed_AppleTalk_Link; /* Framed-AppleTalk-Link */
+ struct dict_object * Framed_AppleTalk_Network; /* Framed-AppleTalk-Network */
+ struct dict_object * Framed_AppleTalk_Zone; /* Framed-AppleTalk-Zone */
+ struct dict_object * Framed_Compression; /* Framed-Compression */
+ struct dict_object * Framed_IP_Address; /* Framed-IP-Address */
+ struct dict_object * Framed_IP_Netmask; /* Framed-IP-Netmask */
+ struct dict_object * Framed_Interface_Id; /* Framed-Interface-Id */
+ struct dict_object * Framed_IPv6_Prefix; /* Framed-IPv6-Prefix */
+ struct dict_object * Framed_IPX_Network; /* Framed-IPX-Network */
+ struct dict_object * Framed_MTU; /* Framed-MTU */
+ struct dict_object * Framed_Protocol; /* Framed-Protocol */
+ struct dict_object * Framed_Pool; /* Framed-Pool */
+ struct dict_object * Framed_IPv6_Route; /* Framed-IPv6-Route */
+ struct dict_object * Framed_IPv6_Pool; /* Framed-IPv6-Pool */
+ struct dict_object * Framed_Route; /* Framed-Route */
+ struct dict_object * Framed_Routing; /* Framed-Routing */
+ struct dict_object * Filter_Id; /* Filter-Id */
+ struct dict_object * Idle_Timeout; /* Idle-Timeout */
+ struct dict_object * Login_IP_Host; /* Login-IP-Host */
+ struct dict_object * Login_IPv6_Host; /* Login-IPv6-Host */
+ struct dict_object * Login_LAT_Group; /* Login-LAT-Group */
+ struct dict_object * Login_LAT_Node; /* Login-LAT-Node */
+ struct dict_object * Login_LAT_Port; /* Login-LAT-Port */
+ struct dict_object * Login_LAT_Service; /* Login-LAT-Service */
+ struct dict_object * Login_Service; /* Login-Service */
+ struct dict_object * Login_TCP_Port; /* Login-TCP-Port */
+ struct dict_object * NAS_Identifier; /* NAS-Identifier */
+ struct dict_object * NAS_IP_Address; /* NAS-IP-Address */
+ struct dict_object * NAS_IPv6_Address; /* NAS-IPv6-Address */
+ struct dict_object * NAS_Port; /* NAS-Port */
+ struct dict_object * NAS_Port_Id; /* NAS-Port-Id */
+ struct dict_object * NAS_Port_Type; /* NAS-Port-Type */
+ struct dict_object * Origin_AAA_Protocol; /* Origin-AAA-Protocol */
+ struct dict_object * Origin_Host; /* Origin-Host */
+ struct dict_object * Origin_Realm; /* Origin-Realm */
+ struct dict_object * Originating_Line_Info; /* Originating-Line-Info */
+ struct dict_object * Port_Limit; /* Port-Limit */
+ struct dict_object * Re_Auth_Request_Type; /* Re-Auth-Request-Type */
+ struct dict_object * Result_Code; /* Result-Code */
+ struct dict_object * Service_Type; /* Service-Type */
+ struct dict_object * Session_Id; /* Session-Id */
+ struct dict_object * Session_Timeout; /* Session-Timeout */
+ struct dict_object * State; /* State */
+ struct dict_object * Termination_Cause; /* Termination-Cause */
+ struct dict_object * Tunneling; /* Tunneling */
+ struct dict_object * Tunnel_Type; /* Tunnel-Type */
+ struct dict_object * Tunnel_Assignment_Id; /* Tunnel-Assignment-Id */
+ struct dict_object * Tunnel_Medium_Type; /* Tunnel-Medium-Type */
+ struct dict_object * Tunnel_Client_Endpoint; /* Tunnel-Client-Endpoint */
+ struct dict_object * Tunnel_Server_Endpoint; /* Tunnel-Server-Endpoint */
+ struct dict_object * Tunnel_Private_Group_Id; /* Tunnel-Private-Group-Id */
+ struct dict_object * Tunnel_Preference; /* Tunnel-Preference */
+ struct dict_object * Tunnel_Client_Auth_Id; /* Tunnel-Client-Auth-Id */
+ struct dict_object * Tunnel_Server_Auth_Id; /* Tunnel-Server-Auth-Id */
+ struct dict_object * User_Name; /* User-Name */
+
+ struct dict_object * Session_Termination_Request;/* STR */
+ } dict; /* cache of the dictionary objects we use */
+ struct session_handler * sess_hdl; /* We store RADIUS request authenticator information in the session */
+ char * confstr;
+
+ int ignore_nai;
+};
+
+/* The state we store in the session */
+struct sess_state {
+ application_id_t auth_appl; /* Auth-Application-Id used for this session, if available (stored in a Class attribute) */
+ int send_str; /* If not 0, we must send a STR when the ACA is received. */
+ uint32_t term_cause; /* If not 0, the Termination-Cause to put in the STR. */
+};
+
+static DECLARE_FD_DUMP_PROTOTYPE(acct_conf_session_state_dump, struct sess_state * st)
+{
+ return fd_dump_extend( FD_DUMP_STD_PARAMS, "[rgwx sess_state](@%p): aai:%x str:%d TC:%u", st, st->auth_appl, st->send_str, st->term_cause);
+}
+
+/* Initialize the plugin */
+static int acct_conf_parse(char * conffile, struct rgwp_config ** state)
+{
+ struct rgwp_config * new;
+ struct dict_object * app;
+
+ TRACE_ENTRY("%p %p", conffile, state);
+ CHECK_PARAMS( state );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct rgwp_config)) );
+ memset(new, 0, sizeof(struct rgwp_config));
+
+ CHECK_FCT( fd_sess_handler_create( &new->sess_hdl, (void *)free, acct_conf_session_state_dump, NULL ) );
+ new->confstr = conffile;
+
+ if (conffile && strstr(conffile, "nonai"))
+ new->ignore_nai = 1;
+
+ /* Resolve all dictionary objects we use */
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Number", &new->dict.Accounting_Record_Number, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Type", &new->dict.Accounting_Record_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Acct-Application-Id", &new->dict.Acct_Application_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Acct-Delay-Time", &new->dict.Acct_Delay_Time, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Input-Octets", &new->dict.Accounting_Input_Octets, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Output-Octets", &new->dict.Accounting_Output_Octets, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Input-Packets", &new->dict.Accounting_Input_Packets, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Output-Packets", &new->dict.Accounting_Output_Packets, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Acct-Authentic", &new->dict.Acct_Authentic, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Acct-Link-Count", &new->dict.Acct_Link_Count, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Acct-Multi-Session-Id", &new->dict.Acct_Multi_Session_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Acct-Session-Id", &new->dict.Acct_Session_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Acct-Session-Time", &new->dict.Acct_Session_Time, ENOENT) );
+
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "ARAP-Password", &new->dict.ARAP_Password, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "ARAP-Security", &new->dict.ARAP_Security, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "ARAP-Security-Data", &new->dict.ARAP_Security_Data, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &new->dict.Auth_Application_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Request-Type", &new->dict.Auth_Request_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Authorization-Lifetime", &new->dict.Authorization_Lifetime, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Callback-Number", &new->dict.Callback_Number, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Callback-Id", &new->dict.Callback_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Called-Station-Id", &new->dict.Called_Station_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Calling-Station-Id", &new->dict.Calling_Station_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Class", &new->dict.Class, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Connect-Info", &new->dict.Connect_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &new->dict.Destination_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &new->dict.Destination_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "EAP-Payload", &new->dict.EAP_Payload, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Message", &new->dict.Error_Message, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Reporting-Host", &new->dict.Error_Reporting_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Event-Timestamp", &new->dict.Event_Timestamp, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Failed-AVP", &new->dict.Failed_AVP, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-AppleTalk-Link", &new->dict.Framed_AppleTalk_Link, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-AppleTalk-Network", &new->dict.Framed_AppleTalk_Network, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-AppleTalk-Zone", &new->dict.Framed_AppleTalk_Zone, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-Compression", &new->dict.Framed_Compression, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-IP-Address", &new->dict.Framed_IP_Address, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-IP-Netmask", &new->dict.Framed_IP_Netmask, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-Interface-Id", &new->dict.Framed_Interface_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-IPv6-Prefix", &new->dict.Framed_IPv6_Prefix, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-IPX-Network", &new->dict.Framed_IPX_Network, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-MTU", &new->dict.Framed_MTU, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-Protocol", &new->dict.Framed_Protocol, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-Pool", &new->dict.Framed_Pool, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-Route", &new->dict.Framed_Route, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-IPv6-Route", &new->dict.Framed_IPv6_Route, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-IPv6-Pool", &new->dict.Framed_IPv6_Pool, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-Routing", &new->dict.Framed_Routing, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Filter-Id", &new->dict.Filter_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Idle-Timeout", &new->dict.Idle_Timeout, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-IP-Host", &new->dict.Login_IP_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-IPv6-Host", &new->dict.Login_IPv6_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-LAT-Group", &new->dict.Login_LAT_Group, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-LAT-Node", &new->dict.Login_LAT_Node, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-LAT-Port", &new->dict.Login_LAT_Port, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-LAT-Service", &new->dict.Login_LAT_Service, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-Service", &new->dict.Login_Service, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-TCP-Port", &new->dict.Login_TCP_Port, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-Identifier", &new->dict.NAS_Identifier, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-IP-Address", &new->dict.NAS_IP_Address, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-IPv6-Address", &new->dict.NAS_IPv6_Address, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-Port", &new->dict.NAS_Port, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-Port-Id", &new->dict.NAS_Port_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-Port-Type", &new->dict.NAS_Port_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-AAA-Protocol", &new->dict.Origin_AAA_Protocol, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &new->dict.Origin_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &new->dict.Origin_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Originating-Line-Info", &new->dict.Originating_Line_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Port-Limit", &new->dict.Port_Limit, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Re-Auth-Request-Type", &new->dict.Re_Auth_Request_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &new->dict.Result_Code, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Service-Type", &new->dict.Service_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &new->dict.Session_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Timeout", &new->dict.Session_Timeout, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "State", &new->dict.State, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Termination-Cause", &new->dict.Termination_Cause, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunneling", &new->dict.Tunneling, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Assignment-Id", &new->dict.Tunnel_Assignment_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Type", &new->dict.Tunnel_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Medium-Type", &new->dict.Tunnel_Medium_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Client-Endpoint", &new->dict.Tunnel_Client_Endpoint, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Server-Endpoint", &new->dict.Tunnel_Server_Endpoint, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Private-Group-Id", &new->dict.Tunnel_Private_Group_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Preference", &new->dict.Tunnel_Preference, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Client-Auth-Id", &new->dict.Tunnel_Client_Auth_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Server-Auth-Id", &new->dict.Tunnel_Server_Auth_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &new->dict.User_Name, ENOENT) );
+
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Request", &new->dict.Session_Termination_Request, ENOENT) );
+
+ /* This plugin provides the following Diameter authentication applications support: */
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Base Accounting", &app, ENOENT) );
+ CHECK_FCT( fd_disp_app_support ( app, NULL, 0, 1 ) );
+
+ *state = new;
+ return 0;
+}
+
+/* deinitialize */
+static void acct_conf_free(struct rgwp_config * state)
+{
+ TRACE_ENTRY("%p", state);
+ CHECK_PARAMS_DO( state, return );
+ CHECK_FCT_DO( fd_sess_handler_destroy( &state->sess_hdl, NULL ), );
+ free(state);
+ return;
+}
+
+/* Incoming RADIUS request */
+static int acct_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+{
+ int idx;
+ int send_str=0;
+ uint32_t str_cause=0;
+ uint32_t e2eid = 0;
+ application_id_t auth_appl=0;
+ int got_id = 0;
+ uint32_t status_type;
+ uint32_t termination_action = 0;
+ uint32_t gigawords_in=0, gigawords_out=0;
+ size_t nattr_used = 0;
+ union avp_value value;
+ struct avp ** avp_tun = NULL, *avp = NULL;
+ struct session * sess;
+
+ const char * prefix = "Diameter/";
+ size_t pref_len;
+ os0_t si = NULL;
+ size_t si_len = 0;
+ os0_t un = NULL;
+ size_t un_len = 0;
+
+ TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
+ CHECK_PARAMS(rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCOUNTING_REQUEST) && rad_ans && diam_fw && *diam_fw);
+
+ pref_len = strlen(prefix);
+
+ /*
+ Either NAS-IP-Address or NAS-Identifier MUST be present in a
+ RADIUS Accounting-Request. It SHOULD contain a NAS-Port or NAS-
+ Port-Type attribute or both unless the service does not involve a
+ port or the NAS does not distinguish among its ports.
+ */
+ /* We also enforce that the message contains a CLASS attribute with Diameter/ prefix containing the Session-Id. */
+ for (idx = 0; idx < rad_req->attr_used; idx++) {
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(rad_req->buf + rad_req->attr_pos[idx]);
+ uint8_t * v = (uint8_t *)(attr + 1);
+ size_t attr_len = attr->length - sizeof(struct radius_attr_hdr);
+
+ switch (attr->type) {
+ case RADIUS_ATTR_NAS_IP_ADDRESS:
+ case RADIUS_ATTR_NAS_IDENTIFIER:
+ case RADIUS_ATTR_NAS_IPV6_ADDRESS:
+ got_id = 1;
+ break;
+
+ case RADIUS_ATTR_TERMINATION_ACTION:
+ CHECK_PARAMS( attr->length == 6 );
+ termination_action = (v[0] << 24)
+ | (v[1] << 16)
+ | (v[2] << 8)
+ | v[3] ;
+ break;
+
+ case RADIUS_ATTR_ACCT_INPUT_GIGAWORDS:
+ CHECK_PARAMS( attr->length == 6 );
+ gigawords_in = (v[0] << 24)
+ | (v[1] << 16)
+ | (v[2] << 8)
+ | v[3] ;
+ break;
+
+ case RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS:
+ CHECK_PARAMS( attr->length == 6 );
+ gigawords_out = (v[0] << 24)
+ | (v[1] << 16)
+ | (v[2] << 8)
+ | v[3] ;
+ break;
+
+ case RADIUS_ATTR_CLASS:
+ if ((attr_len > pref_len ) && ! strncmp((char *)v, prefix, pref_len)) {
+ int i;
+ si = v + pref_len;
+ si_len = attr_len - pref_len;
+ TRACE_DEBUG(ANNOYING, "Found Class attribute with '%s' prefix (attr #%d), SI:'%.*s'.", prefix, idx, (int)si_len, si);
+ /* Remove from the message */
+ for (i = idx + 1; i < rad_req->attr_used; i++)
+ rad_req->attr_pos[i - 1] = rad_req->attr_pos[i];
+ rad_req->attr_used -= 1;
+ }
+ break;
+
+ case RADIUS_ATTR_USER_NAME:
+ if (attr_len) {
+ un = v;
+ un_len = attr_len;
+ TRACE_DEBUG(ANNOYING, "Found a User-Name attribute: '%.*s'", (int)un_len, un);
+ }
+ break;
+
+ }
+ }
+
+ /* Check basic information is there */
+ if (!got_id || radius_msg_get_attr_int32(rad_req, RADIUS_ATTR_ACCT_STATUS_TYPE, &status_type)) {
+ TRACE_DEBUG(INFO, "[acct.rgwx] RADIUS Account-Request from %s did not contain a NAS ip/identifier or Acct-Status-Type attribute, reject.", rgw_clients_id(cli));
+ return EINVAL;
+ }
+
+ /*
+ -- RFC2866:
+ In Accounting-Request Packets, the Authenticator value is a 16
+ octet MD5 [5] checksum, called the Request Authenticator.
+
+ The NAS and RADIUS accounting server share a secret. The Request
+ Authenticator field in Accounting-Request packets contains a one-
+ way MD5 hash calculated over a stream of octets consisting of the
+ Code + Identifier + Length + 16 zero octets + request attributes +
+ shared secret (where + indicates concatenation). The 16 octet MD5
+ hash value is stored in the Authenticator field of the
+ Accounting-Request packet.
+
+ Note that the Request Authenticator of an Accounting-Request can
+ not be done the same way as the Request Authenticator of a RADIUS
+ Access-Request, because there is no User-Password attribute in an
+ Accounting-Request.
+
+
+ -- RFC5080:
+ The Request Authenticator field MUST contain the correct data, as
+ given by the above calculation. Invalid packets are silently
+ discarded. Note that some early implementations always set the
+ Request Authenticator to all zeros. New implementations of RADIUS
+ clients MUST use the above algorithm to calculate the Request
+ Authenticator field. New RADIUS server implementations MUST
+ silently discard invalid packets.
+
+ */
+ {
+ uint8_t save[MD5_MAC_LEN];
+ uint8_t * secret;
+ size_t secret_len;
+
+ /* Get the shared secret */
+ CHECK_FCT(rgw_clients_getkey(cli, &secret, &secret_len));
+
+ /* Copy the received Request Authenticator */
+ memcpy(&save[0], &rad_req->hdr->authenticator[0], MD5_MAC_LEN);
+
+ /* Compute the same authenticator */
+ radius_msg_finish_acct(rad_req, secret, secret_len);
+
+ /* And now compare with the received value */
+ if (memcmp(&save[0], &rad_req->hdr->authenticator[0], MD5_MAC_LEN)) {
+ /* Invalid authenticator */
+ TRACE_BUFFER(FD_LOG_DEBUG, FULL+1, "Received ReqAuth: ", &save[0], MD5_MAC_LEN, "" );
+ TRACE_BUFFER(FD_LOG_DEBUG, FULL+1, "Expected ReqAuth: ", &rad_req->hdr->authenticator[0], MD5_MAC_LEN, "" );
+ TRACE_DEBUG(INFO, "[acct.rgwx] Invalid Request Authenticator in Account-Request from %s, discarding the message.", rgw_clients_id(cli));
+ return EINVAL;
+ }
+ }
+
+
+ /* Handle the Accounting-On case: nothing to do, just reply OK */
+ if (status_type == RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_ON) {
+ TRACE_DEBUG(FULL, "[acct.rgwx] Received Accounting-On Acct-Status-Type attribute, replying without translation to Diameter.");
+ CHECK_MALLOC( *rad_ans = radius_msg_new(RADIUS_CODE_ACCOUNTING_RESPONSE, rad_req->hdr->identifier) );
+ return -2;
+ }
+
+ if (status_type == RADIUS_ACCT_STATUS_TYPE_ACCOUNTING_OFF) {
+ TRACE_DEBUG(FULL, "[acct.rgwx] Received Accounting-Off Acct-Status-Type attribute, we must terminate all active sessions.");
+ TODO("RADIUS side is rebooting, send STR on all sessions???");
+ return ENOTSUP;
+ }
+
+ /* Check if we got a valid session information, otherwise the server will not be able to handle the data... */
+ if (!si) {
+ TRACE_DEBUG(INFO, "[acct.rgwx] RADIUS Account-Request from %s did not contain a CLASS attribute with Diameter session information, reject.", rgw_clients_id(cli));
+ return EINVAL;
+ }
+
+ /* Add the Destination-Realm */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Destination_Realm, 0, &avp ) );
+ idx = 0;
+ if (un && ! cs->ignore_nai) {
+ /* Is there an '@' in the user name? We don't care for decorated NAI here */
+ for (idx = un_len - 2; idx > 0; idx--) {
+ if (un[idx] == '@') {
+ idx++;
+ break;
+ }
+ }
+ }
+ if (idx == 0) {
+ /* Not found in the User-Name => we use the local domain of this gateway */
+ value.os.data = (uint8_t *)fd_g_config->cnf_diamrlm;
+ value.os.len = fd_g_config->cnf_diamrlm_len;
+ } else {
+ value.os.data = un + idx;
+ value.os.len = un_len - idx;
+ }
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+
+ /* Create the Session-Id AVP */
+ {
+ CHECK_FCT( fd_sess_fromsid_msg ( si, si_len, &sess, NULL) );
+
+ TRACE_DEBUG(FULL, "[acct.rgwx] Translating new accounting message for session '%.*s'...", (int)si_len, si);
+
+ /* Add the Session-Id AVP as first AVP */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
+ value.os.data = (unsigned char *)si;
+ value.os.len = si_len;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+ CHECK_FCT( fd_msg_sess_set(*diam_fw, sess) );
+ }
+
+
+ /* Add the command code */
+ {
+ struct msg_hdr * header = NULL;
+ CHECK_FCT( fd_msg_hdr ( *diam_fw, &header ) );
+ header->msg_flags = CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE;
+ header->msg_code = CC_AC;
+ header->msg_appl = AI_ACCT;
+
+ /* Add the Acct-Application-Id */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Acct_Application_Id, 0, &avp ) );
+ value.i32 = header->msg_appl;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+
+ /* save the end to end id */
+ e2eid = header->msg_eteid;
+ }
+
+ /* Convert the RADIUS attributes, as they appear in the message */
+ for (idx = 0; idx < rad_req->attr_used; idx++) {
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(rad_req->buf + rad_req->attr_pos[idx]);
+
+ switch (attr->type) {
+ /*
+ Any attribute valid in a RADIUS Access-Request or Access-Accept
+ packet is valid in a RADIUS Accounting-Request packet, except that
+ the following attributes MUST NOT be present in an Accounting-
+ Request: User-Password, CHAP-Password, Reply-Message, State.
+ */
+ case RADIUS_ATTR_USER_PASSWORD:
+ case RADIUS_ATTR_CHAP_PASSWORD:
+ case RADIUS_ATTR_REPLY_MESSAGE:
+ case RADIUS_ATTR_STATE:
+ case RADIUS_ATTR_MESSAGE_AUTHENTICATOR:
+ case RADIUS_ATTR_EAP_MESSAGE:
+ TRACE_DEBUG(INFO, "[acct.rgwx] RADIUS Account-Request contains a forbidden attribute (%hhd), reject.", attr->type);
+ return EINVAL;
+
+
+ /* This macro converts a RADIUS attribute to a Diameter AVP of type OctetString */
+ #define CONV2DIAM_STR( _dictobj_ ) \
+ CHECK_PARAMS( attr->length >= 2 ); \
+ /* Create the AVP with the specified dictionary model */ \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ value.os.len = attr->length - 2; \
+ value.os.data = (unsigned char *)(attr + 1); \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ /* Add the AVP in the Diameter message. */ \
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); \
+
+ /* Same thing, for scalar AVPs of 32 bits */
+ #define CONV2DIAM_32B( _dictobj_ ) \
+ CHECK_PARAMS( attr->length == 6 ); \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ { \
+ uint8_t * v = (uint8_t *)(attr + 1); \
+ value.u32 = (v[0] << 24) \
+ | (v[1] << 16) \
+ | (v[2] << 8) \
+ | v[3] ; \
+ } \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); \
+
+ /* And the 64b version */
+ #define CONV2DIAM_64B( _dictobj_ ) \
+ CHECK_PARAMS( attr->length == 10); \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ { \
+ uint8_t * v = (uint8_t *)(attr + 1); \
+ value.u64 = ((uint64_t)(v[0]) << 56) \
+ | ((uint64_t)(v[1]) << 48) \
+ | ((uint64_t)(v[2]) << 40) \
+ | ((uint64_t)(v[3]) << 32) \
+ | ((uint64_t)(v[4]) << 24) \
+ | ((uint64_t)(v[5]) << 16) \
+ | ((uint64_t)(v[6]) << 8) \
+ | (uint64_t)(v[7]) ; \
+ } \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); \
+
+
+ /* Attributes as listed in RFC2866, section 5.13 and RFC4005, section 10.2.1 */
+ case RADIUS_ATTR_USER_NAME:
+ CONV2DIAM_STR( User_Name );
+ break;
+
+ case RADIUS_ATTR_NAS_IP_ADDRESS:
+ CONV2DIAM_STR( NAS_IP_Address );
+ break;
+
+ case RADIUS_ATTR_NAS_PORT:
+ CONV2DIAM_32B( NAS_Port );
+ break;
+
+ case RADIUS_ATTR_SERVICE_TYPE:
+ CONV2DIAM_32B( Service_Type );
+ break;
+
+ case RADIUS_ATTR_FRAMED_PROTOCOL:
+ CONV2DIAM_32B( Framed_Protocol );
+ break;
+
+ case RADIUS_ATTR_FRAMED_IP_ADDRESS:
+ CONV2DIAM_STR( Framed_IP_Address );
+ break;
+
+ case RADIUS_ATTR_FRAMED_IP_NETMASK:
+ CONV2DIAM_STR( Framed_IP_Netmask );
+ break;
+
+ case RADIUS_ATTR_FRAMED_ROUTING:
+ CONV2DIAM_32B( Framed_Routing );
+ break;
+
+ case RADIUS_ATTR_FILTER_ID:
+ CONV2DIAM_STR( Filter_Id );
+ break;
+
+ case RADIUS_ATTR_FRAMED_MTU:
+ CONV2DIAM_32B( Framed_MTU );
+ break;
+
+ case RADIUS_ATTR_FRAMED_COMPRESSION:
+ CONV2DIAM_32B( Framed_Compression );
+ break;
+
+ case RADIUS_ATTR_LOGIN_IP_HOST:
+ CONV2DIAM_STR( Login_IP_Host );
+ break;
+
+ case RADIUS_ATTR_LOGIN_SERVICE:
+ CONV2DIAM_32B( Login_Service );
+ break;
+
+ case RADIUS_ATTR_LOGIN_TCP_PORT:
+ CONV2DIAM_32B( Login_TCP_Port );
+ break;
+
+ case RADIUS_ATTR_CALLBACK_NUMBER:
+ CONV2DIAM_STR( Callback_Number );
+ break;
+
+ case RADIUS_ATTR_CALLBACK_ID:
+ CONV2DIAM_STR( Callback_Id );
+ break;
+
+ case RADIUS_ATTR_FRAMED_ROUTE:
+ CONV2DIAM_STR( Framed_Route );
+ break;
+
+ case RADIUS_ATTR_FRAMED_IPX_NETWORK:
+ CONV2DIAM_32B( Framed_IPX_Network );
+ break;
+
+ case RADIUS_ATTR_CLASS:
+ CONV2DIAM_STR( Class );
+ /* In addition, save the data in the session if it is "our" CLASS_AAI_PREFIX Class attribute */
+ {
+ char buf[32];
+ char * attr_val, *auth_val;
+ attr_val = (char *)(attr + 1);
+ auth_val = attr_val + CONSTSTRLEN(CLASS_AAI_PREFIX);
+ if ( (attr->length > sizeof(struct radius_attr_hdr) + CONSTSTRLEN(CLASS_AAI_PREFIX) )
+ && (attr->length < sizeof(struct radius_attr_hdr) + CONSTSTRLEN(CLASS_AAI_PREFIX) + sizeof(buf))
+ && ! strncmp(attr_val, CLASS_AAI_PREFIX, CONSTSTRLEN(CLASS_AAI_PREFIX))) {
+
+ memset(buf, 0, sizeof(buf));
+ memcpy(buf, auth_val, attr->length - sizeof(struct radius_attr_hdr) - CONSTSTRLEN(CLASS_AAI_PREFIX));
+ if (sscanf(buf, "%u", &auth_appl) == 1) {
+ TRACE_DEBUG(ANNOYING, "Found Class attribute with '%s' prefix (attr #%d), AAI:%u.", CLASS_AAI_PREFIX, idx, auth_appl);
+ }
+ }
+ }
+ break;
+
+ case RADIUS_ATTR_VENDOR_SPECIFIC:
+ if (attr->length >= 6) {
+ uint32_t vendor_id;
+ uint8_t * c = (uint8_t *)(attr + 1);
+
+ vendor_id = c[0] << 24 | c[1] << 16 | c[2] << 8 | c[3];
+ c += 4;
+
+ switch (vendor_id) {
+
+ /* For the vendors we KNOW they follow the VSA recommended format, we convert following the rules of RFC4005 (9.6.2) */
+ case RADIUS_VENDOR_ID_MICROSOFT : /* RFC 2548 */
+ /* other vendors ? */
+ {
+ size_t left;
+ struct radius_attr_vendor *vtlv;
+
+ left = attr->length - 6;
+ vtlv = (struct radius_attr_vendor *)c;
+
+ while ((left >= 2) && (vtlv->vendor_length <= left)) {
+ /* Search our dictionary for corresponding Vendor's AVP */
+ struct dict_avp_request req;
+ struct dict_object * avp_model = NULL;
+ memset(&req, 0, sizeof(struct dict_avp_request));
+ req.avp_vendor = vendor_id;
+ req.avp_code = vtlv->vendor_type;
+
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE_AND_VENDOR, &req, &avp_model, 0) );
+ if (!avp_model) {
+ TRACE_DEBUG(FULL, "Unknown attribute (vendor 0x%x, code 0x%x) ignored.", req.avp_vendor, req.avp_code);
+ } else {
+ CHECK_FCT( fd_msg_avp_new ( avp_model, 0, &avp ) );
+ value.os.len = vtlv->vendor_length - 2;
+ value.os.data = (unsigned char *)(vtlv + 1);
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+ c += vtlv->vendor_length;
+ left -= vtlv->vendor_length;
+ vtlv = (struct radius_attr_vendor *)c;
+ }
+ }
+ break;
+
+ /* Other vendors we KNOw how to convert the attributes would be added here... */
+ /* case RADIUS_VENDOR_ID_CISCO :
+ break; */
+ /* case RADIUS_VENDOR_ID_IETF : (extended RADIUS attributes)
+ break; */
+
+ /* When we don't know, just discard the attribute... VSA are optional with regards to RADIUS anyway */
+ default:
+ /* do nothing */
+ TRACE_DEBUG(FULL, "VSA attribute from vendor %d discarded", vendor_id);
+
+ }
+ }
+ break;
+
+ case RADIUS_ATTR_SESSION_TIMEOUT:
+ /* Translation depends on Termination-Action : rfc4005#section-9.2.1 */
+ if (termination_action != RADIUS_TERMINATION_ACTION_RADIUS_REQUEST) {
+ CONV2DIAM_32B( Session_Timeout );
+ } else {
+ CONV2DIAM_32B( Authorization_Lifetime );
+ /* And add this additional AVP */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Re_Auth_Request_Type, 0, &avp ) );
+ value.u32 = ACV_ART_AUTHORIZE_AUTHENTICATE;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+ break;
+
+ case RADIUS_ATTR_IDLE_TIMEOUT:
+ CONV2DIAM_32B( Idle_Timeout );
+ break;
+
+ case RADIUS_ATTR_TERMINATION_ACTION:
+ /* Just remove */
+ break;
+
+ case RADIUS_ATTR_CALLED_STATION_ID:
+ CONV2DIAM_STR( Called_Station_Id );
+ break;
+
+ case RADIUS_ATTR_CALLING_STATION_ID:
+ CONV2DIAM_STR( Calling_Station_Id );
+ break;
+
+ case RADIUS_ATTR_NAS_IDENTIFIER:
+ CONV2DIAM_STR( NAS_Identifier );
+ break;
+
+ /* Proxy-State is handled by echo_drop.rgwx plugin, we ignore it here */
+
+ case RADIUS_ATTR_LOGIN_LAT_SERVICE:
+ CONV2DIAM_STR( Login_LAT_Service );
+ break;
+
+ case RADIUS_ATTR_LOGIN_LAT_NODE:
+ CONV2DIAM_STR( Login_LAT_Node );
+ break;
+
+ case RADIUS_ATTR_LOGIN_LAT_GROUP:
+ CONV2DIAM_STR( Login_LAT_Group );
+ break;
+
+ case RADIUS_ATTR_FRAMED_APPLETALK_LINK:
+ CONV2DIAM_32B( Framed_AppleTalk_Link );
+ break;
+
+ case RADIUS_ATTR_FRAMED_APPLETALK_NETWORK:
+ CONV2DIAM_32B( Framed_AppleTalk_Network );
+ break;
+
+ case RADIUS_ATTR_FRAMED_APPLETALK_ZONE:
+ CONV2DIAM_STR( Framed_AppleTalk_Zone );
+ break;
+
+ case RADIUS_ATTR_ACCT_STATUS_TYPE:
+ /*
+ - If the RADIUS message received is an Accounting-Request, the
+ Acct-Status-Type attribute value must be converted to a
+ Accounting-Record-Type AVP value. If the Acct-Status-Type
+ attribute value is STOP, the local server MUST issue a
+ Session-Termination-Request message once the Diameter
+ Accounting-Answer message has been received.
+ */
+ switch (status_type) {
+ case RADIUS_ACCT_STATUS_TYPE_START:
+ value.u32 = ACV_ART_START_RECORD;
+ break;
+ case RADIUS_ACCT_STATUS_TYPE_STOP:
+ value.u32 = ACV_ART_STOP_RECORD;
+ send_str = 1; /* Register this info in the session */
+ break;
+ case RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE:
+ value.u32 = ACV_ART_INTERIM_RECORD;
+ break;
+ default:
+ TRACE_DEBUG(INFO, "Unknown RADIUS_ATTR_ACCT_STATUS_TYPE value %d, aborting...", status_type);
+ return ENOTSUP;
+ }
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Accounting_Record_Type, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+
+ /* While here, we also add the Accouting-Record-Number AVP.
+ The Accounting-Record-Number AVP (AVP Code 485) is of type Unsigned32
+ and identifies this record within one session. As Session-Id AVPs
+ are globally unique, the combination of Session-Id and Accounting-
+ Record-Number AVPs is also globally unique, and can be used in
+ matching accounting records with confirmations. An easy way to
+ produce unique numbers is to set the value to 0 for records of type
+ EVENT_RECORD and START_RECORD, and set the value to 1 for the first
+ INTERIM_RECORD, 2 for the second, and so on until the value for
+ STOP_RECORD is one more than for the last INTERIM_RECORD.
+
+ -- we actually use the end-to-end id of the message here, which remains constant
+ if we send a duplicate, so it has the same properties as the suggested algorithm.
+ Anyway, it assumes that we are not converting twice the same RADIUS message.
+ . */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Accounting_Record_Number, 0, &avp ) );
+ value.u32 = e2eid;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+
+ break;
+
+ case RADIUS_ATTR_ACCT_DELAY_TIME:
+ CONV2DIAM_32B( Acct_Delay_Time );
+ break;
+
+ /*
+ - If the RADIUS message contains the Accounting-Input-Octets,
+ Accounting-Input-Packets, Accounting-Output-Octets, or
+ Accounting-Output-Packets, these attributes must be converted
+ to the Diameter equivalents. Further, if the Acct-Input-
+ Gigawords or Acct-Output-Gigawords attributes are present,
+ these must be used to properly compute the Diameter accounting
+ AVPs.
+ */
+ case RADIUS_ATTR_ACCT_INPUT_OCTETS:
+ memset(&value, 0, sizeof(value));
+ {
+ uint8_t * v = (uint8_t *)(attr + 1);
+ value.u64 = (v[0] << 24)
+ | (v[1] << 16)
+ | (v[2] << 8)
+ | v[3] ;
+ }
+ value.u64 += ((uint64_t)gigawords_in << 32);
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Accounting_Input_Octets, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ break;
+
+ case RADIUS_ATTR_ACCT_OUTPUT_OCTETS:
+ memset(&value, 0, sizeof(value));
+ {
+ uint8_t * v = (uint8_t *)(attr + 1);
+ value.u64 = (v[0] << 24)
+ | (v[1] << 16)
+ | (v[2] << 8)
+ | v[3] ;
+ }
+ value.u64 += ((uint64_t)gigawords_out << 32);
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Accounting_Output_Octets, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ break;
+
+ case RADIUS_ATTR_ACCT_SESSION_ID:
+ CONV2DIAM_STR( Acct_Session_Id );
+ break;
+
+ case RADIUS_ATTR_ACCT_AUTHENTIC:
+ CONV2DIAM_32B( Acct_Authentic );
+ break;
+
+ case RADIUS_ATTR_ACCT_SESSION_TIME:
+ CONV2DIAM_32B( Acct_Session_Time );
+ break;
+
+ case RADIUS_ATTR_ACCT_INPUT_PACKETS:
+ memset(&value, 0, sizeof(value));
+ {
+ uint8_t * v = (uint8_t *)(attr + 1);
+ value.u64 = (v[0] << 24)
+ | (v[1] << 16)
+ | (v[2] << 8)
+ | v[3] ;
+ }
+ /* value.u64 += (gigawords_in << 32); */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Accounting_Input_Packets, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ break;
+
+ case RADIUS_ATTR_ACCT_OUTPUT_PACKETS:
+ memset(&value, 0, sizeof(value));
+ {
+ uint8_t * v = (uint8_t *)(attr + 1);
+ value.u64 = (v[0] << 24)
+ | (v[1] << 16)
+ | (v[2] << 8)
+ | v[3] ;
+ }
+ /* value.u64 += (gigawords_out << 32); */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Accounting_Output_Packets, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ break;
+
+ /*
+ - If the Accounting message contains an Acct-Termination-Cause
+ attribute, it should be translated to the equivalent
+ Termination-Cause AVP value.
+ */
+ case RADIUS_ATTR_ACCT_TERMINATE_CAUSE:
+ /* rfc4005#section-9.3.5 */
+ {
+ uint8_t * v = (uint8_t *)(attr + 1);
+ str_cause = (v[0] << 24)
+ | (v[1] << 16)
+ | (v[2] << 8)
+ | v[3] ;
+ }
+ str_cause += 10; /* This seems to be the rule, we can modify later if needed */
+ break;
+
+ case RADIUS_ATTR_ACCT_MULTI_SESSION_ID:
+ CONV2DIAM_STR( Acct_Multi_Session_Id );
+ break;
+
+ case RADIUS_ATTR_ACCT_LINK_COUNT:
+ CONV2DIAM_32B( Acct_Link_Count );
+ break;
+
+ /* CHAP-Challenge is not present in Accounting-Request */
+
+ case RADIUS_ATTR_NAS_PORT_TYPE:
+ CONV2DIAM_32B( NAS_Port_Type );
+ break;
+
+ case RADIUS_ATTR_PORT_LIMIT:
+ CONV2DIAM_32B( Port_Limit );
+ break;
+
+ case RADIUS_ATTR_LOGIN_LAT_PORT:
+ CONV2DIAM_STR( Login_LAT_Port );
+ break;
+
+ /* RFC 3162 */
+ case RADIUS_ATTR_NAS_IPV6_ADDRESS:
+ CONV2DIAM_STR( NAS_IPv6_Address );
+ break;
+
+ case RADIUS_ATTR_FRAMED_INTERFACE_ID:
+ CONV2DIAM_64B( Framed_Interface_Id );
+ break;
+
+ case RADIUS_ATTR_FRAMED_IPV6_PREFIX:
+ CONV2DIAM_STR( Framed_IPv6_Prefix );
+ break;
+
+ case RADIUS_ATTR_LOGIN_IPV6_HOST:
+ CONV2DIAM_STR( Login_IPv6_Host );
+ break;
+
+ case RADIUS_ATTR_FRAMED_IPV6_ROUTE:
+ CONV2DIAM_STR( Framed_IPv6_Route );
+ break;
+
+ case RADIUS_ATTR_FRAMED_IPV6_POOL:
+ CONV2DIAM_STR( Framed_IPv6_Pool );
+ break;
+
+ /* RFC 2868 */
+ /* Prepare the top-level Tunneling AVP for each tag values, as needed, and add to the Diameter message.
+ This macro is called when an AVP is added inside the group, so we will not have empty grouped AVPs */
+ #define AVP_TUN_PREPARE() { \
+ if (avp_tun == NULL) { \
+ CHECK_MALLOC( avp_tun = calloc(sizeof(struct avp *), 32 ) ); \
+ } \
+ tag = *(uint8_t *)(attr + 1); \
+ if (tag > 0x1F) tag = 0; \
+ if (avp_tun[tag] == NULL) { \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Tunneling, 0, &avp_tun[tag] ) ); \
+ CHECK_FCT( fd_msg_avp_add (*diam_fw, MSG_BRW_LAST_CHILD, avp_tun[tag]));\
+ } \
+ }
+
+ /* Convert an attribute to an OctetString AVP and add inside the Tunneling AVP corresponding to the tag */
+ #define CONV2DIAM_TUN_STR( _dictobj_ ) { \
+ uint8_t tag; \
+ CHECK_PARAMS( attr->length >= 3); \
+ AVP_TUN_PREPARE(); \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ value.os.len = attr->length - (tag ? 3 : 2); \
+ value.os.data = ((unsigned char *)(attr + 1)) + (tag ? 1 : 0); \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ CHECK_FCT( fd_msg_avp_add ( avp_tun[tag], MSG_BRW_LAST_CHILD, avp) ); \
+ }
+
+ /* Convert an attribute to a scalar AVP and add inside the Tunneling AVP corresponding to the tag */
+ #define CONV2DIAM_TUN_24B( _dictobj_ ) { \
+ uint8_t tag; \
+ CHECK_PARAMS( attr->length == 6); \
+ AVP_TUN_PREPARE(); \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ { \
+ uint8_t * v = (uint8_t *)(attr + 1); \
+ value.u32 = (v[1] << 16) | (v[2] <<8) | v[3] ; \
+ } \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ CHECK_FCT( fd_msg_avp_add ( avp_tun[tag], MSG_BRW_LAST_CHILD, avp) ); \
+ }
+
+ /*
+ - If the RADIUS message contains Tunnel information [RADTunnels],
+ the attributes or tagged groups should each be converted to a
+ Diameter Tunneling Grouped AVP set. If the tunnel information
+ contains a Tunnel-Password attribute, the RADIUS encryption
+ must be resolved, and the password forwarded, by using Diameter
+ security methods.
+ -> If the RADIUS message does not use properly the Tag info, result is unpredictable here..
+ */
+ case RADIUS_ATTR_TUNNEL_TYPE:
+ CONV2DIAM_TUN_24B( Tunnel_Type );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_MEDIUM_TYPE:
+ CONV2DIAM_TUN_24B( Tunnel_Medium_Type );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_CLIENT_ENDPOINT:
+ CONV2DIAM_TUN_STR( Tunnel_Client_Endpoint );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_SERVER_ENDPOINT:
+ CONV2DIAM_TUN_STR( Tunnel_Server_Endpoint );
+ break;
+
+ /* Tunnel-Password never present in an Accounting-Request */
+
+ case RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID:
+ CONV2DIAM_TUN_STR( Tunnel_Private_Group_Id );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_ASSIGNMENT_ID:
+ CONV2DIAM_TUN_STR( Tunnel_Assignment_Id );
+ break;
+
+ /* Tunnel-Reference never present in an Accounting-Request */
+
+ case RADIUS_ATTR_TUNNEL_CLIENT_AUTH_ID:
+ CONV2DIAM_TUN_STR( Tunnel_Client_Auth_Id );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_SERVER_AUTH_ID:
+ CONV2DIAM_TUN_STR( Tunnel_Server_Auth_Id );
+ break;
+
+ /* RFC 2869 */
+ /*
+ Acct-Input-Gigawords, Acct-Output-
+ Gigawords, Event-Timestamp, and NAS-Port-Id may have 0-1 instances in
+ an Accounting-Request packet. Connect-Info may have 0+ instances in
+ an Accounting-Request packet. The other attributes added in this
+ document must not be present in an Accounting-Request.
+ */
+ case RADIUS_ATTR_ACCT_INPUT_GIGAWORDS:
+ break; /* we already saved the value in gigawords_in */
+
+ case RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS:
+ break; /* we already saved the value in gigawords_out */
+
+ case RADIUS_ATTR_EVENT_TIMESTAMP:
+ /* RADIUS:
+ The Value field is four octets encoding an unsigned integer with
+ the number of seconds since January 1, 1970 00:00 UTC.
+ Diameter:
+ The Time format is derived from the OctetString AVP Base Format.
+ The string MUST contain four octets, in the same format as the
+ first four bytes are in the NTP timestamp format. The NTP
+ Timestamp format is defined in Chapter 3 of [RFC4330].
+
+ This represents the number of seconds since 0h on 1 January 1900
+ with respect to the Coordinated Universal Time (UTC).
+
+ -- RFC4330:
+ NTP timestamps are represented as a 64-bit unsigned
+ fixed-point number, in seconds relative to 0h on 1 January 1900. The
+ integer part is in the first 32 bits, and the fraction part in the
+ last 32 bits. In the fraction part, the non-significant low-order
+ bits are not specified and are ordinarily set to 0.
+ */
+ {
+ uint32_t ts;
+
+ uint8_t * v = (uint8_t *)(attr + 1);
+ /* Read the RADIUS attribute value */
+ ts = (v[0] << 24)
+ | (v[1] << 16)
+ | (v[2] << 8)
+ | v[3] ;
+
+ /* Add the 70 missing years */
+ ts += 2208988800U; /* 60 * 60 * 24 * ( 365 * 70 + 17 ) */
+
+ /* Convert to network byte order */
+ ts = htonl(ts);
+
+ /* Diameter Time datatype is derived from OctetString */
+ value.os.data = (void *) &ts;
+ value.os.len = sizeof(uint32_t);
+
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Event_Timestamp, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+ break;
+
+ case RADIUS_ATTR_NAS_PORT_ID:
+ CONV2DIAM_STR( NAS_Port_Id );
+ break;
+
+ case RADIUS_ATTR_CONNECT_INFO:
+ CONV2DIAM_STR( Connect_Info );
+ break;
+
+ case RADIUS_ATTR_FRAMED_POOL: /* To follow the IPv6 version */
+ CONV2DIAM_STR( Framed_Pool );
+ break;
+
+
+ /* RFC 3579 */
+ /*
+ The EAP-Message and Message-Authenticator attributes specified in
+ this document MUST NOT be present in an Accounting-Request.
+ */
+ case RADIUS_ATTR_ORIGINATING_LINE_INFO:
+ CONV2DIAM_STR( Originating_Line_Info );
+ break;
+
+ /* Default */
+ default: /* unknown attribute */
+ /* We just keep the attribute in the RADIUS message */
+ rad_req->attr_pos[nattr_used++] = rad_req->attr_pos[idx];
+ }
+ }
+
+ /* Update the radius message to remove all handled attributes */
+ rad_req->attr_used = nattr_used;
+
+ /* Store useful information in the session */
+ {
+ struct sess_state * st;
+
+ CHECK_MALLOC( st = malloc(sizeof(struct sess_state)) );
+ memset(st, 0, sizeof(struct sess_state));
+ st->auth_appl = auth_appl;
+ if (auth_appl) { /* We use the value 0 for servers which indicated NO STATE MAINTAINED, hence have no need for STR */
+ st->send_str = send_str;
+ }
+ st->term_cause = str_cause;
+ CHECK_FCT( fd_sess_state_store( cs->sess_hdl, sess, &st ) );
+ }
+
+ return 0;
+}
+
+/* Callback when an STA is received after having sent an STR. */
+static void handle_sta(void * data, struct msg ** answer)
+{
+ struct rgwp_config * cs = data;
+ struct avp *avp;
+ struct avp_hdr *ahdr;
+
+ CHECK_PARAMS_DO( data && answer && *answer, goto out );
+
+ /* Check the Diameter error code */
+ CHECK_FCT_DO( fd_msg_search_avp (*answer, cs->dict.Result_Code, &avp), goto out );
+ CHECK_PARAMS_DO( avp, goto out );
+ CHECK_FCT_DO( fd_msg_avp_hdr ( avp, &ahdr ), goto out );
+ if (ahdr->avp_value->u32 != ER_DIAMETER_SUCCESS)
+ goto out;
+
+ /* OK, discard the message without complaining */
+ fd_msg_free(*answer);
+ *answer = NULL;
+
+out:
+ if (answer && *answer) {
+ char * buf = NULL; size_t buflen;
+ CHECK_MALLOC_DO( fd_msg_dump_treeview(&buf, &buflen, NULL, *answer, NULL, 0, 1), );
+ TRACE_DEBUG(INFO, "Received the following problematic STA message, discarding anyway: %s", buf ?: "<error>");
+ free(buf);
+
+ fd_msg_free(*answer);
+ *answer = NULL;
+ }
+ return;
+}
+
+static int acct_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
+{
+ struct session * sess;
+ struct sess_state * st = NULL, stloc;
+ struct avp *avp, *next;
+ struct avp_hdr *ahdr, *oh, *or;
+ os0_t sid = NULL;
+ size_t sidlen;
+
+ TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
+ CHECK_PARAMS(cs);
+
+ CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_ans, &sess, NULL) );
+ if (sess) {
+ CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, sess, &st ) );
+ CHECK_FCT( fd_sess_getsid(sess, &sid, &sidlen) );
+ }
+
+ if (!st) {
+ TRACE_DEBUG(INFO, "Received an ACA without corresponding session information, cannot translate to RADIUS");
+ return EINVAL;
+ }
+
+ /* Free the state */
+ memcpy(&stloc, st, sizeof(struct sess_state));
+ free(st);
+ st = &stloc;
+
+ /* Search these AVPs first */
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Origin_Host, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &oh ) );
+
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Origin_Realm, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &or ) );
+
+ /* Check the Diameter error code */
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Result_Code, &avp) );
+ ASSERT( avp ); /* otherwise the message should have been discarded a lot earlier because of ABNF */
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+ switch (ahdr->avp_value->u32) {
+ case ER_DIAMETER_SUCCESS:
+ case ER_DIAMETER_LIMITED_SUCCESS:
+ (*rad_fw)->hdr->code = RADIUS_CODE_ACCOUNTING_RESPONSE;
+ break;
+
+ default:
+ fd_log_debug("[acct.rgwx] Received Diameter answer with error code '%d' from server '%.*s', session %.*s, not translating into Accounting-Response",
+ ahdr->avp_value->u32,
+ (int)oh->avp_value->os.len, oh->avp_value->os.data,
+ (int)sidlen, sid);
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Error_Message, &avp) );
+ if (avp) {
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+ fd_log_debug("[acct.rgwx] Error-Message content: '%.*s'",
+ (int)ahdr->avp_value->os.len, ahdr->avp_value->os.data);
+ }
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Error_Reporting_Host, &avp) );
+ if (avp) {
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+ fd_log_debug("[acct.rgwx] Error-Reporting-Host: '%.*s'",
+ (int)ahdr->avp_value->os.len, ahdr->avp_value->os.data);
+ }
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Failed_AVP, &avp) );
+ if (avp) {
+ fd_log_debug("[acct.rgwx] Failed-AVP was included in the message.");
+ /* Dump its content ? */
+ }
+
+ /* Now, destroy the Diameter message, since we know it is not converted to RADIUS */
+ CHECK_FCT( fd_msg_free(*diam_ans) );
+ *diam_ans = NULL;
+
+ return -1;
+ }
+ /* Remove this Result-Code avp */
+ CHECK_FCT( fd_msg_free( avp ) );
+
+ /* If it was a response to a STOP record, we must send an STR for this session */
+ if (st->send_str) {
+ struct msg * str = NULL;
+ struct msg_hdr * hdr = NULL;
+ DiamId_t fqdn;
+ size_t fqdn_len;
+ DiamId_t realm;
+ size_t realm_len;
+ union avp_value avp_val;
+
+ /* Create a new STR message */
+ CHECK_FCT( fd_msg_new ( cs->dict.Session_Termination_Request, MSGFL_ALLOC_ETEID, &str ) );
+
+ /* Set the application-id to the auth application if available, accounting otherwise (not sure what is actually expected...) */
+ CHECK_FCT( fd_msg_hdr ( str, &hdr ) );
+ hdr->msg_appl = st->auth_appl ?: AI_ACCT;
+
+ /* Add the Session-Id AVP as first AVP */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
+ avp_val.os.data = sid;
+ avp_val.os.len = sidlen;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
+ CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_FIRST_CHILD, avp) );
+ CHECK_FCT( fd_sess_ref_msg(sess) );
+
+ /* Add the Destination-Realm as next AVP */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Destination_Realm, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, or->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) );
+
+ /* Get information on the NAS */
+ CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &fqdn_len, &realm, &realm_len) );
+
+ /* Add the Origin-Host as next AVP */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Origin_Host, 0, &avp ) );
+ memset(&avp_val, 0, sizeof(avp_val));
+ avp_val.os.data = (unsigned char *)fqdn;
+ avp_val.os.len = fqdn_len;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
+ CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) );
+
+ /* Add the Origin-Realm as next AVP */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Origin_Realm, 0, &avp ) );
+ memset(&avp_val, 0, sizeof(avp_val));
+ avp_val.os.data = (unsigned char *)realm;
+ avp_val.os.len = realm_len;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
+ CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) );
+
+ /* Auth-Application-Id -- if we did not get it from our Class attribute, we just set "0" */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Auth_Application_Id, 0, &avp ) );
+ avp_val.u32 = st->auth_appl;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
+ CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) );
+
+ /* Termination-Cause */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Termination_Cause, 0, &avp ) );
+ avp_val.u32 = st->term_cause;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
+ CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) );
+
+ /* Send this message */
+ CHECK_FCT( fd_msg_send ( &str, handle_sta, cs ) );
+ }
+
+ /*
+ No attributes should be found in
+ Accounting-Response packets except Proxy-State and possibly Vendor-
+ Specific.
+ */
+
+ /* Now loop in the list of AVPs and convert those that we know how */
+ CHECK_FCT( fd_msg_browse(*diam_ans, MSG_BRW_FIRST_CHILD, &next, NULL) );
+
+ while (next) {
+ int handled = 1;
+ avp = next;
+ CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &next, NULL) );
+
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+
+ if (!(ahdr->avp_flags & AVP_FLAG_VENDOR)) {
+ switch (ahdr->avp_code) {
+ /* Based on RFC4005, sec 3.10 */
+ case DIAM_ATTR_SESSION_ID:
+ case DIAM_ATTR_ORIGIN_HOST:
+ case DIAM_ATTR_ORIGIN_REALM:
+ case DIAM_ATTR_ACCOUNTING_RECORD_TYPE:
+ case DIAM_ATTR_ACCOUNTING_RECORD_NUMBER:
+ case DIAM_ATTR_ACCT_APPLICATION_ID:
+ case DIAM_ATTR_VENDOR_SPECIFIC_APPLICATION_ID:
+ case DIAM_ATTR_USER_NAME:
+ case DIAM_ATTR_ACCOUNTING_SUB_SESSION_ID:
+ case DIAM_ATTR_ACCT_SESSION_ID:
+ case DIAM_ATTR_ACCT_MULTI_SESSION_ID:
+ case DIAM_ATTR_EVENT_TIMESTAMP:
+ case DIAM_ATTR_ORIGIN_AAA_PROTOCOL:
+ case DIAM_ATTR_ORIGIN_STATE_ID:
+ case DIAM_ATTR_NAS_IDENTIFIER:
+ case DIAM_ATTR_NAS_IP_ADDRESS:
+ case DIAM_ATTR_NAS_IPV6_ADDRESS:
+ case DIAM_ATTR_NAS_PORT:
+ case DIAM_ATTR_NAS_PORT_ID:
+ case DIAM_ATTR_NAS_PORT_TYPE:
+ case DIAM_ATTR_SERVICE_TYPE:
+ case DIAM_ATTR_TERMINATION_CAUSE:
+ case DIAM_ATTR_ACCOUNTING_REALTIME_REQUIRED:
+ case DIAM_ATTR_ACCT_INTERIM_INTERVAL:
+ case DIAM_ATTR_CLASS:
+ /* We just remove these AVP, they are not expected in RADIUS client */
+ break;
+
+ default:
+ /* Leave the AVP in the message for further treatment */
+ handled = 0;
+ }
+ } else {
+ /* Vendor-specific AVPs */
+ switch (ahdr->avp_vendor) {
+
+ default: /* unknown vendor */
+ handled = 0;
+ }
+ }
+
+ if (handled) {
+ CHECK_FCT( fd_msg_free( avp ) );
+ }
+ }
+
+ /*
+ The Authenticator field in an Accounting-Response packet is called
+ the Response Authenticator, and contains a one-way MD5 hash
+ calculated over a stream of octets consisting of the Accounting-
+ Response Code, Identifier, Length, the Request Authenticator field
+ from the Accounting-Request packet being replied to, and the
+ response attributes if any, followed by the shared secret. The
+ resulting 16 octet MD5 hash value is stored in the Authenticator
+ field of the Accounting-Response packet.
+
+ -- done in radius_msg_finish_srv
+ */
+
+ return 0;
+}
+
+/* The exported symbol */
+struct rgw_api rgwp_descriptor = {
+ .rgwp_name = "acct",
+ .rgwp_conf_parse = acct_conf_parse,
+ .rgwp_conf_free = acct_conf_free,
+ .rgwp_rad_req = acct_rad_req,
+ .rgwp_diam_ans = acct_diam_ans
+};
diff --git a/extensions/app_radgw/rgwx_auth.c b/extensions/app_radgw/rgwx_auth.c
new file mode 100644
index 0000000..f78b97e
--- /dev/null
+++ b/extensions/app_radgw/rgwx_auth.c
@@ -0,0 +1,1961 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* RADIUS Access-Request messages translation plugin */
+
+#include "rgw_common.h"
+
+/* Attributes missing from radius.h */
+#define RADIUS_ATTR_CHAP_PASSWORD 3
+#define RADIUS_ATTR_ARAP_PASSWORD 70
+
+/* Other constants we use */
+#define AI_NASREQ 1 /* Diameter NASREQ */
+#define AI_EAP 5 /* Diameter EAP application */
+#define CC_AA 265 /* AAR */
+#define CC_DIAMETER_EAP 268 /* DER */
+#define ACV_ART_AUTHORIZE_AUTHENTICATE 3 /* AUTHORIZE_AUTHENTICATE */
+#define ACV_OAP_RADIUS 1 /* RADIUS */
+#define ACV_ASS_STATE_MAINTAINED 0 /* STATE_MAINTAINED */
+#define ACV_ASS_NO_STATE_MAINTAINED 1 /* NO_STATE_MAINTAINED */
+
+/* The state we keep for this plugin */
+struct rgwp_config {
+ struct {
+ struct dict_object * ARAP_Password; /* ARAP-Password */
+ struct dict_object * ARAP_Security; /* ARAP-Security */
+ struct dict_object * ARAP_Security_Data; /* ARAP-Security-Data */
+ struct dict_object * Auth_Application_Id; /* Auth-Application-Id */
+ struct dict_object * Auth_Request_Type; /* Auth-Request-Type */
+ struct dict_object * Authorization_Lifetime; /* Authorization-Lifetime */
+ struct dict_object * Callback_Number; /* Callback-Number */
+ struct dict_object * Called_Station_Id; /* Called-Station-Id */
+ struct dict_object * Calling_Station_Id; /* Calling-Station-Id */
+ struct dict_object * CHAP_Algorithm; /* CHAP-Algorithm */
+ struct dict_object * CHAP_Auth; /* CHAP-Auth */
+ struct dict_object * CHAP_Challenge; /* CHAP-Challenge */
+ struct dict_object * CHAP_Ident; /* CHAP-Ident */
+ struct dict_object * CHAP_Response; /* CHAP-Response */
+ struct dict_object * Destination_Host; /* Destination-Host */
+ struct dict_object * Destination_Realm; /* Destination-Realm */
+ struct dict_object * Connect_Info; /* Connect-Info */
+ struct dict_object * EAP_Payload; /* EAP-Payload */
+ struct dict_object * Error_Message; /* Error-Message */
+ struct dict_object * Error_Reporting_Host; /* Error-Reporting-Host */
+ struct dict_object * Failed_AVP; /* Failed-AVP */
+ struct dict_object * Framed_Compression; /* Framed-Compression */
+ struct dict_object * Framed_IP_Address; /* Framed-IP-Address */
+ struct dict_object * Framed_IP_Netmask; /* Framed-IP-Netmask */
+ struct dict_object * Framed_Interface_Id; /* Framed-Interface-Id */
+ struct dict_object * Framed_IPv6_Prefix; /* Framed-IPv6-Prefix */
+ struct dict_object * Framed_MTU; /* Framed-MTU */
+ struct dict_object * Framed_Protocol; /* Framed-Protocol */
+ struct dict_object * Login_IP_Host; /* Login-IP-Host */
+ struct dict_object * Login_IPv6_Host; /* Login-IPv6-Host */
+ struct dict_object * Login_LAT_Group; /* Login-LAT-Group */
+ struct dict_object * Login_LAT_Node; /* Login-LAT-Node */
+ struct dict_object * Login_LAT_Port; /* Login-LAT-Port */
+ struct dict_object * Login_LAT_Service; /* Login-LAT-Service */
+ struct dict_object * NAS_Identifier; /* NAS-Identifier */
+ struct dict_object * NAS_IP_Address; /* NAS-IP-Address */
+ struct dict_object * NAS_IPv6_Address; /* NAS-IPv6-Address */
+ struct dict_object * NAS_Port; /* NAS-Port */
+ struct dict_object * NAS_Port_Id; /* NAS-Port-Id */
+ struct dict_object * NAS_Port_Type; /* NAS-Port-Type */
+ struct dict_object * Origin_AAA_Protocol; /* Origin-AAA-Protocol */
+ struct dict_object * Origin_Host; /* Origin-Host */
+ struct dict_object * Origin_Realm; /* Origin-Realm */
+ struct dict_object * Originating_Line_Info; /* Originating-Line-Info */
+ struct dict_object * Port_Limit; /* Port-Limit */
+ struct dict_object * Re_Auth_Request_Type; /* Re-Auth-Request-Type */
+ struct dict_object * Result_Code; /* Result-Code */
+ struct dict_object * Service_Type; /* Service-Type */
+ struct dict_object * Session_Id; /* Session-Id */
+ struct dict_object * Session_Timeout; /* Session-Timeout */
+ struct dict_object * State; /* State */
+ struct dict_object * Tunneling; /* Tunneling */
+ struct dict_object * Tunnel_Type; /* Tunnel-Type */
+ struct dict_object * Tunnel_Medium_Type; /* Tunnel-Medium-Type */
+ struct dict_object * Tunnel_Client_Endpoint; /* Tunnel-Client-Endpoint */
+ struct dict_object * Tunnel_Server_Endpoint; /* Tunnel-Server-Endpoint */
+ struct dict_object * Tunnel_Private_Group_Id; /* Tunnel-Private-Group-Id */
+ struct dict_object * Tunnel_Preference; /* Tunnel-Preference */
+ struct dict_object * Tunnel_Client_Auth_Id; /* Tunnel-Client-Auth-Id */
+ struct dict_object * Tunnel_Server_Auth_Id; /* Tunnel-Server-Auth-Id */
+ struct dict_object * User_Name; /* User-Name */
+ struct dict_object * User_Password; /* User-Password */
+
+ } dict; /* cache of the dictionary objects we use */
+ struct session_handler * sess_hdl; /* We store RADIUS request authenticator information in the session */
+ char * confstr;
+
+ int ignore_nai;
+};
+
+struct sess_state {
+ uint8_t req_auth[16];
+};
+
+
+/* Initialize the plugin */
+static int auth_conf_parse(char * confstr, struct rgwp_config ** state)
+{
+ struct rgwp_config * new;
+ struct dict_object * app;
+
+ TRACE_ENTRY("%p %p", confstr, state);
+ CHECK_PARAMS( state );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct rgwp_config)) );
+ memset(new, 0, sizeof(struct rgwp_config));
+
+ CHECK_FCT( fd_sess_handler_create( &new->sess_hdl, (void *)free, NULL, NULL ) );
+ new->confstr = confstr;
+
+ if (confstr && strstr(confstr, "nonai"))
+ new->ignore_nai = 1;
+
+ /* Resolve all dictionary objects we use */
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "ARAP-Password", &new->dict.ARAP_Password, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "ARAP-Security", &new->dict.ARAP_Security, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "ARAP-Security-Data", &new->dict.ARAP_Security_Data, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &new->dict.Auth_Application_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Request-Type", &new->dict.Auth_Request_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Authorization-Lifetime", &new->dict.Authorization_Lifetime, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Callback-Number", &new->dict.Callback_Number, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Called-Station-Id", &new->dict.Called_Station_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Calling-Station-Id", &new->dict.Calling_Station_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "CHAP-Algorithm", &new->dict.CHAP_Algorithm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "CHAP-Auth", &new->dict.CHAP_Auth, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "CHAP-Challenge", &new->dict.CHAP_Challenge, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "CHAP-Ident", &new->dict.CHAP_Ident, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "CHAP-Response", &new->dict.CHAP_Response, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Connect-Info", &new->dict.Connect_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &new->dict.Destination_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &new->dict.Destination_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "EAP-Payload", &new->dict.EAP_Payload, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Message", &new->dict.Error_Message, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Reporting-Host", &new->dict.Error_Reporting_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Failed-AVP", &new->dict.Failed_AVP, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-Compression", &new->dict.Framed_Compression, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-IP-Address", &new->dict.Framed_IP_Address, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-IP-Netmask", &new->dict.Framed_IP_Netmask, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-Interface-Id", &new->dict.Framed_Interface_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-IPv6-Prefix", &new->dict.Framed_IPv6_Prefix, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-MTU", &new->dict.Framed_MTU, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Framed-Protocol", &new->dict.Framed_Protocol, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-IP-Host", &new->dict.Login_IP_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-IPv6-Host", &new->dict.Login_IPv6_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-LAT-Group", &new->dict.Login_LAT_Group, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-LAT-Node", &new->dict.Login_LAT_Node, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-LAT-Port", &new->dict.Login_LAT_Port, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Login-LAT-Service", &new->dict.Login_LAT_Service, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-Identifier", &new->dict.NAS_Identifier, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-IP-Address", &new->dict.NAS_IP_Address, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-IPv6-Address", &new->dict.NAS_IPv6_Address, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-Port", &new->dict.NAS_Port, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-Port-Id", &new->dict.NAS_Port_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "NAS-Port-Type", &new->dict.NAS_Port_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-AAA-Protocol", &new->dict.Origin_AAA_Protocol, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &new->dict.Origin_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &new->dict.Origin_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Originating-Line-Info", &new->dict.Originating_Line_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Port-Limit", &new->dict.Port_Limit, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Re-Auth-Request-Type", &new->dict.Re_Auth_Request_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &new->dict.Result_Code, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Service-Type", &new->dict.Service_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &new->dict.Session_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Timeout", &new->dict.Session_Timeout, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "State", &new->dict.State, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunneling", &new->dict.Tunneling, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Type", &new->dict.Tunnel_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Medium-Type", &new->dict.Tunnel_Medium_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Client-Endpoint", &new->dict.Tunnel_Client_Endpoint, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Server-Endpoint", &new->dict.Tunnel_Server_Endpoint, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Private-Group-Id", &new->dict.Tunnel_Private_Group_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Preference", &new->dict.Tunnel_Preference, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Client-Auth-Id", &new->dict.Tunnel_Client_Auth_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Tunnel-Server-Auth-Id", &new->dict.Tunnel_Server_Auth_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &new->dict.User_Name, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Password", &new->dict.User_Password, ENOENT) );
+
+ /* This plugin provides the following Diameter authentication applications support: */
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Network Access Server Application", &app, ENOENT) );
+ CHECK_FCT( fd_disp_app_support ( app, NULL, 1, 0 ) );
+
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Extensible Authentication Protocol (EAP) Application", &app, ENOENT) );
+ CHECK_FCT( fd_disp_app_support ( app, NULL, 1, 0 ) );
+
+ *state = new;
+ return 0;
+}
+
+/* deinitialize */
+static void auth_conf_free(struct rgwp_config * state)
+{
+ TRACE_ENTRY("%p", state);
+ CHECK_PARAMS_DO( state, return );
+ CHECK_FCT_DO( fd_sess_handler_destroy( &state->sess_hdl, NULL ), );
+ free(state);
+ return;
+}
+
+/* Handle an incoming RADIUS request */
+static int auth_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+{
+ int idx;
+ int got_id = 0;
+ int got_mac = 0;
+ int got_passwd = 0;
+ int got_eap = 0;
+ int got_empty_eap = 0;
+ const char * prefix = "Diameter/";
+ size_t pref_len;
+ os0_t dh = NULL;
+ size_t dh_len = 0;
+ os0_t dr = NULL;
+ size_t dr_len = 0;
+ os0_t si = NULL;
+ size_t si_len = 0;
+ os0_t un = NULL;
+ size_t un_len = 0;
+ size_t nattr_used = 0;
+ struct avp ** avp_tun = NULL, *avp = NULL;
+ union avp_value value;
+ struct session * sess;
+
+ TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
+ CHECK_PARAMS(cs && rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCESS_REQUEST) && rad_ans && diam_fw && *diam_fw);
+
+ pref_len = strlen(prefix);
+
+ /*
+ Guidelines:
+ http://tools.ietf.org/html/rfc4005#section-9.1
+ http://tools.ietf.org/html/rfc4072#section-6.1
+
+ When a Translation Agent receives a RADIUS message, the following
+ steps should be taken:
+
+ - If a Message-Authenticator attribute is present, the value MUST
+ be checked but not included in the Diameter message. If it is
+ incorrect, the RADIUS message should be silently discarded.
+ The gateway system SHOULD generate and include a Message-
+ Authenticator in returned RADIUS responses.
+ -> done in rgw_msg_auth_check
+
+ - The transport address of the sender MUST be checked against the
+ NAS identifying attributes. See the description of NAS-
+ Identifier and NAS-IP-Address below.
+ -> done in rgw_clients_check_origin
+
+ - The Translation Agent must maintain transaction state
+ information relevant to the RADIUS request, such as the
+ Identifier field in the RADIUS header, any existing RADIUS
+ Proxy-State attribute, and the source IP address and port
+ number of the UDP packet. These may be maintained locally in a
+ state table or saved in a Proxy-Info AVP group. A Diameter
+ Session-Id AVP value must be created using a session state
+ mapping mechanism.
+ -> Identifier, source and port are saved along with the request,
+ and associated with the session state.
+ -> sub_echo_drop should handle the Proxy-State attribute (conf issue)
+
+ - The Diameter Origin-Host and Origin-Realm AVPs MUST be created
+ and added by using the information from an FQDN corresponding
+ to the NAS-IP-Address attribute (preferred if available),
+ and/or to the NAS-Identifier attribute. (Note that the RADIUS
+ NAS-Identifier is not required to be an FQDN.)
+ -> done in rgw_clients_create_origin.
+
+ - The response MUST have an Origin-AAA-Protocol AVP added,
+ indicating the protocol of origin of the message.
+ -> what "response" ??? Added to the AAR / DER in this function.
+
+ - The Proxy-Info group SHOULD be added, with the local server's
+ identity specified in the Proxy-Host AVP. This should ensure
+ that the response is returned to this system.
+ -> We don't need this, answer is always routed here anyway.
+
+ For EAP:
+
+ o RADIUS EAP-Message attribute(s) are translated to a Diameter
+ EAP-Payload AVP. If multiple RADIUS EAP-Message attributes are
+ present, they are concatenated and translated to a single Diameter
+ EAP-Payload AVP.
+ -> concatenation done by radius_msg_get_eap
+
+ -> the remaining is specific conversion rules
+ */
+
+ /* Check basic information is there, and also retrieve some attribute information */
+ for (idx = 0; idx < rad_req->attr_used; idx++) {
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(rad_req->buf + rad_req->attr_pos[idx]);
+ uint8_t * attr_val = (uint8_t *)(attr + 1);
+ size_t attr_len = attr->length - sizeof(struct radius_attr_hdr);
+
+ switch (attr->type) {
+ case RADIUS_ATTR_NAS_IP_ADDRESS:
+ case RADIUS_ATTR_NAS_IDENTIFIER:
+ case RADIUS_ATTR_NAS_IPV6_ADDRESS:
+ got_id = 1;
+ break;
+ case RADIUS_ATTR_MESSAGE_AUTHENTICATOR:
+ got_mac = 1;
+ break;
+ case RADIUS_ATTR_EAP_MESSAGE:
+ got_eap = 1;
+ if (attr->length == 2)
+ got_empty_eap = 1;
+ break;
+ case RADIUS_ATTR_USER_PASSWORD:
+ case RADIUS_ATTR_CHAP_PASSWORD:
+ case RADIUS_ATTR_ARAP_PASSWORD:
+ got_passwd += 1;
+ break;
+
+ /* Is there a State attribute with prefix "Diameter/" in the message? (in that case: Diameter/Destination-Host/Destination-Realm/Session-Id) */
+ /* NOTE: RFC4005 says "Origin-Host" here, but it's not coherent with the rules for answers. Destination-Host makes more sense */
+ case RADIUS_ATTR_STATE:
+ if ((attr_len > pref_len + 5 /* for the '/'s and non empty strings */ )
+ && ! memcmp(attr_val, prefix, pref_len)) {
+ int i, start;
+
+ TRACE_DEBUG(ANNOYING, "Found a State attribute with '%s' prefix (attr #%d).", prefix, idx);
+
+ /* Now parse the value and check its content is valid. Unfortunately we cannot use strchr here since strings are not \0-terminated */
+
+ i = start = pref_len;
+ dh = attr_val + i;
+ for (; (i < attr_len - 2) && (attr_val[i] != '/'); i++) /* loop */;
+ if ( i >= attr_len - 2 ) continue; /* the attribute format is not good */
+ dh_len = i - start;
+
+ start = ++i;
+ dr = attr_val + i;
+ for (; (i < attr_len - 1) && (attr_val[i] != '/'); i++) /* loop */;
+ if ( i >= attr_len - 1 ) continue; /* the attribute format is not good */
+ dr_len = i - start;
+
+ i++;
+ si = attr_val + i;
+ si_len = attr_len - i;
+
+ TRACE_DEBUG(ANNOYING, "Attribute parsed successfully: DH:'%.*s' DR:'%.*s' SI:'%.*s'.", (int)dh_len, dh, (int)dr_len, dr, (int)si_len, si);
+ /* Remove from the message */
+ for (i = idx + 1; i < rad_req->attr_used; i++)
+ rad_req->attr_pos[i - 1] = rad_req->attr_pos[i];
+ rad_req->attr_used -= 1;
+ idx--;
+ }
+ break;
+
+ case RADIUS_ATTR_USER_NAME:
+ TRACE_DEBUG(ANNOYING, "Found a User-Name attribute: '%.*s'", (int)attr_len, attr_len ? (char *)attr_val : "");
+ un = attr_val;
+ un_len = attr_len;
+ break;
+
+ }
+ }
+ if (!got_id) {
+ TRACE_DEBUG(INFO, "RADIUS Access-Request did not contain a NAS IP or Identifier attribute, reject.");
+ return EINVAL;
+ }
+ /* [Note 1] An Access-Request that contains either a User-Password or
+ CHAP-Password or ARAP-Password or one or more EAP-Message attributes
+ MUST NOT contain more than one type of those four attributes. If it
+ does not contain any of those four attributes, it SHOULD contain a
+ Message-Authenticator. If any packet type contains an EAP-Message
+ attribute it MUST also contain a Message-Authenticator. A RADIUS
+ server receiving an Access-Request not containing any of those four
+ attributes and also not containing a Message-Authenticator attribute
+ SHOULD silently discard it. */
+ if (((got_eap + got_passwd) > 1) || (got_eap && !got_mac) || (!got_eap && !got_passwd && !got_mac)) {
+ TRACE_DEBUG(INFO, "RADIUS Access-Request not conform to RFC3579 sec 3.3 note 1, discard.");
+ return EINVAL;
+ }
+
+
+
+ /*
+ - If the RADIUS request contained a State attribute and the
+ prefix of the data is "Diameter/", the data following the
+ prefix contains the Diameter Origin-Host/Origin-Realm/Session-
+ Id. If no such attributes are present and the RADIUS command
+ is an Access-Request, a new Session-Id is created. The
+ Session-Id is included in the Session-Id AVP.
+ */
+
+ /* Add the Destination-Realm AVP */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Destination_Realm, 0, &avp ) );
+ if (dr) {
+ value.os.data = (unsigned char *)dr;
+ value.os.len = dr_len;
+ } else {
+ int i = 0;
+ if (un && ! cs->ignore_nai) {
+ /* Is there an '@' in the user name? We don't care for decorated NAI here */
+ for (i = un_len - 2; i > 0; i--) {
+ if (un[i] == '@') {
+ i++;
+ break;
+ }
+ }
+ }
+ if (i <= 0) {
+ /* Not found in the User-Name => we use the local domain of this gateway */
+ value.os.data = (uint8_t *)fd_g_config->cnf_diamrlm;
+ value.os.len = fd_g_config->cnf_diamrlm_len;
+ } else {
+ value.os.data = un + i;
+ value.os.len = un_len - i;
+ }
+ }
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+
+ /* Add the Destination-Host if found */
+ if (dh) {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Destination_Host, 0, &avp ) );
+ value.os.data = (unsigned char *)dh;
+ value.os.len = dh_len;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+ }
+
+ /* Create the session if it is not already done */
+ {
+ os0_t sess_str = NULL;
+ size_t sess_strlen;
+
+ if (si_len) {
+ /* We already have the Session-Id, just use it */
+ CHECK_FCT( fd_sess_fromsid_msg ( si, si_len, &sess, NULL) );
+ } else {
+ /* Create a new Session-Id string */
+
+ DiamId_t fqdn;
+ size_t fqdnlen;
+ DiamId_t realm;
+ size_t realmlen;
+
+ /* Get information on the RADIUS client */
+ CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &fqdnlen, &realm, &realmlen) );
+
+ /* If we have a user name, create the new session with it */
+ if (un) {
+ int len;
+ /* If not found, create a new Session-Id. Our format is: {fqdn;hi32;lo32;username;diamid} */
+ CHECK_MALLOC( sess_str = malloc(un_len + 1 /* ';' */ + fd_g_config->cnf_diamid_len + 1 /* '\0' */) );
+ len = sprintf((char *)sess_str, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
+ CHECK_FCT( fd_sess_new(&sess, fqdn, fqdnlen, sess_str, len) );
+ free(sess_str);
+ } else {
+ /* We don't have enough information to create the Session-Id, the RADIUS message is probably invalid */
+ TRACE_DEBUG(INFO, "RADIUS Access-Request does not contain a User-Name attribute, rejecting.");
+ return EINVAL;
+ }
+ }
+
+ /* Now, add the Session-Id AVP at beginning of Diameter message */
+ CHECK_FCT( fd_sess_getsid(sess, &sess_str, &sess_strlen) );
+ TRACE_DEBUG(FULL, "[auth.rgwx] Translating new message for session '%s'...", sess_str);
+
+ /* Now add this session in the message */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
+ value.os.data = sess_str;
+ value.os.len = sess_strlen;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+ CHECK_FCT( fd_msg_sess_set(*diam_fw, sess) );
+ }
+
+
+ /* Add the appropriate command code & Auth-Application-Id */
+ {
+ struct msg_hdr * header = NULL;
+ CHECK_FCT( fd_msg_hdr ( *diam_fw, &header ) );
+ header->msg_flags = CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE;
+ if (got_eap) {
+ header->msg_code = CC_DIAMETER_EAP;
+ header->msg_appl = AI_EAP;
+ } else {
+ header->msg_code = CC_AA;
+ header->msg_appl = AI_NASREQ;
+ }
+
+ /* Add the Auth-Application-Id */
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = header->msg_appl;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+ }
+
+ /* The type of request is identified through the Auth-Request-Type AVP
+ [BASE]. The recommended value for most RADIUS interoperabily
+ situations is AUTHORIZE_AUTHENTICATE. */
+
+ /* Add Auth-Request-Type AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Auth_Request_Type, 0, &avp ) );
+ value.i32 = ACV_ART_AUTHORIZE_AUTHENTICATE;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ /* Add Origin-AAA-Protocol AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Origin_AAA_Protocol, 0, &avp ) );
+ value.i32 = ACV_OAP_RADIUS;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ /* Convert the EAP payload (concat RADIUS attributes) */
+ if (got_eap) {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.EAP_Payload, 0, &avp ) );
+
+ /* o An empty RADIUS EAP-Message attribute (with length 2) signifies
+ EAP-Start, and it is translated to an empty EAP-Payload AVP. */
+ if (got_empty_eap) {
+ value.os.len = 0;
+ value.os.data = (uint8_t *)"";
+ } else {
+ CHECK_MALLOC( value.os.data = radius_msg_get_eap(rad_req, &value.os.len) );
+ }
+
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ /* Tunnel AVPs need some preparation */
+ /* Convert the attributes one by one */
+ for (idx = 0; idx < rad_req->attr_used; idx++) {
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(rad_req->buf + rad_req->attr_pos[idx]);
+
+ switch (attr->type) {
+
+ /* This macro converts a RADIUS attribute to a Diameter AVP of type OctetString */
+ #define CONV2DIAM_STR( _dictobj_ ) \
+ CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) ); \
+ /* Create the AVP with the specified dictionary model */ \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ value.os.len = attr->length - sizeof(struct radius_attr_hdr); \
+ value.os.data = (os0_t)(attr + 1); \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ /* Add the AVP in the Diameter message. */ \
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); \
+
+ /* Same thing, for scalar AVPs of 32 bits */
+ #define CONV2DIAM_32B( _dictobj_ ) \
+ CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint32_t) );\
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ { \
+ uint8_t * v = (uint8_t *)(attr + 1); \
+ value.u32 = (v[0] << 24) \
+ | (v[1] << 16) \
+ | (v[2] << 8) \
+ | v[3] ; \
+ } \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); \
+
+ /* And the 64b version */
+ #define CONV2DIAM_64B( _dictobj_ ) \
+ CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint64_t) );\
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ { \
+ uint8_t * v = (uint8_t *)(attr + 1); \
+ value.u64 = ((uint64_t)(v[0]) << 56) \
+ | ((uint64_t)(v[1]) << 48) \
+ | ((uint64_t)(v[2]) << 40) \
+ | ((uint64_t)(v[3]) << 32) \
+ | ((uint64_t)(v[4]) << 24) \
+ | ((uint64_t)(v[5]) << 16) \
+ | ((uint64_t)(v[6]) << 8) \
+ | (uint64_t)(v[7]) ; \
+ } \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); \
+
+ /* RFC 2865 */
+ /*
+ - The Destination-Realm AVP is created from the information found
+ in the RADIUS User-Name attribute.
+ -> done in rgw_clients_create_origin
+ */
+ case RADIUS_ATTR_USER_NAME:
+ CONV2DIAM_STR( User_Name );
+ break;
+
+ /*
+ - If the RADIUS User-Password attribute is present, the password
+ must be unencrypted by using the link's RADIUS shared secret.
+ The unencrypted value must be forwarded in a User-Password AVP
+ using Diameter security.
+ */
+ case RADIUS_ATTR_USER_PASSWORD:
+ if ((attr->length - 2) % 16) {
+ TRACE_DEBUG(INFO, "Invalid length of User-Password attribute: %hhd", attr->length);
+ return EINVAL;
+ }
+ {
+ /* Decipher following this logic (refers to rfc2865#section-5.2 )
+ b1 = MD5(S + RA) p1 = c(1) xor b1
+ b2 = MD5(S + c(1)) p2 = c(2) xor b2
+ ...
+ */
+
+ uint8_t *ciph = (uint8_t *)(attr+1); /* c(i) */
+ size_t ciph_len = attr->length - 2;
+ uint8_t deciph[128]; /* pi */
+ size_t deciph_len = 0;
+ uint8_t * secret; /* S */
+ size_t secret_len;
+ uint8_t hash[16]; /* b(i) */
+ const uint8_t *addr[2];
+ size_t len[2];
+
+ /* Retrieve the shared secret */
+ CHECK_FCT(rgw_clients_getkey(cli, &secret, &secret_len));
+
+ /* Initial b1 = MD5(S + RA) */
+ addr[0] = secret;
+ len[0] = secret_len;
+ addr[1] = rad_req->hdr->authenticator;
+ len[1] = 16;
+ md5_vector(2, addr, len, hash);
+
+ /* loop */
+ while (deciph_len < ciph_len) {
+ int i;
+ /* pi = c(i) xor bi */
+ for (i = 0; i < 16; i++)
+ deciph[deciph_len + i] = ciph[deciph_len + i] ^ hash[i];
+ /* do we have to remove the padding '\0's ? */
+
+ /* b(i+1) = MD5(S + c(i) */
+ addr[1] = ciph + deciph_len;
+ md5_vector(2, addr, len, hash);
+
+ deciph_len += 16;
+ }
+
+ /* Now save this value in the AVP */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.User_Password, 0, &avp ) );
+ value.os.data = &deciph[0];
+ value.os.len = deciph_len;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+ break;
+
+
+ /*
+ - If the RADIUS CHAP-Password attribute is present, the Ident and
+ Data portion of the attribute are used to create the CHAP-Auth
+ grouped AVP.
+ */
+ case RADIUS_ATTR_CHAP_PASSWORD:
+ CHECK_PARAMS( attr->length == 19 /* RFC 2865 */);
+ {
+ uint8_t * c = (uint8_t *)(attr + 1);
+ struct avp * chap_auth;
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.CHAP_Auth, 0, &chap_auth ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, chap_auth) );
+
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.CHAP_Algorithm, 0, &avp ) );
+ value.u32 = 5; /* The only value defined currently... */
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( chap_auth, MSG_BRW_LAST_CHILD, avp) );
+
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.CHAP_Ident, 0, &avp ) );
+ value.os.data = c;
+ value.os.len = 1;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( chap_auth, MSG_BRW_LAST_CHILD, avp) );
+
+ c++;
+
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.CHAP_Response, 0, &avp ) );
+ value.os.data = c;
+ value.os.len = attr->length - 3;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( chap_auth, MSG_BRW_LAST_CHILD, avp) );
+ }
+ break;
+
+ case RADIUS_ATTR_NAS_IP_ADDRESS:
+ CONV2DIAM_STR( NAS_IP_Address );
+ break;
+
+ case RADIUS_ATTR_NAS_PORT:
+ CONV2DIAM_32B( NAS_Port );
+ break;
+
+ case RADIUS_ATTR_SERVICE_TYPE:
+ CONV2DIAM_32B( Service_Type );
+ break;
+
+ case RADIUS_ATTR_FRAMED_PROTOCOL:
+ CONV2DIAM_32B( Framed_Protocol );
+ break;
+
+ case RADIUS_ATTR_FRAMED_IP_ADDRESS:
+ CONV2DIAM_STR( Framed_IP_Address );
+ break;
+
+ case RADIUS_ATTR_FRAMED_IP_NETMASK:
+ CONV2DIAM_STR( Framed_IP_Netmask );
+ break;
+
+ /* Framed-Routing never present in an Access-Request */
+ /* Filter-Id never present in an Access-Request */
+
+ case RADIUS_ATTR_FRAMED_MTU:
+ CONV2DIAM_32B( Framed_MTU );
+ break;
+
+ case RADIUS_ATTR_FRAMED_COMPRESSION:
+ CONV2DIAM_32B( Framed_Compression );
+ break;
+
+ case RADIUS_ATTR_LOGIN_IP_HOST:
+ CONV2DIAM_STR( Login_IP_Host );
+ break;
+
+ /* Login-Service never present in an Access-Request */
+ /* Login-TCP-Port never present in an Access-Request */
+ /* Reply-Message never present in an Access-Request */
+
+ case RADIUS_ATTR_CALLBACK_NUMBER:
+ CONV2DIAM_STR( Callback_Number );
+ break;
+
+ /* Callback-Id never present in an Access-Request */
+ /* Framed-Route never present in an Access-Request */
+ /* Framed-IPX-Network never present in an Access-Request */
+
+ case RADIUS_ATTR_STATE:
+ CONV2DIAM_STR( State );
+ break;
+
+ /* Class never present in an Access-Request */
+
+ case RADIUS_ATTR_VENDOR_SPECIFIC:
+ /* RFC 4005, Section 9.6 :
+ Systems that don't have vendor format knowledge MAY discard such
+ attributes without knowing a suitable translation.
+
+ [conversion rule in 9.6.2]
+ */
+ if (attr->length >= 6) {
+ uint32_t vendor_id;
+ uint8_t * c = (uint8_t *)(attr + 1);
+
+ vendor_id = c[0] << 24 | c[1] << 16 | c[2] << 8 | c[3];
+ c += 4;
+
+ switch (vendor_id) {
+
+ /* For the vendors we KNOW they follow the VSA recommended format, we convert following the rules of RFC4005 (9.6.2) */
+ case RADIUS_VENDOR_ID_MICROSOFT : /* RFC 2548 */
+ /* other vendors ? */
+ {
+ size_t left;
+ struct radius_attr_vendor *vtlv;
+
+ left = attr->length - 6;
+ vtlv = (struct radius_attr_vendor *)c;
+
+ while ((left >= 2) && (vtlv->vendor_length <= left)) {
+ /* Search our dictionary for corresponding Vendor's AVP */
+ struct dict_avp_request req;
+ struct dict_object * avp_model = NULL;
+ memset(&req, 0, sizeof(struct dict_avp_request));
+ req.avp_vendor = vendor_id;
+ req.avp_code = vtlv->vendor_type;
+
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE_AND_VENDOR, &req, &avp_model, 0) );
+ if (!avp_model) {
+ TRACE_DEBUG(FULL, "Unknown attribute (vendor 0x%x, code 0x%x) ignored.", req.avp_vendor, req.avp_code);
+ } else {
+ CHECK_FCT( fd_msg_avp_new ( avp_model, 0, &avp ) );
+ value.os.len = vtlv->vendor_length - 2;
+ value.os.data = (unsigned char *)(vtlv + 1);
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+ c += vtlv->vendor_length;
+ left -= vtlv->vendor_length;
+ vtlv = (struct radius_attr_vendor *)c;
+ }
+ }
+ break;
+
+ /* Other vendors we KNOw how to convert the attributes would be added here... */
+ /* case RADIUS_VENDOR_ID_CISCO :
+ break; */
+ /* case RADIUS_VENDOR_ID_IETF : (extended RADIUS attributes)
+ break; */
+
+ /* When we don't know, just discard the attribute... VSA are optional with regards to RADIUS anyway */
+ default:
+ /* do nothing */
+ TRACE_DEBUG(FULL, "VSA attribute from vendor %d discarded", vendor_id);
+
+ }
+ }
+ break;
+
+ /* Session-Timeout never present in an Access-Request */
+ /* Idle-Timeout never present in an Access-Request */
+ /* Termination-Action never present in an Access-Request */
+
+ case RADIUS_ATTR_CALLED_STATION_ID:
+ CONV2DIAM_STR( Called_Station_Id );
+ break;
+
+ case RADIUS_ATTR_CALLING_STATION_ID:
+ CONV2DIAM_STR( Calling_Station_Id );
+ break;
+
+ case RADIUS_ATTR_NAS_IDENTIFIER:
+ CONV2DIAM_STR( NAS_Identifier );
+ break;
+
+ /* Proxy-State is handled by echo_drop.rgwx plugin, we ignore it here */
+
+ case RADIUS_ATTR_LOGIN_LAT_SERVICE:
+ CONV2DIAM_STR( Login_LAT_Service );
+ break;
+
+ case RADIUS_ATTR_LOGIN_LAT_NODE:
+ CONV2DIAM_STR( Login_LAT_Node );
+ break;
+
+ case RADIUS_ATTR_LOGIN_LAT_GROUP:
+ CONV2DIAM_STR( Login_LAT_Group );
+ break;
+
+ /* Framed-AppleTalk-Link never present in an Access-Request */
+ /* Framed-AppleTalk-Network never present in an Access-Request */
+ /* Framed-AppleTalk-Zone never present in an Access-Request */
+
+ case RADIUS_ATTR_CHAP_CHALLENGE:
+ CONV2DIAM_STR( CHAP_Challenge );
+ break;
+
+ case RADIUS_ATTR_NAS_PORT_TYPE:
+ CONV2DIAM_32B( NAS_Port_Type );
+ break;
+
+ case RADIUS_ATTR_PORT_LIMIT:
+ CONV2DIAM_32B( Port_Limit );
+ break;
+
+ case RADIUS_ATTR_LOGIN_LAT_PORT:
+ CONV2DIAM_STR( Login_LAT_Port );
+ break;
+
+
+ /* RFC 3162 */
+ case RADIUS_ATTR_NAS_IPV6_ADDRESS:
+ CONV2DIAM_STR( NAS_IPv6_Address );
+ break;
+
+ case RADIUS_ATTR_FRAMED_INTERFACE_ID:
+ CONV2DIAM_64B( Framed_Interface_Id );
+ break;
+
+ case RADIUS_ATTR_FRAMED_IPV6_PREFIX:
+ CONV2DIAM_STR( Framed_IPv6_Prefix );
+ break;
+
+ case RADIUS_ATTR_LOGIN_IPV6_HOST:
+ CONV2DIAM_STR( Login_IPv6_Host );
+ break;
+
+ /* Framed-IPv6-Route never present in an Access-Request */
+ /* Framed-IPv6-Pool never present in an Access-Request */
+
+
+ /* RFC 2868 */
+ /* Prepare the top-level Tunneling AVP for each tag values, as needed, and add to the Diameter message.
+ This macro is called when an AVP is added inside the group, so we will not have empty grouped AVPs */
+ #define AVP_TUN_PREPARE() { \
+ if (avp_tun == NULL) { \
+ CHECK_MALLOC( avp_tun = calloc(sizeof(struct avp *), 32 ) ); \
+ } \
+ tag = *(uint8_t *)(attr + 1); \
+ if (tag > 0x1F) tag = 0; \
+ if (avp_tun[tag] == NULL) { \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Tunneling, 0, &avp_tun[tag] ) ); \
+ CHECK_FCT( fd_msg_avp_add (*diam_fw, MSG_BRW_LAST_CHILD, avp_tun[tag]));\
+ } \
+ }
+
+ /* Convert an attribute to an OctetString AVP and add inside the Tunneling AVP corresponding to the tag */
+ #define CONV2DIAM_TUN_STR( _dictobj_ ) { \
+ uint8_t tag; \
+ CHECK_PARAMS( attr->length >= 3); \
+ AVP_TUN_PREPARE(); \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ value.os.len = attr->length - (tag ? 3 : 2); \
+ value.os.data = ((unsigned char *)(attr + 1)) + (tag ? 1 : 0); \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ CHECK_FCT( fd_msg_avp_add ( avp_tun[tag], MSG_BRW_LAST_CHILD, avp) ); \
+ }
+
+ /* Convert an attribute to a scalar AVP and add inside the Tunneling AVP corresponding to the tag */
+ #define CONV2DIAM_TUN_24B( _dictobj_ ) { \
+ uint8_t tag; \
+ CHECK_PARAMS( attr->length == 6); \
+ AVP_TUN_PREPARE(); \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ { \
+ uint8_t * v = (uint8_t *)(attr + 1); \
+ value.u32 = (v[1] << 16) | (v[2] <<8) | v[3] ; \
+ } \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ CHECK_FCT( fd_msg_avp_add ( avp_tun[tag], MSG_BRW_LAST_CHILD, avp) ); \
+ }
+
+ /*
+ - If the RADIUS message contains Tunnel information [RADTunnels],
+ the attributes or tagged groups should each be converted to a
+ Diameter Tunneling Grouped AVP set. If the tunnel information
+ contains a Tunnel-Password attribute, the RADIUS encryption
+ must be resolved, and the password forwarded, by using Diameter
+ security methods.
+ -> If the RADIUS message does not use properly the Tag info, result is unpredictable here..
+ */
+ case RADIUS_ATTR_TUNNEL_TYPE:
+ CONV2DIAM_TUN_24B( Tunnel_Type );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_MEDIUM_TYPE:
+ CONV2DIAM_TUN_24B( Tunnel_Medium_Type );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_CLIENT_ENDPOINT:
+ CONV2DIAM_TUN_STR( Tunnel_Client_Endpoint );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_SERVER_ENDPOINT:
+ CONV2DIAM_TUN_STR( Tunnel_Server_Endpoint );
+ break;
+
+ /* Tunnel-Password never present in an Access-Request */
+
+ case RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID:
+ CONV2DIAM_TUN_STR( Tunnel_Private_Group_Id );
+ break;
+
+ /* Tunnel-Assignment-ID never present in an Access-Request */
+
+ case RADIUS_ATTR_TUNNEL_PREFERENCE:
+ CONV2DIAM_TUN_24B( Tunnel_Preference );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_CLIENT_AUTH_ID:
+ CONV2DIAM_TUN_STR( Tunnel_Client_Auth_Id );
+ break;
+
+ case RADIUS_ATTR_TUNNEL_SERVER_AUTH_ID:
+ CONV2DIAM_TUN_STR( Tunnel_Server_Auth_Id );
+ break;
+
+
+ /* RFC 2869 */
+ case RADIUS_ATTR_ARAP_PASSWORD:
+ CONV2DIAM_STR( ARAP_Password );
+ break;
+
+ /* ARAP-Features never present in an Access-Request */
+ /* ARAP-Zone-Access never present in an Access-Request */
+
+ case RADIUS_ATTR_ARAP_SECURITY:
+ CONV2DIAM_32B( ARAP_Security );
+ break;
+
+ case RADIUS_ATTR_ARAP_SECURITY_DATA:
+ CONV2DIAM_STR( ARAP_Security_Data );
+ break;
+
+ /* Password-Retry never present in an Access-Request */
+ /* Prompt never present in an Access-Request */
+
+ case RADIUS_ATTR_CONNECT_INFO:
+ CONV2DIAM_STR( Connect_Info );
+ break;
+
+ /* Configuration-Token never present in an Access-Request */
+ /* ARAP-Challenge-Response never present in an Access-Request */
+ /* Acct-Interim-Interval never present in an Access-Request */
+
+ case RADIUS_ATTR_NAS_PORT_ID:
+ CONV2DIAM_STR( NAS_Port_Id );
+ break;
+
+ /* Framed-Pool never present in an Access-Request */
+
+
+ /* RFC 2869 / 3579 */
+ case RADIUS_ATTR_ORIGINATING_LINE_INFO:
+ CONV2DIAM_STR( Originating_Line_Info );
+ break;
+
+ case RADIUS_ATTR_MESSAGE_AUTHENTICATOR:
+ case RADIUS_ATTR_EAP_MESSAGE:
+ /* It was already handled, just remove the attribute */
+ break;
+
+ /* Default */
+ default: /* unknown attribute */
+ /* We just keep the attribute in the RADIUS message */
+ rad_req->attr_pos[nattr_used++] = rad_req->attr_pos[idx];
+ }
+ }
+
+ /* Destroy tunnel pointers (if we used it) */
+ free(avp_tun);
+
+ /* Update the radius message to remove all handled attributes */
+ rad_req->attr_used = nattr_used;
+
+ /* Store the request identifier in the session (if provided) */
+ {
+ struct sess_state *st;
+ CHECK_MALLOC(st = malloc(sizeof(struct sess_state)));
+ memcpy(st->req_auth, &rad_req->hdr->authenticator[0], 16);
+
+ CHECK_FCT( fd_sess_state_store( cs->sess_hdl, sess, &st ) );
+ }
+
+ return 0;
+}
+
+static int auth_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
+{
+ struct msg_hdr * hdr;
+ struct avp *avp, *next, *avp_x, *avp_y, *aoh;
+ struct avp_hdr *ahdr, *oh;
+ uint8_t buf[254]; /* to store some attributes values (with final '\0') */
+ size_t sz;
+ int ta_set = 0;
+ int no_str = 0; /* indicate if an STR is required for this server */
+ uint8_t tuntag = 0;
+ struct sess_state *st;
+ int error_cause = 0;
+ struct session * sess;
+ os0_t sid = NULL;
+ size_t sidlen;
+
+ TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
+ CHECK_PARAMS(cs && diam_ans && *diam_ans && rad_fw && *rad_fw);
+
+ /* Retrieve the request identified which was stored in the session */
+ CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_ans, &sess, NULL) );
+ if (sess) {
+ CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, sess, &st ) );
+ CHECK_FCT( fd_sess_getsid(sess, &sid, &sidlen) );
+ } /* else ? */
+
+ /*
+ - If the Diameter Command-Code is set to AA-Answer and the
+ Result-Code AVP is set to DIAMETER_MULTI_ROUND_AUTH, the
+ gateway must send a RADIUS Access-Challenge. This must have
+ the Origin-Host, Origin-Realm, and Diameter Session-Id AVPs
+ encapsulated in the RADIUS State attribute, with the prefix
+ "Diameter/", concatenated in the above order separated with "/"
+ characters, in UTF-8 [UTF-8]. This is necessary to ensure that
+ the Translation Agent receiving the subsequent RADIUS Access-
+ Request will have access to the Session Identifier and be able
+ to set the Destination-Host to the correct value.
+ -> done here below
+
+ - If the Command-Code is set to AA-Answer, the Diameter Session-
+ Id AVP is saved in a new RADIUS Class attribute whose format
+ consists of the string "Diameter/" followed by the Diameter
+ Session Identifier. This will ensure that the subsequent
+ Accounting messages, which could be received by any Translation
+ Agent, would have access to the original Diameter Session
+ Identifier.
+ -> done here but only for Access-Accept messages (Result-Code = success)
+ */
+
+ /* MACROS to help in the process: convert AVP data to RADIUS attributes. */
+ /* Control large attributes: _trunc_ = 0 => error; _trunc_ = 1 => truncate; _trunc = 2 => create several attributes */
+ #define CONV2RAD_STR( _attr_, _data_, _len_, _trunc_) { \
+ size_t __l = (size_t)(_len_); \
+ size_t __off = 0; \
+ TRACE_DEBUG(FULL, "Converting AVP to "#_attr_); \
+ if ((_trunc_) == 0) { \
+ CHECK_PARAMS( __l <= 253 ); \
+ } \
+ if ((__l > 253) && (_trunc_ == 1)) { \
+ TRACE_DEBUG(INFO, "[auth.rgwx] AVP truncated in "#_attr_); \
+ __l = 253; \
+ } \
+ do { \
+ size_t __w = (__l > 253) ? 253 : __l; \
+ CHECK_MALLOC(radius_msg_add_attr(*rad_fw, (_attr_), (_data_) + __off, __w)); \
+ __off += __w; \
+ __l -= __w; \
+ } while (__l); \
+ }
+
+ #define CONV2RAD_32B( _attr_, _data_) { \
+ uint32_t __v = htonl((uint32_t)(_data_)); \
+ TRACE_DEBUG(FULL, "Converting AVP to "#_attr_); \
+ CHECK_MALLOC(radius_msg_add_attr(*rad_fw, (_attr_), (uint8_t *)&__v, sizeof(__v))); \
+ }
+
+ #define CONV2RAD_64B( _attr_, _data_) { \
+ uint64_t __v = htonll((uint64_t)(_data_)); \
+ TRACE_DEBUG(FULL, "Converting AVP to "#_attr_); \
+ CHECK_MALLOC(radius_msg_add_attr(*rad_fw, (_attr_), (uint8_t *)&__v, sizeof(__v))); \
+ }
+
+ /* Search the different AVPs we handle here */
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Origin_Host, &aoh) );
+ CHECK_FCT( fd_msg_avp_hdr ( aoh, &oh ) );
+
+ /* Check the Diameter error code */
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Result_Code, &avp) );
+ ASSERT( avp ); /* otherwise the message should have been discarded a lot earlier because of ABNF */
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+ switch (ahdr->avp_value->u32) {
+ case ER_DIAMETER_MULTI_ROUND_AUTH:
+ (*rad_fw)->hdr->code = RADIUS_CODE_ACCESS_CHALLENGE;
+ break;
+ case ER_DIAMETER_SUCCESS:
+ case ER_DIAMETER_LIMITED_SUCCESS:
+ (*rad_fw)->hdr->code = RADIUS_CODE_ACCESS_ACCEPT;
+ break;
+
+ default:
+ /* Can we convert the value to a natural Error-Cause ? */
+ switch (ahdr->avp_value->u32) {
+ case ER_DIAMETER_AVP_UNSUPPORTED:
+ error_cause = 401; /* Unsupported Attribute */
+ break;
+
+ case ER_DIAMETER_MISSING_AVP:
+ error_cause = 402; /* Missing Attribute */
+ break;
+
+ case ER_DIAMETER_UNABLE_TO_COMPLY:
+ error_cause = 404; /* Invalid Request */
+ break;
+
+ case ER_DIAMETER_APPLICATION_UNSUPPORTED:
+ error_cause = 405; /* Unsupported Service */
+ break;
+
+ case ER_DIAMETER_COMMAND_UNSUPPORTED:
+ error_cause = 406; /* Unsupported Extension */
+ break;
+
+ case ER_DIAMETER_INVALID_AVP_VALUE:
+ error_cause = 407; /* Invalid Attribute Value */
+ break;
+
+ case ER_DIAMETER_AVP_NOT_ALLOWED:
+ error_cause = 501; /* Administratively Prohibited */
+ break;
+
+ case ER_DIAMETER_REALM_NOT_SERVED:
+ case ER_DIAMETER_LOOP_DETECTED:
+ case ER_DIAMETER_UNKNOWN_PEER:
+ case ER_DIAMETER_UNABLE_TO_DELIVER:
+ error_cause = 502; /* Request Not Routable (Proxy) */
+ break;
+
+ case ER_DIAMETER_UNKNOWN_SESSION_ID:
+ error_cause = 503; /* Session Context Not Found */
+ break;
+
+ case ER_DIAMETER_TOO_BUSY:
+ case ER_DIAMETER_OUT_OF_SPACE:
+ error_cause = 506; /* Resources Unavailable */
+ break;
+
+#if 0
+ /* remaining Diameter Result-Code & RADIUS Error-Cause */
+ case ER_DIAMETER_REDIRECT_INDICATION:
+ case ER_DIAMETER_INVALID_HDR_BITS:
+ case ER_DIAMETER_INVALID_AVP_BITS:
+ case ER_DIAMETER_AUTHENTICATION_REJECTED:
+ case ER_ELECTION_LOST:
+ case ER_DIAMETER_AUTHORIZATION_REJECTED:
+ case ER_DIAMETER_RESOURCES_EXCEEDED:
+ case ER_DIAMETER_CONTRADICTING_AVPS:
+ case ER_DIAMETER_AVP_OCCURS_TOO_MANY_TIMES
+ case ER_DIAMETER_NO_COMMON_APPLICATION:
+ case ER_DIAMETER_UNSUPPORTED_VERSION:
+ case ER_DIAMETER_INVALID_BIT_IN_HEADER:
+ case ER_DIAMETER_INVALID_AVP_LENGTH:
+ case ER_DIAMETER_INVALID_MESSAGE_LENGTH:
+ case ER_DIAMETER_INVALID_AVP_BIT_COMBO:
+ case ER_DIAMETER_NO_COMMON_SECURITY:
+ error_cause = 403; /* NAS Identification Mismatch */
+ error_cause = 504; /* Session Context Not Removable */
+ error_cause = 505; /* Other Proxy Processing Error */
+ error_cause = 507; /* Request Initiated */
+ error_cause = 508; /* Multiple Session Selection Unsupported */
+#endif /* 0 */
+ }
+ /* In any case, the following is processed: */
+ (*rad_fw)->hdr->code = RADIUS_CODE_ACCESS_REJECT;
+ fd_log_debug("[auth.rgwx] Received Diameter answer with error code '%d' from server '%.*s', session %.*s, translating into Access-Reject",
+ ahdr->avp_value->u32,
+ (int)oh->avp_value->os.len, oh->avp_value->os.data,
+ (int)sidlen, sid);
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Error_Message, &avp_x) );
+ if (avp_x) {
+ CHECK_FCT( fd_msg_avp_hdr ( avp_x, &ahdr ) );
+ fd_log_debug("[auth.rgwx] Error-Message content: '%.*s'",
+ (int)ahdr->avp_value->os.len, ahdr->avp_value->os.data);
+ }
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Error_Reporting_Host, &avp_x) );
+ if (avp_x) {
+ CHECK_FCT( fd_msg_avp_hdr ( avp_x, &ahdr ) );
+ fd_log_debug("[auth.rgwx] Error-Reporting-Host: '%.*s'",
+ (int)ahdr->avp_value->os.len, ahdr->avp_value->os.data);
+ }
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Failed_AVP, &avp_x) );
+ if (avp_x) {
+ fd_log_debug("[auth.rgwx] Failed-AVP was included in the message.");
+ /* Dump its content ? */
+ }
+ }
+ /* Remove this Result-Code avp */
+ CHECK_FCT( fd_msg_free( avp ) );
+
+ /* Creation of the State or Class attribute with session information */
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Origin_Realm, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+
+ /* Now, save the session-id and eventually server info in a STATE or CLASS attribute */
+ if ((*rad_fw)->hdr->code == RADIUS_CODE_ACCESS_CHALLENGE) {
+ if (sizeof(buf) < (sz = snprintf((char *)buf, sizeof(buf), "Diameter/%.*s/%.*s/%.*s",
+ (int)oh->avp_value->os.len, (char *)oh->avp_value->os.data,
+ (int)ahdr->avp_value->os.len, (char *)ahdr->avp_value->os.data,
+ (int)sidlen, (char *)sid))) {
+ TRACE_DEBUG(INFO, "Data truncated in State attribute: %s", buf);
+ }
+ CONV2RAD_STR(RADIUS_ATTR_STATE, buf, sz, 0);
+ }
+
+ if ((*rad_fw)->hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
+ /* Add the Session-Id */
+ if (sizeof(buf) < (sz = snprintf((char *)buf, sizeof(buf), "Diameter/%.*s",
+ (int)sidlen, sid))) {
+ TRACE_DEBUG(INFO, "Data truncated in Class attribute: %s", buf);
+ }
+ CONV2RAD_STR(RADIUS_ATTR_CLASS, buf, sz, 0);
+ }
+
+ /* Unlink the Origin-Realm now; the others are unlinked at the end of this function */
+ CHECK_FCT( fd_msg_free( avp ) );
+
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Session_Timeout, &avp) );
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Authorization_Lifetime, &avp_x) );
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Re_Auth_Request_Type, &avp_y) );
+ /*
+ When translating a Diameter AA-Answer (with successful result code)
+ to RADIUS Access-Accept that contains a Session-Timeout or
+ Authorization-Lifetime AVP, take the following steps:
+
+ - If the Diameter message contains a Session-Timeout AVP but no
+ Authorization-Lifetime AVP, translate it to a Session-Timeout
+ attribute (not a Termination-Action).
+ */
+ if ((avp != NULL) && (avp_x == NULL)) {
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+ CONV2RAD_32B( RADIUS_ATTR_SESSION_TIMEOUT, ahdr->avp_value->u32 );
+ }
+
+ /*
+ - If the Diameter message contains an Authorization-Lifetime AVP
+ but no Session-Timeout AVP, translate it to a Session-Timeout
+ attribute and a Termination-Action set to AA-REQUEST. (Remove
+ Authorization-Lifetime and Re-Auth-Request-Type.)
+ */
+ if ((avp == NULL) && (avp_x != NULL)) {
+ CHECK_FCT( fd_msg_avp_hdr ( avp_x, &ahdr ) );
+ CONV2RAD_32B( RADIUS_ATTR_SESSION_TIMEOUT, ahdr->avp_value->u32 );
+ CONV2RAD_32B( RADIUS_ATTR_TERMINATION_ACTION, RADIUS_TERMINATION_ACTION_RADIUS_REQUEST );
+ ta_set = 1;
+ }
+
+ /*
+ - If the Diameter message has both, the Session-Timeout must be
+ greater than or equal to the Authorization-Lifetime (required
+ by [BASE]). Translate it to a Session-Timeout value (with
+ value from Authorization-Lifetime AVP, the smaller one) and
+ with the Termination-Action set to AA-REQUEST. (Remove the
+ Authorization-Lifetime and Re-Auth-Request-Type.)
+ */
+ if ((avp != NULL) && (avp_x != NULL)) {
+ CHECK_FCT( fd_msg_avp_hdr ( avp_x, &ahdr ) );
+ CONV2RAD_32B( RADIUS_ATTR_SESSION_TIMEOUT, ahdr->avp_value->u32 );
+ CONV2RAD_32B( RADIUS_ATTR_TERMINATION_ACTION, RADIUS_TERMINATION_ACTION_RADIUS_REQUEST );
+ ta_set = 1;
+ }
+
+ /* -> Not too sure about Auth-Grace-Period... we'll just discard it for now */
+
+ if (avp) {
+ CHECK_FCT( fd_msg_free( avp ) );
+ }
+ if (avp_x) {
+ CHECK_FCT( fd_msg_free( avp_x ) );
+ }
+ if (avp_y) {
+ CHECK_FCT( fd_msg_free( avp_y ) );
+ }
+
+
+ /*
+ - If a Proxy-State attribute was present in the RADIUS request,
+ the same attribute is added in the response. This information
+ may be found in the Proxy-Info AVP group, or in a local state
+ table.
+ -> handled by sub_echo_drop
+
+ - If state information regarding the RADIUS request was saved in
+ a Proxy-Info AVP or local state table, the RADIUS Identifier
+ and UDP IP Address and port number are extracted and used in
+ issuing the RADIUS reply.
+ -> was saved with the full request
+ */
+
+
+ /* Now loop in the list of AVPs and convert those that we know how */
+ CHECK_FCT( fd_msg_browse(*diam_ans, MSG_BRW_FIRST_CHILD, &next, NULL) );
+
+ while (next) {
+ int handled = 1;
+ avp = next;
+ CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &next, NULL) );
+
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+
+ if (!(ahdr->avp_flags & AVP_FLAG_VENDOR)) {
+ switch (ahdr->avp_code) {
+ /* In case of Diameter error, include the Reply-Message attribute */
+ case DIAM_ATTR_ERROR_MESSAGE:
+ CONV2RAD_STR(RADIUS_ATTR_REPLY_MESSAGE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 2);
+ break;
+
+ case DIAM_ATTR_ERROR_REPORTING_HOST:
+ {
+ char buf[254];
+ int bsz = snprintf(buf, sizeof(buf), "Error-Reporting-Host: %*s", (int)(ahdr->avp_value->os.len), ahdr->avp_value->os.data);
+ CONV2RAD_STR(RADIUS_ATTR_REPLY_MESSAGE, (uint8_t *)buf, bsz, 2);
+ }
+ break;
+
+ case DIAM_ATTR_FAILED_AVP:
+ {
+ struct avp * favp;
+ CHECK_FCT( fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &favp, NULL) );
+ if (favp) {
+ char buf[254];
+ int bsz;
+ struct dict_object * favp_model;
+
+ CHECK_FCT( fd_msg_model(favp, &favp_model) );
+ if (favp_model) {
+ struct dict_avp_data fadata;
+ CHECK_FCT( fd_dict_getval(favp_model, &fadata) );
+ bsz = snprintf(buf, sizeof(buf), "Failed-AVP: %s", fadata.avp_name);
+ } else {
+ struct avp_hdr * favp_hdr;
+ CHECK_FCT( fd_msg_avp_hdr ( favp, &favp_hdr ) );
+ bsz = snprintf(buf, sizeof(buf), "Failed-AVP: code %u, vendor %u", favp_hdr->avp_code, favp_hdr->avp_vendor);
+ }
+ CONV2RAD_STR(RADIUS_ATTR_REPLY_MESSAGE, (uint8_t *)buf, bsz, 2);
+ }
+ }
+ break;
+
+ /* RFC 4005 (AVP in the order of the AA-Request/Answer AVP Table) */
+ case DIAM_ATTR_ACCT_INTERIM_INTERVAL:
+ CONV2RAD_32B(RADIUS_ATTR_ACCT_INTERIM_INTERVAL, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_ARAP_CHALLENGE_RESPONSE:
+ CONV2RAD_STR(RADIUS_ATTR_ARAP_CHALLENGE_RESPONSE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
+ break;
+
+ case DIAM_ATTR_ARAP_FEATURES:
+ CONV2RAD_STR(RADIUS_ATTR_ARAP_FEATURES, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
+ break;
+
+ /* ARAP-Password is not present in answers */
+
+ case DIAM_ATTR_ARAP_SECURITY:
+ CONV2RAD_32B(RADIUS_ATTR_ARAP_SECURITY, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_ARAP_SECURITY_DATA:
+ CONV2RAD_STR(RADIUS_ATTR_ARAP_SECURITY_DATA, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 2);
+ break;
+
+ case DIAM_ATTR_ARAP_ZONE_ACCESS:
+ CONV2RAD_32B(RADIUS_ATTR_ARAP_ZONE_ACCESS, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_AUTH_APPLICATION_ID:
+ /* We just remove this AVP */
+ break;
+
+ case DIAM_ATTR_AUTH_GRACE_PERIOD:
+ /* We just remove this AVP (?) */
+ break;
+
+ case DIAM_ATTR_AUTH_REQUEST_TYPE:
+ /* We only check the value */
+ if (ahdr->avp_value->u32 != 3) {
+ fd_log_debug("[auth.rgwx] Received Diameter answer with Auth-Request-Type set to %d (%s) from server %.*s, session %.*s."
+ " This may cause interoperability problems with RADIUS.",
+ ahdr->avp_value->u32,
+ (ahdr->avp_value->u32 == 1) ? "AUTHENTICATE_ONLY" :
+ ((ahdr->avp_value->u32 == 2) ? "AUTHORIZE_ONLY" : "???"),
+ (int)oh->avp_value->os.len, oh->avp_value->os.data,
+ (int)sidlen, sid);
+ }
+ break;
+
+ case DIAM_ATTR_AUTH_SESSION_STATE:
+ if ((!ta_set) && (ahdr->avp_value->u32 == ACV_ASS_STATE_MAINTAINED)) {
+ CONV2RAD_32B( RADIUS_ATTR_TERMINATION_ACTION, RADIUS_TERMINATION_ACTION_RADIUS_REQUEST );
+ }
+
+ if (ahdr->avp_value->u32 == ACV_ASS_NO_STATE_MAINTAINED) {
+ no_str = 1;
+ }
+ break;
+
+ /* Authorization-Lifetime already handled */
+
+ case DIAM_ATTR_CALLBACK_ID:
+ CONV2RAD_STR(RADIUS_ATTR_CALLBACK_ID, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_CALLBACK_NUMBER:
+ CONV2RAD_STR(RADIUS_ATTR_CALLBACK_NUMBER, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ /* Called-Station-Id is not present in answers */
+ /* Calling-Station-Id is not present in answers */
+ /* CHAP-Auth is not present in answers */
+ /* CHAP-Challenge is not present in answers */
+
+ case DIAM_ATTR_CLASS:
+ CONV2RAD_STR(RADIUS_ATTR_CLASS, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 2);
+ break;
+
+ case DIAM_ATTR_CONFIGURATION_TOKEN:
+ /* We might as well remove it since it's not supposed to be sent to the NAS... */
+ CONV2RAD_STR(RADIUS_ATTR_CONFIGURATION_TOKEN, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 2);
+ break;
+
+ /* Connect-Info is not present in answers */
+
+ case DIAM_ATTR_FILTER_ID:
+ CONV2RAD_STR(RADIUS_ATTR_FILTER_ID, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 2);
+ break;
+
+ case DIAM_ATTR_FRAMED_APPLETALK_LINK:
+ CONV2RAD_32B(RADIUS_ATTR_FRAMED_APPLETALK_LINK, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_FRAMED_APPLETALK_NETWORK:
+ CONV2RAD_32B(RADIUS_ATTR_FRAMED_APPLETALK_NETWORK, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_FRAMED_APPLETALK_ZONE:
+ CONV2RAD_STR(RADIUS_ATTR_FRAMED_APPLETALK_ZONE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_FRAMED_COMPRESSION:
+ CONV2RAD_32B(RADIUS_ATTR_FRAMED_COMPRESSION, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_FRAMED_INTERFACE_ID:
+ CONV2RAD_64B(RADIUS_ATTR_FRAMED_INTERFACE_ID, ahdr->avp_value->u64);
+ break;
+
+ case DIAM_ATTR_FRAMED_IP_ADDRESS:
+ CONV2RAD_STR(RADIUS_ATTR_FRAMED_IP_ADDRESS, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
+ break;
+
+ case DIAM_ATTR_FRAMED_IP_NETMASK:
+ CONV2RAD_STR(RADIUS_ATTR_FRAMED_IP_NETMASK, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
+ break;
+
+ case DIAM_ATTR_FRAMED_IPV6_PREFIX:
+ CONV2RAD_STR(RADIUS_ATTR_FRAMED_IPV6_PREFIX, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
+ break;
+
+ case DIAM_ATTR_FRAMED_IPV6_POOL:
+ CONV2RAD_STR(RADIUS_ATTR_FRAMED_IPV6_POOL, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_FRAMED_IPV6_ROUTE:
+ CONV2RAD_STR(RADIUS_ATTR_FRAMED_IPV6_ROUTE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_FRAMED_IPX_NETWORK:
+ CONV2RAD_32B(RADIUS_ATTR_FRAMED_IPX_NETWORK, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_FRAMED_MTU:
+ CONV2RAD_32B(RADIUS_ATTR_FRAMED_MTU, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_FRAMED_POOL:
+ CONV2RAD_STR(RADIUS_ATTR_FRAMED_POOL, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_FRAMED_PROTOCOL:
+ CONV2RAD_32B(RADIUS_ATTR_FRAMED_PROTOCOL, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_FRAMED_ROUTE:
+ CONV2RAD_STR(RADIUS_ATTR_FRAMED_ROUTE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_FRAMED_ROUTING:
+ CONV2RAD_32B(RADIUS_ATTR_FRAMED_ROUTING, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_IDLE_TIMEOUT:
+ CONV2RAD_32B(RADIUS_ATTR_IDLE_TIMEOUT, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_LOGIN_IP_HOST:
+ CONV2RAD_STR(RADIUS_ATTR_LOGIN_IP_HOST, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
+ break;
+
+ case DIAM_ATTR_LOGIN_IPV6_HOST:
+ CONV2RAD_STR(RADIUS_ATTR_LOGIN_IPV6_HOST, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
+ break;
+
+ case DIAM_ATTR_LOGIN_LAT_GROUP:
+ CONV2RAD_STR(RADIUS_ATTR_LOGIN_LAT_GROUP, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_LOGIN_LAT_NODE:
+ CONV2RAD_STR(RADIUS_ATTR_LOGIN_LAT_NODE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_LOGIN_LAT_PORT:
+ CONV2RAD_STR(RADIUS_ATTR_LOGIN_LAT_PORT, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_LOGIN_LAT_SERVICE:
+ CONV2RAD_STR(RADIUS_ATTR_LOGIN_LAT_SERVICE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_LOGIN_SERVICE:
+ CONV2RAD_32B(RADIUS_ATTR_LOGIN_SERVICE, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_LOGIN_TCP_PORT:
+ CONV2RAD_32B(RADIUS_ATTR_LOGIN_TCP_PORT, ahdr->avp_value->u32);
+ break;
+
+ /*
+ - If the
+ Multi-Round-Time-Out AVP is present, the value of the AVP MUST
+ be inserted in the RADIUS Session-Timeout AVP.
+
+ o As described in [NASREQ], if the Result-Code AVP set to
+ DIAMETER_MULTI_ROUND_AUTH and the Multi-Round-Time-Out AVP is
+ present, it is translated to the RADIUS Session-Timeout attribute.
+ */
+ case DIAM_ATTR_MULTI_ROUND_TIMEOUT:
+ CONV2RAD_32B(RADIUS_ATTR_SESSION_TIMEOUT, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_NAS_FILTER_RULE:
+ /* This is not translatable to RADIUS */
+ fd_log_debug("[auth.rgwx] Received Diameter answer with non-translatable NAS-Filter-Rule AVP from '%.*s' (session: '%.*s'), ignoring.",
+ (int)oh->avp_value->os.len, oh->avp_value->os.data,
+ (int)sidlen, sid);
+ handled = 0;
+ break;
+
+ /* NAS-Identifier is not present in answers */
+ /* NAS-IP-Address is not present in answers */
+ /* NAS-IPv6-Address is not present in answers */
+ /* NAS-Port is not present in answers */
+ /* NAS-Port-Id is not present in answers */
+ /* NAS-Port-Type is not present in answers */
+
+ case DIAM_ATTR_ORIGIN_AAA_PROTOCOL:
+ /* We just remove this AVP */
+ break;
+
+ /* Originating-Line-Info is not present in answers */
+
+ case DIAM_ATTR_PASSWORD_RETRY:
+ CONV2RAD_32B(RADIUS_ATTR_PASSWORD_RETRY, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_PORT_LIMIT:
+ CONV2RAD_32B(RADIUS_ATTR_PORT_LIMIT, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_PROMPT:
+ CONV2RAD_32B(RADIUS_ATTR_PROMPT, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_QOS_FILTER_RULE:
+ /* This is not translatable to RADIUS */
+ fd_log_debug("[auth.rgwx] Received Diameter answer with non-translatable QoS-Filter-Rule AVP from '%.*s' (session: '%.*s'), ignoring.",
+ (int)oh->avp_value->os.len, oh->avp_value->os.data,
+ (int)sidlen, sid);
+ handled = 0;
+ break;
+
+ /* Re-Auth-Request-Type already handled */
+
+ case DIAM_ATTR_REPLY_MESSAGE:
+ CONV2RAD_STR(RADIUS_ATTR_REPLY_MESSAGE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 2);
+ break;
+
+ case DIAM_ATTR_SERVICE_TYPE:
+ CONV2RAD_32B(RADIUS_ATTR_SERVICE_TYPE, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_STATE:
+ CONV2RAD_STR(RADIUS_ATTR_STATE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 2);
+ break;
+
+ case DIAM_ATTR_TUNNELING:
+ {
+#define CONV2RAD_TUN_STR( _attr_, _data_, _len_, _trunc_) { \
+ size_t __l = (size_t)(_len_); \
+ size_t __w = (__l > 252) ? 252 : __l; \
+ size_t __off = 0; \
+ if ((_trunc_) == 0) { \
+ CHECK_PARAMS( __l <= 252 ); \
+ } \
+ if ((__l > 252) && (_trunc_ == 1)) { \
+ TRACE_DEBUG(FULL, "Attribute truncated!"); \
+ __l = 252; \
+ } \
+ buf[0] = tuntag; \
+ memcpy(&buf[1], (_data_), __w); \
+ CHECK_MALLOC(radius_msg_add_attr(*rad_fw, (_attr_), &buf[0], __w + 1)); \
+ while (__l -= __w) { \
+ __off += __w; \
+ __w = (__l > 253) ? 253 : __l; \
+ CHECK_MALLOC(radius_msg_add_attr(*rad_fw, (_attr_), (_data_) + __off, __w)); \
+ } \
+}
+
+#define CONV2RAD_TUN_32B( _attr_, _data_) { \
+ uint32_t __v = htonl((uint32_t)(_data_) | (tuntag << 24)); \
+ CHECK_MALLOC(radius_msg_add_attr(*rad_fw, (_attr_), (uint8_t *)&__v, sizeof(__v))); \
+}
+ struct avp *inavp, *innext;
+ tuntag++;
+ CHECK_FCT( fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &innext, NULL) );
+ while (innext) {
+ inavp = innext;
+ CHECK_FCT( fd_msg_browse(inavp, MSG_BRW_NEXT, &innext, NULL) );
+ CHECK_FCT( fd_msg_avp_hdr ( inavp, &ahdr ) );
+
+ if ( ! (ahdr->avp_flags & AVP_FLAG_VENDOR)) {
+ switch (ahdr->avp_code) {
+ case DIAM_ATTR_TUNNEL_TYPE:
+ CONV2RAD_TUN_32B( RADIUS_ATTR_TUNNEL_TYPE, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_TUNNEL_MEDIUM_TYPE:
+ CONV2RAD_TUN_32B( RADIUS_ATTR_TUNNEL_MEDIUM_TYPE, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_TUNNEL_CLIENT_ENDPOINT:
+ CONV2RAD_TUN_STR(RADIUS_ATTR_TUNNEL_CLIENT_ENDPOINT, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_TUNNEL_SERVER_ENDPOINT:
+ CONV2RAD_TUN_STR(RADIUS_ATTR_TUNNEL_SERVER_ENDPOINT, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_TUNNEL_PREFERENCE:
+ CONV2RAD_TUN_32B( RADIUS_ATTR_TUNNEL_PREFERENCE, ahdr->avp_value->u32);
+ break;
+
+ case DIAM_ATTR_TUNNEL_CLIENT_AUTH_ID:
+ CONV2RAD_TUN_STR(RADIUS_ATTR_TUNNEL_CLIENT_AUTH_ID, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_TUNNEL_SERVER_AUTH_ID:
+ CONV2RAD_TUN_STR(RADIUS_ATTR_TUNNEL_SERVER_AUTH_ID, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_TUNNEL_ASSIGNMENT_ID:
+ CONV2RAD_TUN_STR(RADIUS_ATTR_TUNNEL_ASSIGNMENT_ID, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ case DIAM_ATTR_TUNNEL_PASSWORD:
+ {
+ /* This AVP must be encoded for RADIUS (similar to radius_msg_add_attr_user_password)
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type | Length | Tag | Salt
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ Salt (cont) | String ...
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ size_t pos;
+ int i;
+ uint8_t * secret; /* S */
+ size_t secret_len;
+ uint8_t hash[16]; /* b(i) */
+ const uint8_t *addr[3];
+ size_t len[3];
+
+ /* We need the request authenticator */
+ CHECK_PARAMS(st);
+
+ /* Retrieve the shared secret */
+ CHECK_FCT(rgw_clients_getkey(cli, &secret, &secret_len));
+
+ /* Beginning of the buffer */
+ buf[0] = tuntag;
+ buf[1] = (uint8_t)(lrand48()); /* A (hi bits) */
+ buf[2] = (uint8_t)(lrand48()); /* A (low bits) */
+
+ /* The plain text string P */
+ CHECK_PARAMS(ahdr->avp_value->os.len < 240);
+ buf[3] = ahdr->avp_value->os.len;
+ memcpy(&buf[4], ahdr->avp_value->os.data, ahdr->avp_value->os.len);
+ memset(&buf[4 + ahdr->avp_value->os.len], 0, sizeof(buf) - 4 - ahdr->avp_value->os.len);
+
+ /* Initial b1 = MD5(S + R + A) */
+ addr[0] = secret;
+ len[0] = secret_len;
+ addr[1] = st->req_auth;
+ len[1] = 16;
+ addr[2] = &buf[1];
+ len[2] = 2;
+ md5_vector(3, addr, len, hash);
+
+ /* Initial c(1) = p(1) xor b(1) */
+ for (i = 0; i < 16; i++) {
+ buf[i + 3] ^= hash[i];
+ }
+ pos = 16;
+
+ /* loop */
+ while (pos < ahdr->avp_value->os.len + 1) {
+ addr[0] = secret;
+ len[0] = secret_len;
+ addr[1] = &buf[pos - 13];
+ len[1] = 16;
+ /* b(i) = MD5( S + c(i-1) */
+ md5_vector(2, addr, len, hash);
+
+ /* c(i) = p(i) xor b(i) */
+ for (i = 0; i < 16; i++)
+ buf[pos + i + 3] ^= hash[i];
+
+ pos += 16;
+ }
+
+ CONV2RAD_STR(RADIUS_ATTR_TUNNEL_PASSWORD, &buf[0], pos + 3, 0);
+ }
+ break;
+
+ case DIAM_ATTR_TUNNEL_PRIVATE_GROUP_ID:
+ CONV2RAD_TUN_STR(RADIUS_ATTR_TUNNEL_PRIVATE_GROUP_ID, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ default:
+ TRACE_DEBUG(FULL, "Ignored unknown AVP inside Tunneling AVP (%d)", ahdr->avp_code);
+ }
+ } else {
+ TRACE_DEBUG(FULL, "Ignored unknown Vendor AVP inside Tunneling AVP (%d, %d)", ahdr->avp_vendor, ahdr->avp_code);
+ }
+ }
+ }
+ break;
+
+ case DIAM_ATTR_USER_NAME:
+ CONV2RAD_STR(RADIUS_ATTR_USER_NAME, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ /* User-Password never present in answers */
+
+ /* RFC 4072 (AVP in the order of the EAP Command AVP Table) */
+ /*
+ o Diameter Accounting-EAP-Auth-Method AVPs, if present, are
+ discarded.
+ */
+ case DIAM_ATTR_ACCOUNTING_EAP_AUTH_METHOD:
+ break;
+
+ /*
+ o Diameter EAP-Master-Session-Key AVP can be translated to the
+ vendor-specific RADIUS MS-MPPE-Recv-Key and MS-MPPE-Send-Key
+ attributes [RFC2548]. The first up to 32 octets of the key is
+ stored into MS-MPPE-Recv-Key, and the next up to 32 octets (if
+ present) are stored into MS-MPPE-Send-Key. The encryption of this
+ attribute is described in [RFC2548].
+ */
+ case DIAM_ATTR_EAP_MASTER_SESSION_KEY:
+ {
+ uint8_t * secret; /* S */
+ size_t secret_len;
+ size_t recv_len, send_len;
+
+ /* We need the request authenticator */
+ CHECK_PARAMS(st);
+
+ /* Retrieve the shared secret */
+ CHECK_FCT(rgw_clients_getkey(cli, &secret, &secret_len));
+
+ if (ahdr->avp_value->os.len != 64) {
+ TRACE_DEBUG(INFO, "Received EAP-Master-Session-Key attribute with length %zd != 64.", ahdr->avp_value->os.len)
+ }
+
+ CHECK_PARAMS(ahdr->avp_value->os.len <= 64);
+ recv_len = ahdr->avp_value->os.len >= 32 ? 32 : ahdr->avp_value->os.len;
+ send_len = ahdr->avp_value->os.len - recv_len;
+
+ if ( ! radius_msg_add_mppe_keys(*rad_fw, st->req_auth, secret, secret_len,
+ ahdr->avp_value->os.data + recv_len, send_len,
+ ahdr->avp_value->os.data, recv_len) ) {
+ TRACE_DEBUG(INFO, "Error while converting EAP-Master-Session-Key to RADIUS message");
+ return ENOMEM;
+ }
+ }
+ break;
+
+ case DIAM_ATTR_EAP_KEY_NAME:
+ CONV2RAD_STR(RADIUS_ATTR_EAP_KEY_NAME, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+
+ /*
+ o Diameter EAP-Payload AVP is translated to RADIUS EAP-Message
+ attribute(s). If necessary, the value is split into multiple
+ RADIUS EAP-Message attributes.
+ */
+ case DIAM_ATTR_EAP_PAYLOAD:
+ if ( ! radius_msg_add_eap(*rad_fw, ahdr->avp_value->os.data, ahdr->avp_value->os.len) ) {
+ TRACE_DEBUG(INFO, "Error while converting EAP payload to RADIUS message");
+ return ENOMEM;
+ }
+ break;
+
+ /*
+ o Diameter EAP-Reissued-Payload AVP is translated to a message that
+ contains RADIUS EAP-Message attribute(s), and a RADIUS Error-Cause
+ attribute [RFC3576] with value 202 (decimal), "Invalid EAP Packet
+ (Ignored)" [RFC3579].
+ */
+ case DIAM_ATTR_EAP_REISSUED_PAYLOAD:
+ if ( ! radius_msg_add_eap(*rad_fw, ahdr->avp_value->os.data, ahdr->avp_value->os.len) ) {
+ TRACE_DEBUG(INFO, "Error while converting EAP reissued payload to RADIUS message");
+ return ENOMEM;
+ }
+
+ error_cause = 202; /* Invalid EAP Packet */
+ break;
+
+ default:
+ /* Leave the AVP in the message for further treatment */
+ handled = 0;
+ }
+ } else {
+ /* Vendor-specific AVPs */
+ switch (ahdr->avp_vendor) {
+
+ default: /* unknown vendor */
+ handled = 0;
+ }
+ }
+
+ if (handled) {
+ CHECK_FCT( fd_msg_free( avp ) );
+ }
+ }
+
+ CHECK_FCT( fd_msg_free( aoh ) );
+ free(st);
+
+ if (error_cause) {
+ if ( ! radius_msg_add_attr_int32(*rad_fw, RADIUS_ATTR_ERROR_CAUSE, error_cause) ) {
+ TRACE_DEBUG(INFO, "Error while adding Error-Cause attribute in RADIUS message");
+ return ENOMEM;
+ }
+ }
+
+ if ((*rad_fw)->hdr->code == RADIUS_CODE_ACCESS_ACCEPT) {
+ /* Add the auth-application-id required for STR, or 0 if no STR is required */
+ CHECK_FCT( fd_msg_hdr( *diam_ans, &hdr ) );
+ if (sizeof(buf) < (sz = snprintf((char *)buf, sizeof(buf), CLASS_AAI_PREFIX "%u",
+ no_str ? 0 : hdr->msg_appl))) {
+ TRACE_DEBUG(INFO, "Data truncated in Class attribute: %s", buf);
+ }
+ CONV2RAD_STR(RADIUS_ATTR_CLASS, buf, sz, 0);
+ }
+
+ return 0;
+}
+
+/* The exported symbol */
+struct rgw_api rgwp_descriptor = {
+ .rgwp_name = "auth",
+ .rgwp_conf_parse = auth_conf_parse,
+ .rgwp_conf_free = auth_conf_free,
+ .rgwp_rad_req = auth_rad_req,
+ .rgwp_diam_ans = auth_diam_ans
+};
diff --git a/extensions/app_radgw/rgwx_debug.c b/extensions/app_radgw/rgwx_debug.c
new file mode 100644
index 0000000..282b028
--- /dev/null
+++ b/extensions/app_radgw/rgwx_debug.c
@@ -0,0 +1,143 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Debug plugin for app_radgw */
+
+#include "rgw_common.h"
+
+/* Store the configuration string in the state */
+static int debug_conf_parse ( char * conf_file, struct rgwp_config ** state )
+{
+ TRACE_ENTRY("%p %p", conf_file, state);
+ CHECK_PARAMS(state);
+
+ *state = (void *)conf_file;
+
+ return 0;
+}
+
+
+/* Function to display the content of a RADIUS message (more friendly way than radius_msg_dump) */
+static void debug_dump_radius(struct radius_msg *msg)
+{
+ unsigned char *auth;
+ size_t i;
+
+ auth = &(msg->hdr->authenticator[0]);
+ fd_log_debug(" id : 0x%02hhx, code: %hhd (%s)", msg->hdr->identifier, msg->hdr->code, rgw_msg_code_str(msg->hdr->code));
+ fd_log_debug(" auth: %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx",
+ auth[0], auth[1], auth[2], auth[3],
+ auth[4], auth[5], auth[6], auth[7]);
+ fd_log_debug(" %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx",
+ auth[8], auth[9], auth[10], auth[11],
+ auth[12], auth[13], auth[14], auth[15]);
+ for (i = 0; i < msg->attr_used; i++) {
+ struct radius_attr_hdr *attr = (struct radius_attr_hdr *)(msg->buf + msg->attr_pos[i]);
+ fd_log_debug(" - len:%3hhu, type:0x%02hhx (%s)", attr->length, attr->type, rgw_msg_attrtype_str(attr->type));
+ /* If we need to dump the value, it's better to call directly radius_msg_dump instead... */
+ }
+}
+
+/* Function called when a new RADIUS message is being converted to Diameter */
+static int debug_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+{
+ TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
+
+ fd_log_debug("------------- RADIUS/Diameter Request Debug%s%s%s -------------", cs ? " [" : "", cs ? (char *)cs : "", cs ? "]" : "");
+
+ if (!rad_req) {
+ fd_log_debug(" RADIUS request: NULL pointer");
+ } else {
+ fd_log_debug(" RADIUS request (%p) DUMP:", rad_req);
+ debug_dump_radius(rad_req);
+ }
+
+ if (!rad_ans || ! *rad_ans) {
+ fd_log_debug(" RADIUS answer: NULL pointer");
+ } else {
+ fd_log_debug(" RADIUS answer (%p) DUMP:", *rad_ans);
+ debug_dump_radius(*rad_ans);
+ }
+
+ if (!diam_fw || ! *diam_fw) {
+ fd_log_debug(" Diameter message: NULL pointer");
+ } else {
+ char * buf = NULL; size_t buflen;
+ CHECK_MALLOC( fd_msg_dump_treeview(&buf, &buflen, NULL, *diam_fw, NULL, 0, 1) );
+ fd_log_debug(" Diameter message (%p) DUMP: %s", *diam_fw, buf);
+ free(buf);
+ }
+
+ fd_log_debug("=========== Debug%s%s%s complete =============", cs ? " [" : "", cs ? (char *)cs : "", cs ? "]" : "");
+
+ return 0;
+}
+
+/* This one, when Diameter answer is converted to RADIUS */
+static int debug_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
+{
+ TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
+
+ fd_log_debug("------------- RADIUS/Diameter Answer Debug%s%s%s -------------", cs ? " [" : "", cs ? (char *)cs : "", cs ? "]" : "");
+
+ if (!diam_ans || ! *diam_ans) {
+ fd_log_debug(" Diameter message: NULL pointer");
+ } else {
+ char * buf = NULL; size_t buflen;
+ CHECK_MALLOC( fd_msg_dump_treeview(&buf, &buflen, NULL, *diam_ans, NULL, 0, 1) );
+ fd_log_debug(" Diameter message (%p) DUMP: %s", *diam_ans, buf);
+ free(buf);
+ }
+
+ if (!rad_fw || ! *rad_fw) {
+ fd_log_debug(" RADIUS answer: NULL pointer");
+ } else {
+ fd_log_debug(" RADIUS answer (%p) DUMP:", *rad_fw);
+ debug_dump_radius(*rad_fw);
+ }
+
+ fd_log_debug("=========== Debug%s%s%s complete =============", cs ? " [" : "", cs ? (char *)cs : "", cs ? "]" : "");
+ return 0;
+}
+
+
+/* The exported symbol */
+struct rgw_api rgwp_descriptor = {
+ .rgwp_name = "debug",
+ .rgwp_conf_parse = debug_conf_parse,
+ .rgwp_conf_free = NULL,
+ .rgwp_rad_req = debug_rad_req,
+ .rgwp_diam_ans = debug_diam_ans
+};
diff --git a/extensions/app_radgw/rgwx_echodrop.c b/extensions/app_radgw/rgwx_echodrop.c
new file mode 100644
index 0000000..c8f4333
--- /dev/null
+++ b/extensions/app_radgw/rgwx_echodrop.c
@@ -0,0 +1,309 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* See rgwx_echodrop.h for details */
+
+#include "rgwx_echodrop.h"
+
+struct sess_state {
+ struct fd_list sentinel;
+};
+
+/* If a session is destroyed, empty the list of ed_saved_attribute */
+static void state_delete(struct sess_state * arg, os0_t sid, void * opaque) {
+ while (!FD_IS_LIST_EMPTY(&arg->sentinel)) {
+ struct ed_saved_attribute * esa = (struct ed_saved_attribute *)(arg->sentinel.next);
+ fd_list_unlink(&esa->chain);
+ free(esa);
+ }
+ free(arg);
+}
+
+static DECLARE_FD_DUMP_PROTOTYPE(ed_session_state_dump, struct sess_state * st)
+{
+ struct fd_list * li;
+ CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "[rgwx sess_state](@%p):\n", st), return NULL);
+ for (li = st->sentinel.next; li != &st->sentinel; li = li->next) {
+ struct ed_saved_attribute * esa = (struct ed_saved_attribute *)(li);
+ CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "[rgwx sess_state {esa}] t:%2hhx l:%2hhx d:", esa->attr.type, esa->attr.length), return NULL);
+ CHECK_MALLOC_DO( fd_dump_extend_hexdump(FD_DUMP_STD_PARAMS, (&esa->attr.length) + 1, esa->attr.length - 2, 0,0), return NULL);
+ CHECK_MALLOC_DO( fd_dump_extend( FD_DUMP_STD_PARAMS, "\n"), return NULL);
+ }
+ return *buf;
+}
+
+/* Initialize the plugin and parse the configuration. */
+static int ed_conf_parse(char * conffile, struct rgwp_config ** state)
+{
+ struct rgwp_config * new;
+
+ TRACE_ENTRY("%p %p", conffile, state);
+ CHECK_PARAMS( state );
+ CHECK_PARAMS_DO( conffile, { fd_log_debug("[echodrop.rgwx] The configuration file is not optional for this plugin."); return EINVAL; } );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct rgwp_config)) );
+ memset(new, 0, sizeof(struct rgwp_config));
+
+ /* Initialize the list of attributes to handle */
+ fd_list_init(&new->attributes, NULL);
+
+ /* Create the session handler */
+ CHECK_FCT( fd_sess_handler_create( &new->sess_hdl, state_delete, ed_session_state_dump, NULL ) );
+
+ /* Parse the configuration file */
+ CHECK_FCT( ed_conffile_parse(conffile, new) );
+
+ if (TRACE_BOOL(FULL)) {
+ TRACE_DEBUG(INFO, "Echo/Drop plugin configuration ('%s'):", conffile);
+ struct fd_list * li;
+
+ for (li = new->attributes.next; li != &new->attributes; li = li->next) {
+ struct ed_conf_attribute * eca = (struct ed_conf_attribute *)li;
+ char * act = (eca->action == ACT_ECHO) ? "ECHO" : "DROP";
+ if (eca->ext) {
+ fd_log_debug(" %s Code: %hhu, Vendor: %u, Ext-Type: %hu", act, eca->code, eca->vendor_id, eca->extype);
+ continue;
+ }
+ if (eca->tlv) {
+ fd_log_debug(" %s Code: %hhu, Vendor: %u, Type: %hhu", act, eca->code, eca->vendor_id, eca->type);
+ continue;
+ }
+ if (eca->vsa) {
+ fd_log_debug(" %s Code: %hhu, Vendor: %u", act, eca->code, eca->vendor_id);
+ continue;
+ }
+ fd_log_debug(" %s Code: %hhu", act, eca->code);
+ }
+ }
+
+ /* OK, we are done */
+ *state = new;
+ return 0;
+}
+
+/* Destroy the state */
+static void ed_conf_free(struct rgwp_config * state)
+{
+ TRACE_ENTRY("%p", state);
+ CHECK_PARAMS_DO( state, return );
+ CHECK_FCT_DO( fd_sess_handler_destroy( &state->sess_hdl, NULL ), );
+ while (! FD_IS_LIST_EMPTY(&state->attributes) ) {
+ struct fd_list * li = state->attributes.next;
+ fd_list_unlink(li);
+ free(li);
+ }
+ free(state);
+ return;
+}
+
+
+/* Handle attributes from a RADIUS request as specified in the configuration */
+static int ed_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+{
+ size_t nattr_used = 0;
+ int idx;
+ struct fd_list echo_list = FD_LIST_INITIALIZER(echo_list);
+ struct fd_list *li;
+
+ TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
+ CHECK_PARAMS(cs && rad_req);
+
+ /* For each attribute in the original message */
+ for (idx = 0; idx < rad_req->attr_used; idx++) {
+ int action = 0;
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(rad_req->buf + rad_req->attr_pos[idx]);
+
+ /* Look if we have a matching attribute in our configuration */
+ for (li = cs->attributes.next; li != &cs->attributes; li = li->next) {
+ struct ed_conf_attribute * eca = (struct ed_conf_attribute *)li;
+ uint32_t vid;
+ unsigned char * ptr;
+
+ if (eca->code < attr->type)
+ continue;
+ if (eca->code > attr->type)
+ break;
+
+ /* the code matches one in our configuration, check additional data if needed */
+
+ if (! eca->vsa) {
+ action = eca->action;
+ break;
+ }
+
+ if (attr->length < 8)
+ continue;
+
+ ptr = (unsigned char *)(attr + 1);
+ /* since attr is not aligned, we may not access *(attr+1) directly */
+ memcpy(&vid, ptr, sizeof(uint32_t));
+
+ if (eca->vendor_id < ntohl(vid))
+ continue;
+ if (eca->vendor_id > ntohl(vid))
+ break;
+
+ /* The vendor matches our configured line... */
+
+ if ( ! eca->tlv && ! eca->ext ) {
+ action = eca->action;
+ break;
+ }
+
+ if (attr->length < 10)
+ continue;
+
+ if (eca->tlv) {
+ struct radius_attr_vendor * tl = (struct radius_attr_vendor *)(ptr + sizeof(uint32_t));
+ if (tl->vendor_type == eca->type) {
+ action = eca->action;
+ break;
+ }
+ continue;
+ }
+
+ if (eca->ext) {
+ /* To be done */
+ fd_log_debug("Extended attributes are not implemented yet!");
+ ASSERT(0);
+ continue;
+ }
+ }
+
+ switch (action) {
+ case ACT_DROP:
+ TRACE_DEBUG(FULL, "Dropping attribute with code %hhd", attr->type);
+ break;
+
+ case ACT_ECHO:
+ {
+ struct ed_saved_attribute * esa = NULL;
+ TRACE_DEBUG(FULL, "Saving attribute with code %hhd", attr->type);
+ CHECK_MALLOC( esa = malloc(sizeof(struct ed_saved_attribute) + attr->length - sizeof(struct radius_attr_hdr)) );
+ fd_list_init(&esa->chain, NULL);
+ memcpy(&esa->attr, attr, attr->length);
+ fd_list_insert_before(&echo_list, &esa->chain);
+ }
+ break;
+
+ default: /* Attribute was not specified in the configuration */
+ /* We just keep the attribute in the RADIUS message */
+ rad_req->attr_pos[nattr_used++] = rad_req->attr_pos[idx];
+ }
+ }
+ rad_req->attr_used = nattr_used;
+
+ /* Save the echoed values in the session, if any */
+ if (!FD_IS_LIST_EMPTY(&echo_list)) {
+ struct session * sess;
+ struct sess_state * st;
+
+ CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_fw, &sess, NULL) );
+
+ CHECK_PARAMS_DO(sess,
+ {
+ fd_log_debug( "[echodrop.rgwx] The extension is configured to echo some attributes from this message, but no session object has been created for it (yet)."
+ " Please check your configuration file and include a session-generating extension BEFORE calling echodrop.rgwx to echo attributes."
+ " Please use debug.rgwx to retrieve more information." );
+ return EINVAL;
+ } );
+
+ /* Move the values in a dynamically allocated list */
+ CHECK_MALLOC( st = malloc(sizeof(struct sess_state)) );
+ fd_list_init(&st->sentinel, NULL);
+ fd_list_move_end(&st->sentinel, &echo_list);
+
+ /* Save the list in the session */
+ CHECK_FCT( fd_sess_state_store( cs->sess_hdl, sess, &st ) );
+ }
+
+ return 0;
+}
+
+/* Process an answer: add the ECHO attributes back, if any */
+static int ed_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
+{
+ struct session * sess;
+ struct sess_state * st;
+
+ TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
+ CHECK_PARAMS(cs);
+
+ CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_ans, &sess, NULL) );
+
+ /* If there is no session associated, just give up */
+ if (! sess ) {
+ TRACE_DEBUG(FULL, "No session associated with the message, nothing to do here...");
+ return 0;
+ }
+
+ /* Now try and retrieve any data from the session */
+ CHECK_FCT( fd_sess_state_retrieve( cs->sess_hdl, sess, &st ) );
+ if (st == NULL) {
+ /* No attribute saved in the session, just return */
+ return 0;
+ }
+
+ /* From this point on, we have a list of attributes to add to the radius message */
+
+ CHECK_PARAMS( rad_fw && *rad_fw);
+
+ while (! FD_IS_LIST_EMPTY(&st->sentinel) ) {
+ struct ed_saved_attribute * esa = (struct ed_saved_attribute *)(st->sentinel.next);
+
+ fd_list_unlink(&esa->chain);
+
+ TRACE_DEBUG(FULL, "Echo attribute in the RADIUS answer: type %hhu, len: %hhu", esa->attr.type, esa->attr.length);
+
+ /* Add this attribute in the RADIUS message */
+ CHECK_MALLOC( radius_msg_add_attr(*rad_fw, esa->attr.type, (unsigned char *)(esa + 1), esa->attr.length - sizeof(struct radius_attr_hdr)) );
+
+ free(esa);
+ }
+ free(st);
+
+ return 0;
+}
+
+
+
+/* The exported symbol */
+struct rgw_api rgwp_descriptor = {
+ .rgwp_name = "echo/drop",
+ .rgwp_conf_parse = ed_conf_parse,
+ .rgwp_conf_free = ed_conf_free,
+ .rgwp_rad_req = ed_rad_req,
+ .rgwp_diam_ans = ed_diam_ans
+};
diff --git a/extensions/app_radgw/rgwx_echodrop.h b/extensions/app_radgw/rgwx_echodrop.h
new file mode 100644
index 0000000..db84fbd
--- /dev/null
+++ b/extensions/app_radgw/rgwx_echodrop.h
@@ -0,0 +1,84 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* RADIUS translation plugin, to handle specific RADIUS attributes by either caching them and
+adding them to a corresponding RADIUS reply, or just dropping the attributes (no conversion to Diameter) */
+/* This extension is a kind of swiss army-knife for interoperability, must be used with care.
+ All attribute behaviors are specified through the configuration file of the extension
+ */
+
+#include "rgw_common.h"
+
+/* Action associated with an attribute */
+#define ACT_ECHO 1
+#define ACT_DROP 2
+
+/* Result of configuration parsing */
+struct rgwp_config {
+ /* list of attributes and associated actions */
+ struct fd_list attributes;
+
+ /* Handler to store the echo'ed attributes values */
+ struct session_handler * sess_hdl;
+};
+
+/* An item of the attribute list */
+struct ed_conf_attribute {
+ struct fd_list chain; /* link in the list */
+
+ struct {
+ unsigned action :2; /* ACT_ECHO or ACT_DROP */
+ unsigned vsa :1; /* Interpret as Vendor-Specific, and match the vendor id in addition to the code */
+ unsigned tlv :1; /* Interpret as Vendor-Specific with TLV format, and match the type also */
+ unsigned ext :1; /* Interpret as radius extended attribute, and match the ext-type also */
+ };
+
+ uint32_t vendor_id; /* vendor id to match when vsa = 1 */
+ uint16_t extype; /* Ext-Type value to match if ext = 1 */
+ uint8_t type; /* Type value to match if tlv = 1; */
+
+ uint8_t code; /* The attribute code, the list is ordered by this value */
+};
+
+/* For ECHO items, we save a list of these in the session */
+struct ed_saved_attribute {
+ struct fd_list chain;
+ struct radius_attr_hdr attr; /* copy of the attribute */
+ /* The data of the attribute follows ... */
+};
+
+
+/* The yacc parser */
+int ed_conffile_parse(char * conffile, struct rgwp_config *cs);
diff --git a/extensions/app_radgw/rgwx_echodrop.l b/extensions/app_radgw/rgwx_echodrop.l
new file mode 100644
index 0000000..aab2841
--- /dev/null
+++ b/extensions/app_radgw/rgwx_echodrop.l
@@ -0,0 +1,99 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Tokenizer for echo/drop plugin */
+
+%{
+#include "rgwx_echodrop.h"
+#include "rgwx_echodrop.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* %option noinput ? */
+#define YY_NO_INPUT
+%}
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+<*>\n {
+ /* Update the line count */
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+<*>([[:space:]]{-}[\n])+ ; /* Eat all spaces, not new lines */
+<*>#.*$ ; /* Eat all comments */
+
+[[:digit:]]+ {
+ /* Match an integer (not hexa) */
+ int ret = sscanf(yytext, "%d", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("[echodrop.rgwx] Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+(?i:"echo") { return TOK_ECHO; }
+(?i:"drop") { return TOK_DROP; }
+(?i:"code") { return TOK_CODE; }
+(?i:"vendor") { return TOK_VENDOR; }
+(?i:"tlv") { return TOK_TLV; }
+(?i:"ext") { return TOK_EXT; }
+
+ /* Valid single characters for yyparse */
+<*>[;] { return yytext[0]; }
+
+
+ /* Unrecognized token */
+<*>[[:alnum:]]+ | /* This rule is only useful to print a complete token in error messages */
+ /* Unrecognized character */
+<*>. {
+ fd_log_debug("[echodrop.rgwx] Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/app_radgw/rgwx_echodrop.y b/extensions/app_radgw/rgwx_echodrop.y
new file mode 100644
index 0000000..fccaf06
--- /dev/null
+++ b/extensions/app_radgw/rgwx_echodrop.y
@@ -0,0 +1,255 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc parser for echo/drop plugin.
+See doc/echodrop.rgwx.conf.sample for description of the parsed format. */
+
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename and the conf structure as parameter */
+%parse-param {char * conffile}
+%parse-param {struct rgwp_config *cs}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "rgwx_echodrop.h"
+#include "rgwx_echodrop.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+
+/* Forward declaration */
+int yyparse(char * conffile, struct rgwp_config *cs);
+
+/* The Lex parser prototype */
+int rgwx_echodroplex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+
+/* Parse the configuration file */
+int ed_conffile_parse(char * conffile, struct rgwp_config *cs)
+{
+ extern FILE * rgwx_echodropin;
+ int ret;
+
+ rgwx_echodropin = fopen(conffile, "r");
+ if ((rgwx_echodropin == NULL) && (*conffile != '/')) { /* We received a relative path, try adding DEFAULT_CONF_PATH prefix */
+ char * fullpath;
+ CHECK_MALLOC( fullpath = malloc( strlen(conffile) + strlen(DEFAULT_CONF_PATH) + 2 ) );
+ sprintf( fullpath, DEFAULT_CONF_PATH "/%s", conffile );
+ rgwx_echodropin = fopen(fullpath, "r");
+ free(fullpath);
+ }
+ if (rgwx_echodropin == NULL) {
+ ret = errno;
+ fd_log_debug("[echodrop.rgwx] Unable to open plugin configuration file %s for reading: %s", conffile, strerror(ret));
+ return ret;
+ }
+
+ ret = rgwx_echodropparse(conffile, cs);
+
+ fclose(rgwx_echodropin);
+
+ if (ret != 0) {
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, struct rgwp_config *cs, char const *s)
+{
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+static struct {
+ struct {
+ unsigned vendor :1;
+ unsigned tlv :1;
+ unsigned ext :1;
+ };
+ uint8_t type;
+ uint16_t extype;
+ uint32_t vendor_id;
+} attrinfo;
+
+
+%}
+
+/* Values returned by lex for tokens */
+%union {
+ unsigned integer; /* Value */
+}
+
+/* typed data */
+%token <integer> INTEGER
+%type <integer> action
+
+/* simple tokens */
+%token TOK_ECHO
+%token TOK_DROP
+%token TOK_CODE
+%token TOK_VENDOR
+%token TOK_TLV
+%token TOK_EXT
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK */
+ | conffile attrdef
+ ;
+
+ /* An attribute line */
+attrdef: {
+ memset(&attrinfo, 0, sizeof(attrinfo));
+ }
+ action TOK_CODE INTEGER vendordef ';'
+ {
+ struct ed_conf_attribute * new;
+ struct fd_list * li;
+
+ if ($4 >= 256) {
+ yyerror (&yylloc, conffile, cs, "Too big value for attribute CODE");
+ YYERROR;
+ }
+
+ /* Create a new list item */
+ CHECK_MALLOC_DO( new = malloc(sizeof(struct ed_conf_attribute)),
+ {
+ yyerror (&yylloc, conffile, cs, "Memory allocation error");
+ YYERROR;
+ } );
+ memset(new, 0, sizeof(struct ed_conf_attribute));
+
+ fd_list_init(&new->chain, NULL);
+
+ new->action = $2;
+ new->vsa = attrinfo.vendor;
+ new->tlv = attrinfo.tlv;
+ new->ext = attrinfo.ext;
+
+ if (new->vsa)
+ new->vendor_id = attrinfo.vendor_id;
+ if (new->tlv)
+ new->type = attrinfo.type;
+ if (new->ext)
+ new->extype = attrinfo.extype;
+
+ new->code = $4;
+
+ /* Now place this attribute in the list */
+ for (li = cs->attributes.next; li != &cs->attributes; li = li->next) {
+ struct ed_conf_attribute *eca = (struct ed_conf_attribute *)li;
+ /* Order first by attribute code */
+ if (eca->code > new->code)
+ break;
+ if (eca->code < new->code)
+ continue;
+
+ /* Then by VSA flag */
+ if (! new->vsa)
+ break;
+ if (! eca->vsa)
+ continue;
+
+ /* Then by vendor value */
+ if (eca->vendor_id >= new->vendor_id)
+ break;
+ }
+
+ fd_list_insert_before(li, &new->chain);
+ }
+ ;
+
+ /* What to do with the specified attribute */
+action: TOK_ECHO
+ {
+ $$ = ACT_ECHO;
+ }
+ |
+ TOK_DROP
+ {
+ $$ = ACT_DROP;
+ }
+ ;
+
+ /* Vendor specifics, if any */
+vendordef: /* empty OK */
+ | TOK_VENDOR INTEGER specif
+ {
+ attrinfo.vendor_id = $2;
+ attrinfo.vendor = 1;
+ }
+ ;
+
+ /* Any additional specification ? */
+specif: /* empty OK */
+ | TOK_TLV INTEGER
+ {
+ if ($2 >= (1 << 8)) {
+ yyerror (&yylloc, conffile, cs, "Too big value for TLV type");
+ YYERROR;
+ }
+ attrinfo.type = $2;
+ attrinfo.tlv = 1;
+ }
+ | TOK_EXT INTEGER
+ {
+ if ($2 >= (1 << 16)) {
+ yyerror (&yylloc, conffile, cs, "Too big value for Ext-Type");
+ YYERROR;
+ }
+ attrinfo.extype = $2;
+ attrinfo.ext = 1;
+ yyerror (&yylloc, conffile, cs, "The EXT option is not supported in this version.");
+ YYERROR;
+ }
+ ;
+
diff --git a/extensions/app_radgw/rgwx_sample.c b/extensions/app_radgw/rgwx_sample.c
new file mode 100644
index 0000000..4e2cd03
--- /dev/null
+++ b/extensions/app_radgw/rgwx_sample.c
@@ -0,0 +1,97 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Sample radius/diameter gateway plugin, for developers to see the structure of a plugin. */
+
+#include "rgw_common.h"
+
+/* The state of this extension */
+struct rgwp_config {
+ /* In a real extension, we would store the parsed configuration file, and the states of the extension */
+ int init;
+
+ /* If needed to store information between sent Diameter request and received answer, the session is probably the best place.
+ See rgwx_echodrop for an example. */
+};
+
+/* The function called at plugin initialization */
+static int sample_conf_parse ( char * conf_file, struct rgwp_config ** state )
+{
+ TRACE_ENTRY("%p %p", conf_file, state);
+ CHECK_PARAMS(state);
+
+ CHECK_MALLOC( *state = malloc(sizeof(struct rgwp_config)) );
+
+ (*state)->init = 1;
+
+ return 0;
+}
+
+/* This function is called when the plugin is unloaded, to cleanup all the states */
+static void sample_conf_free(struct rgwp_config * state)
+{
+ TRACE_ENTRY("%p", state);
+ CHECK_PARAMS_DO( state, );
+ free(state);
+ return;
+}
+
+/* This function is called on incoming RADIUS messages. It should handle (some) RADIUS data and store into the Diameter message. */
+static int sample_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+{
+ TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
+ CHECK_PARAMS(cs);
+ TRACE_DEBUG(INFO, "RADIUS/Diameter Sample plugin received a new RADIUS message.");
+ return 0;
+}
+
+/* This function is called when a Diameter answer is coming back. It should remove the AVPs and add the attributes in the RADIUS message. */
+static int sample_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
+{
+ TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
+ CHECK_PARAMS(cs);
+ TRACE_DEBUG(INFO, "RADIUS/Diameter Sample plugin received a new Diameter answer.");
+ return 0;
+}
+
+
+/* Finally, we declare the structure that will be loaded by main RADIUS/Diameter gateway extension */
+struct rgw_api rgwp_descriptor = {
+ .rgwp_name = "sample",
+ .rgwp_conf_parse = sample_conf_parse,
+ .rgwp_conf_free = sample_conf_free,
+ .rgwp_rad_req = sample_rad_req,
+ .rgwp_diam_ans = sample_diam_ans
+};
diff --git a/extensions/app_radgw/rgwx_sip.c b/extensions/app_radgw/rgwx_sip.c
new file mode 100644
index 0000000..b4fd91e
--- /dev/null
+++ b/extensions/app_radgw/rgwx_sip.c
@@ -0,0 +1,855 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* * *
+* Copyright (c) 2013, WIDE Project and NICT *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. *
+* *
+* All rights reserved. *
+* Based on rgwx_auth plugin (Sebastien Decugis <sdecugis@freediameter.net>) *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+
+/* RADIUS Access-Request messages translation plugin */
+
+#include "rgw_common.h"
+#include <string.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Other constants we use */
+#define AI_SIP 6 /* Diameter SIP application */
+#define CC_MULTIMEDIA_AUTH_REQUEST 286 /* MAR */
+#define CC_MULTIMEDIA_AUTH_ANSWER 286 /* MAA */
+#define ACV_ASS_STATE_MAINTAINED 0 /* STATE_MAINTAINED */
+#define ACV_ASS_NO_STATE_MAINTAINED 1 /* NO_STATE_MAINTAINED */
+#define ER_DIAMETER_SUCCESS_AUTH_SENT_SERVER_NOT_STORED 2008
+#define ER_DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED 2006
+
+
+
+/* This macro converts a RADIUS attribute to a Diameter AVP of type OctetString */
+#define CONV2DIAM_STR( _dictobj_ ) \
+ CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) ); \
+ /* Create the AVP with the specified dictionary model */ \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ value.os.len = attr->length - sizeof(struct radius_attr_hdr); \
+ value.os.data = (os0_t)(attr + 1); \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ /* Add the AVP in the Diameter message. */ \
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); \
+
+#define CONV2DIAM_STR_AUTH( _dictobj_ ) \
+ CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) ); \
+ /* Create the AVP with the specified dictionary model */ \
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ value.os.len = attr->length - sizeof(struct radius_attr_hdr); \
+ value.os.data = (os0_t)(attr + 1); \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ /* Add the AVP in the Diameter message. */ \
+ CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) ); \
+
+/* Same thing, for scalar AVPs of 32 bits */
+#define CONV2DIAM_32B( _dictobj_ ) \
+ CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint32_t) );\
+ CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \
+ { \
+ uint8_t * v = (uint8_t *)(attr + 1); \
+ value.u32 = (v[0] << 24) \
+ | (v[1] << 16) \
+ | (v[2] << 8) \
+ | v[3] ; \
+ } \
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); \
+
+
+
+
+
+/* The state we keep for this plugin */
+struct rgwp_config {
+ struct {
+ struct dict_object * Session_Id;
+ struct dict_object * Auth_Application_Id;
+ struct dict_object * Auth_Session_State;
+ struct dict_object * Origin_Host;
+ struct dict_object * Origin_Realm;
+ struct dict_object * Destination_Realm;
+ struct dict_object * SIP_AOR;
+ struct dict_object * SIP_Method;
+ struct dict_object * Destination_Host;
+ struct dict_object * User_Name;
+ struct dict_object * SIP_Server_URI;
+ struct dict_object * SIP_Number_Auth_Items;
+ struct dict_object * SIP_Authorization;
+ struct dict_object * SIP_Authentication_Scheme;
+ struct dict_object * SIP_Authentication_Info;
+ struct dict_object * SIP_Auth_Data_Item;
+ struct dict_object * Proxy_Info;
+ struct dict_object * Route_Record;
+ struct dict_object * Service_Type;
+ struct dict_object * Result_Code;
+ struct dict_object * Digest_URI;
+ struct dict_object * Digest_Nonce;
+ struct dict_object * Digest_CNonce;
+ struct dict_object * Digest_Nonce_Count;
+ struct dict_object * Digest_Realm;
+ struct dict_object * Digest_Response;
+ struct dict_object * Digest_Method;
+ struct dict_object * Digest_Response_Auth;
+ struct dict_object * Digest_Username;
+ struct dict_object * Digest_Algorithm;
+ struct dict_object * Digest_QOP;
+
+
+
+ } dict; /* cache of the dictionary objects we use */
+ char * confstr;
+ //Chained list of nonce
+ struct fd_list listnonce;
+ //This will be used to lock access to chained list
+ pthread_mutex_t nonce_mutex;
+};
+
+typedef struct noncechain noncechain;
+struct noncechain
+{
+ struct fd_list chain;
+ os0_t sid;
+ size_t sidlen;
+ os0_t nonce;
+ size_t noncelen;
+
+};
+
+static int nonce_add_element(os0_t nonce, size_t noncelen, os0_t sid, size_t sidlen, struct rgwp_config * state)
+{
+ CHECK_PARAMS(nonce && state && sid && sidlen && noncelen);
+
+ noncechain *newelt;
+ CHECK_MALLOC(newelt=malloc(sizeof(noncechain)));
+
+ CHECK_MALLOC(newelt->nonce= os0dup(nonce, noncelen));
+ newelt->noncelen=noncelen;
+
+ CHECK_MALLOC(newelt->sid=os0dup(sid, sidlen));
+ newelt->sidlen=sidlen;
+
+ fd_list_init(&newelt->chain,NULL);
+
+ CHECK_POSIX(pthread_mutex_lock(&state->nonce_mutex));
+ fd_list_insert_before(&state->listnonce,&newelt->chain);
+ CHECK_POSIX(pthread_mutex_unlock(&state->nonce_mutex));
+
+ return 0;
+}
+/*
+static void nonce_del_element(char * nonce, struct rgwp_config *state)
+{
+ struct fd_list * li;
+
+ CHECK_PARAMS_DO(nonce && state, return);
+
+ for(li=state->listnonce.next;li!=&state->listnonce;li=li->next)
+ {
+ noncechain *temp=(noncechain *)li;
+
+ if(strcmp(temp->nonce,nonce)==0)
+ {
+ fd_list_unlink (li);
+ free(temp->sid);
+ free(temp->nonce);
+ free(temp);
+ break;
+ }
+ }
+}
+*/
+//Retrieve sid from nonce
+static os0_t nonce_get_sid(os0_t nonce, size_t noncelen, size_t * sidlen, struct rgwp_config *state)
+{
+ struct fd_list * li;
+ os0_t sid=NULL;
+
+ CHECK_PARAMS_DO(nonce && state && noncelen && sidlen, return NULL);
+ *sidlen=0;
+
+ // **Start mutex
+ CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),);
+ for(li=state->listnonce.next;li!=&state->listnonce;li=li->next)
+ {
+ noncechain *temp=(noncechain *)li;
+
+ if (!fd_os_cmp(temp->nonce, temp->noncelen, nonce, noncelen))
+ {
+ fd_list_unlink (li);
+ sid=temp->sid;
+ *sidlen=temp->sidlen;
+ free(temp->nonce);
+ free(temp);
+ break;
+ }
+
+ }
+ CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),);
+ // ***Stop mutex
+ return sid;
+}
+
+static void nonce_deletelistnonce(struct rgwp_config *state)
+{
+ // **Start mutex
+ CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),);
+ while(!(FD_IS_LIST_EMPTY(&state->listnonce)) )
+ {
+ noncechain *temp=(noncechain *)state->listnonce.next;
+
+ fd_list_unlink (&temp->chain);
+ free(temp->sid);
+ free(temp->nonce);
+ free(temp);
+
+ }
+ CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),);
+ // ***Stop mutex
+}
+
+/* Initialize the plugin */
+static int sip_conf_parse(char * conffile, struct rgwp_config ** state)
+{
+ struct rgwp_config * new;
+ struct dict_object * app;
+
+
+ TRACE_ENTRY("%p %p", conffile, state);
+ CHECK_PARAMS( state );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct rgwp_config)) );
+ memset(new, 0, sizeof(struct rgwp_config));
+
+ new->confstr = conffile;
+
+ /* Resolve all dictionary objects we use */
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &new->dict.Session_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &new->dict.Auth_Application_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Session-State", &new->dict.Auth_Session_State, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &new->dict.Origin_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &new->dict.Origin_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &new->dict.Destination_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-AOR", &new->dict.SIP_AOR, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Method", &new->dict.SIP_Method, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &new->dict.Destination_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &new->dict.User_Name, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-URI", &new->dict.SIP_Server_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Number-Auth-Items", &new->dict.SIP_Number_Auth_Items, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authorization", &new->dict.SIP_Authorization, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Auth-Data-Item", &new->dict.SIP_Auth_Data_Item, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Scheme", &new->dict.SIP_Authentication_Scheme, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Info", &new->dict.SIP_Authentication_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Proxy-Info", &new->dict.Proxy_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Route-Record", &new->dict.Route_Record, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &new->dict.Result_Code, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-URI", &new->dict.Digest_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce", &new->dict.Digest_Nonce, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Method", &new->dict.Digest_Method, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-CNonce", &new->dict.Digest_CNonce, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce-Count", &new->dict.Digest_Nonce_Count, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Realm", &new->dict.Digest_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Response", &new->dict.Digest_Response, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Response-Auth", &new->dict.Digest_Response_Auth, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Username", &new->dict.Digest_Username, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Algorithm", &new->dict.Digest_Algorithm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-QoP", &new->dict.Digest_QOP, ENOENT) );
+
+
+
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Session Initiation Protocol (SIP) Application", &app, ENOENT) );
+ CHECK_FCT( fd_disp_app_support ( app, NULL, 1, 0 ) );
+
+ //chained list
+ fd_list_init(&new->listnonce,NULL);
+ CHECK_POSIX(pthread_mutex_init(&new->nonce_mutex,NULL));
+
+ *state = new;
+ return 0;
+}
+
+/* deinitialize */
+static void sip_conf_free(struct rgwp_config * state)
+{
+ TRACE_ENTRY("%p", state);
+ CHECK_PARAMS_DO( state, return );
+
+ nonce_deletelistnonce(state);
+ CHECK_POSIX_DO(pthread_mutex_destroy(&state->nonce_mutex), /*continue*/);
+
+ free(state);
+ return;
+}
+
+/* Handle an incoming RADIUS request */
+static int sip_rad_req( struct rgwp_config * cs, struct radius_msg * rad_req, struct radius_msg ** rad_ans, struct msg ** diam_fw, struct rgw_client * cli )
+{
+ int idx;
+ int got_AOR = 0;
+ int got_Dusername = 0;
+ int got_Drealm = 0;
+ int got_Duri = 0;
+ int got_Dmethod = 0;
+ int got_Dnonce = 0;
+ int got_Dresponse = 0;
+ int got_Dalgorithm = 0;
+ os0_t sid = NULL;
+ size_t sidlen;
+ os0_t un=NULL;
+ size_t un_len;
+ size_t nattr_used = 0;
+ struct avp *auth_data=NULL, *auth=NULL, *avp = NULL;
+ union avp_value value;
+ struct session * sess;
+
+ TRACE_ENTRY("%p %p %p %p %p", cs, rad_req, rad_ans, diam_fw, cli);
+
+ CHECK_PARAMS(rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCESS_REQUEST) && rad_ans && diam_fw && *diam_fw);
+
+ /*
+ RFC5090 RADIUS Extension Digest Application
+ */
+ CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_fw, &sess, NULL) );
+ if (sess != NULL) {
+ TRACE_DEBUG(INFO,"INTERNAL ERROR: We are not supposed to receive a session in radSIP plugin.");
+ return EINVAL;
+ }
+
+ /* Check basic information is there */
+ for (idx = 0; idx < rad_req->attr_used; idx++) {
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(rad_req->buf + rad_req->attr_pos[idx]);
+
+
+ switch (attr->type) {
+
+ case RADIUS_ATTR_USER_NAME:
+ if (attr->length>sizeof(struct radius_attr_hdr))
+ {
+ TRACE_DEBUG(ANNOYING, "Found a User-Name attribute: '%.*s'", (int)(attr->length- sizeof(struct radius_attr_hdr)), (char *)(attr+1));
+ un = (os0_t)(attr + 1);
+ un_len =attr->length - sizeof(struct radius_attr_hdr);
+ }
+ break;
+ case RADIUS_ATTR_DIGEST_USERNAME:
+ got_Dusername = 1;
+ break;
+ case RADIUS_ATTR_DIGEST_REALM:
+ got_Drealm = 1;
+ break;
+ case RADIUS_ATTR_DIGEST_URI:
+ got_Duri = 1;
+ break;
+ case RADIUS_ATTR_DIGEST_METHOD:
+ got_Dmethod = 1;
+ break;
+ // case RADIUS_ATTR_DIGEST_QOP:
+ // got_Dqop = 1;
+ // break;
+ // case RADIUS_ATTR_DIGEST_NONCE_COUNT:
+ // got_Dnonce_count = 1;
+ // break;
+ case RADIUS_ATTR_DIGEST_NONCE:
+ got_Dnonce = 1;
+
+ sid=nonce_get_sid((os0_t)(attr+1), attr->length - sizeof(struct radius_attr_hdr), &sidlen, cs);
+ if(!sid)
+ {
+ TRACE_DEBUG(INFO,"We haven't found the session.'");
+ return EINVAL;
+ }
+ CHECK_FCT(fd_sess_fromsid_msg (sid, sidlen, &sess, NULL));
+ free(sid);
+
+
+ break;
+ // case RADIUS_ATTR_DIGEST_CNONCE:
+ // got_Dcnonce = 1;
+ // break;
+ case RADIUS_ATTR_DIGEST_RESPONSE:
+ got_Dresponse = 1;
+ break;
+ case RADIUS_ATTR_DIGEST_ALGORITHM:
+ got_Dalgorithm = 1;
+ break;
+ case RADIUS_ATTR_SIP_AOR:
+ got_AOR = 1;
+ break;
+ }
+ }
+ if(!un)
+ {
+ TRACE_DEBUG(INFO,"No Username in request");
+ return EINVAL;
+ }
+
+ /* Create the session if it is not already done */
+ if (!sess) {
+
+ DiamId_t fqdn;
+ size_t fqdn_len;
+ DiamId_t realm;
+ size_t realm_len;
+
+ /* Get information on the RADIUS client */
+ CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &fqdn_len, &realm, &realm_len) );
+
+ /* Create a new Session-Id. The format is: {fqdn;hi32;lo32;username;diamid} */
+ CHECK_MALLOC( sid = malloc(un_len + 1 /* ';' */ + fd_g_config->cnf_diamid_len + 1 /* '\0' */) );
+ sidlen = sprintf((char *)sid, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
+ CHECK_FCT( fd_sess_new(&sess, fqdn, fqdn_len, sid, sidlen) );
+ free(sid);
+ }
+
+ /* Now, add the Session-Id AVP at beginning of Diameter message */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
+ value.os.data = sid;
+ value.os.len = sidlen;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
+
+ TRACE_DEBUG(FULL, "[sip.rgwx] Translating new message for session '%s'...", sid);
+
+ /* Now add this session in the message */
+ CHECK_FCT( fd_msg_sess_set(*diam_fw, sess) );
+
+ /* Add the Destination-Realm AVP */
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Destination_Realm, 0, &avp ) );
+
+ int i = 0;
+
+ /* Is there an '@' in the user name? We don't care for decorated NAI here */
+ for (i = un_len - 2; i > 0; i--) {
+ if (un[i] == '@') {
+ i++;
+ break;
+ }
+ }
+
+ if (i == 0) {
+ /* Not found in the User-Name => we use the local domain of this gateway */
+ value.os.data = (os0_t)fd_g_config->cnf_diamrlm;
+ value.os.len = fd_g_config->cnf_diamrlm_len;
+ } else {
+ value.os.data = un + i;
+ value.os.len = un_len - i;
+ }
+
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+
+ /*
+ If the RADIUS Access-Request message does not
+ contain any Digest-* attribute, then the RADIUS client does not want
+ to apply HTTP Digest authentication, in which case, actions at the
+ gateway are outside the scope of this document.
+ */
+
+ if(!(got_Dmethod && got_Duri))
+ {
+ TRACE_DEBUG(INFO,"No Digest attributes in request, we drop it...");
+ return 1;
+ }
+
+ /* Add the appropriate command code & Auth-Application-Id */
+ {
+ struct msg_hdr * header = NULL;
+ CHECK_FCT( fd_msg_hdr ( *diam_fw, &header ) );
+ header->msg_flags = CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE;
+ header->msg_code = CC_MULTIMEDIA_AUTH_REQUEST;
+ header->msg_appl = AI_SIP;
+
+
+ /* Add the Auth-Application-Id */
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = header->msg_appl;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+ }
+ /*Add Auth_Session_State AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Auth_Session_State, 0, &avp ) );
+ value.i32 = ACV_ASS_NO_STATE_MAINTAINED;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+
+ /*Add SIP_Number_Auth_Items AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Number_Auth_Items, 0, &avp ) );
+ value.i32 = 1; //We just treat one auth per request in gateway
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ /* Add SIP_Auth_Data_Item AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Auth_Data_Item, 0, &auth_data ) );
+ }
+ /* Add SIP_Authentication_Scheme AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Authentication_Scheme, 0, &avp ) );
+ value.i32=0; //There is only Digest Auth in RFC for now
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( auth_data, MSG_BRW_LAST_CHILD, avp) );
+
+ }
+
+
+ /* Add SIP_Authorization AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Authorization, 0, &auth ) );
+ CHECK_FCT( fd_msg_avp_add ( auth_data, MSG_BRW_LAST_CHILD, auth) );
+ }
+
+ for (idx = 0; idx < rad_req->attr_used; idx++)
+ {
+ struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(rad_req->buf + rad_req->attr_pos[idx]);
+
+ switch (attr->type) {
+
+ case RADIUS_ATTR_USER_NAME:
+ CONV2DIAM_STR( User_Name );
+
+ if(!got_Dusername)
+ {
+ CONV2DIAM_STR_AUTH(Digest_Username);
+ got_Dusername=1;
+ }
+
+ break;
+
+ case RADIUS_ATTR_DIGEST_URI:
+
+ CONV2DIAM_STR_AUTH(Digest_URI);
+
+ //All of these attributes are required by Diameter but not defined in RFC5090 so we provide FAKE values (only in first exchange)
+ if(!got_AOR)
+ {
+ CONV2DIAM_STR( SIP_AOR );
+ got_AOR=1;
+ }
+ /*
+ We must provide a fake nonce because of RFC4740 problem
+ TODO: remove when RFC is updated
+ ==START of FAKE
+ */
+ if(!got_Dresponse)
+ {
+ CONV2DIAM_STR_AUTH(Digest_Response);
+ got_Dresponse=1;
+ }
+ /*
+ ==END of FAKE
+ */
+ if(!got_Drealm)
+ {
+ //We extract Realm from Digest_URI
+ DiamId_t realm=NULL;
+ size_t realm_len = 0;
+ os0_t temp;
+
+ temp = (os0_t)(attr + 1);
+
+ for (i=attr->length - sizeof(struct radius_attr_hdr) - 1; i>=0; i--) {
+ if (temp[i] == '@') {
+ realm = (DiamId_t)temp + i + 1;
+ CHECK_FCT_DO( fd_os_validate_DiameterIdentity(&realm, &realm_len, 1),
+ realm = NULL );
+ break;
+ }
+ }
+
+ if(realm!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Realm, 0, &avp ) );
+ value.os.data=(os0_t)realm;
+ value.os.len=realm_len;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );
+
+ //We add SIP-Server-URI AVP because SIP server is registrar (through gateway)
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Server_URI, 0, &avp ) );
+ value.os.data=(os0_t)realm;
+ value.os.len=realm_len;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+
+ free(realm);
+ }
+ else
+ {
+ TRACE_DEBUG(INFO, "Can't extract domain from URI, droping request...");
+ return 1;
+ }
+ got_Drealm=1;
+ }
+ break;
+
+ case RADIUS_ATTR_DIGEST_METHOD:
+ CONV2DIAM_STR(SIP_Method);
+ CONV2DIAM_STR_AUTH(Digest_Method);
+ break;
+ case RADIUS_ATTR_DIGEST_REALM:
+ CONV2DIAM_STR_AUTH(Digest_Realm);
+
+ //We add SIP-Server-URI AVP because SIP server is registrar (through gateway)
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Server_URI, 0, &avp ) );
+ os0_t temp;
+ #define SIP_PREFIX "sip:"
+ size_t temp_len = attr->length - sizeof(struct radius_attr_hdr) + CONSTSTRLEN(SIP_PREFIX) + 1;
+ CHECK_MALLOC( temp = malloc(temp_len) );
+ temp_len = snprintf((char *)temp, temp_len, SIP_PREFIX "%.*s", (int)(attr->length - sizeof(struct radius_attr_hdr)), (char *)(attr + 1));
+
+ value.os.data=temp;
+ value.os.len=temp_len;
+
+ free(temp);
+
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
+ break;
+
+ case RADIUS_ATTR_DIGEST_USERNAME:
+ CONV2DIAM_STR_AUTH(Digest_Username);
+ break;
+
+ case RADIUS_ATTR_DIGEST_QOP:
+ CONV2DIAM_STR_AUTH( Digest_QOP );
+ break;
+ case RADIUS_ATTR_DIGEST_ALGORITHM:
+ CONV2DIAM_STR_AUTH( Digest_Algorithm );
+ break;
+ case RADIUS_ATTR_DIGEST_CNONCE:
+ CONV2DIAM_STR_AUTH( Digest_CNonce );
+ break;
+ case RADIUS_ATTR_DIGEST_NONCE:
+ CONV2DIAM_STR_AUTH( Digest_Nonce );
+ break;
+ case RADIUS_ATTR_DIGEST_NONCE_COUNT:
+ CONV2DIAM_STR_AUTH( Digest_Nonce_Count );
+ break;
+ case RADIUS_ATTR_DIGEST_RESPONSE:
+ CONV2DIAM_STR_AUTH( Digest_Response );
+ break;
+ case RADIUS_ATTR_SIP_AOR:
+ CONV2DIAM_STR( SIP_AOR );
+ break;
+
+ default:
+ if(!got_Dalgorithm)
+ {
+ //[Note 3] If Digest-Algorithm is missing, 'MD5' is assumed.
+ #define DIGEST_ALGO_MD5 "MD5"
+
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Algorithm, 0, &avp ) );
+
+ value.os.data = (os0_t)DIGEST_ALGO_MD5;
+ value.os.len = CONSTSTRLEN(DIGEST_ALGO_MD5) - 1;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );
+ got_Dalgorithm=1;
+ }
+
+ if(!got_Dnonce)
+ {
+ //We give a fake nonce because it will be calculated at the server.
+ CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Nonce, 0, &avp ) );
+ value.os.data=(unsigned char *)"nonce";
+ value.os.len=strlen((const char *)value.os.data);
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );
+ got_Dnonce=1;
+ }
+ break;
+
+ }
+ }
+
+
+ CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, auth_data) );
+
+ /* Update the radius message to remove all handled attributes */
+ rad_req->attr_used = nattr_used;
+
+ //fd_msg_dump_walk(1,*diam_fw);
+
+
+ return 0;
+}
+
+static int sip_diam_ans( struct rgwp_config * cs, struct msg ** diam_ans, struct radius_msg ** rad_fw, struct rgw_client * cli )
+{
+
+
+ struct avp *avp, *next;
+ struct avp_hdr *ahdr;
+ //char buf[254]; /* to store some attributes values (with final '\0') */
+ struct session * sess;
+ os0_t sid = NULL;
+ size_t sidlen;
+
+ TRACE_ENTRY("%p %p %p %p", cs, diam_ans, rad_fw, cli);
+ CHECK_PARAMS(cs && diam_ans && *diam_ans && rad_fw && *rad_fw);
+
+
+ /* MACROS to help in the process: convert AVP data to RADIUS attributes. */
+ /* Control large attributes: _trunc_ = 0 => error; _trunc_ = 1 => truncate; _trunc = 2 => create several attributes */
+ #define CONV2RAD_STR( _attr_, _data_, _len_, _trunc_) { \
+ size_t __l = (size_t)(_len_); \
+ size_t __off = 0; \
+ TRACE_DEBUG(FULL, "Converting AVP to "#_attr_); \
+ if ((_trunc_) == 0) { \
+ CHECK_PARAMS( __l <= 253 ); \
+ } \
+ if ((__l > 253) && (_trunc_ == 1)) { \
+ TRACE_DEBUG(INFO, "[authSIP.rgwx] AVP truncated in "#_attr_); \
+ __l = 253; \
+ } \
+ do { \
+ size_t __w = (__l > 253) ? 253 : __l; \
+ CHECK_MALLOC(radius_msg_add_attr(*rad_fw, (_attr_), (_data_) + __off, __w)); \
+ __off += __w; \
+ __l -= __w; \
+ } while (__l); \
+ }
+
+ #define CONV2RAD_32B( _attr_, _data_) { \
+ uint32_t __v = htonl((uint32_t)(_data_)); \
+ TRACE_DEBUG(FULL, "Converting AVP to "#_attr_); \
+ CHECK_MALLOC(radius_msg_add_attr(*rad_fw, (_attr_), (uint8_t *)&__v, sizeof(__v))); \
+ }
+
+ /* Search the different AVPs we handle here */
+ CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, *diam_ans, &sess, NULL) );
+ if (sess) {
+ CHECK_FCT( fd_sess_getsid(sess, &sid, &sidlen) );
+ }
+
+
+ /* Check the Diameter error code */
+ CHECK_FCT( fd_msg_search_avp (*diam_ans, cs->dict.Result_Code, &avp) );
+ ASSERT( avp ); /* otherwise the message should have been discarded a lot earlier because of ABNF */
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+ switch (ahdr->avp_value->u32) {
+ case ER_DIAMETER_MULTI_ROUND_AUTH:
+ case ER_DIAMETER_SUCCESS_AUTH_SENT_SERVER_NOT_STORED:
+ (*rad_fw)->hdr->code = RADIUS_CODE_ACCESS_CHALLENGE;
+ //struct timespec nowts;
+ //CHECK_SYS(clock_gettime(CLOCK_REALTIME, &nowts));
+ //nowts.tv_sec+=600;
+ //CHECK_FCT(fd_sess_settimeout(session, &nowts ));
+ break;
+ case ER_DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED:
+ case ER_DIAMETER_SUCCESS:
+ (*rad_fw)->hdr->code = RADIUS_CODE_ACCESS_ACCEPT;
+ // in_success=1;
+ break;
+
+ default:
+ (*rad_fw)->hdr->code = RADIUS_CODE_ACCESS_REJECT;
+ fd_log_debug("[sip.rgwx] Received Diameter answer with error code '%d', session %.*s, translating into Access-Reject",
+ ahdr->avp_value->u32, (int)sidlen, sid);
+ return 0;
+ }
+ /* Remove this Result-Code avp */
+ CHECK_FCT( fd_msg_free( avp ) );
+
+ /* Now loop in the list of AVPs and convert those that we know how */
+ CHECK_FCT( fd_msg_browse(*diam_ans, MSG_BRW_FIRST_CHILD, &next, NULL) );
+
+ while (next) {
+ int handled = 1;
+ avp = next;
+ CHECK_FCT( fd_msg_browse(avp, MSG_BRW_WALK, &next, NULL) );
+
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+
+ if (!(ahdr->avp_flags & AVP_FLAG_VENDOR)) {
+ switch (ahdr->avp_code) {
+
+
+ case DIAM_ATTR_DIGEST_NONCE:
+ CONV2RAD_STR(DIAM_ATTR_DIGEST_NONCE, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
+ nonce_add_element(ahdr->avp_value->os.data, ahdr->avp_value->os.len, sid, sidlen, cs);
+ break;
+ case DIAM_ATTR_DIGEST_REALM:
+ CONV2RAD_STR(DIAM_ATTR_DIGEST_REALM, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+ case DIAM_ATTR_DIGEST_QOP:
+ CONV2RAD_STR(DIAM_ATTR_DIGEST_QOP, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+ case DIAM_ATTR_DIGEST_ALGORITHM:
+ CONV2RAD_STR(DIAM_ATTR_DIGEST_ALGORITHM, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 1);
+ break;
+ case DIAM_ATTR_DIGEST_RESPONSE_AUTH:
+ CONV2RAD_STR(DIAM_ATTR_DIGEST_RESPONSE_AUTH, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0);
+ break;
+ default:
+ handled=0;
+ break;
+ }
+ }
+ else
+ {
+ /* Vendor-specific AVPs */
+ switch (ahdr->avp_vendor) {
+
+ default: /* unknown vendor */
+ handled = 0;
+ }
+ }
+ if (handled) {
+ CHECK_FCT( fd_msg_free( avp ) );
+ }
+ }
+
+ return 0;
+}
+
+/* The exported symbol */
+struct rgw_api rgwp_descriptor = {
+ .rgwp_name = "sip",
+ .rgwp_conf_parse = sip_conf_parse,
+ .rgwp_conf_free = sip_conf_free,
+ .rgwp_rad_req = sip_rad_req,
+ .rgwp_diam_ans = sip_diam_ans
+};
+
diff --git a/extensions/app_redirect/CMakeLists.txt b/extensions/app_redirect/CMakeLists.txt
new file mode 100644
index 0000000..3b61915
--- /dev/null
+++ b/extensions/app_redirect/CMakeLists.txt
@@ -0,0 +1,42 @@
+# The app_redirect extension
+PROJECT("Configurable Redirects server extension" C)
+
+# Check if REG_STARTEND is provided on the host
+SET(CHECK_REG_STARTEND_SOURCE_CODE "
+ #include <unistd.h>
+ #include <regex.h>
+ int main() {
+ return regexec(NULL, NULL, 0, NULL, REG_STARTEND);
+ }
+ ")
+CHECK_C_SOURCE_COMPILES("${CHECK_REG_STARTEND_SOURCE_CODE}" HAVE_REG_STARTEND)
+# Generate the host.h file
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/ard-host.h.in ${CMAKE_CURRENT_BINARY_DIR}/ard-host.h)
+
+# Parser files
+BISON_FILE(ard_conf.y)
+FLEX_FILE(ard_conf.l)
+SET_SOURCE_FILES_PROPERTIES(lex.ard_conf.c ard_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( APP_REDIR_SRC
+ app_redir.c
+ app_redir.h
+ lex.ard_conf.c
+ ard_conf.tab.c
+ ard_conf.tab.h
+ ard_rules.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(app_redirect ${APP_REDIR_SRC})
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS app_redirect
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-app_redirect)
diff --git a/extensions/app_redirect/app_redir.c b/extensions/app_redirect/app_redir.c
new file mode 100644
index 0000000..d199687
--- /dev/null
+++ b/extensions/app_redirect/app_redir.c
@@ -0,0 +1,100 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * Configurable routing of messages for freeDiameter.
+ */
+
+#include "app_redir.h"
+
+static struct fd_rt_fwd_hdl * ard_fwd_cb = NULL;
+
+/* entry point */
+static int ard_entry(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* Parse the configuration file */
+ CHECK_FCT( ard_conf_handle(conffile) );
+
+ /* Resolve the dictionary objects we use */
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host", &avp_Redirect_Host, ENOENT ));
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host-Usage", &avp_Redirect_Host_Usage, ENOENT ));
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Max-Cache-Time", &avp_Redirect_Max_Cache_Time, ENOENT ));
+
+ /* Register the proxy callback */
+ CHECK_FCT( fd_rt_fwd_register(ard_rule_apply, NULL, RT_FWD_REQ, &ard_fwd_cb) );
+
+ /* We're done */
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+
+ /* Unregister the proxy callback */
+ if (ard_fwd_cb) {
+ CHECK_FCT_DO( fd_rt_fwd_unregister(ard_fwd_cb, NULL), );
+ }
+
+ /* Destroy all rules */
+ while (!FD_IS_LIST_EMPTY(&ard_conf->rules)) {
+ struct ard_rule * r = ard_conf->rules.next->o;
+ fd_list_unlink(&r->chain);
+ while (!FD_IS_LIST_EMPTY(&r->criteria)) {
+ struct ard_criteria * c = r->criteria.next->o;
+ fd_list_unlink(&c->chain);
+ if (c->is_regex) {
+ regfree(&c->preg);
+ }
+ free(c->s);
+ free(c);
+ }
+ while (!FD_IS_LIST_EMPTY(&r->targets)) {
+ struct ard_target * t = r->targets.next->o;
+ fd_list_unlink(&t->chain);
+ free(t->s);
+ free(t);
+ }
+ free(r);
+ }
+
+ /* Done */
+ return ;
+}
+
+EXTENSION_ENTRY("app_redirect", ard_entry);
diff --git a/extensions/app_redirect/app_redir.h b/extensions/app_redirect/app_redir.h
new file mode 100644
index 0000000..732c33d
--- /dev/null
+++ b/extensions/app_redirect/app_redir.h
@@ -0,0 +1,121 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Header file for the app_redirect extension.
+ *
+ * See the app_redirect.conf.sample file for the format of the configuration file.
+ */
+
+/* FreeDiameter's common include file */
+#include <freeDiameter/extension.h>
+
+/* Host configuration for this specific extension */
+#include <ard-host.h>
+#include <regex.h>
+
+/* Extension's configuration */
+struct ard_config {
+ uint32_t default_rct; /* redirect-cache-time to use unless overwritten by a rule */
+ struct fd_list rules; /* the list of rules in the order they appear in the conf file. */
+};
+extern struct ard_config * ard_conf; /* initialized in ard_conf.y */
+
+/* The types of redirects (from Redirect-Host-Usage AVP value) */
+enum redir_h_u {
+ DONT_CACHE = 0,
+ ALL_SESSION,
+ ALL_REALM,
+ REALM_AND_APPLICATION,
+ ALL_APPLICATION,
+ ALL_HOST,
+ ALL_USER
+};
+#define H_U_MAX ALL_USER
+
+/* A rule */
+struct ard_rule {
+ struct fd_list chain; /* link in configuration */
+
+ enum redir_h_u type; /* What kind of rule is this? */
+ uint32_t rct; /* overwrite default_rct is not 0 */
+
+ struct fd_list criteria; /* list of criteria to match. The rule is applied if all criteria match */
+
+ struct fd_list targets; /* list of Redirect-Host values to send. */
+};
+
+/* What kind of criteria exist */
+enum rule_criteria { /* note: the order of the values reflects the complexity of matching -- it should be kept this way */
+ APP_ID,
+ FROM_ID,
+ FROM_REALM,
+ AVP_INT,
+ AVP_STR
+};
+
+/* A criteria in the list */
+struct ard_criteria {
+ struct fd_list chain; /* link in ard_rule->criteria */
+ enum rule_criteria type; /* What is this rule */
+
+ /* the data that must be matched -- everything is not used by all criteria types */
+ char * s;
+ size_t sl;
+ int is_regex;
+ regex_t preg;
+ uint32_t i;
+ struct dict_avp_data avp_info;
+};
+
+/* A target entry in the ard_rule->targets list */
+struct ard_target {
+ struct fd_list chain;
+ os0_t s; /* must be freed afterwards */
+ size_t l;
+};
+
+/* The AVPs we use */
+extern struct dict_object * avp_Redirect_Host;
+extern struct dict_object * avp_Redirect_Host_Usage;
+extern struct dict_object * avp_Redirect_Max_Cache_Time;
+
+/* Parse the configuration file */
+int ard_conf_handle(char * conffile);
+
+/* Dump a rule (debug) */
+void ard_rule_dump(struct ard_rule * r);
+
+/* Check if a rule applies, and if found, create the reply */
+int ard_rule_apply(void * cbdata, struct msg ** msg);
diff --git a/extensions/app_redirect/ard-host.h.in b/extensions/app_redirect/ard-host.h.in
new file mode 100644
index 0000000..34e05a5
--- /dev/null
+++ b/extensions/app_redirect/ard-host.h.in
@@ -0,0 +1,42 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Configuration from compile-time */
+#ifndef RTD_IS_CONFIG
+#define RTD_IS_CONFIG
+
+#cmakedefine HAVE_REG_STARTEND
+
+#endif /* RTD_IS_CONFIG */
diff --git a/extensions/app_redirect/ard_conf.l b/extensions/app_redirect/ard_conf.l
new file mode 100644
index 0000000..0c39949
--- /dev/null
+++ b/extensions/app_redirect/ard_conf.l
@@ -0,0 +1,140 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Tokenizer
+ *
+ */
+
+%{
+#include "app_redir.h"
+/* Include yacc tokens definitions */
+#include "ard_conf.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+qstring \"[^\"\n]*\"
+
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+ /* Recognize any integer */
+[[:digit:]]+ {
+ /* Convert this to an u32 value */
+ int ret=0;
+ ret = sscanf(yytext, "%u", &yylval->u32);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return TOK_LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return TOK_U32VAL;
+ }
+
+ /* Recognize bracketed quoted strings */
+[[]{qstring}[]] {
+ /* Match a quoted string containing a regex */
+ CHECK_MALLOC_DO( yylval->tstring.str = strdup(yytext+2),
+ {
+ TRACE_DEBUG(INFO, "Unable to copy the string '%s': %s", yytext, strerror(errno));
+ return TOK_LEX_ERROR; /* trig an error in yacc parser */
+ } );
+ yylval->tstring.str[strlen(yytext) - 4] = '\0';
+ yylval->tstring.regex = 1;
+ return TOK_TSTRING;
+ }
+
+ /* Recognize quoted strings (since it comes after the previous rule, the string should not be quoted) */
+{qstring} {
+ /* Match a quoted string. */
+ CHECK_MALLOC_DO( yylval->tstring.str = strdup(yytext+1),
+ {
+ TRACE_DEBUG(INFO, "Unable to copy the string '%s': %s", yytext, strerror(errno));
+ return TOK_LEX_ERROR; /* trig an error in yacc parser */
+ } );
+ yylval->tstring.str[strlen(yytext) - 2] = '\0';
+ yylval->tstring.regex = 0;
+ return TOK_TSTRING;
+ }
+
+ /* The key words */
+(?i:"default_redirect_cache_time") { return TOK_DEFAULT_RCT; }
+(?i:"to") { return TOK_TO; }
+(?i:"DONT_CACHE") { return TOK_DONT_CACHE; }
+(?i:"ALL_SESSION") { return TOK_ALL_SESSION; }
+(?i:"ALL_REALM") { return TOK_ALL_REALM; }
+(?i:"REALM_AND_APPLICATION") { return TOK_REALM_AND_APPLICATION; }
+(?i:"ALL_APPLICATION") { return TOK_ALL_APPLICATION; }
+(?i:"ALL_HOST") { return TOK_ALL_HOST; }
+(?i:"ALL_USER") { return TOK_ALL_USER; }
+(?i:"from.id") { return TOK_FROM_ID; }
+(?i:"from.realm") { return TOK_FROM_REALM; }
+(?i:"app") { return TOK_APP; }
+
+ /* Valid single characters for yyparse */
+[:=;] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]\":=;\n]+ {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return TOK_LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/app_redirect/ard_conf.y b/extensions/app_redirect/ard_conf.y
new file mode 100644
index 0000000..14a1280
--- /dev/null
+++ b/extensions/app_redirect/ard_conf.y
@@ -0,0 +1,451 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ * See doc/app_redirect.conf.sample for configuration file format
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "app_redir.h"
+#include "ard_conf.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+static int rules_added = 0;
+
+/* We initialize statically the config */
+static struct ard_config local_conf = { .default_rct = 86400, .rules = FD_LIST_INITIALIZER(local_conf.rules) };
+struct ard_config * ard_conf = &local_conf;
+
+/* We use these lists in the rules parsing */
+static struct fd_list temp_list_criteria = FD_LIST_INITIALIZER(temp_list_criteria);
+static struct fd_list temp_list_target = FD_LIST_INITIALIZER(temp_list_target);
+
+/* Local variable */
+static struct ard_criteria * c;
+
+/* Dump the configuration */
+static void ard_conf_dump()
+{
+ struct fd_list * li;
+ if (!TRACE_BOOL(FULL))
+ return;
+
+ fd_log_debug("app_redirect: configuration dump:");
+ fd_log_debug(" default_redirect_cache_time : %u sec", ard_conf->default_rct);
+ for (li = ard_conf->rules.next; li != &ard_conf->rules; li = li->next) {
+ ard_rule_dump(li->o);
+ }
+ fd_log_debug("app_redirect: end of configuration dump");
+}
+
+/* Parse the configuration file */
+int ard_conf_handle(char * conffile)
+{
+ extern FILE * ard_confin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ ard_confin = fopen(conffile, "r");
+ if (ard_confin == NULL) {
+ ret = errno;
+ TRACE_DEBUG(INFO, "Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(ard_confin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ } else {
+ TRACE_DEBUG(FULL, "Added %d Redirect RULES successfully.", rules_added);
+ ard_conf_dump();
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int ard_conflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line) {
+ TRACE_DEBUG (INFO, "%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ } else if (ploc->first_column != ploc->last_column) {
+ TRACE_DEBUG (INFO, "%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ } else {
+ TRACE_DEBUG (INFO, "%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+ }
+}
+
+/* Compile a regular expression pattern */
+static int compile_regex( regex_t * preg, char * str )
+{
+ int err;
+
+ /* Compile the regular expression */
+ err = regcomp(preg, str, REG_EXTENDED | REG_NOSUB);
+ if (err != 0) {
+ char * buf;
+ size_t bl;
+
+ /* Error while compiling the regex */
+ TRACE_DEBUG(INFO, "Error while compiling the regular expression '%s':", str);
+
+ /* Get the error message size */
+ bl = regerror(err, preg, NULL, 0);
+
+ /* Alloc the buffer for error message */
+ CHECK_MALLOC( buf = malloc(bl) );
+
+ /* Get the error message content */
+ regerror(err, preg, buf, bl);
+ TRACE_DEBUG(INFO, "\t%s", buf);
+
+ /* Free the buffer, return the error */
+ free(buf);
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ /* returned by lex */
+ uint32_t u32; /* Store integer values */
+ struct {
+ char * str;
+ int regex; /* true or false */
+ } tstring; /* typed string */
+}
+
+/* In case of error in the lexical analysis */
+%token TOK_LEX_ERROR
+
+/* A string (malloc'd in lex parser; it must be freed after use):*/
+%token <tstring> TOK_TSTRING
+
+/* An integer value */
+%token <u32> TOK_U32VAL
+
+%type <u32> rule_type
+%type <u32> rule_duration
+
+/* Tokens */
+%token TOK_DEFAULT_RCT
+
+%token TOK_TO
+
+%token TOK_DONT_CACHE
+%token TOK_ALL_SESSION
+%token TOK_ALL_REALM
+%token TOK_REALM_AND_APPLICATION
+%token TOK_ALL_APPLICATION
+%token TOK_ALL_HOST
+%token TOK_ALL_USER
+
+%token TOK_FROM_ID
+%token TOK_FROM_REALM
+
+%token TOK_APP
+
+
+
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK */
+ | conffile def_rct
+ | conffile rule
+ ;
+
+ /* Overwrite default cache time value */
+def_rct: TOK_DEFAULT_RCT '=' TOK_U32VAL ';'
+ {
+ ard_conf->default_rct = $3;
+ }
+ ;
+
+ /* a RULE entry */
+rule: rule_type rule_duration ':' criteria_list TOK_TO target_list ';'
+ {
+ struct ard_rule * r;
+ /* Create the new rule with data in file */
+ CHECK_MALLOC_DO( r = malloc(sizeof(struct ard_rule)),
+ {
+ yyerror (&yylloc, conffile, "Error while allocating new memory...");
+ YYERROR;
+ } );
+ memset(r, 0, sizeof(struct ard_rule));
+ fd_list_init(&r->chain, r);
+ r->type = $1;
+ r->rct = $2;
+ fd_list_init(&r->criteria, NULL);
+ fd_list_move_end(&r->criteria, &temp_list_criteria);
+ fd_list_init(&r->targets, NULL);
+ fd_list_move_end(&r->targets, &temp_list_target);
+
+ /* Add the new rule in config */
+ fd_list_insert_before(&ard_conf->rules, &r->chain);
+ rules_added++;
+ }
+ ;
+
+rule_type: TOK_DONT_CACHE
+ {
+ $$ = DONT_CACHE;
+ }
+ | TOK_ALL_SESSION
+ {
+ $$ = ALL_SESSION;
+ }
+ | TOK_ALL_REALM
+ {
+ $$ = ALL_REALM;
+ }
+ | TOK_REALM_AND_APPLICATION
+ {
+ $$ = REALM_AND_APPLICATION;
+ }
+ | TOK_ALL_APPLICATION
+ {
+ $$ = ALL_APPLICATION;
+ }
+ | TOK_ALL_HOST
+ {
+ $$ = ALL_HOST;
+ }
+ | TOK_ALL_USER
+ {
+ $$ = ALL_USER;
+ }
+ ;
+
+rule_duration: /* empty */
+ {
+ $$ = 0;
+ }
+ |
+ TOK_U32VAL
+ {
+ $$ = $1;
+ }
+ ;
+
+criteria_list: /* empty is OK */
+ | criteria_list criteria_item;
+ ;
+
+criteria_item: {
+ /* Create the new criteria */
+ CHECK_MALLOC_DO( c = malloc(sizeof(struct ard_criteria)),
+ {
+ yyerror (&yylloc, conffile, "Error while allocating new memory...");
+ YYERROR;
+ } );
+ memset(c, 0, sizeof(struct ard_criteria));
+ fd_list_init(&c->chain, c);
+ }
+ criteria_item_inside
+ {
+ struct fd_list * li;
+ /* If there is a string, save its length */
+ if (c->s)
+ c->sl = strlen(c->s);
+ /* If the criteria contains a regex, parse it */
+ if (c->is_regex) {
+ CHECK_FCT_DO( compile_regex( &c->preg, c->s ),
+ {
+ yyerror (&yylloc, conffile, "Error parsing a regular expression...");
+ YYERROR;
+ } );
+ }
+
+ /* Now link this new criteria in the list. Order by criteria type to accelerate the search */
+ for (li = temp_list_criteria.next; li != &temp_list_criteria; li = li->next) {
+ struct ard_criteria * nc = li->o;
+ if (nc->type >= c->type)
+ break;
+ }
+ fd_list_insert_before(li, &c->chain);
+ }
+ ;
+
+criteria_item_inside: TOK_FROM_ID '=' TOK_TSTRING
+ {
+ c->type = FROM_ID;
+ c->s = $3.str;
+ c->is_regex = $3.regex;
+ }
+ |
+ TOK_FROM_REALM '=' TOK_TSTRING
+ {
+ c->type = FROM_REALM;
+ c->s = $3.str;
+ c->is_regex = $3.regex;
+ }
+ |
+ TOK_APP '=' TOK_U32VAL
+ {
+ c->type = APP_ID;
+ c->i = $3;
+ }
+ |
+ TOK_TSTRING '=' TOK_U32VAL
+ {
+ struct dict_object * avp = NULL;
+ if ($1.regex) {
+ yyerror(&yylloc, conffile, "Error: the AVP name cannot be specified as regular expression");
+ YYERROR;
+ }
+ CHECK_FCT_DO( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS, $1.str, &avp, ENOENT ),
+ {
+ TRACE_DEBUG(INFO, "Error while searching for AVP '%s'. Did you load the relevant dictionary extensions?", $1.str);
+ yyerror(&yylloc, conffile, "Unable to resolve specified AVP name.");
+ YYERROR;
+ } );
+ CHECK_FCT_DO( fd_dict_getval(avp, &c->avp_info),
+ {
+ TRACE_DEBUG(INFO, "Error while retrieving the description for AVP '%s'", $1.str);
+ yyerror(&yylloc, conffile, "Unable to retrieve specified AVP's data.");
+ YYERROR;
+ } );
+ if (c->avp_info.avp_basetype != AVP_TYPE_UNSIGNED32) {
+ TRACE_DEBUG(INFO, "The AVP '%s' is not of type UNSIGNED32, matching is not supported (yet)", $1.str);
+ yyerror(&yylloc, conffile, "Invalid AVP for this operation.");
+ YYERROR;
+ }
+
+ c->type = AVP_INT;
+ c->i = $3;
+ }
+ |
+ TOK_TSTRING '=' TOK_TSTRING
+ {
+ struct dict_object * avp = NULL;
+ if ($1.regex) {
+ yyerror(&yylloc, conffile, "Error: the AVP name cannot be specified as regular expression");
+ YYERROR;
+ }
+ CHECK_FCT_DO( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS, $1.str, &avp, ENOENT ),
+ {
+ TRACE_DEBUG(INFO, "Error while searching for AVP '%s'. Did you load the relevant dictionary extensions?", $1.str);
+ yyerror(&yylloc, conffile, "Unable to resolve specified AVP name.");
+ YYERROR;
+ } );
+ CHECK_FCT_DO( fd_dict_getval(avp, &c->avp_info),
+ {
+ TRACE_DEBUG(INFO, "Error while retrieving the description for AVP '%s'", $1.str);
+ yyerror(&yylloc, conffile, "Unable to retrieve specified AVP's data.");
+ YYERROR;
+ } );
+ if (c->avp_info.avp_basetype != AVP_TYPE_OCTETSTRING) {
+ TRACE_DEBUG(INFO, "The AVP '%s' is not of type OCTETSTRING, matching is not supported (yet)", $1.str);
+ yyerror(&yylloc, conffile, "Invalid AVP for this operation.");
+ YYERROR;
+ }
+
+ c->type = AVP_STR;
+ c->s = $3.str;
+ c->is_regex = $3.regex;
+ }
+ ;
+
+target_list: /* This list cannot be empty */
+ target_item
+ | target_list target_item
+ ;
+
+target_item: TOK_TSTRING
+ {
+ struct ard_target * t;
+
+ if ($1.regex) {
+ yyerror(&yylloc, conffile, "Regular expressions are not allowed in Redirect-Host specification.");
+ YYERROR;
+ }
+
+ /* Check if the format is valid */
+ CHECK_FCT_DO( fd_os_parse_DiameterURI((uint8_t *)$1.str, strlen($1.str), NULL, NULL, NULL, NULL, NULL, NULL),
+ {
+ TRACE_DEBUG(INFO, "Error while parsing DiameterURI '%s'", $1.str);
+ yyerror(&yylloc, conffile, "Specified DiameterURI is invalid.");
+ YYERROR;
+ } );
+
+ /* Ok. we create the new target */
+ CHECK_MALLOC_DO( t = malloc(sizeof(struct ard_target)),
+ {
+ yyerror (&yylloc, conffile, "Error while allocating new memory...");
+ YYERROR;
+ } );
+ memset(t, 0, sizeof(struct ard_target));
+ fd_list_init(&t->chain, t);
+
+ t->s = (os0_t) $1.str;
+ t->l = strlen($1.str);
+
+ fd_list_insert_before(&temp_list_target, &t->chain);
+ }
+ ;
diff --git a/extensions/app_redirect/ard_rules.c b/extensions/app_redirect/ard_rules.c
new file mode 100644
index 0000000..c7a3861
--- /dev/null
+++ b/extensions/app_redirect/ard_rules.c
@@ -0,0 +1,298 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "app_redir.h"
+
+static const char * redir_type_str[] = {
+ "DONT_CACHE",
+ "ALL_SESSION",
+ "ALL_REALM",
+ "REALM_AND_APPLICATION",
+ "ALL_APPLICATION",
+ "ALL_HOST",
+ "ALL_USER"
+};
+
+struct dict_object * avp_Redirect_Host = NULL;
+struct dict_object * avp_Redirect_Host_Usage = NULL;
+struct dict_object * avp_Redirect_Max_Cache_Time = NULL;
+
+
+void ard_rule_dump(struct ard_rule * r)
+{
+ struct fd_list * li;
+ fd_log_debug(" rule @%p: %s, %us", r, redir_type_str[r->type], r->rct);
+ for (li = r->criteria.next; li != &r->criteria; li = li->next) {
+ struct ard_criteria * c = li->o;
+ switch (c->type) {
+ case FROM_ID:
+ fd_log_debug(" Criteria: received from peer %s'%s'", c->is_regex?"REGEX":"", c->s);
+ break;
+ case FROM_REALM:
+ fd_log_debug(" Criteria: received from realm %s'%s'", c->is_regex?"REGEX":"", c->s);
+ break;
+ case APP_ID:
+ fd_log_debug(" Criteria: application id is %u", c->i);
+ break;
+ case AVP_INT:
+ fd_log_debug(" Criteria: contains '%s' AVP with value '%d'", c->avp_info.avp_name, c->i);
+ break;
+ case AVP_STR:
+ fd_log_debug(" Criteria: contains '%s' AVP with value %s'%s'", c->avp_info.avp_name, c->is_regex?"REGEX":"", c->s);
+ break;
+
+ default:
+ fd_log_debug(" Criteria: invalid (%d)!", c->type);
+ }
+ }
+ for (li = r->targets.next; li != &r->targets; li = li->next) {
+ struct ard_target * t = li->o;
+ fd_log_debug(" Redirect to: '%s'", t->s);
+ }
+}
+
+/* Tells if the string in s (is0term or not) matches the string in the criteria (regex or not) */
+static int str_match(struct ard_criteria * c, uint8_t *s, size_t l, int is0term, int * match)
+{
+ TRACE_ENTRY("%p %p %zd %d %p", c, s, l, is0term, match);
+
+ *match = 0;
+
+ if (c->is_regex == 0) {
+ if ( ! fd_os_almostcasesrch(c->s, c->sl, s, l, NULL) )
+ *match = 1;
+ } else {
+ int err;
+#ifdef HAVE_REG_STARTEND
+ regmatch_t pmatch[1];
+ memset(pmatch, 0, sizeof(pmatch));
+ pmatch[0].rm_so = 0;
+ pmatch[0].rm_eo = l;
+ err = regexec(&c->preg, (char *)s, 0, pmatch, REG_STARTEND);
+#else /* HAVE_REG_STARTEND */
+ if (!is0term) {
+ /* We have to create a copy of the string in this case */
+ char *mystrcpy;
+ CHECK_MALLOC( mystrcpy = (char *)os0dup(s, l) );
+ err = regexec(&c->preg, mystrcpy, 0, NULL, 0);
+ free(mystrcpy);
+ } else {
+ err = regexec(&c->preg, (char *)s, 0, NULL, 0);
+ }
+#endif /* HAVE_REG_STARTEND */
+
+ /* Now check the result */
+ if (err == 0) {
+ /* We have a match */
+ *match = 1;
+ } else if (err != REG_NOMATCH) {
+ /* An error occurred */
+ char * buf;
+ size_t bl;
+
+ /* Error while compiling the regex */
+ TRACE_DEBUG(INFO, "Error while executing the regular expression '%s':", c->s);
+
+ /* Get the error message size */
+ bl = regerror(err, &c->preg, NULL, 0);
+
+ /* Alloc the buffer for error message */
+ CHECK_MALLOC( buf = malloc(bl) );
+
+ /* Get the error message content */
+ regerror(err, &c->preg, buf, bl);
+ TRACE_DEBUG(INFO, "\t%s", buf);
+
+ /* Free the buffer, return the error */
+ free(buf);
+ return (err == REG_ESPACE) ? ENOMEM : EINVAL;
+ }
+ }
+ return 0;
+}
+
+/* Search the first matching rule in the config */
+static int find_rule(struct msg * msg, struct ard_rule ** found)
+{
+ struct fd_list * li;
+ struct msg_hdr * mhdr = NULL;
+ struct peer_hdr * phdr = NULL;
+
+ ASSERT(msg && found);
+ *found = NULL;
+
+ /* Get the message's header */
+ CHECK_FCT( fd_msg_hdr(msg, &mhdr) );
+
+ /* Get the message's origin */
+ {
+ DiamId_t id;
+ size_t len;
+ CHECK_FCT( fd_msg_source_get(msg, &id, &len) );
+ CHECK_FCT( fd_peer_getbyid(id, len, 0, &phdr) );
+ }
+
+ /* Now for each rule check if all criteria match */
+ for (li = ard_conf->rules.next; li != &ard_conf->rules; li = li->next) {
+ struct fd_list * lic;
+ struct ard_rule * r = li->o;
+ int is_match = 1;
+
+ for (lic = r->criteria.next; is_match && (lic != &r->criteria); lic = lic->next) {
+ struct ard_criteria * c = lic->o;
+
+ /* Does this criteria match ? */
+ switch (c->type) {
+ case APP_ID:
+ if (c->i != mhdr->msg_appl)
+ is_match = 0;
+ break;
+
+ case FROM_ID:
+ CHECK_FCT( str_match(c, (uint8_t *)phdr->info.pi_diamid, phdr->info.pi_diamidlen, 1, &is_match) );
+ break;
+
+ case FROM_REALM:
+ if (phdr->info.runtime.pir_realm) {
+ CHECK_FCT( str_match(c, (uint8_t *)phdr->info.runtime.pir_realm, phdr->info.runtime.pir_realmlen, 1, &is_match) );
+ } else {
+ /* since we don't have the realm it was received from, assume it does not match */
+ TRACE_DEBUG(INFO, "Missing realm info for peer '%s', skipping rule %p", phdr->info.pi_diamid, r);
+ is_match = 0;
+ }
+ break;
+
+ case AVP_INT:
+ case AVP_STR:
+ /* We have to search the whole message for the matching AVP */
+ {
+ is_match = 0;
+ struct avp * avp = NULL;
+ CHECK_FCT( fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, &avp, NULL) );
+ while (avp && !is_match) {
+ struct avp_hdr * ahdr = NULL;
+ CHECK_FCT( fd_msg_avp_hdr(avp, &ahdr) );
+
+ if ( (ahdr->avp_code == c->avp_info.avp_code)
+ && (ahdr->avp_vendor == c->avp_info.avp_vendor) ) /* always 0 if no V flag */
+ {
+ /* dict-parse this AVP to ensure it has a value */
+ CHECK_FCT( fd_msg_parse_dict( avp, fd_g_config->cnf_dict, NULL ) );
+
+ /* Now check if the value matches our criteria */
+ if (c->type == AVP_INT) {
+ if (ahdr->avp_value->u32 == c->i)
+ is_match = 1;
+ } else {
+ /* it is AVP_STR */
+ CHECK_FCT( str_match(c, ahdr->avp_value->os.data, ahdr->avp_value->os.len, 0, &is_match) );
+ }
+
+ if (is_match)
+ break;
+ }
+
+ /* go to next */
+ CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) );
+ }
+
+ }
+
+ break;
+
+ }
+ }
+
+ if (is_match) {
+ /* We found the first rule that matches for this message */
+ *found = r;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/* The forward callback */
+int ard_rule_apply(void * cbdata, struct msg ** msg)
+{
+ struct ard_rule * rule = NULL;
+
+ TRACE_ENTRY("%p %p", cbdata, msg);
+ CHECK_PARAMS(msg && *msg);
+
+ /* First, check if we have a rule that applies to this message */
+ CHECK_FCT( find_rule(*msg, &rule) );
+
+ if (rule) {
+ struct avp * avp;
+ union avp_value val;
+ struct fd_list * li;
+
+ /* We have to reply a Redirect message in this case */
+ CHECK_FCT( fd_msg_new_answer_from_req(fd_g_config->cnf_dict, msg, MSGFL_ANSW_ERROR) );
+
+ CHECK_FCT( fd_msg_rescode_set( *msg, "DIAMETER_REDIRECT_INDICATION", NULL, NULL, 1 ) );
+
+ /* Now add the Redirect-* AVPs */
+ CHECK_FCT( fd_msg_avp_new( avp_Redirect_Host_Usage, 0, &avp ) );
+ val.u32 = rule->type;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) );
+ CHECK_FCT( fd_msg_avp_add( *msg, MSG_BRW_LAST_CHILD, avp ) );
+
+ if (rule->type) {
+ CHECK_FCT( fd_msg_avp_new( avp_Redirect_Max_Cache_Time, 0, &avp ) );
+ val.u32 = rule->rct ?: ard_conf->default_rct;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) );
+ CHECK_FCT( fd_msg_avp_add( *msg, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ for (li = rule->targets.next; li != &rule->targets; li = li->next) {
+ struct ard_target * t = li->o;
+
+ CHECK_FCT( fd_msg_avp_new( avp_Redirect_Host, 0, &avp ) );
+ val.os.data = t->s;
+ val.os.len = t->l;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) );
+ CHECK_FCT( fd_msg_avp_add( *msg, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ /* Send this answer */
+ CHECK_FCT( fd_msg_send( msg, NULL, NULL) );
+ }
+
+ return 0;
+}
+
diff --git a/extensions/app_sip/CMakeLists.txt b/extensions/app_sip/CMakeLists.txt
new file mode 100644
index 0000000..8bd89d1
--- /dev/null
+++ b/extensions/app_sip/CMakeLists.txt
@@ -0,0 +1,47 @@
+# The app_sip extension
+PROJECT("Diameter SIP Application (RFC4740)" C)
+
+FIND_PACKAGE(MySQL REQUIRED)
+INCLUDE_DIRECTORIES(${MySQL_INCLUDE_DIR})
+
+# Parser files
+BISON_FILE(app_sip.y)
+FLEX_FILE(app_sip.l)
+SET_SOURCE_FILES_PROPERTIES(lex.app_sip.c app_sip.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( DIAM_SIP_SRC
+ lex.app_sip.c
+ app_sip.tab.c
+ app_sip.tab.h
+ app_sip.c
+ app_sip.h
+ libapp_sip.c
+ md5.c
+ multimediaauth.c
+ registrationtermination.c
+ userauthorization.c
+ pushprofile.c
+ serverassignment.c
+ locationinfo.c
+ locationinfosl.c
+)
+
+# Compile as a module
+FD_ADD_EXTENSION(app_sip ${DIAM_SIP_SRC})
+
+TARGET_LINK_LIBRARIES(app_sip ${MySQL_LIBRARIES})
+
+SUBDIRS(tools)
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS app_sip
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-sip-server)
+
+INSTALL(FILES README TODO
+ DESTINATION /usr/share/doc/freeDiameter-sip-server
+ CONFIGURATIONS DebianPackage
+ COMPONENT freeDiameter-sip-server)
diff --git a/extensions/app_sip/README b/extensions/app_sip/README
new file mode 100644
index 0000000..fbc5536
--- /dev/null
+++ b/extensions/app_sip/README
@@ -0,0 +1,39 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+
+Diameter-SIP Application will be fully compliant with RFC4740 (server part). However, there is still some work to do so it should be considered as experimental for now.
+
diff --git a/extensions/app_sip/TODO b/extensions/app_sip/TODO
new file mode 100644
index 0000000..661face
--- /dev/null
+++ b/extensions/app_sip/TODO
@@ -0,0 +1,57 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+Diameter-SIP implementation is still under development.
+
+TODO List
+* add in malloc the size of char
+* when getting results from mysql, check lenght
+* sort capabilities in LIR/LIA
+* make functions for database access in MAR/MAA
+* order diamsip.h because it's becoming a mess ^^
+* replace password in MAR/MAA and libdiamsip from table to malloc char!
+* display errors of mysql
+* check that all user data inserted in requests are purified
+* add accounting server uri in database and diamsip
+* add mutex on mysql writing
+* check multithreading of mysql!
+* get destination host in database for RTR and PPR
+
+
+
+
+
+
diff --git a/extensions/app_sip/app_sip.c b/extensions/app_sip/app_sip.c
new file mode 100644
index 0000000..dfabdcc
--- /dev/null
+++ b/extensions/app_sip/app_sip.c
@@ -0,0 +1,252 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "app_sip.h"
+
+//Diameter-SIP server
+struct disp_hdl * app_sip_MAR_hdl=NULL;
+struct disp_hdl * app_sip_LIR_hdl=NULL;
+struct disp_hdl * app_sip_UAR_hdl=NULL;
+struct disp_hdl * app_sip_SAR_hdl=NULL;
+struct disp_hdl * app_sip_PPA_hdl=NULL;
+struct disp_hdl * app_sip_RTA_hdl=NULL;
+
+//Suscriber Locator
+struct disp_hdl * app_sip_SL_LIR_hdl=NULL;
+
+
+
+struct disp_hdl * app_sip_default_hdl=NULL;
+struct session_handler * ds_sess_hdl;
+
+//configuration stucture
+struct as_conf * as_conf=NULL;
+static struct as_conf app_sip_conf;
+
+//dictionary of SIP
+struct app_sip_dict sip_dict;
+
+int app_sip_default_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ TRACE_ENTRY("%p %p %p %p %p", msg, avp, sess, opaque, act);
+
+ return 0;
+}
+
+void dump_config()
+{
+ TRACE_DEBUG(FULL,"***Configuration of Diameter-SIP extension***");
+ TRACE_DEBUG(FULL,"# mode: *%d*",as_conf->mode);
+ TRACE_DEBUG(FULL,"# datasource: *%d*",as_conf->datasource);
+ TRACE_DEBUG(FULL,"# mysql_login: *%s*",as_conf->mysql_login);
+ TRACE_DEBUG(FULL,"# mysql_password: *%s*",as_conf->mysql_password);
+ TRACE_DEBUG(FULL,"# mysql_database: *%s*",as_conf->mysql_database);
+ TRACE_DEBUG(FULL,"# mysql_server: *%s*",as_conf->mysql_server);
+ TRACE_DEBUG(FULL,"# mysql_port: *%d*",as_conf->mysql_port);
+ TRACE_DEBUG(FULL,"# mysql_port: *%s*",as_conf->mysql_prefix);
+ TRACE_DEBUG(FULL,"***End of Diameter-SIP configuration extension***");
+}
+
+static int as_conf_init(void)
+{
+ as_conf=&app_sip_conf;
+ //memset(app_sip_conf, 0, sizeof(struct as_conf));
+
+
+ return 0;
+}
+
+/* entry point */
+int as_entry(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ struct dict_object * app=NULL;
+ struct disp_when data;
+ pthread_t rtr_thread, ppr_thread;
+
+ /* Initialize configuration */
+ CHECK_FCT( as_conf_init() );
+
+
+ //We parse the configuration file
+ if (conffile != NULL) {
+ CHECK_FCT( as_conf_handle(conffile) );
+ }
+ else
+ {
+ TRACE_DEBUG(INFO, "We need a configuration file for Diameter-SIP extension. See doc/ for an example.");
+ }
+
+ //TODO: replace by configuration file!!
+ strcpy(as_conf->mysql_prefix,"as_");
+
+ //We can dump the configuration extracted from app_sip.conf
+ //dump_config();
+
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Session Initiation Protocol (SIP) Application", &app, ENOENT) );
+ CHECK_FCT( fd_disp_app_support ( app, NULL, 1, 0 ) );
+
+
+
+ //We set useful AVPs
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Session-State", &sip_dict.Auth_Session_State, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &sip_dict.Auth_Application_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &sip_dict.Destination_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &sip_dict.Destination_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sip_dict.Session_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host", &sip_dict.Redirect_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host-Usage", &sip_dict.Redirect_Host_Usage, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Auth-Data-Item", &sip_dict.SIP_Auth_Data_Item, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authorization", &sip_dict.SIP_Authorization, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authenticate", &sip_dict.SIP_Authenticate, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Number-Auth-Items", &sip_dict.SIP_Number_Auth_Items, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Scheme", &sip_dict.SIP_Authentication_Scheme, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Info", &sip_dict.SIP_Authentication_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-URI", &sip_dict.SIP_Server_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-Capabilities", &sip_dict.SIP_Server_Capabilities, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Mandatory-Capability", &sip_dict.SIP_Mandatory_Capability, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Optional-Capability", &sip_dict.SIP_Optional_Capability, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Method", &sip_dict.SIP_Method, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-AOR", &sip_dict.SIP_AOR, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Deregistration-Reason", &sip_dict.SIP_Deregistration_Reason, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Code", &sip_dict.SIP_Reason_Code, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Info", &sip_dict.SIP_Reason_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Accounting-Information", &sip_dict.SIP_Accounting_Information, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Accounting-Server-URI", &sip_dict.SIP_Accounting_Server_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Credit-Control-Server-URI", &sip_dict.SIP_Credit_Control_Server_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-Assignment-Type", &sip_dict.SIP_Server_Assignment_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Item-Number", &sip_dict.SIP_Item_Number, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Authorization-Type", &sip_dict.SIP_User_Authorization_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Supported-User-Data-Type", &sip_dict.SIP_Supported_User_Data_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data", &sip_dict.SIP_User_Data, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Type", &sip_dict.SIP_User_Data_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Contents", &sip_dict.SIP_User_Data_Contents, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Already-Available", &sip_dict.SIP_User_Data_Already_Available, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Visited-Network-Id", &sip_dict.SIP_Visited_Network_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Realm", &sip_dict.Digest_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-URI", &sip_dict.Digest_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce", &sip_dict.Digest_Nonce, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-CNonce", &sip_dict.Digest_CNonce, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Method", &sip_dict.Digest_Method, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce-Count", &sip_dict.Digest_Nonce_Count, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Realm", &sip_dict.Digest_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Response", &sip_dict.Digest_Response, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Response-Auth", &sip_dict.Digest_Response_Auth, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Username", &sip_dict.Digest_Username, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Algorithm", &sip_dict.Digest_Algorithm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-QoP", &sip_dict.Digest_QOP, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &sip_dict.User_Name, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-HA1", &sip_dict.Digest_HA1, ENOENT) );
+
+
+ //Register Application
+ memset(&data, 0, sizeof(data));
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Session Initiation Protocol (SIP) Application", &data.app, ENOENT) );
+
+ if(as_conf->mode==1)
+ {
+ // **Command Codes
+ //MAR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Multimedia-Auth-Request", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( app_sip_MAR_cb, DISP_HOW_CC, &data, NULL, &app_sip_MAR_hdl ) );
+ //RTA
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Answer", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( app_sip_RTA_cb, DISP_HOW_CC, &data, NULL, &app_sip_RTA_hdl ) );
+ //PPA
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Push-Profile-Answer", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( app_sip_PPA_cb, DISP_HOW_CC, &data, NULL, &app_sip_PPA_hdl ) );
+ //LIR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( app_sip_LIR_cb, DISP_HOW_CC, &data, NULL, &app_sip_LIR_hdl ) );
+ //UAR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "User-Authorization-Request", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( app_sip_UAR_cb, DISP_HOW_CC, &data, NULL, &app_sip_UAR_hdl ) );
+ //SAR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Server-Assignment-Request", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( app_sip_SAR_cb, DISP_HOW_CC, &data, NULL, &app_sip_SAR_hdl ) );
+ }
+ if(as_conf->mode==2)
+ {
+ //LIR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( app_sip_SL_LIR_cb, DISP_HOW_CC, &data, NULL, &app_sip_SL_LIR_hdl ) );
+ }
+ //Callback for unexpected messages
+ CHECK_FCT( fd_disp_register( app_sip_default_cb, DISP_HOW_APPID, &data, NULL, &app_sip_default_hdl ) );
+
+
+ //We start database connection
+ if(start_mysql_connection())
+ return EINVAL;
+
+ CHECK_FCT(fd_sess_handler_create(&ds_sess_hdl, (void *)free, NULL, NULL));
+
+ //Creation of thread for Registration Termination
+ if(pthread_create(&rtr_thread, NULL,rtr_socket, NULL))
+ {
+ TRACE_DEBUG(INFO,"Creation of thread failed, abort!");
+ return EINVAL;
+ }
+ //Creation of thread for Push Profile
+ if(pthread_create(&ppr_thread, NULL,ppr_socket, NULL))
+ {
+ TRACE_DEBUG(INFO,"Creation of thread failed, abort!");
+ return EINVAL;
+ }
+
+
+ return 0;
+}
+
+//Cleanup callback
+void fd_ext_fini(void)
+{
+ //TODO:unregister other callbacks
+
+ (void) fd_disp_unregister(&app_sip_MAR_hdl, NULL);
+ CHECK_FCT_DO( fd_sess_handler_destroy(&ds_sess_hdl, NULL),return);
+
+
+ //We close database connection
+ close_mysql_connection();
+
+
+
+ TRACE_ENTRY();
+ return ;
+}
+
+EXTENSION_ENTRY("app_sip", as_entry, "dict_sip");
diff --git a/extensions/app_sip/app_sip.h b/extensions/app_sip/app_sip.h
new file mode 100644
index 0000000..a6532b7
--- /dev/null
+++ b/extensions/app_sip/app_sip.h
@@ -0,0 +1,266 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freesipserver.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include <freeDiameter/extension.h>
+#include <sys/time.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+GCC_DIAG_OFF("-Wdeprecated-declarations")
+#include <gcrypt.h>
+GCC_DIAG_ON("-Wdeprecated-declarations")
+#include <string.h>
+#include <mysql.h>
+#include "md5.h"
+
+
+#define NONCE_SIZE 16
+#define DIGEST_LEN 16
+
+
+/* Mode for the extension */
+#define MODE_DSSERVER 0x1
+#define MODE_SL 0x2
+
+//Redirect_Host_Usage
+#define ALL_USER 6
+
+/* The module configuration */
+struct as_conf {
+ int mode; /* default MODE_DSSERVER | MODE_SL */
+ enum {ASMYSQL} datasource;
+ char * mysql_login;
+ char * mysql_password;
+ char * mysql_database;
+ char * mysql_server;
+ char mysql_prefix[10]; //default: as_
+ uint16_t mysql_port; //if 0, default port will be used
+ uint16_t rtr_port;
+ uint16_t ppr_port;
+};
+extern struct as_conf * as_conf;
+
+/* Parse the configuration file */
+int as_conf_handle(char * conffile);
+
+
+extern MYSQL *conn;
+
+
+
+void calc_md5(char *buffer, char * data);
+void clear_digest(uint8_t * digest, char * readable_digest, int digestlength);
+struct avp_hdr * walk_digest(struct avp *avp, int avp_code);
+
+
+//MySQL part
+int start_mysql_connection();
+void request_mysql(char *query);
+void close_mysql_connection();
+int get_sipserver_uri(const unsigned char *sip_aor, const size_t sipaorlen, unsigned char ** sipserver_uri, size_t *sipserverurilen);
+int exist_username(const unsigned char *sip_aor, const size_t sipaorlen);
+int get_sipserver_cap(const unsigned char *sip_aor, const size_t sipaorlen, struct avp **capabilities);
+int get_password(const unsigned char *username, const size_t usernamelen, char *password);
+int check_sipaor(const unsigned char *username, const size_t usernamelen, const char * sip_aor,const size_t sipaorlen);
+int add_user_datatype(const unsigned char *sip_aor, const size_t sipaorlen,struct msg *message);
+int set_pending_flag(const unsigned char *username, const size_t usernamelen);
+int clear_pending_flag(const unsigned char *username, const size_t usernamelen);
+int set_real_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen);
+int set_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen);
+//int get_sipserver_uri(const unsigned char *sip_aor, const size_t sipaorlen, unsigned char ** sipserver_uri, size_t *sipserverurilen);
+int allow_roaming(const unsigned char *username, const size_t usernamelen, const char * network,const size_t networklen);
+int get_diameter_uri(const unsigned char *sip_aor, const size_t sipaorlen, char ** diameter_uri, size_t *diameterurilen);
+//count functions
+int count_avp(struct msg * message, int code, int vendor);
+
+
+void DigestCalcHA1(char * pszAlg,char * pszUserName,char * pszRealm,char * pszPassword,char * pszNonce,char * pszCNonce,HASHHEX SessionKey);
+void DigestCalcResponse(HASHHEX HA1,char * pszNonce,char * pszNonceCount,char * pszCNonce,char * pszQop,char * pszMethod,char * pszDigestUri,HASHHEX HEntity,HASHHEX Response);
+void DigestCalcResponseAuth(HASHHEX HA1,char * pszNonce,char * pszNonceCount,char * pszCNonce,char * pszQop,char * pszMethod,char * pszDigestUri,HASHHEX HEntity,HASHHEX Response);
+
+int fd_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp );
+
+//thread procedure
+void *rtr_socket(void *);
+void *ppr_socket(void *);
+
+struct rtrsipaor
+{
+ char username[200];
+ char sip_aor1[200];
+ char sip_aor2[200];
+ char sip_aor3[200];
+ char strreason[200];
+ char desthost[200];
+ int reason;
+};
+struct pprsipaor
+{
+ char username[200];
+ char datatype1[255];
+ char datatype2[255];
+ char datatype3[255];
+ int accounting;
+};
+
+int app_sip_RTR_cb(struct rtrsipaor *structure);
+int app_sip_PPR_cb(struct pprsipaor *structure);
+
+
+int ds_entry();
+void fd_ext_fini(void);
+int app_sip_default_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int app_sip_MAR_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int app_sip_RTA_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int app_sip_PPA_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int app_sip_LIR_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int app_sip_UAR_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int app_sip_SAR_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+
+//Suscriber Locator
+int app_sip_SL_LIR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act);
+//int app_sip_SL_SAR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act);
+
+#define SQL_GETPASSWORD "SELECT `password` FROM ds_users WHERE `username` ='%s'"
+#define SQL_GETPASSWORD_LEN sizeof(SQL_GETPASSWORD)-2
+
+//username by SIP-AOR
+#define SQL_GETUSERNAME "SELECT `username` FROM ds_users, ds_sip_aor WHERE `sip_aor` ='%s' AND `ds_sip_aor`.`id_user` = `ds_users`.`id_user`"
+#define SQL_GETUSERNAME_LEN sizeof(SQL_GETUSERNAME)-2
+
+//sip server uri by username
+#define SQL_GETSIPURI "SELECT `sip_server_uri` FROM ds_users WHERE `username` ='%s'"
+#define SQL_GETSIPURI_LEN sizeof(SQL_GETSIPURI)-2
+
+//sip server uri by SIP-AOR
+#define SQL_GETSIPSERURI "SELECT `ds_sip_aor`.`sip_server_uri` FROM ds_users, ds_sip_aor WHERE `sip_aor` ='%s' AND `ds_sip_aor`.`id_user` = `ds_users`.`id_user`"
+#define SQL_GETSIPSERURI_LEN sizeof(SQL_GETSIPSERURI)-2
+
+//sip capabilities for a SIP-AOR
+#define SQL_GETSIPSERCAP "SELECT `compulsory`,`id_service` FROM ds_user_services, ds_sip_aor WHERE `sip_aor` ='%s' AND `ds_sip_aor`.`id_user` = `ds_user_services`.`id_user`"
+#define SQL_GETSIPSERCAP_LEN sizeof(SQL_GETSIPSERCAP)-2
+
+//user data for a user data supported
+#define SQL_GETSIPDATA "SELECT `label_type`,`data` FROM ds_sip_aor, ds_user_data, ds_data_types WHERE `sip_aor` ='%s' AND `ds_sip_aor`.`id_sip_aor` = `ds_user_data`.`id_sip_aor` AND `ds_data_types`.`id_data_type`=`ds_user_data`.`id_data_type`"
+#define SQL_GETSIPDATA_LEN sizeof(SQL_GETSIPDATA)-2
+
+#define SQL_GETDIAMURI "SELECT `sipserver_uri` FROM ds_sip_aor_map WHERE `sip_aor` ='%s'"
+#define SQL_GETDIAMURI_LEN sizeof(SQL_GETDIAMURI)-2
+
+//networks for this user
+#define SQL_GETUSERNET "SELECT `label_network` FROM ds_users, ds_user_networks, ds_networks WHERE `ds_users`.`username` ='%s' AND `ds_user_networks`.`id_user` = `ds_users`.`id_user` AND `ds_user_networks`.`id_network` = `ds_networks`.`id_network`"
+#define SQL_GETUSERNET_LEN sizeof(SQL_GETUSERNET)-2
+
+#define SQL_SETSIPURI "UPDATE ds_users SET `temp_sip_server_uri`='%s' WHERE `username` ='%s'"
+#define SQL_SETSIPURI_LEN sizeof(SQL_SETSIPURI)-4
+
+//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
+#define SQL_RMSIPURI "UPDATE ds_users SET `temp_sip_server_uri`='', `sip_server_uri`='' WHERE `id_user` ='%s'"
+#define SQL_RMSIPURI_LEN sizeof(SQL_RMSIPURI)-2
+//TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO
+
+#define SQL_SETREALSIPURI "UPDATE ds_users SET `sip_server_uri`='%s' WHERE `username` ='%s'"
+#define SQL_SETREALSIPURI_LEN sizeof(SQL_SETREALSIPURI)-4
+
+#define SQL_SETFLAG "UPDATE ds_users SET `authentication_pending`=1 WHERE `username` ='%s'"
+#define SQL_SETFLAG_LEN sizeof(SQL_SETFLAG)-2
+
+#define SQL_CLEARFLAG "UPDATE ds_users SET `authentication_pending`=0, `registrated`=1 WHERE `username` ='%s'"
+#define SQL_CLEARFLAG_LEN sizeof(SQL_CLEARFLAG)-2
+
+#define SQL_GETSIPAOR "SELECT `sip_aor` FROM `ds_sip_aor`, `ds_users` WHERE `ds_sip_aor`.`id_user` = `ds_users`.`id_user` AND `ds_users`.`username` = '%s'"
+#define SQL_GETSIPAOR_LEN sizeof(SQL_GETSIPAOR)-2
+
+//#define SQL_CLEARFLAG "UPDATE ds_users SET `authentication_pending`=0 WHERE `username` ='%s'"
+//#define SQL_CLEARFLAG_LEN 67
+
+extern struct session_handler * ds_sess_hdl;
+
+//AVP code
+#define CODE_SIP_USER_DATA_TYPE 388
+#define CODE_SIP_AOR 122
+
+//Storage for some useful AVPs
+struct app_sip_dict{
+ struct dict_object * Auth_Session_State;
+ struct dict_object * Auth_Application_Id;
+ struct dict_object * Destination_Host;
+ struct dict_object * Destination_Realm;
+ struct dict_object * User_Name;
+ struct dict_object * Session_Id;
+ struct dict_object * Redirect_Host;
+ struct dict_object * Redirect_Host_Usage;
+ struct dict_object * SIP_Auth_Data_Item;
+ struct dict_object * SIP_Accounting_Information;
+ struct dict_object * SIP_Accounting_Server_URI;
+ struct dict_object * SIP_Credit_Control_Server_URI;
+ struct dict_object * SIP_Server_Assignment_Type;
+ struct dict_object * SIP_Item_Number;
+ struct dict_object * SIP_User_Authorization_Type;
+ struct dict_object * SIP_Supported_User_Data_Type;
+ struct dict_object * SIP_User_Data;
+ struct dict_object * SIP_User_Data_Type;
+ struct dict_object * SIP_User_Data_Contents;
+ struct dict_object * SIP_User_Data_Already_Available;
+ struct dict_object * SIP_Visited_Network_Id;
+ struct dict_object * SIP_Authorization;
+ struct dict_object * SIP_Authenticate;
+ struct dict_object * SIP_Number_Auth_Items;
+ struct dict_object * SIP_Authentication_Scheme;
+ struct dict_object * SIP_Authentication_Info;
+ struct dict_object * SIP_Server_URI;
+ struct dict_object * SIP_Server_Capabilities;
+ struct dict_object * SIP_Mandatory_Capability;
+ struct dict_object * SIP_Optional_Capability;
+ struct dict_object * SIP_Method;
+ struct dict_object * SIP_AOR;
+ struct dict_object * SIP_Deregistration_Reason;
+ struct dict_object * SIP_Reason_Code;
+ struct dict_object * SIP_Reason_Info;
+ struct dict_object * Digest_URI;
+ struct dict_object * Digest_Nonce;
+ struct dict_object * Digest_Nonce_Count;
+ struct dict_object * Digest_CNonce;
+ struct dict_object * Digest_Realm;
+ struct dict_object * Digest_Response;
+ struct dict_object * Digest_Response_Auth;
+ struct dict_object * Digest_Username;
+ struct dict_object * Digest_Method;
+ struct dict_object * Digest_QOP;
+ struct dict_object * Digest_Algorithm;
+ struct dict_object * Digest_HA1;
+};
+
+extern struct app_sip_dict sip_dict;
diff --git a/extensions/app_sip/app_sip.l b/extensions/app_sip/app_sip.l
new file mode 100644
index 0000000..f8e9044
--- /dev/null
+++ b/extensions/app_sip/app_sip.l
@@ -0,0 +1,162 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. *
+* *
+* All rights reserved. *
+* Based on ta_conf.l (Sebastien Decugis <sdecugis@freediameter.net>) *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+
+
+%{
+#include "app_sip.h"
+/* Include yacc tokens definitions */
+#include "app_sip.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+ /* Recognize any integer */
+[-]?[[:digit:]]+ {
+ /* Convert this to an integer value */
+ int ret=0;
+ ret = sscanf(yytext, "%i", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+ /* Recognize quoted strings -- we do not support escaped \" in the string currently. */
+\"[^\"]+\" {
+ /* Match a quoted string. Let's be very permissive. */
+ yylval->string = strdup(yytext+1);
+ if (!yylval->string) {
+ fd_log_debug("Unable to copy the string '%s': %s", yytext, strerror(errno));
+ TRACE_DEBUG(INFO, "strdup failed");
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+ yylval->string[strlen(yytext) - 2] = '\0';
+ return QSTRING;
+ }
+
+
+
+ /* Recognize the tokens */
+(?i:"mysql_login") {
+ return ASMYSQL_LOGIN;
+ }
+
+(?i:"mysql_password") {
+ return ASMYSQL_PASSWORD;
+ }
+
+(?i:"mysql_database") {
+ return ASMYSQL_DATABASE;
+ }
+
+(?i:"mysql_server") {
+ return ASMYSQL_SERVER;
+ }
+
+(?i:"mysql_port") {
+ return ASMYSQL_PORT;
+ }
+(?i:"rtr_port") {
+ return RTR_PORT;
+ }
+(?i:"ppr_port") {
+ return PPR_PORT;
+ }
+(?i:"mode") {
+ return MODE;
+ }
+
+(?i:"datasource") {
+ return DATASOURCE;
+ }
+
+(?i:"mysql") {
+ yylval->integer = ASMYSQL;
+ return INTEGER;
+ }
+(?i:"dsserver") {
+ yylval->integer = MODE_DSSERVER;
+ return INTEGER;
+ }
+
+(?i:"sl") {
+ yylval->integer = MODE_SL;
+ return INTEGER;
+ }
+
+
+
+ /* Valid single characters for yyparse */
+[=;] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]"*=>;\n]+ {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/app_sip/app_sip.y b/extensions/app_sip/app_sip.y
new file mode 100644
index 0000000..6c288a4
--- /dev/null
+++ b/extensions/app_sip/app_sip.y
@@ -0,0 +1,208 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. *
+* *
+* All rights reserved. *
+* Based on ta_conf.y (Sebastien Decugis <sdecugis@freediameter.net>) *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "app_sip.h"
+#include "app_sip.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+#include <string.h>
+#include <errno.h>
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+/* Parse the configuration file */
+int as_conf_handle(char * conffile)
+{
+ extern FILE * app_sipin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ app_sipin = fopen(conffile, "r");
+ if (app_sipin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(app_sipin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int app_siplex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ char *string; /* The string is allocated by strdup in lex.*/
+ int integer; /* Store integer values */
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+/* Key words */
+%token MODE
+%token DATASOURCE
+%token ASMYSQL_LOGIN
+%token ASMYSQL_PASSWORD
+%token ASMYSQL_DATABASE
+%token ASMYSQL_SERVER
+%token ASMYSQL_PORT
+%token RTR_PORT
+%token PPR_PORT
+
+/* Tokens and types for routing table definition */
+/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */
+%token <string> QSTRING
+
+/* An integer value */
+%token <integer> INTEGER
+
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK */
+ | conffile mode
+ | conffile datasource
+ | conffile mysql_login
+ | conffile mysql_password
+ | conffile mysql_database
+ | conffile mysql_server
+ | conffile mysql_port
+ | conffile rtr_port
+ | conffile ppr_port
+ ;
+
+mode: MODE '=' INTEGER ';'
+ {
+ as_conf->mode = $3;
+ }
+ ;
+
+datasource: DATASOURCE '=' INTEGER ';'
+ {
+ as_conf->datasource = $3;
+ }
+ ;
+
+mysql_login: ASMYSQL_LOGIN '=' QSTRING ';'
+ {
+ free(as_conf->mysql_login);
+ as_conf->mysql_login = $3;
+ }
+ ;
+
+mysql_password: ASMYSQL_PASSWORD '=' QSTRING ';'
+ {
+ free(as_conf->mysql_password);
+ as_conf->mysql_password = $3;
+ }
+ ;
+
+mysql_database: ASMYSQL_DATABASE '=' QSTRING ';'
+ {
+ free(as_conf->mysql_database);
+ as_conf->mysql_database = $3;
+ }
+ ;
+
+mysql_server: ASMYSQL_SERVER '=' QSTRING ';'
+ {
+ free(as_conf->mysql_server);
+ as_conf->mysql_server = $3;
+ }
+ ;
+
+mysql_port: ASMYSQL_PORT '=' INTEGER ';'
+ {
+ as_conf->mysql_port = (uint16_t)$3;
+ }
+ ;
+rtr_port: RTR_PORT '=' INTEGER ';'
+ {
+ as_conf->rtr_port = (uint16_t)$3;
+ }
+ ;
+ppr_port: PPR_PORT '=' INTEGER ';'
+ {
+ as_conf->ppr_port = (uint16_t)$3;
+ }
+ ;
diff --git a/extensions/app_sip/libapp_sip.c b/extensions/app_sip/libapp_sip.c
new file mode 100644
index 0000000..6442ff4
--- /dev/null
+++ b/extensions/app_sip/libapp_sip.c
@@ -0,0 +1,1078 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+//#include <mysql.h>
+#include "app_sip.h"
+
+MYSQL *conn;
+
+void clear_digest(uint8_t * digest, char * readable_digest, int digestlength)
+{
+ int i=0;
+ for(i=0;i<digestlength * 2;i++)
+ sprintf(&readable_digest[2 * i], "%2.2hhx", digest[i]);
+ readable_digest[2 * digestlength]='\0';
+
+ return;
+}
+
+// You must create a table like this "char clearDigest[DIGEST_LEN*2+1];"
+void calc_md5(char *clearDigest, char * data)
+{
+ gcry_md_hd_t md5;
+ uint8_t * binDigest=NULL;
+
+ CHECK_MALLOC_DO(binDigest=malloc(DIGEST_LEN),return);
+
+ gcry_md_open(&md5,GCRY_MD_MD5, 0);
+ gcry_md_write(md5, (char *)data, sizeof(data));
+ memcpy(binDigest, gcry_md_read(md5, GCRY_MD_MD5),gcry_md_get_algo_dlen(GCRY_MD_MD5));
+ gcry_md_close(md5);
+
+ clear_digest(binDigest, clearDigest, DIGEST_LEN);
+ free(binDigest);
+ return;
+}
+
+
+/* Search a given AVP model in an AVP (extracted from libfreediameter/message.c ) */
+int fd_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp )
+{
+ struct avp * nextavp;
+ struct avp_hdr * nextavphdr;
+ struct dict_avp_data dictdata;
+
+
+ TRACE_ENTRY("%p %p %p", groupedavp, what, avp);
+
+ CHECK_FCT( fd_dict_getval(what, &dictdata) );
+
+ // Loop only in the group AVP
+ CHECK_FCT( fd_msg_browse(groupedavp, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) );
+ CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) );
+
+ while (nextavphdr) {
+
+ if ( (nextavphdr->avp_code == dictdata.avp_code) && (nextavphdr->avp_vendor == dictdata.avp_vendor) ) // always 0 if no Vendor flag
+ {
+ break;
+ }
+
+ // Otherwise move to next AVP in the grouped AVP
+ CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) );
+
+ if(nextavp!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) );
+ }
+ else
+ nextavphdr=NULL;
+ }
+ if (avp)
+ *avp = nextavp;
+
+ if (avp && nextavp) {
+ struct dictionary * dict;
+ CHECK_FCT( fd_dict_getdict( what, &dict) );
+ CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), );
+ }
+
+ if (avp || nextavp)
+ return 0;
+ else
+ return ENOENT;
+}
+struct avp_hdr *walk_digest(struct avp *avp, int avp_code)
+{
+ struct avp_hdr *temphdr=NULL;
+ CHECK_FCT_DO(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL),return NULL);
+
+ while(avp!=NULL)
+ {
+
+ CHECK_FCT_DO( fd_msg_avp_hdr( avp,&temphdr ),return NULL);
+
+ if(temphdr->avp_code==avp_code)
+ {
+ //We found the AVP so we set avp to NULL to exit the loop
+ avp=NULL;
+ return temphdr;
+
+ }
+ else if(temphdr->avp_code==380)//SIP-Authorization AVP
+ {
+ //We didn't found the AVP but we finished browsing the Authentication AVP
+ avp=NULL;
+ temphdr=NULL;
+
+ return temphdr;
+ }
+ else
+ {
+ CHECK_FCT_DO(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL),return NULL);
+ temphdr=NULL;
+
+ }
+ }
+
+ return temphdr;
+}
+
+int start_mysql_connection()
+{
+ conn = mysql_init(NULL);
+
+ mysql_options(conn, MYSQL_OPT_RECONNECT, "true");
+
+ if (!mysql_real_connect(conn, as_conf->mysql_server,as_conf->mysql_login, as_conf->mysql_password, as_conf->mysql_database, as_conf->mysql_port, NULL, 0))
+ {//TODO: display error from mysql
+ TRACE_DEBUG(INFO,"Unable to connect to database (%s) with login:%s",as_conf->mysql_database,as_conf->mysql_login);
+ return 1;
+ }
+ return 0;
+
+}
+
+
+void request_mysql(char *query)
+{
+ //We check if the connection is still up
+ mysql_ping(conn);
+
+ if (mysql_query(conn, query))
+ {
+ TRACE_DEBUG(INFO,"Query %s failed", query);
+
+ }
+
+}
+
+void close_mysql_connection()
+{
+ mysql_close(conn);
+
+}
+
+//If password is null, we just verify this user exist
+//We don't need the password length because it is a table'
+int get_password(const unsigned char *username, const size_t usernamelen, char *password)
+{
+ CHECK_PARAMS(username && usernamelen);
+
+ int not_found=2;
+ size_t querylen, usernamepurelen;
+ char *query, *username_pure;
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+ //We allocate the double size of username because at worst it can be all quotes
+ username_pure=malloc(usernamelen*2+1);
+ //We purify username not to have forbidden characters
+ usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
+
+ //We copy username in query
+ querylen=SQL_GETPASSWORD_LEN + usernamepurelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_GETPASSWORD, username_pure);
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ if(password!=NULL)
+ password[0]='\0';
+ free(query);
+ return 2;
+ }
+
+
+
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(strlen(row[0])>0)
+ {
+ if(password!=NULL)
+ strcpy(password,row[0]);
+
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+ break;
+ }
+ return not_found;
+}
+
+int check_sipaor(const unsigned char *username, const size_t usernamelen, const char * sip_aor,const size_t sipaorlen)
+{
+ CHECK_PARAMS(username && usernamelen && sip_aor && sipaorlen);
+
+ int not_found=2;
+ size_t querylen, usernamepurelen;
+ char *query, *username_pure;
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+ //We allocate the double size of username because at worst it can be all quotes
+ username_pure=malloc(usernamelen*2+1);
+ //We purify username not to have forbidden characters
+ usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
+
+ //We get the list of AOR owned by this user
+ querylen=SQL_GETSIPAOR_LEN + usernamepurelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_GETSIPAOR, username_pure);
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ free(query);
+ return 2;
+ }
+
+
+ not_found=1;
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(strncmp((const char *)sip_aor,row[0],sipaorlen)==0)
+ {
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+ break;
+ }
+ return not_found;
+}
+
+int get_diameter_uri(const unsigned char *sip_aor, const size_t sipaorlen, char ** diameter_uri, size_t *diameterurilen)
+{
+ CHECK_PARAMS(sip_aor && sipaorlen);
+
+ size_t querylen, sipaorpurelen;
+ char *query, *sipaor_pure;
+ int not_found=2;
+
+
+
+
+ //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
+ if(sipaorlen<5)
+ return 2;
+
+ //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+
+ querylen=SQL_GETDIAMURI_LEN + sipaorlen;
+
+
+ //We allocate the double size of SIP-URI because at worst it can be all quotes
+ CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
+ //We purify SIP-URI not to have forbidden characters
+ sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
+
+
+ query = malloc(querylen+sipaorpurelen+ 2);
+ snprintf(query, querylen+1, SQL_GETDIAMURI, sipaor_pure);
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ diameter_uri=NULL;
+ return 2;
+ }
+
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ *diameterurilen=strlen(row[0]);
+ if(*diameterurilen>0)
+ {
+ CHECK_MALLOC(*diameter_uri=malloc(*diameterurilen+1));
+ strcpy(*diameter_uri,row[0]);
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+ free(sipaor_pure);
+ break;
+
+ default:
+
+ //We must never go here, if so, we must stop diameter_sip
+ diameter_uri=NULL;
+ return 2;
+
+ break;
+ }
+
+ //0 if it was found
+ return not_found;
+
+}
+
+
+int exist_username(const unsigned char *sip_aor, const size_t sipaorlen)
+{
+ CHECK_PARAMS(sip_aor && sipaorlen);
+
+ size_t querylen, sipaorpurelen;
+ char *query, *sipaor_pure;
+ int not_found=1;
+
+ //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
+ if(sipaorlen<5)
+ return 2;
+
+ //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+
+ querylen=SQL_GETUSERNAME_LEN + sipaorlen;
+
+
+ //We allocate the double size of SIP-URI because at worst it can be all quotes
+ CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
+ //We purify SIP-URI not to have forbidden characters
+ sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
+
+
+ query = malloc(querylen+sipaorpurelen+ 2);
+ snprintf(query, querylen+1, SQL_GETUSERNAME, sipaor_pure);
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ return 2;
+ }
+
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(strlen(row[0])>0)
+ {
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+ free(sipaor_pure);
+ break;
+
+ default:
+
+ //We must never go here, if so, we must stop diameter_sip
+ TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!");
+ return 2;
+
+ break;
+ }
+
+ //0 if it was found
+ return not_found;
+
+}
+
+//We check if this user can go in the given network
+int allow_roaming(const unsigned char *username, const size_t usernamelen, const char * network,const size_t networklen)
+{
+ CHECK_PARAMS(username && usernamelen && network && networklen);
+
+ int not_found=2;
+ size_t querylen, usernamepurelen;
+ char *query, *username_pure;
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+ //We allocate the double size of username because at worst it can be all quotes
+ username_pure=malloc(usernamelen*2+1);
+ //We purify username not to have forbidden characters
+ usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
+
+ //We get the list of AOR owned by this user
+ querylen=SQL_GETUSERNET_LEN + usernamepurelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_GETUSERNET, username_pure);
+
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ free(query);
+ return 2;
+ }
+
+
+ not_found=1;
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(strncmp((const char *)network,row[0],networklen)==0)
+ {
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+ break;
+ }
+ return not_found;
+}
+
+//SIP-Server-Capabilities for the SIP-AOR
+int get_sipserver_cap(const unsigned char *sip_aor, const size_t sipaorlen, struct avp **capabilities)
+{
+ CHECK_PARAMS(sip_aor && sipaorlen && capabilities);
+
+ size_t querylen, sipaorpurelen;
+ char *query, *sipaor_pure;
+ int not_found=2;
+ union avp_value value;
+ struct avp *avp;
+
+ //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
+ if(sipaorlen<5)
+ return 2;
+
+ //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+
+ querylen=SQL_GETSIPSERCAP_LEN + sipaorlen;
+
+
+ //We allocate the double size of SIP-URI because at worst it can be all quotes
+ CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
+ //We purify SIP-URI not to have forbidden characters
+ sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
+
+
+ query = malloc(querylen+sipaorpurelen+ 2);
+ snprintf(query, querylen+1, SQL_GETSIPSERCAP, sipaor_pure);
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ return 2;
+ }
+ not_found=1;
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(atoi(row[0])==1)
+ {//mandatory
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Mandatory_Capability, 0, &avp ) );
+ value.i32=(uint32_t)atoi(row[1]);
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *capabilities, MSG_BRW_LAST_CHILD, avp) );
+
+ }
+ else
+ {//optional
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Optional_Capability, 0, &avp ) );
+ value.i32=(uint32_t)atoi(row[1]);
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( *capabilities, MSG_BRW_LAST_CHILD, avp) );
+ }
+ not_found=0;
+ }
+
+ mysql_free_result(res);
+ free(query);
+ free(sipaor_pure);
+ break;
+
+ default:
+
+ //We must never go here, if so, we must stop diameter_sip
+ TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!");
+ return 2;
+
+ break;
+ }
+
+ //0 if it was found
+ return not_found;
+
+}
+
+
+//We retrieve datatype
+int add_user_datatype(const unsigned char *sip_aor, const size_t sipaorlen,struct msg *message)
+{
+ CHECK_PARAMS(sip_aor && sipaorlen && message );
+
+ size_t querylen, sipaorpurelen;
+ char *query, *sipaor_pure;
+ int not_found=2;
+ union avp_value value;
+ struct avp *avp, *rootavp;
+ unsigned long *length;
+
+ //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
+ if(sipaorlen<5)
+ return 2;
+
+ //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+
+ querylen=SQL_GETSIPDATA_LEN + sipaorlen;
+
+
+ //We allocate the double size of SIP-URI because at worst it can be all quotes
+ CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
+ //We purify SIP-URI not to have forbidden characters
+ sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
+
+
+ query = malloc(querylen+sipaorpurelen+ 2);
+ snprintf(query, querylen+1, SQL_GETSIPDATA, sipaor_pure);
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ return 2;
+ }
+ not_found=1;
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ length=mysql_fetch_lengths(res);
+
+ if(strlen(row[0])>1)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data, 0, &rootavp ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data_Type, 0, &avp ) );
+ CHECK_MALLOC(value.os.data=malloc(length[0]*sizeof(unsigned char)));
+ strncpy((char *)value.os.data,(char *)row[0],length[0]);
+ value.os.len=(size_t)length[0];
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( rootavp, MSG_BRW_LAST_CHILD, avp) );
+
+
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data_Contents, 0, &avp ) );
+ CHECK_MALLOC(value.os.data=malloc(length[1]*sizeof(unsigned char)));
+ memcpy(value.os.data,row[1],length[1]);
+ value.os.len=(size_t)length[1];
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( rootavp, MSG_BRW_LAST_CHILD, avp) );
+
+ //We add SIP_User_Data to message
+ CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, rootavp) );
+ not_found=0;
+ }
+
+ }
+
+ mysql_free_result(res);
+ free(query);
+ free(sipaor_pure);
+ break;
+
+ default:
+
+ //We must never go here, if so, we must stop diameter_sip
+ TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!");
+ return 2;
+
+ break;
+ }
+
+ //0 if it was found
+ return not_found;
+
+
+
+}
+
+int set_pending_flag(const unsigned char *username, const size_t usernamelen)
+{
+ CHECK_PARAMS(username && usernamelen);
+
+
+ size_t querylen, usernamepurelen;
+ char *query, *username_pure;
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+ //We allocate the double size of username because at worst it can be all quotes
+ username_pure=malloc(usernamelen*2+1);
+ //We purify username not to have forbidden characters
+ usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
+
+
+
+ //We clear the flag "authentication pending"
+ querylen=SQL_SETFLAG_LEN + usernamepurelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_SETFLAG, username_pure);
+
+ if (mysql_query(conn, query))
+ {
+ TRACE_DEBUG(INFO,"Query %s failed", query);
+ free(query);
+ return 2;
+ }
+
+ free(query);
+ break;
+ }
+ return 0;
+}
+int clear_pending_flag(const unsigned char *username, const size_t usernamelen)
+{
+ CHECK_PARAMS(username && usernamelen);
+
+
+ size_t querylen, usernamepurelen;
+ char *query, *username_pure;
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+ //We allocate the double size of username because at worst it can be all quotes
+ username_pure=malloc(usernamelen*2+1);
+ //We purify username not to have forbidden characters
+ usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
+
+
+
+ //We clear the flag "authentication pending"
+ querylen=SQL_CLEARFLAG_LEN + usernamepurelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_CLEARFLAG, username_pure);
+
+ if (mysql_query(conn, query))
+ {
+ TRACE_DEBUG(INFO,"Query %s failed", query);
+ free(query);
+ return 2;
+ }
+
+ free(query);
+ break;
+ }
+ return 0;
+}
+
+
+
+int set_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen)
+{
+ CHECK_PARAMS(username && usernamelen && sipserver_uri && sipserverurilen);
+
+
+ size_t querylen, usernamepurelen, sipserveruripurelen;
+ char *query, *username_pure, *sipserveruri_pure;
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+ //We allocate the double size of username because at worst it can be all quotes
+ username_pure=malloc(usernamelen*2+1);
+ //We purify username not to have forbidden characters
+ usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
+
+ //We allocate the double size of username because at worst it can be all quotes
+ sipserveruri_pure=malloc(sipserverurilen*2+1);
+ //We purify username not to have forbidden characters
+ sipserveruripurelen=mysql_real_escape_string(conn, sipserveruri_pure, (const char *)sipserver_uri, sipserverurilen);
+
+ //We clear the flag "authentication pending"
+ querylen=SQL_SETSIPURI_LEN + usernamepurelen + sipserveruripurelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_SETSIPURI, sipserveruri_pure,username_pure);
+
+ if (mysql_query(conn, query))
+ {
+ TRACE_DEBUG(INFO,"Query %s failed", query);
+ free(query);
+ return 2;
+ }
+
+ free(query);
+ break;
+ }
+ return 0;
+}
+int remove_sipserver_uri(const unsigned char *sipserver_uri,const size_t sipserverurilen)
+{
+ CHECK_PARAMS(sipserver_uri && sipserverurilen);
+
+
+ size_t querylen, sipserveruripurelen;
+ char *query, *sipserveruri_pure;
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+ //We allocate the double size of username because at worst it can be all quotes
+ sipserveruri_pure=malloc(sipserverurilen*2+1);
+ //We purify username not to have forbidden characters
+ sipserveruripurelen=mysql_real_escape_string(conn, sipserveruri_pure, (const char *)sipserver_uri, sipserverurilen);
+
+ //We clear the flag "authentication pending"
+ querylen=SQL_RMSIPURI_LEN + sipserveruripurelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_RMSIPURI, sipserveruri_pure);
+
+ if (mysql_query(conn, query))
+ {
+ TRACE_DEBUG(INFO,"Query %s failed", query);
+ free(query);
+ return 2;
+ }
+
+ free(query);
+ break;
+ }
+ return 0;
+}
+int set_real_sipserver_uri(const unsigned char *username, const size_t usernamelen, const unsigned char *sipserver_uri,const size_t sipserverurilen)
+{
+ CHECK_PARAMS(username && usernamelen && sipserver_uri && sipserverurilen);
+
+
+ size_t querylen, usernamepurelen, sipserveruripurelen;
+ char *query, *username_pure, *sipserveruri_pure;
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+ //We allocate the double size of username because at worst it can be all quotes
+ username_pure=malloc(usernamelen*2+1);
+ //We purify username not to have forbidden characters
+ usernamepurelen=mysql_real_escape_string(conn, username_pure, (const char *)username, usernamelen);
+
+ //We allocate the double size of username because at worst it can be all quotes
+ sipserveruri_pure=malloc(sipserverurilen*2+1);
+ //We purify username not to have forbidden characters
+ sipserveruripurelen=mysql_real_escape_string(conn, sipserveruri_pure, (const char *)sipserver_uri, sipserverurilen);
+
+ //We clear the flag "authentication pending"
+ querylen=SQL_SETREALSIPURI_LEN + usernamepurelen + sipserveruripurelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_SETREALSIPURI, sipserveruri_pure,username_pure);
+
+ if (mysql_query(conn, query))
+ {
+ TRACE_DEBUG(INFO,"Query %s failed", query);
+ free(query);
+ return 2;
+ }
+
+ free(query);
+ break;
+ }
+ return 0;
+}
+
+int get_sipserver_uri(const unsigned char *sip_aor, const size_t sipaorlen, unsigned char ** sipserver_uri, size_t *sipserverurilen)
+{
+ CHECK_PARAMS(sip_aor && sipaorlen && sipserver_uri && sipserverurilen );
+
+ size_t querylen, sipaorpurelen;
+ char *query, *sipaor_pure;
+ int not_found=2;
+
+
+
+
+ //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
+ if(sipaorlen<5)
+ return 2;
+
+ //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
+
+ switch(as_conf->datasource)
+ {
+ //MySQL
+ case ASMYSQL:
+
+ querylen=SQL_GETSIPSERURI_LEN + sipaorlen;
+
+ //We allocate the double size of SIP-URI because at worst it can be all quotes
+ CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
+ //We purify SIP-URI not to have forbidden characters
+ sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
+
+
+ query = malloc(querylen+sipaorpurelen+ 2);
+ snprintf(query, querylen+1, SQL_GETSIPSERURI, sipaor_pure);
+
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ sipserver_uri=NULL;
+ return 2;
+ }
+
+ not_found=1;
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ *sipserverurilen=strlen(row[0]);
+ if(*sipserverurilen>4)
+ {
+ CHECK_MALLOC(*sipserver_uri=malloc(*sipserverurilen+1));
+ strcpy((char *)*sipserver_uri,row[0]);
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+ free(sipaor_pure);
+ break;
+
+ default:
+
+ //We must never go here, if so, we must stop diameter_sip
+ TRACE_DEBUG(INFO,"FATAL ERROR: the datasource is unknown, please check your config file!");
+ sipserver_uri=NULL;
+ return 2;
+
+ break;
+ }
+
+ //0 if it was found
+ return not_found;
+
+}
+
+
+int count_avp(struct msg * message, int code, int vendor)
+{
+ CHECK_PARAMS(message);
+
+ struct avp_hdr *temphdr;
+ struct avp *avp;
+ int counter=0;
+
+ CHECK_FCT(fd_msg_browse (message, MSG_BRW_WALK, &avp, NULL));
+
+ while(avp!=NULL)
+ {
+
+ CHECK_FCT( fd_msg_avp_hdr( avp,&temphdr ));
+
+ if(temphdr->avp_code==code && temphdr->avp_vendor==vendor)
+ {
+ counter++;
+ }
+
+ CHECK_FCT(fd_msg_browse (avp, MSG_BRW_WALK, &avp, NULL));
+ }
+ return counter;
+}
+/*
+void nonce_add_element(char * nonce)
+{
+ noncechain *newelt=malloc(sizeof(noncechain));
+
+ newelt->nonce=nonce;
+
+ newelt->timestamp=(int)time(NULL);
+ newelt->next=NULL;
+
+ if(listnonce==NULL)
+ {
+ listnonce=newelt;
+ }
+ else
+ {
+ noncechain* temp=listnonce;
+
+ while(temp->next != NULL)
+ {
+ if(temp->timestamp < ((int)time(NULL)-300))
+ {
+ listnonce=temp->next;
+ free(temp);
+ temp=listnonce;
+ }
+ temp = temp->next;
+ }
+ temp->next = newelt;
+ }
+
+}
+void nonce_del_element(char * nonce)
+{
+ if(listnonce!=NULL)
+ {
+ noncechain *temp=listnonce, *tempbefore=NULL;
+
+ if(listnonce->next==NULL && strcmp(listnonce->nonce,nonce)==0)
+ {
+ free(listnonce);
+ listnonce=NULL;
+ return;
+ }
+ while(temp->next != NULL)
+ {
+ if(strcmp(temp->nonce,nonce)==0)
+ {
+ if(tempbefore==NULL)
+ {
+ listnonce=temp->next;
+ free(temp);
+ return;
+ }
+ tempbefore->next=temp->next;
+ free(temp);
+ break;
+ }
+ tempbefore=temp;
+ temp = temp->next;
+ }
+
+ }
+
+}
+int nonce_check_element(char * nonce)
+{
+ if(listnonce==NULL)
+ {
+ //Not found
+ return 0;
+ }
+ else
+ {
+ noncechain* temp=listnonce;
+
+ while(temp->next != NULL)
+ {
+ if(strcmp(temp->nonce,nonce)==0)
+ return 1;
+ else
+ temp = temp->next;
+ }
+ }
+ return 0;
+}
+
+void nonce_deletelistnonce()
+{
+ if(listnonce !=NULL)
+ {
+ noncechain* temp=listnonce;
+
+ while(listnonce->next != NULL)
+ {
+ temp = listnonce->next;
+
+ free(listnonce);
+
+ listnonce=temp;
+ }
+ free(listnonce);
+ }
+}
+*/
diff --git a/extensions/app_sip/locationinfo.c b/extensions/app_sip/locationinfo.c
new file mode 100644
index 0000000..e2c372a
--- /dev/null
+++ b/extensions/app_sip/locationinfo.c
@@ -0,0 +1,208 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "app_sip.h"
+
+
+int app_sip_LIR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
+
+ struct msg *ans, *qry;
+ struct avp *avp, *groupedavp;
+ struct avp_hdr *avphdr;
+ union avp_value value;
+ int ret=0;
+
+ //Result_Code to return in the answer
+ char result[55];
+
+ if (msg == NULL)
+ return EINVAL;
+
+
+ // Create answer header
+ qry = *msg;
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+ //Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = 6;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+ }
+ // Add the Auth-Session-State AVP
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+
+ //Add a SIP_Server_URI
+ {
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+
+
+
+
+ ret=exist_username(avphdr->avp_value->os.data, avphdr->avp_value->os.len);
+
+
+ if(ret==2)
+ {//error
+ /*
+ If the Diameter server cannot process the Diameter LIR command, e.g.,
+ due to a database error, the Diameter server MUST set the Result-Code
+ AVP value to DIAMETER_UNABLE_TO_COMPLY and return it in a Diameter
+ LIA message.
+ */
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ else if(ret==1)
+ {//not found
+ /*
+ One of the errors that the Diameter server may find is that the
+ SIP-AOR AVP value is not a valid user in the realm. In such cases,
+ the Diameter server MUST set the Result-Code AVP value to
+ DIAMETER_ERROR_USER_UNKNOWN and return it in a Diameter LIA message.
+
+ */
+ strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN");
+ goto out;
+ }
+
+ //If we arrive here, the user is known
+ size_t sipserverurilen;
+ unsigned char * sipserver_uri=NULL;
+
+ ret=get_sipserver_uri(avphdr->avp_value->os.data, avphdr->avp_value->os.len, &sipserver_uri, &sipserverurilen);
+
+
+ if(ret==0)
+ {//found
+ if(sipserver_uri==NULL)
+ {
+ //There is a problem because we must get a Diameter_URI here
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ else
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_URI, 0, &avp ) );
+ value.os.data=(unsigned char *)sipserver_uri;
+ value.os.len=sipserverurilen;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+
+ strcpy(result,"DIAMETER_SUCCESS");
+ }
+ }
+ else if(ret==1)
+ {//not found
+ //We don't know this SIP_AOR in SL, that means
+ strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN");
+ goto out;
+ }
+ else
+ {// returned 2, impossible to make request
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+
+ //Adding SIP-Server-Capabilities
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_Capabilities, 0, &groupedavp ) );
+ //We add mandatory and optional capabilities
+ ret=get_sipserver_cap(avphdr->avp_value->os.data, avphdr->avp_value->os.len, &groupedavp);
+
+
+ if(ret==0)
+ {//found
+ if(sipserver_uri==NULL)
+ {
+ //There is a problem because we must get a Diameter_URI here
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ CHECK_FCT( fd_msg_free( groupedavp ) );
+ goto out;
+ }
+ else
+ {
+
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) );
+
+ strcpy(result,"DIAMETER_SUCCESS");
+ }
+ }
+ else if(ret==1)
+ {//not found
+ //We don't know this SIP_AOR in SL, that means
+ strcpy(result,"DIAMETER_ERROR_IDENTITY_NOT_REGISTERED");
+ CHECK_FCT( fd_msg_free( groupedavp ) );
+ goto out;
+ }
+ else
+ {// returned 2, impossible to make request
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ CHECK_FCT( fd_msg_free( groupedavp ) );
+ goto out;
+ }
+
+
+
+ }
+
+
+
+
+out:
+ CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
+
+ CHECK_FCT( fd_msg_send( msg, NULL, NULL ));
+
+
+
+ return 0;
+}
diff --git a/extensions/app_sip/locationinfosl.c b/extensions/app_sip/locationinfosl.c
new file mode 100644
index 0000000..f28beef
--- /dev/null
+++ b/extensions/app_sip/locationinfosl.c
@@ -0,0 +1,144 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "app_sip.h"
+
+//This callback is specific to SUSCRIBER LOCATOR. We must look for the "serving" SIP server
+int app_sip_SL_LIR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
+
+ struct msg *ans, *qry;
+ struct avp *avp;
+ struct avp_hdr *avphdr;
+ union avp_value value;
+
+ //Result_Code to return in the answer
+ char result[55];
+ int ret=0;
+
+
+ if (msg == NULL)
+ return EINVAL;
+
+
+
+ // Create answer header
+ qry = *msg;
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+
+ //Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = 6;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ // Add the Auth-Session-State AVP
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+
+ // Add the Redirect Host AVP
+ {
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+ size_t diameterurilen;
+ char * diameter_uri=NULL;
+
+
+
+ ret=get_diameter_uri(avphdr->avp_value->os.data, avphdr->avp_value->os.len, &diameter_uri, &diameterurilen);
+
+ //found
+ if(ret==0)
+ {
+ if(diameter_uri==NULL)
+ {
+ //There is a problem because we must get a Diameter_URI here
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ else
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Redirect_Host, 0, &avp ) );
+ value.os.data=(unsigned char *)diameter_uri;
+ value.os.len=diameterurilen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Redirect_Host_Usage, 0, &avp ) );
+ value.i32=ALL_USER; //All the request about the same user must be sent to this server
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ strcpy(result,"DIAMETER_SUCCESS");
+ }
+ }
+ else if(ret==1)
+ {//not found
+ //We don't know this SIP_AOR in SL
+ strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN");
+ goto out;
+ }
+ else
+ {// returned 2, impossible to make request
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+
+
+out:
+ CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
+
+
+
+ CHECK_FCT( fd_msg_send( msg, NULL, NULL ));
+
+
+
+ return 0;
+}
diff --git a/extensions/app_sip/md5.c b/extensions/app_sip/md5.c
new file mode 100644
index 0000000..4079bda
--- /dev/null
+++ b/extensions/app_sip/md5.c
@@ -0,0 +1,421 @@
+/*********************************************************************************/
+/* freeDiameter author note:
+ * The content from this file comes directly from the hostap project.
+ * It is redistributed under the terms of the BSD license, as allowed
+ * by the original copyright reproduced below.
+ * In addition to this notice, only the #include directives have been modified.
+ */
+
+/*********************************************************************************/
+#include"app_sip.h"
+
+/*
+ * MD5 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+void CvtHex(
+ IN HASH Bin,
+ OUT HASHHEX Hex
+ )
+{
+ unsigned short i;
+ unsigned char j;
+
+ for (i = 0; i < HASHLEN; i++) {
+ j = (Bin[i] >> 4) & 0xf;
+ if (j <= 9)
+ Hex[i*2] = (j + '0');
+ else
+ Hex[i*2] = (j + 'a' - 10);
+ j = Bin[i] & 0xf;
+ if (j <= 9)
+ Hex[i*2+1] = (j + '0');
+ else
+ Hex[i*2+1] = (j + 'a' - 10);
+ }
+ Hex[HASHHEXLEN] = '\0';
+}
+
+// calculate H(A1) as per spec
+void DigestCalcHA1(char * pszAlg,char * pszUserName,char * pszRealm,char * pszPassword,char * pszNonce,char * pszCNonce,HASHHEX SessionKey)
+{
+ MD5_CTX Md5Ctx;
+ HASH HA1;
+
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszUserName, strlen(pszUserName));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszRealm, strlen(pszRealm));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszPassword, strlen(pszPassword));
+ MD5Final((unsigned char *)HA1, &Md5Ctx);
+ if (strcmp(pszAlg, "md5-sess") == 0) {
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, (const unsigned char *)HA1, HASHLEN);
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszNonce, strlen(pszNonce));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszCNonce, strlen(pszCNonce));
+ MD5Final((unsigned char *)HA1, &Md5Ctx);
+ }
+ CvtHex(HA1, SessionKey);
+}
+
+// calculate request-digest as SIP Digest spec RFC5090
+void DigestCalcResponse(HASHHEX HA1,char * pszNonce,char * pszNonceCount,char * pszCNonce,char * pszQop,char * pszMethod,char * pszDigestUri,HASHHEX HEntity,HASHHEX Response)
+{
+ MD5_CTX Md5Ctx;
+ HASH HA2;
+ HASH RespHash;
+ HASHHEX HA2Hex;
+
+ // calculate H(A2)
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszMethod, strlen(pszMethod));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszDigestUri, strlen(pszDigestUri));
+ if (strcmp(pszQop, "auth-int") == 0) {
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)HEntity, HASHHEXLEN);
+ }
+ MD5Final((unsigned char *)HA2, &Md5Ctx);
+ CvtHex(HA2, HA2Hex);
+
+ // calculate response
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, (const unsigned char *)HA1, HASHHEXLEN);
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx,(const unsigned char *) pszNonce, strlen(pszNonce));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ if (*pszQop) {
+ MD5Update(&Md5Ctx, (const unsigned char *)pszNonceCount, strlen(pszNonceCount));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszCNonce, strlen(pszCNonce));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszQop, strlen(pszQop));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ }
+ MD5Update(&Md5Ctx, (const unsigned char *)HA2Hex, HASHHEXLEN);
+ MD5Final((unsigned char *)RespHash, &Md5Ctx);
+ CvtHex(RespHash, Response);
+}
+// calculate Digest_response_Auth as per SIP Digest spec RFC5090
+void DigestCalcResponseAuth(HASHHEX HA1,char * pszNonce,char * pszNonceCount,char * pszCNonce,char * pszQop,char * pszMethod,char * pszDigestUri,HASHHEX HEntity,HASHHEX Response)
+{
+ MD5_CTX Md5Ctx;
+ HASH HA2;
+ HASH RespHash;
+ HASHHEX HA2Hex;
+
+ // calculate H(A2)
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszDigestUri, strlen(pszDigestUri));
+ if (strcmp(pszQop, "auth-int") == 0) {
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)HEntity, HASHHEXLEN);
+ }
+ MD5Final((unsigned char *)HA2, &Md5Ctx);
+ CvtHex(HA2, HA2Hex);
+
+ // calculate response
+ MD5Init(&Md5Ctx);
+ MD5Update(&Md5Ctx, (const unsigned char *)HA1, HASHHEXLEN);
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszNonce, strlen(pszNonce));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ if (*pszQop) {
+ MD5Update(&Md5Ctx, (const unsigned char *)pszNonceCount, strlen(pszNonceCount));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszCNonce, strlen(pszCNonce));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ MD5Update(&Md5Ctx, (const unsigned char *)pszQop, strlen(pszQop));
+ MD5Update(&Md5Ctx, (const unsigned char *)":", 1);
+ }
+ MD5Update(&Md5Ctx, (const unsigned char *)HA2Hex, HASHHEXLEN);
+ MD5Final((unsigned char *)RespHash, &Md5Ctx);
+ CvtHex(RespHash, Response);
+}
+
+
+
+
+
+static void MD5Transform(u32 buf[4], u32 const in[16]);
+
+
+
+
+/**
+ * md5_vector - MD5 hash for data vector
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
+ * @mac: Buffer for the hash
+ */
+void md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
+{
+ MD5_CTX ctx;
+ size_t i;
+
+ MD5Init(&ctx);
+ for (i = 0; i < num_elem; i++)
+ MD5Update(&ctx, addr[i], len[i]);
+ MD5Final(mac, &ctx);
+}
+
+
+/* ===== start - public domain MD5 implementation ===== */
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#ifndef WORDS_BIGENDIAN
+#define byteReverse(buf, len) /* Nothing */
+#else
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(unsigned char *buf, unsigned longs)
+{
+ u32 t;
+ do {
+ t = (u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(u32 *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
+{
+ u32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((u32) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ os_memcpy(p, buf, len);
+ return;
+ }
+ os_memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (u32 *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ os_memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (u32 *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ os_memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ os_memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (u32 *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ os_memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ os_memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((u32 *) ctx->in)[14] = ctx->bits[0];
+ ((u32 *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Transform(ctx->buf, (u32 *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ os_memcpy(digest, ctx->buf, 16);
+ os_memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+static void MD5Transform(u32 buf[4], u32 const in[16])
+{
+ register u32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+/* ===== end - public domain MD5 implementation ===== */
+
diff --git a/extensions/app_sip/md5.h b/extensions/app_sip/md5.h
new file mode 100644
index 0000000..fc55872
--- /dev/null
+++ b/extensions/app_sip/md5.h
@@ -0,0 +1,59 @@
+/*********************************************************************************/
+/* freeDiameter author note:
+ * The content from this file comes directly from the hostap project.
+ * It is redistributed under the terms of the BSD license, as allowed
+ * by the original copyright reproduced below.
+ * The file has not been modified, except for this notice.
+ */
+/*********************************************************************************/
+
+/*
+ * MD5 hash implementation and interface functions
+ * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef MD5_H
+#define MD5_H
+
+#define MD5_MAC_LEN 16
+
+typedef uint64_t u64;
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+typedef int64_t s64;
+typedef int32_t s32;
+typedef int16_t s16;
+typedef int8_t s8;
+
+#define HASHLEN 16
+typedef char HASH[HASHLEN];
+#define HASHHEXLEN 32
+typedef char HASHHEX[HASHHEXLEN+1];
+#define IN
+#define OUT
+
+struct MD5Context {
+ u32 buf[4];
+ u32 bits[2];
+ u8 in[64];
+};
+typedef struct MD5Context MD5_CTX;
+#define os_memcpy(d, s, n) memcpy((d), (s), (n))
+#define os_memset(s, c, n) memset(s, c, n)
+
+
+void MD5Init(struct MD5Context *ctx);
+void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len);
+void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
+
+#endif /* MD5_H */
diff --git a/extensions/app_sip/multimediaauth.c b/extensions/app_sip/multimediaauth.c
new file mode 100644
index 0000000..12c1bcb
--- /dev/null
+++ b/extensions/app_sip/multimediaauth.c
@@ -0,0 +1,762 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "app_sip.h"
+
+struct sess_state
+{
+ char *nonce;
+};
+
+
+int app_sip_MAR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ struct msg *ans, *qry;
+ struct avp *avp, *a2, *authdataitem;
+ //struct msg_hdr * header = NULL;
+ struct avp_hdr * avphdr=NULL, *avpheader=NULL, *avpheader_auth=NULL,*digestheader=NULL;
+ union avp_value val;
+ int found_cnonce=0;
+ struct avp * tempavp=NULL,*sipAuthentication=NULL,*sipAuthenticate=NULL;
+ char * result;
+ char password[51];
+ int idx=0, number_of_auth_items=0,i=0, ret=0;
+ //Flags and variables for Database
+ int sipurinotstored=0, authenticationpending=0;
+ size_t querylen=0, usernamelen=0;
+ char *query=NULL;
+ unsigned char *username=NULL;
+
+ //The nonce we will store and retrieve in session
+ struct sess_state *storednonce=NULL;
+
+
+ TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
+
+ if (msg == NULL)
+ return EINVAL;
+
+
+ /* Create answer header */
+ qry = *msg;
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+
+
+ /* Add the appropriate command code & Auth-Application-Id
+ {
+
+ CHECK_FCT( fd_msg_hdr ( *msg, &header ) );
+ header->msg_flags = CMD_FLAG_PROXIABLE;
+ header->msg_code = 286;
+ header->msg_appl = 6;
+
+
+ // Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ ASSERT(avp);
+ val.i32 = header->msg_appl;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &val ) );
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+ }
+ }*/
+
+
+ /* Add the Auth-Session-State AVP */
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+
+
+ /* Check if method is REGISTER then User-Name must be present */
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Method, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avpheader ));
+
+
+ char *method=NULL;
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.User_Name, &avp) );
+ if(avp!=NULL)
+ {
+
+ int not_found=1;
+ MYSQL_RES *res=NULL;
+ MYSQL_ROW row;
+
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+
+
+
+ if((strncmp((const char *)avpheader->avp_value->os.data,"REGISTER",avpheader->avp_value->os.len)==0))
+ {
+ not_found=1;
+
+ //TODO TODO TODO TODO TODO TODO TODO: maybe doesn't work!!'
+ ret=get_password(avphdr->avp_value->os.data, avphdr->avp_value->os.len, (char *)&password);
+
+ if(ret>1)
+ {
+ //We couldn't make the request
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ goto out;
+ }
+ not_found=ret;
+
+ if(not_found)
+ {
+ TRACE_DEBUG(FULL,"The user %s doesn't exist!",username);
+ result="DIAMETER_ERROR_USER_UNKNOWN";
+ free(username);
+ goto out;
+ }
+
+
+ //We allocate the double size of username because at worst it can be all quotes
+ username=malloc(avphdr->avp_value->os.len*2+1);
+ //We purify username not to have forbidden characters
+ usernamelen=mysql_real_escape_string(conn, (char *)username, (const char *)avphdr->avp_value->os.data, avphdr->avp_value->os.len);
+
+ //Now that we know the user exist, we get the list of AOR owned by this user
+ querylen=SQL_GETSIPAOR_LEN + usernamelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_GETSIPAOR, username);
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ goto out;
+ }
+
+ //We retrieve the SIP-AOR from AVP to check if the user can us it
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ not_found=1;
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(strncmp((const char *)avphdr->avp_value->os.data,row[0],avphdr->avp_value->os.len)==0)
+ {
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+
+ if(not_found)
+ {
+ TRACE_DEBUG(FULL,"The user %s can't use this SIP-AOR!",username);
+ result="DIAMETER_ERROR_IDENTITIES_DONT_MATCH";
+ free(username);
+ goto out;
+ }
+
+ }
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ));
+
+ if(avphdr!=NULL)
+ {
+ unsigned char *sipuri=NULL;
+ int sipurilen=0;
+
+ //We allocate the double size of SIP-URI because at worst it can be all quotes
+ CHECK_MALLOC(sipuri=malloc(avphdr->avp_value->os.len*2+1));
+ //We purify SIP-URI not to have forbidden characters
+ sipurilen=mysql_real_escape_string(conn, (char *)sipuri, (const char *)avphdr->avp_value->os.data, avphdr->avp_value->os.len);
+
+
+ //We get the SIP-URI assignated to the user
+ querylen=SQL_GETSIPURI_LEN + usernamelen;
+ CHECK_MALLOC(query = malloc(querylen+2));
+ snprintf(query, querylen+1, SQL_GETSIPURI, username);
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ goto out;
+ }
+ not_found=1;
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(strncmp((const char *)avphdr->avp_value->os.data,row[0],avphdr->avp_value->os.len)==0)
+ {
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+
+ if(not_found)
+ {
+ //Temporary
+ set_sipserver_uri(username, usernamelen, sipuri,sipurilen);
+
+
+ set_pending_flag(username, usernamelen);
+
+
+ authenticationpending=1;
+ }
+ free(sipuri);
+
+ }
+ else
+ sipurinotstored=1;
+
+ }
+ else
+ {
+ result="DIAMETER_USER_NAME_REQUIRED";
+ goto out;
+ }
+
+
+ free(method);
+
+ }
+
+
+ //TODO: remove loop for authdataitem because RFC say only one (wait for answer from Garcia)
+ // How many Auth Data Items?
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Number_Auth_Items, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avpheader ) );
+
+
+ if(avp!=NULL)
+ {
+ CHECK_FCT(fd_msg_search_avp ( qry, sip_dict.SIP_Auth_Data_Item, &avp));
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ if(avp!=NULL)
+ {
+ //First is Authentication Scheme
+ CHECK_FCT(fd_msg_browse ( avp, MSG_BRW_FIRST_CHILD, &avp, NULL) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ //Digest-Authentication?
+ if(avphdr->avp_value->i32==0)
+ {
+
+ for(idx=0;idx<avpheader->avp_value->i32;idx++)
+ {
+ //We look for SIP Auth items
+ CHECK_FCT(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL) );
+
+ if(avp!=NULL)
+ {
+
+ CHECK_FCT( fd_msg_avp_hdr( avp,&avphdr ));
+
+ if(avphdr->avp_code==380) //We only create Auth-Data-Item to answer Auth-Data-Item
+ {
+ /* Add the Auth-Data-Item AVP */
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Auth_Data_Item, 0, &authdataitem ) );
+
+ /* Add the Authentication Scheme AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Authentication_Scheme, 0, &a2 ) );
+ val.i32=0; //We only know Digest Authentication
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( authdataitem, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+
+ //We need to know if there is a Cnonce attribute (only in the second MAR request)
+
+ //CHECK_FCT(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL) );
+
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_CNonce, &a2 ));
+
+ if(a2!=NULL)
+ found_cnonce=1;
+ else
+ found_cnonce=0;
+
+ if(!found_cnonce)
+ {
+ /*
+ We are in the case of first access request so we need to challenge the user.
+ */
+ TRACE_DEBUG(FULL,"First Authorization in progress...");
+
+ /* Create a new session */ //this create a new session Id !!!
+ //CHECK_FCT_DO( fd_sess_new( &sess, fd_g_config->cnf_diamid, "diamsip", 7), goto out );
+
+
+ /* Create the SIP-Authenticate AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Authenticate, 0, &sipAuthenticate ) );
+ }
+
+ /* Add the Digest QOP AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_QOP, 0, &a2 ) );
+ val.os.data=(unsigned char *)"auth";
+ val.os.len=strlen((const char *)val.os.data);
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthenticate, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+ /* Add the Digest Nonce AVP */
+ {
+ uint8_t buffer[NONCE_SIZE];
+ char nonce[NONCE_SIZE * 2 + 1];
+
+
+ gcry_create_nonce ((uint8_t *)buffer, sizeof(buffer));
+
+ for(i=0;i<NONCE_SIZE;i++)
+ sprintf(&nonce[2 * i], "%2.2hhx", buffer[i]);
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_Nonce, 0, &a2 ) );
+
+
+ //We store the nonce (storednonce structure) inside the session
+ storednonce=malloc(sizeof(struct sess_state));
+ memset(storednonce,0,sizeof(struct sess_state));
+ CHECK_MALLOC(storednonce->nonce=malloc(NONCE_SIZE*2+1));
+ memcpy(storednonce->nonce,(char *)nonce,NONCE_SIZE*2+1);
+ CHECK_FCT( fd_sess_state_store ( ds_sess_hdl, sess, &storednonce ));
+
+ val.os.data=(unsigned char *)nonce;
+ val.os.len=NONCE_SIZE * 2;
+
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthenticate, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+ /* Add the Digest Algorithm AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_Algorithm, 0, &a2 ) );
+ val.os.data=(unsigned char *)"MD5";
+ val.os.len=strlen((const char *)val.os.data);
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthenticate, MSG_BRW_LAST_CHILD, a2 ) );
+
+ }
+ /* Add the Digest Realm AVP */
+ {
+ tempavp=avp;
+
+ avpheader_auth=walk_digest(tempavp, 104);
+ if(avpheader_auth!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_Realm, 0, &a2 ) );
+ CHECK_FCT( fd_msg_avp_setvalue( a2, avpheader_auth->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthenticate, MSG_BRW_LAST_CHILD, a2 ) );
+
+ }
+ }
+
+
+ //We add SIP Authenticate to Auth Data Item
+ CHECK_FCT( fd_msg_avp_add( authdataitem, MSG_BRW_LAST_CHILD, sipAuthenticate ) );
+ //We add Auth Data Item to Answer
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, authdataitem ) );
+
+ number_of_auth_items++;
+ if(sipurinotstored)
+ result="DIAMETER_SUCCESS_AUTH_SENT_SERVER_NOT_STORED";
+ else
+ result="DIAMETER_MULTI_ROUND_AUTH";
+ found_cnonce=0;
+ }
+ else
+ {
+ /*
+ We are in the case of access request after challenge so we need to check credentials.
+ */
+ TRACE_DEBUG(FULL,"Authentication after challenge");
+
+ /* Search the session, retrieve its data */
+ {
+ //int new=0;
+
+ //TRACE_DEBUG(FULL,"new: *%d*",new);
+ //ASSERT( new == 0 );
+ CHECK_FCT( fd_sess_state_retrieve( ds_sess_hdl, sess, &storednonce ));
+ if(storednonce ==NULL)
+ {
+ result="DIAMETER_UNABLE_TO_COMPLY";
+
+ if(username!=NULL)
+ free(username);
+ goto out;
+ }
+ }
+
+ /* Create the SIP-Authentication-Info AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Authentication_Info, 0, &sipAuthentication ) );
+ }
+
+
+
+ /* Add the Digest response Auth AVP */
+ {
+ //uint8_t bufferresp[DIGEST_LEN];
+ //char response[DIGEST_LEN*2+1];
+
+
+ //We extract all the data we need
+ tempavp=avp;
+
+ char * digest_username=NULL, *digest_uri=NULL, *digest_response=NULL, *digest_realm=NULL, *digest_nonce=NULL, *digest_method=NULL, *digest_qop=NULL, *digest_algorithm=NULL, *digest_cnonce=NULL, *digest_noncecount=NULL;
+
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Nonce, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+
+ digest_nonce = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_nonce, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_nonce[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_nonce);
+ TRACE_DEBUG(FULL,"Stored Nonce:*%s*",storednonce->nonce);
+
+ if(strcmp(digest_nonce,storednonce->nonce)!=0)
+ {
+ free(digest_nonce);
+ free(storednonce->nonce);
+ free(storednonce);
+ result="DIAMETER_UNABLE_TO_COMPLY";
+
+ if(username!=NULL)
+ free(username);
+ goto out;
+ }
+
+ }
+
+ }
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Response, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_response = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_response, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_response[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_response);
+ }
+
+ }
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Realm, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_realm = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_realm, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_realm[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_realm);
+ }
+ }
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Method, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_method = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_method, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_method[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_method);
+ }
+ }
+ else
+ digest_method="";
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_URI, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_uri = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_uri, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_uri[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_uri);
+ }
+ }
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_QOP, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_qop = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_qop, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_qop[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_qop);
+ }
+ }
+ else
+ digest_qop=NULL;
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Algorithm, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_algorithm = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_algorithm, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_algorithm[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_algorithm);
+ }
+ }
+ else
+ digest_algorithm=NULL;
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_CNonce, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_cnonce = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_cnonce, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_cnonce[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_cnonce);
+ }
+ }
+ else
+ digest_cnonce="";
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Nonce_Count, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_noncecount = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_noncecount, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_noncecount[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_noncecount);
+ }
+ }
+ else
+ digest_noncecount="";
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Username, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_username = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_username, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_username[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_username);
+ }
+ }
+ //TODO: replace by authentication function
+
+ HASHHEX HA1;
+ HASHHEX HA2 = "";
+ HASHHEX response, responseauth;
+
+
+ DigestCalcHA1(digest_algorithm, digest_username, digest_realm, password, digest_nonce,digest_cnonce, HA1);
+ DigestCalcResponse(HA1, digest_nonce, digest_noncecount, digest_cnonce, digest_qop,digest_method, digest_uri, HA2, response);
+
+
+ // We check that the Digest-Response is the same (UA, Diameter)
+ if(strcmp(response,digest_response)!=0)
+ {
+ TRACE_DEBUG(FULL,"Response calculated by Diameter server:%s",response);
+ TRACE_DEBUG(FULL,"Response calculated by UA:%s",digest_response);
+ TRACE_DEBUG(INFO,"Digest-Response does not match!");
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ free(digest_algorithm);
+ free(digest_cnonce);
+ free(digest_nonce);
+ free(digest_noncecount);
+ free(digest_method);
+ free(digest_username);
+ free(digest_uri);
+ free(digest_qop);
+ free(digest_response);
+ free(digest_realm);
+ free(storednonce->nonce);
+ free(storednonce);
+ if(username!=NULL)
+ free(username);
+ goto out;
+
+ }
+ //We calculate Digest_Response_Auth
+ DigestCalcResponseAuth(HA1, digest_nonce, digest_noncecount, digest_cnonce, digest_qop,digest_method, digest_uri, HA2, responseauth);
+
+ TRACE_DEBUG(FULL,"Response calculated by Diameter server:%s",response);
+ TRACE_DEBUG(FULL,"Response calculated by UA:%s",digest_response);
+ if(strcmp(digest_qop,"auth-int")==0)
+ {
+ //Digest-HA1 MUST be used instead of Digest-Response-Auth if Digest-Qop is 'auth-int'.
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_HA1, 0, &a2 ) );
+ val.os.data=(unsigned char *)HA1;
+ val.os.len=HASHHEXLEN+1;
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthentication, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+ else
+ {
+ //Digest-Response-Auth MUST be used instead of Digest-HA1 if Digest-Qop is 'auth'.
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_Response_Auth, 0, &a2 ) );
+ val.os.data=(unsigned char *)responseauth;
+ val.os.len=DIGEST_LEN*2;
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthentication, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+ free(digest_algorithm);
+ free(digest_cnonce);
+ free(digest_nonce);
+ free(digest_noncecount);
+ free(digest_method);
+ free(digest_username);
+ free(digest_uri);
+ free(digest_qop);
+ free(digest_response);
+ free(digest_realm);
+ free(storednonce->nonce);
+ free(storednonce);
+
+ number_of_auth_items++;
+ }
+
+
+ //We add SIP Authentication-Info to Auth Data Item
+ CHECK_FCT( fd_msg_avp_add( authdataitem, MSG_BRW_LAST_CHILD, sipAuthentication ) );
+ //We add Auth Data Item to Answer
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, authdataitem ) );
+
+
+ if(username!=NULL && authenticationpending)
+ {
+ //We clear the pending flag
+ clear_pending_flag(username, usernamelen);
+ }
+
+ if(sipurinotstored)
+ result="DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED";
+ else
+ result="DIAMETER_SUCCESS";
+ found_cnonce=0;
+ }
+ }
+ }
+ else
+ TRACE_DEBUG(INFO,"No auth data items!");
+ }
+ /*Add SIP_Number_Auth_Items AVP */
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Number_Auth_Items, 0, &avp ) );
+ val.i32 = number_of_auth_items;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &val ) );
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+
+ }
+ else
+ {
+ TRACE_DEBUG(INFO,"We only support DIGEST for now, unable to comply");
+ result="DIAMETER_ERROR_AUTH_SCHEME_NOT_SUPPORTED";
+ if(username!=NULL)
+ free(username);
+ goto out;
+ }
+ }
+ }
+ else
+ {
+ //TODO: remove this because Number_Auth_Items is not compulsory
+ TRACE_DEBUG(FULL,"Number-Auth-Items is not included.");
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ if(username!=NULL)
+ free(username);
+ goto out;
+ }
+
+ if(username!=NULL)
+ free(username);
+
+
+out:
+ /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */
+ CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
+
+
+ /* Send the answer */
+ CHECK_FCT( fd_msg_send( msg, NULL, NULL ) );
+
+
+ return 0;
+}
diff --git a/extensions/app_sip/pushprofile.c b/extensions/app_sip/pushprofile.c
new file mode 100644
index 0000000..e6233ed
--- /dev/null
+++ b/extensions/app_sip/pushprofile.c
@@ -0,0 +1,319 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "app_sip.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+typedef int SOCKET;
+typedef struct sockaddr_in SOCKADDR_IN;
+typedef struct sockaddr SOCKADDR;
+
+//Procedure which always wait for data on socket
+void *ppr_socket(void *arg)
+{
+
+ SOCKET sock;
+ SOCKADDR_IN sin, csin;
+ struct pprsipaor pprsip;
+ int rcvbytes=0;
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(as_conf->ppr_port);
+ socklen_t sinsize = sizeof(csin);
+ int accepted=0;
+
+
+ if(!bind(sock, (SOCKADDR*)&sin, sizeof(sin)))
+ {
+ if(listen(sock,1))
+ {
+ TRACE_DEBUG(INFO,"ERROR on listen!");
+ }
+
+ while(1)
+ {
+ accepted=accept(sock, (struct sockaddr *)&csin,&sinsize);
+ if(accepted>-1)
+ {
+ rcvbytes=recv(accepted, &pprsip, sizeof(struct pprsipaor),0);
+
+ if(rcvbytes>-1)
+ {
+ //We received something, we can send an PPR
+ app_sip_PPR_cb(&pprsip);
+ }
+ }
+ }
+
+
+ }
+ else
+ TRACE_DEBUG(INFO,"Can't create socket!");
+
+
+ pthread_exit(NULL);
+
+}
+//Called to send a PPR
+int app_sip_PPR_cb(struct pprsipaor *structure)
+{
+ /*
+ TRACE_ENTRY("%p", structure);
+
+ int got_username=0;
+ int got_streason=0;
+ int num_aor=0;//How many SIP-AOR?
+ struct dict_object * rtr_model=NULL;
+ struct msg * message=NULL;
+ struct avp *groupedavp=NULL, *avp=NULL;
+ struct session *sess=NULL;
+ union avp_value value;
+
+ //We must check that we have all needed value in structure
+ if(structure.username[0]!='\0')
+ got_username=1;
+
+ if(structure.sip_aor1[0]!='\0')
+ {
+ num_aor++;
+ if(structure.sip_aor2[0]!='\0')
+ {
+ num_aor++;
+ if(structure.sip_aor3[0]!='\0')
+ num_aor++;
+ }
+ }
+
+ if(structure.strreason!='\0')
+ got_streason=1;
+
+
+ TRACE_DEBUG(INFO,"We have %d SIP_AOR",num_aor);
+
+ if((got_username + num_aor)==0)
+ {
+ //We must have a least a SIP_AOR or a Username
+ TRACE_DEBUG(INFO,"Can not proceed because there is no SIP_AOR or Username");
+ return EINVAL;
+ }
+ if(structure.reason<0)
+ {
+ //We must have a least a SIP_AOR or a Username
+ TRACE_DEBUG(INFO,"Incorrect Reason-Code");
+ return EINVAL;
+ }
+
+ if(structure.desthost[0]=='\0')
+ {
+ //We must have a least a SIP_AOR or a Username
+ TRACE_DEBUG(INFO,"No Destination_Host was provided!");
+ return EINVAL;
+ }
+ //Create the base message for an RTR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Request", &rtr_model, ENOENT) );
+ CHECK_FCT( fd_msg_new (rtr_model, 0, &message));
+
+ // Create a new session
+ {
+ CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, "app_sip", 7 ));
+ char * sid;
+ CHECK_FCT( fd_sess_getsid ( sess, &sid ));
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
+ value.os.data = (uint8_t *)sid;
+ value.os.len = strlen(sid);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
+ }
+
+
+ //Auth_Session_State
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ value.i32=1;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //Origin_Host & Origin_Realm
+ CHECK_FCT( fd_msg_add_origin ( message, 0 ));
+
+ //Destination_Host
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
+ value.os.data=(unsigned char *)structure.desthost;
+ value.os.len=(size_t)strlen(structure.desthost);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+
+ //SIP Deregistration Reason (Grouped AVP)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Deregistration_Reason, 0, &groupedavp ) );
+
+ //Reason Code
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Code, 0, &avp ) );
+ value.i32=structure.reason;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
+
+ if(got_streason)
+ {
+ //Reason Info
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Info, 0, &avp ) );
+ value.os.data=(unsigned char *)structure.strreason;
+ value.os.len=(size_t)strlen(structure.strreason);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //We add the grouped AVP to the message
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, groupedavp ) );
+ }
+
+ //Username
+ {
+ if(got_username)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.User_Name, 0, &avp ) );
+ value.os.data=(unsigned char *)structure.username;
+ value.os.len=(size_t)strlen(structure.username);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ }
+
+ //SIP_AOR
+ {
+ if(num_aor>0)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)structure.sip_aor1;
+ value.os.len=(size_t)strlen(structure.sip_aor1);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ if(num_aor>1)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)structure.sip_aor2;
+ value.os.len=(size_t)strlen(structure.sip_aor2);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ if(num_aor>2)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)structure.sip_aor3;
+ value.os.len=(size_t)strlen(structure.sip_aor3);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ }
+ }
+ }
+
+ fd_msg_dump_walk(INFO,message);
+ CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
+ */
+ return 0;
+}
+
+//Called when an PPA arrive
+int app_sip_PPA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ //TODO: PPA reception
+/*
+ //TODO:remove unused variables
+ struct msg *ans, *qry;
+ struct avp *avp, *a2, *authdataitem;
+ struct msg_hdr * header = NULL;
+ struct avp_hdr * avphdr=NULL, *avpheader=NULL, *avpheader_auth=NULL,*digestheader=NULL;
+ union avp_value val;
+ int found_cnonce=0;
+ struct avp * tempavp=NULL,*sipAuthentication=NULL,*sipAuthenticate=NULL;
+ char * result;
+ int idx=0, idx2=0, number_of_auth_items=0,i=0;
+ //Flags and variables for Database
+ int sipurinotstored=0, authenticationpending=0, querylen=0, usernamelen=0;
+ char *query=NULL,*username=NULL;
+
+
+
+ TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+
+ if (msg == NULL)
+ return EINVAL;
+
+
+ // Create answer header
+ qry = *msg;
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+
+ // Add the Auth-Session-State AVP
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Deregistration_Reason, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+
+
+
+
+
+
+
+
+
+
+
+
+ */
+ return 0;
+
+}
+
diff --git a/extensions/app_sip/registrationtermination.c b/extensions/app_sip/registrationtermination.c
new file mode 100644
index 0000000..9300467
--- /dev/null
+++ b/extensions/app_sip/registrationtermination.c
@@ -0,0 +1,315 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "app_sip.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+typedef int SOCKET;
+typedef struct sockaddr_in SOCKADDR_IN;
+typedef struct sockaddr SOCKADDR;
+
+//Procedure which always wait for data on socket
+void *rtr_socket(void *arg)
+{
+ SOCKET sock;
+ SOCKADDR_IN sin, csin;
+ struct rtrsipaor rtrsip;
+ int rcvbytes=0;
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(as_conf->rtr_port);
+ socklen_t sinsize = sizeof(csin);
+ int accepted=0;
+
+ if(!bind(sock, (SOCKADDR*)&sin, sizeof(sin)))
+ {
+ if(listen(sock,1))
+ {
+ TRACE_DEBUG(INFO,"ERROR on listen!");
+ }
+
+ while(1)
+ {
+ accepted=accept(sock, (struct sockaddr *)&csin,&sinsize);
+ if(accepted>-1)
+ {
+ rcvbytes=recv(accepted, &rtrsip, sizeof(struct rtrsipaor),0);
+
+ if(rcvbytes>-1)
+ {
+ //We received something, we can send an RTR
+ app_sip_RTR_cb(&rtrsip);
+ }
+ }
+ }
+ }
+ else
+ TRACE_DEBUG(INFO,"Can't create socket!");
+
+
+ pthread_exit(NULL);
+
+}
+//Called to send a RTR
+int app_sip_RTR_cb(struct rtrsipaor *structure)
+{
+ TRACE_ENTRY("%p", structure);
+
+ int got_username=0;
+ int got_streason=0;
+ int num_aor=0;//How many SIP-AOR?
+ struct dict_object * rtr_model=NULL;
+ struct msg * message=NULL;
+ struct avp *groupedavp=NULL, *avp=NULL;
+ union avp_value value;
+
+ //We must check that we have all needed value in structure
+ if(structure->username[0]!='\0')
+ got_username=1;
+
+ if(structure->sip_aor1[0]!='\0')
+ {
+ num_aor++;
+ if(structure->sip_aor2[0]!='\0')
+ {
+ num_aor++;
+ if(structure->sip_aor3[0]!='\0')
+ num_aor++;
+ }
+ }
+
+ if(structure->strreason!='\0')
+ got_streason=1;
+
+
+ TRACE_DEBUG(FULL,"Request for %d SIP_AOR to be deregistred.",num_aor);
+
+ if((got_username + num_aor)==0)
+ {
+ //We must have a least a SIP_AOR or a Username
+ TRACE_DEBUG(INFO,"Can not proceed because there is no SIP_AOR or Username");
+ return EINVAL;
+ }
+ if(structure->reason<0)
+ {
+ //We must have a least a SIP_AOR or a Username
+ TRACE_DEBUG(INFO,"Incorrect Reason-Code");
+ return EINVAL;
+ }
+
+ if(structure->desthost[0]=='\0')
+ {
+ //We must have a least a SIP_AOR or a Username
+ TRACE_DEBUG(INFO,"No Destination_Host was provided!");
+ return EINVAL;
+ }
+ //Create the base message for an RTR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Request", &rtr_model, ENOENT) );
+ CHECK_FCT( fd_msg_new (rtr_model, 0, &message));
+
+ // Create a new session
+ {
+ #define APP_SIP_SID_OPT "app_sip"
+ CHECK_FCT( fd_msg_new_session( message, (os0_t)APP_SIP_SID_OPT, CONSTSTRLEN(APP_SIP_SID_OPT) ) );
+ }
+
+ //Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = 6;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ //Auth_Session_State
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ value.i32=1;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //Origin_Host & Origin_Realm
+ CHECK_FCT( fd_msg_add_origin ( message, 0 ));
+
+ //Destination_Host
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
+ value.os.data=(unsigned char *)structure->desthost;
+ value.os.len=(size_t)strlen(structure->desthost);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+
+ //SIP Deregistration Reason (Grouped AVP)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Deregistration_Reason, 0, &groupedavp ) );
+
+ //Reason Code
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Code, 0, &avp ) );
+ value.i32=structure->reason;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
+
+ if(got_streason)
+ {
+ //Reason Info
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Info, 0, &avp ) );
+ value.os.data=(unsigned char *)structure->strreason;
+ value.os.len=(size_t)strlen(structure->strreason);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //We add the grouped AVP to the message
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, groupedavp ) );
+ }
+
+ //Username
+ {
+ if(got_username)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.User_Name, 0, &avp ) );
+ value.os.data=(unsigned char *)structure->username;
+ value.os.len=(size_t)strlen(structure->username);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ }
+
+ //SIP_AOR
+ {
+ if(num_aor>0)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)structure->sip_aor1;
+ value.os.len=(size_t)strlen(structure->sip_aor1);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ if(num_aor>1)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)structure->sip_aor2;
+ value.os.len=(size_t)strlen(structure->sip_aor2);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ if(num_aor>2)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)structure->sip_aor3;
+ value.os.len=(size_t)strlen(structure->sip_aor3);
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ }
+ }
+ }
+
+ //TODO:remove for debug
+ //fd_msg_dump_walk(INFO,message);
+ CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
+
+ return 0;
+}
+
+//Called when an RTA arrive
+int app_sip_RTA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ //TODO: RTA reception
+/*
+ //TODO:remove unused variables
+ struct msg *ans, *qry;
+ struct avp *avp, *a2, *authdataitem;
+ struct msg_hdr * header = NULL;
+ struct avp_hdr * avphdr=NULL, *avpheader=NULL, *avpheader_auth=NULL,*digestheader=NULL;
+ union avp_value val;
+ int found_cnonce=0;
+ struct avp * tempavp=NULL,*sipAuthentication=NULL,*sipAuthenticate=NULL;
+ char * result;
+ int idx=0, idx2=0, number_of_auth_items=0,i=0;
+ //Flags and variables for Database
+ int sipurinotstored=0, authenticationpending=0, querylen=0, usernamelen=0;
+ char *query=NULL,*username=NULL;
+
+
+
+ TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+
+ if (msg == NULL)
+ return EINVAL;
+
+
+ // Create answer header
+ qry = *msg;
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+
+ // Add the Auth-Session-State AVP
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Deregistration_Reason, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+
+
+
+
+
+
+
+
+
+
+
+
+ */
+ return 0;
+
+}
+
diff --git a/extensions/app_sip/serverassignment.c b/extensions/app_sip/serverassignment.c
new file mode 100644
index 0000000..fa31a81
--- /dev/null
+++ b/extensions/app_sip/serverassignment.c
@@ -0,0 +1,484 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "app_sip.h"
+
+
+int app_sip_SAR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
+
+ struct msg *ans, *qry;
+ struct avp *avp;
+ struct avp_hdr *avphdr, *sipaorhdr, *usernamehdr, *sipuserdataalreadyavailable;
+ union avp_value value;
+ int ret=0, assignment_type=0, got_datatype=1;
+
+
+ struct listdatatype
+ {
+ struct fd_list datatype;
+ char * type;
+ size_t typelen;
+ };
+
+ //Result_Code to return in the answer
+ char result[55];
+
+ if (msg == NULL)
+ return EINVAL;
+
+
+ // Create answer header
+ qry = *msg;
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+ //Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = 6;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+ }
+ // Add the Auth-Session-State AVP
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ //Retrieve SIP-AOR
+ {
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
+ if(avp!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( avp, &sipaorhdr ) );
+ }
+ else
+ sipaorhdr=NULL;
+
+ }
+
+ //We check if we have a username AVP
+ {
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.User_Name, &avp) );
+ if(avp!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( avp, &usernamehdr ) );
+
+ ret=get_password(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, NULL);
+
+
+ if(ret==1)
+ {//not found
+ strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN");
+ goto out;
+ }
+ else if(ret==2)
+ {//error
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ else if(ret==0)
+ {//found
+
+ if(sipaorhdr!=NULL)
+ {
+ //We must check that this user can use this SIP-AOR
+ ret=check_sipaor(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len,(const char *) sipaorhdr->avp_value->os.data,sipaorhdr->avp_value->os.len);
+
+ if(ret==0)
+ {
+ //The SIP-AOR and Username are ok!
+ ret=clear_pending_flag(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len);
+ if(ret==2)
+ {
+ TRACE_DEBUG(INFO,"ERROR: We couldn't clear the flag of pending authentication.'");
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ else if(ret==1)
+ {//not found
+ strcpy(result,"DIAMETER_ERROR_IDENTITIES_DONT_MATCH");
+ goto out;
+ }
+ else
+ {//error
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ else
+ {
+ TRACE_DEBUG(INFO,"ERROR: There is no SIP-AOR AVP!'");
+ strcpy(result,"DIAMETER_ERROR_IDENTITIES_DONT_MATCH");
+ goto out;
+ }
+ }
+ }
+ else
+ {
+ if(sipaorhdr!=NULL)
+ {//If we have a SIP-AOR, we want the user to check it.
+ strcpy(result,"DIAMETER_USER_NAME_REQUIRED");
+ goto out;
+ }
+ usernamehdr=NULL;
+ }
+
+ }
+
+ //We get the SIP_Server_Assignment_Type
+ {
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_Assignment_Type, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ assignment_type=avphdr->avp_value->i32;
+ }
+
+
+
+
+
+ //We get SIP_User_Data_Already_Available AVP
+ {
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_User_Data_Already_Available, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &sipuserdataalreadyavailable ) );
+ }
+
+ if(assignment_type==1 || assignment_type==2)
+ {//registration & re-registration
+ if(count_avp(qry,CODE_SIP_AOR,0)==1)
+ {
+
+ if(sipuserdataalreadyavailable->avp_value->i32==0)
+ {//Data not available, we must provide it
+ ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
+
+ if(ret==0)
+ {
+ //We found and added datatype
+ got_datatype=1;
+ }
+ else if(ret==1)
+ {
+ //No data type was found
+ got_datatype=0;
+ }
+ else
+ {//error
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ strcpy(result,"DIAMETER_SUCCESS");
+ goto out;
+ }
+ else
+ {//There is more than 1 SIP-AOR AVP
+ strcpy(result,"DIAMETER_AVP_OCCURS_TOO_MANY_TIMES");
+ goto out;
+ }
+ }
+ else if(assignment_type==3)
+ {//Unregistered user
+
+ //TODO:place user unknown here!
+ if(count_avp(qry,CODE_SIP_AOR,0)==1)
+ {
+ if(sipuserdataalreadyavailable->avp_value->i32==0)
+ {//Data not available, we must provide it
+ if(got_datatype==1)
+ {
+ ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
+
+ if(ret==0)
+ {
+ //We found and added datatype
+ got_datatype=1;
+ }
+ else if(ret==1)
+ {
+ //No data type was found
+ got_datatype=0;
+ }
+ else
+ {//error
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ }
+ strcpy(result,"DIAMETER_SUCCESS");
+ goto out;
+ }
+ else
+ {//There is more than 1 SIP-AOR AVP
+ strcpy(result,"DIAMETER_AVP_OCCURS_TOO_MANY_TIMES");
+ goto out;
+ }
+
+ if(sipuserdataalreadyavailable->avp_value->i32==0)
+ {//Data not available, we must provide it
+ if(got_datatype==1)
+ {
+ ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
+
+ if(ret==0)
+ {
+ //We found and added datatype
+ got_datatype=1;
+ }
+ else if(ret==1)
+ {
+ //No data type was found
+ got_datatype=0;
+ }
+ else
+ {//error
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ }
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) );
+ if(avp!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ));
+
+ set_real_sipserver_uri(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, avphdr->avp_value->os.data,avphdr->avp_value->os.len);
+ strcpy(result,"DIAMETER_SUCCESS");
+ goto out;
+ }
+ else
+ {
+ TRACE_DEBUG(INFO,"There is no SIP_Server_URI AVP in this Unregistered User Request!");
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ else if(assignment_type==4 || assignment_type==5 || assignment_type==11 || assignment_type==8)
+ {//Unregistered user
+
+ if(got_datatype==1)
+ {
+ if(sipuserdataalreadyavailable->avp_value->i32==0)
+ {//Data not available, we must provide it
+
+ ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
+
+ if(ret==0)
+ {
+ //We found and added datatype
+ got_datatype=1;
+ }
+ else if(ret==1)
+ {
+ //No data type was found
+ got_datatype=0;
+ }
+ else
+ {//error
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ }
+
+ if(sipaorhdr==NULL)
+ {
+ //We don't have any SIP-AOR to unregister, this is strange!'
+ TRACE_DEBUG(INFO, "There was no SIP-AOR in this request, we can't proceed request!'");
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ else
+ {
+ //TODO: unregister SIP-Server-URI for all SIP-AOR
+ }
+ strcpy(result,"DIAMETER_SUCCESS");
+ goto out;
+ }
+ else if(assignment_type==6 || assignment_type==7)
+ {
+
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) );
+ if(avp!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ));
+
+ //TODO: set SIP server URI for each AOR
+
+ //TODO: unregister all SIP-AOR provided
+
+ //set_real_sipserver_uri(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, avphdr->avp_value->os.data,avphdr->avp_value->os.len);
+ strcpy(result,"DIAMETER_SUCCESS");
+ goto out;
+ }
+ else
+ {
+
+
+ //TODO: unregister all SIP-AOR provided
+
+ //TODO: clear sip server uri in database for the sip-aor
+
+
+ TRACE_DEBUG(INFO,"There is no SIP_Server_URI AVP in this Deregistration User Request! We just unregister SIP-AOR");
+ strcpy(result,"DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED");
+ goto out;
+ }
+ }
+ else if(assignment_type==0)
+ {
+
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) );
+ if(avp!=NULL)
+ {
+ unsigned char * sipserver_uri;
+ size_t sipserverurilen;
+
+
+
+
+ ret=get_sipserver_uri(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len, &sipserver_uri, &sipserverurilen);
+
+ if(ret==0)
+ {//found
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ));
+
+
+
+
+ if(strncmp((char *)avphdr->avp_value->os.data,(char *)sipserver_uri,sipserverurilen))
+ {
+ if(got_datatype==1)
+ {
+ if(sipuserdataalreadyavailable->avp_value->i32==0)
+ {//Data not available, we must provide it
+
+ ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
+
+ if(ret==0)
+ {
+ //We found and added datatype
+ got_datatype=1;
+ }
+ else if(ret==1)
+ {
+ //No data type was found
+ got_datatype=0;
+ }
+ else
+ {//error
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ }
+ }
+ else
+ {//error
+ TRACE_DEBUG(FULL,"SIP_Server_URI is different from the one in database");
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ else
+ {
+ TRACE_DEBUG(FULL,"SIP_Server_URI is different from the one in database");
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+
+
+
+
+
+
+
+ //set_real_sipserver_uri(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, avphdr->avp_value->os.data,avphdr->avp_value->os.len);
+ strcpy(result,"DIAMETER_SUCCESS");
+ goto out;
+ }
+ else
+ {
+ TRACE_DEBUG(INFO, "There was no SIP_Server_URI in this request, we can't proceed request!'");
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ else if(assignment_type==9 || assignment_type==10)
+ {
+ if(count_avp(qry, CODE_SIP_AOR,0)==1)
+ {
+ //TODO: remove SIP-server URI for sip_aor
+ //TODO: unregister it
+ strcpy(result,"DIAMETER_SUCCESS");
+ goto out;
+ }
+ else
+ {//There is more than 1 SIP-AOR AVP
+ strcpy(result,"DIAMETER_AVP_OCCURS_TOO_MANY_TIMES");
+ goto out;
+ }
+ }
+ out:
+ CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
+
+
+ //fd_msg_dump_walk(INFO,ans);
+
+ CHECK_FCT( fd_msg_send( msg, NULL, NULL ));
+
+
+
+ return 0;
+}
diff --git a/extensions/app_sip/tools/CMakeLists.txt b/extensions/app_sip/tools/CMakeLists.txt
new file mode 100644
index 0000000..c80ccff
--- /dev/null
+++ b/extensions/app_sip/tools/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Utilities for app_sip
+PROJECT("Diameter SIP Application (RFC4740) tools" C)
+
+ADD_EXECUTABLE(freediameter-sip-rtr app_sip_rtr.c)
+ADD_EXECUTABLE(freediameter-sip-ppr app_sip_ppr.c)
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS freediameter-sip-rtr freediameter-sip-ppr
+ RUNTIME DESTINATION ${INSTALL_DAEMON_SUFFIX}
+ COMPONENT freeDiameter-sip-server)
diff --git a/extensions/app_sip/tools/app_sip_ppr.c b/extensions/app_sip/tools/app_sip_ppr.c
new file mode 100644
index 0000000..d8d8056
--- /dev/null
+++ b/extensions/app_sip/tools/app_sip_ppr.c
@@ -0,0 +1,237 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+
+// This file is separated from the source code because it is a separate command which will call push profile function in Diameter-SIP
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+typedef int SOCKET;
+typedef struct sockaddr_in SOCKADDR_IN;
+typedef struct sockaddr SOCKADDR;
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <errno.h>
+
+struct pprsipaor
+{
+ char username[200];
+ char datatype1[255];
+ char datatype2[255];
+ char datatype3[255];
+ int accounting;
+};
+
+int main (int argc, char **argv)
+{
+ SOCKET sock;
+ SOCKADDR_IN sin;
+ struct pprsipaor pprsip;
+ int numdatatype=0,i=0;
+ int port=667;
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+ sin.sin_family = AF_INET;
+
+
+ //We initialize the structure
+ pprsip.username[0]='\0';
+ pprsip.datatype1[0]='\0';
+ pprsip.datatype2[0]='\0';
+ pprsip.datatype3[0]='\0';
+ pprsip.accounting=0;
+
+ //Start of arguments check
+ if(argc<3)
+ {
+ fprintf(stderr,"Missing arguments! You must at least provide a username.\n");
+ return 1;
+ }
+
+
+ for (i=1;i<argc;i++)
+ {
+ //We must check if it is a value or the name
+ if(strncmp(argv[i],"-",1)==0)
+ {
+ if(strcmp(argv[i],"-u")==0)
+ {
+ //Username
+ if(strlen(argv[i+1])<199)
+ {
+ strcpy(pprsip.username,argv[i+1]);
+ //We must not check the value
+ i++;
+ }
+ else
+ {
+ fprintf(stderr,"Username is too long!\n");
+ }
+ }
+ else if(strcmp(argv[i],"-t")==0)
+ {//User-data types
+ i++;
+ int j=i;
+
+ for(j=i;j<argc;j++)
+ {
+
+ if(strncmp(argv[i],"-",1)!=0)
+ {
+ if(strlen(argv[i])>254)
+ {
+ fprintf(stderr,"User-data type is too long!\n");
+ }
+ else
+ {
+ if(numdatatype<3)
+ {
+ switch(numdatatype)
+ {
+ case 0:
+ strcpy(pprsip.datatype1,argv[i]);
+ break;
+ case 1:
+ strcpy(pprsip.datatype2,argv[i]);
+ break;
+ case 2:
+ strcpy(pprsip.datatype3,argv[i]);
+ break;
+ }
+ numdatatype++;
+ }
+ else
+ {
+ fprintf(stderr,"You can not provide more than 3 User-data type at the same time!\n");
+ break;
+ }
+ }
+ i=j+1;
+ }
+ else
+ {
+ //We have a new argument
+ i--;
+ break;
+ }
+ }
+ }
+ else if(strcmp(argv[i],"-a")==0)
+ {
+ pprsip.accounting=1;
+
+
+ }
+ else if(strcmp(argv[i],"-p")==0)
+ {
+
+ if(sscanf(argv[i+1],"%d", &port)!=1)
+ {
+ fprintf(stderr,"Incorrect port number!\n");
+ return 1;
+ }
+
+
+ i++;
+ }
+
+ }
+ else
+ {
+ fprintf(stderr,"Unknown argument: %s\n",argv[i]);
+ i++;
+ }
+
+ }
+
+ //We set the port number
+ sin.sin_port = htons(port);
+
+
+ //We want a username
+ if(strlen(pprsip.username)==0)
+ {
+ fprintf(stderr,"You must provide a username!\n");
+ return 1;
+ }
+
+
+ fprintf(stderr,"%d!\n",port);
+
+ /*
+ //DEBUG
+ fprintf(stderr,"*%s*\n",pprsip.username);
+ fprintf(stderr,"*%s*\n",pprsip.datatype1);
+ fprintf(stderr,"*%s*\n",pprsip.datatype2);
+ fprintf(stderr,"*%s*\n",pprsip.datatype3);
+ fprintf(stderr,"*%d*\n",pprsip.accounting);
+
+ return 0;
+ */
+
+
+ //TODO: check args
+ if(!connect(sock, (SOCKADDR*)&sin, sizeof(sin)))
+ {
+ fprintf(stderr,"Connexion succeed!\n");
+
+
+ if(send(sock, &pprsip, sizeof(struct pprsipaor), 0))
+ fprintf(stderr,"sent OK!\n");
+ else
+ fprintf(stderr,"not sent\n");
+
+ }
+ else
+ {
+ fprintf(stderr,"Unable to connect\n");
+ }
+
+ close(sock);
+
+ return 0;
+}
+
+
+
+
+
+
diff --git a/extensions/app_sip/tools/app_sip_rtr.c b/extensions/app_sip/tools/app_sip_rtr.c
new file mode 100644
index 0000000..21c3c60
--- /dev/null
+++ b/extensions/app_sip/tools/app_sip_rtr.c
@@ -0,0 +1,303 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+
+// This file is separated from the source code because it is a separate command which will call registration termination function in Diameter-SIP
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+typedef int SOCKET;
+typedef struct sockaddr_in SOCKADDR_IN;
+typedef struct sockaddr SOCKADDR;
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+struct rtrsipaor
+{
+ char username[200];
+ char sip_aor1[200];
+ char sip_aor2[200];
+ char sip_aor3[200];
+ char strreason[200];
+ char desthost[200];
+ int reason;
+};
+
+int main (int argc, char **argv)
+{
+ SOCKET sock;
+ SOCKADDR_IN sin;
+ struct rtrsipaor rtrsip;
+ int numaor=0,i=0;
+ int port=666;
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+ sin.sin_family = AF_INET;
+
+
+ //We initialize the structure
+ rtrsip.username[0]='\0';
+ rtrsip.sip_aor1[0]='\0';
+ rtrsip.sip_aor2[0]='\0';
+ rtrsip.sip_aor3[0]='\0';
+ rtrsip.strreason[0]='\0';
+ rtrsip.desthost[0]='\0';
+ rtrsip.reason=-1;
+
+
+ //Start of arguments check
+ if(argc<3)
+ {
+ fprintf(stderr,"Missing arguments! You must at least provide a username.\n");
+ return 1;
+ }
+
+
+ for (i=1;i<argc;i++)
+ {
+ //We must check if it is a value or the name
+ if(strncmp(argv[i],"-",1)==0)
+ {
+ if(strcmp(argv[i],"-u")==0)
+ {
+ //Username
+ if(strlen(argv[i+1])<199)
+ {
+ strcpy(rtrsip.username,argv[i+1]);
+ //We must not check the value
+ i++;
+ }
+ else
+ {
+ fprintf(stderr,"Username is too long!\n");
+ }
+ }
+ else if(strcmp(argv[i],"-a")==0)
+ {
+ i++;
+ int j=i;
+
+ for(j=i;j<argc;j++)
+ {
+
+ if(strncmp(argv[i],"-",1)!=0)
+ {
+ if(strlen(argv[i])>199)
+ {
+ fprintf(stderr,"SIP-AOR is too long!\n");
+ }
+ else if(strncmp(argv[i],"sip",3)!=0)
+ {
+ //Bad format of SIP-AOR
+ fprintf(stderr,"A SIP-AOR must start by 'sip:' or 'sips:'. Aborting...\n");
+ return 1;
+ }
+ else
+ {
+ if(numaor<3)
+ {
+ switch(numaor)
+ {
+ case 0:
+ strcpy(rtrsip.sip_aor1,argv[i]);
+ break;
+ case 1:
+ strcpy(rtrsip.sip_aor2,argv[i]);
+ break;
+ case 2:
+ strcpy(rtrsip.sip_aor3,argv[i]);
+ break;
+ }
+ numaor++;
+ }
+ else
+ {
+ fprintf(stderr,"You can not provide more than 3 SIP-AOR at the same time!\n");
+ break;
+ }
+ }
+ i=j+1;
+ }
+ else
+ {
+ //We have a new argument
+ i--;
+ break;
+ }
+ }
+ }
+ else if(strcmp(argv[i],"-r")==0)
+ {
+
+ if(strlen(argv[i+1])>199)
+ {
+ fprintf(stderr,"Deregistration reason is too long!\n");
+ }
+ else
+ {
+ strcpy(rtrsip.strreason,argv[i+1]);
+ }
+ i++;
+ }
+ else if(strcmp(argv[i],"-h")==0)
+ {
+ //Remote SIP Server
+ if(strlen(argv[i+1])>199)
+ {
+ fprintf(stderr,"Host is too long!\n");
+ }
+ else if(strlen(argv[i+1])<5)
+ {
+ fprintf(stderr,"Host is too short!\n");
+ }
+ else
+ {
+ strcpy(rtrsip.desthost,argv[i+1]);
+ }
+ i++;
+ }
+ else if(strcmp(argv[i],"-pt")==0)
+ {
+ //Permanent Termination
+ rtrsip.reason=0;
+ }
+ else if(strcmp(argv[i],"-nssa")==0)
+ {
+ //New SIP Server Assigned
+ rtrsip.reason=1;
+ }
+ else if(strcmp(argv[i],"-ssc")==0)
+ {
+ //SIP Server Change
+ rtrsip.reason=2;
+ }
+ else if(strcmp(argv[i],"-rss")==0)
+ {
+ //Remote SIP Server
+ rtrsip.reason=3;
+ }
+ else if(strcmp(argv[i],"-p")==0)
+ {
+
+ if(sscanf(argv[i+1],"%d", &port)!=1)
+ {
+ fprintf(stderr,"Incorrect port number!\n");
+ return 1;
+ }
+
+
+ i++;
+ }
+ else
+ {
+ fprintf(stderr,"Unknown argument: %s\n",argv[i]);
+ }
+ }
+ else
+ {
+ fprintf(stderr,"Unknown argument: %s\n",argv[i]);
+ i++;
+ }
+
+ }
+
+ //If no SIP-AOR provided, we remove all
+ if(numaor<1)
+ {
+ fprintf(stderr,"All SIP-AOR of %s will be deregistrated.\n",rtrsip.username);
+ }
+
+ //We want a username
+ if(strlen(rtrsip.username)==0)
+ {
+ fprintf(stderr,"You must provide a username!\n");
+ return 1;
+ }
+
+ if(rtrsip.desthost[0]=='\0')
+ {
+ fprintf(stderr,"You must provide the hostname of SIP-Server!\n");
+ return 1;
+ }
+
+ //We set the port number
+ sin.sin_port = htons(port);
+
+
+ /*
+ fprintf(stderr,"*%s*\n",rtrsip.username);
+ fprintf(stderr,"*%s*\n",rtrsip.sip_aor1);
+ fprintf(stderr,"*%s*\n",rtrsip.sip_aor2);
+ fprintf(stderr,"*%s*\n",rtrsip.sip_aor3);
+ fprintf(stderr,"*%d*\n",rtrsip.reason);
+ fprintf(stderr,"*%s*\n",rtrsip.strreason);
+
+ //return 0;
+ */
+
+
+ //TODO: check args
+ if(!connect(sock, (SOCKADDR*)&sin, sizeof(sin)))
+ {
+ fprintf(stderr,"Connexion succeed!\n");
+
+
+ if(send(sock, &rtrsip, sizeof(struct rtrsipaor), 0))
+ fprintf(stderr,"sent OK!\n");
+ else
+ fprintf(stderr,"not sent\n");
+
+ }
+ else
+ {
+ fprintf(stderr,"Unable to connect\n");
+ }
+
+ close(sock);
+
+ return 0;
+}
+
+
+
+
+
+
diff --git a/extensions/app_sip/userauthorization.c b/extensions/app_sip/userauthorization.c
new file mode 100644
index 0000000..f87ceb6
--- /dev/null
+++ b/extensions/app_sip/userauthorization.c
@@ -0,0 +1,337 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "app_sip.h"
+
+
+int app_sip_UAR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
+
+ struct msg *ans, *qry;
+ struct avp *avp, *groupedavp=NULL;
+ struct avp_hdr *avphdr, *sipaorhdr, *visitednethdr, *usernamehdr;
+ union avp_value value;
+ int ret=0, hascap=0;
+
+ //Result_Code to return in the answer
+ char result[55];
+
+ if (msg == NULL)
+ return EINVAL;
+
+
+ // Create answer header
+ qry = *msg;
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+ //Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = 6;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+ }
+ // Add the Auth-Session-State AVP
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //Retrieve SIP-AOR
+ {
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &sipaorhdr ) );
+ }
+
+ //We check if we have a User-Name AVP
+ {
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.User_Name, &avp) );
+ if(avp!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( avp, &usernamehdr ) );
+
+ ret=get_password(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, NULL);
+
+
+ if(ret==1)
+ {//not found
+ strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN");
+ goto out;
+ }
+ else if(ret==2)
+ {//error
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ else if(ret==0)
+ {//found
+
+ //We must check that this user can use this SIP-AOR
+ ret=check_sipaor(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, (const char *)sipaorhdr->avp_value->os.data,sipaorhdr->avp_value->os.len);
+
+ if(ret==0)
+ {
+ //The SIP-AOR and Username are ok!
+ }
+ else if(ret==1)
+ {//not found
+ strcpy(result,"DIAMETER_ERROR_IDENTITIES_DONT_MATCH");
+ goto out;
+ }
+ else
+ {//error
+ //We couldn't make the request, we must stop process!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ }
+ }
+
+ //We check if we have a SIP-Visited-Network-Id AVP
+ {
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Visited_Network_Id, &avp) );
+
+ if(avp!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( avp, &visitednethdr ) );
+ }
+ else
+ visitednethdr=NULL;
+ }
+
+ //We check if we have a SIP_User_Authorization_Type
+ {
+ int auth_type;
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_User_Authorization_Type, &avp) );
+
+ if(avp!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+ auth_type=avphdr->avp_value->i32;
+
+ if(auth_type==0 || auth_type==2)
+ {
+ if(visitednethdr!=NULL)
+ {
+ /*
+ If there is a SIP-Visited-Network-Id AVP in the Diameter UAR message,
+ and the SIP-User-Authorization-Type AVP value received in the
+ Diameter UAR message is set to REGISTRATION or REGISTRATION&
+ CAPABILITIES, then the Diameter server SHOULD verify whether the user
+ is allowed to roam into the network specified in the
+ SIP-Visited-Network-Id AVP in the Diameter UAR message. If the user
+ is not allowed to roam into that network, the Diameter AAA server
+ MUST set the Result-Code AVP value in the Diameter UAA message to
+ DIAMETER_ERROR_ROAMING_NOT_ALLOWED.
+ */
+ ret=allow_roaming(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, (const char *)visitednethdr->avp_value->os.data,visitednethdr->avp_value->os.len);
+
+ if(ret==0)
+ {
+ //This user can come in this network
+ }
+ else if(ret==1)
+ {
+ strcpy(result,"DIAMETER_ERROR_ROAMING_NOT_ALLOWED");
+ goto out;
+ }
+ else
+ {
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+
+ }
+ /*
+ If the SIP-User-Authorization-Type AVP value received in the Diameter
+ UAR message is set to REGISTRATION or REGISTRATION&CAPABILITIES, then
+ the Diameter server SHOULD verify whether the SIP-AOR AVP value is
+ authorized to register in the Home Realm. Where the SIP AOR is not
+ authorized to register in the Home Realm, the Diameter server MUST
+ set the Result-Code AVP to DIAMETER_AUTHORIZATION_REJECTED and send
+ it in a Diameter UAA message.
+ */
+ ret=exist_username(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len);
+ if(ret==0)
+ {
+ //The SIP_AOR exists in this realm
+ }
+ else if(ret==1)
+ {
+ strcpy(result,"DIAMETER_AUTHORIZATION_REJECTED");
+ goto out;
+ }
+ else
+ {
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+ }
+ else
+ auth_type=0; //Registration only (default value if absent)
+
+
+ //Let's look for the SIP_Server_URI'
+ unsigned char *sipserver_uri;
+ size_t sipserverurilen;
+
+ ret=get_sipserver_uri(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len, &sipserver_uri, &sipserverurilen);
+
+ if(ret==0)
+ {//We know a SIP Server so we must provide it
+ //We only add this AVP when we have registration or deregistration
+ if(auth_type==0 ||auth_type==1)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_URI, 0, &avp ) );
+ value.os.data=sipserver_uri;
+ value.os.len=sipserverurilen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ }
+ else if(ret==1)
+ {
+ sipserver_uri=NULL;
+ sipserverurilen=0;
+
+ }
+ else
+ {
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+
+ //If we have a REGISTRATION or REGISTRATION & CAPABILITIES
+ if(auth_type==0 ||auth_type==2)
+ {
+ //Adding SIP-Server-Capabilities
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_Capabilities, 0, &groupedavp ) );
+
+ ret=get_sipserver_cap(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,&groupedavp);
+
+ if(ret==0)
+ {
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) );
+ hascap=1;
+ }
+ else if(ret==1)
+ {
+
+ hascap=0;
+ }
+ else
+ {
+ CHECK_FCT( fd_msg_free( groupedavp ) );
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+
+
+
+ if(auth_type==0)
+ {//Registration
+
+ if(sipserver_uri==NULL)
+ {
+ strcpy(result,"DIAMETER_FIRST_REGISTRATION");
+ }
+ else
+ {
+ if(hascap==1)
+ {
+ strcpy(result,"DIAMETER_SERVER_SELECTION");
+ }
+ else
+ {
+ //We free the Capabilities AVP because we didn't found any'
+ if(groupedavp!=NULL)
+ CHECK_FCT( fd_msg_free( groupedavp ) );
+ strcpy(result,"DIAMETER_SUBSEQUENT_REGISTRATION");
+ }
+ }
+ }
+ else if(auth_type==2)
+ {//Registration & Capabilities
+ //We let the groupedavp in the message even if there is no capabilities
+
+ if(hascap==0)
+ {
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, groupedavp) );
+ }
+ strcpy(result,"DIAMETER_SUCCESS");
+ }
+ else if(auth_type==1)
+ {//Deregistration
+ if(sipserver_uri==NULL)
+ {
+ strcpy(result,"DIAMETER_ERROR_IDENTITY_NOT_REGISTERED");
+ }
+ else
+ {
+ strcpy(result,"DIAMETER_SUCCESS");
+ }
+ }
+ else
+ {//We should never be here!!
+ strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+ goto out;
+ }
+ }
+
+
+out:
+ CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
+
+
+ //fd_msg_dump_walk(INFO,ans);
+
+ CHECK_FCT( fd_msg_send( msg, NULL, NULL ));
+
+
+
+ return 0;
+}
diff --git a/extensions/dbg_interactive/CMakeLists.txt b/extensions/dbg_interactive/CMakeLists.txt
new file mode 100644
index 0000000..4bb3eb0
--- /dev/null
+++ b/extensions/dbg_interactive/CMakeLists.txt
@@ -0,0 +1,77 @@
+# The dbg_interactive extension
+PROJECT("Interactive debug facility based on SWIG" C)
+
+
+# This module is using Python
+SET(Python_ADDITIONAL_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
+FIND_PACKAGE(PythonLibs)
+INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
+
+#####
+# Wrapper to fD in python
+FIND_PACKAGE(SWIG REQUIRED)
+INCLUDE(${SWIG_USE_FILE})
+SET(CMAKE_SWIG_FLAGS -castmode -threads)
+
+# Add the dependencies for re-swig-ing the file
+SET(SWIG_MODULE_fDpy_EXTRA_DEPS
+ ${CMAKE_BINARY_DIR}/include/freeDiameter/freeDiameter-host.h
+ ${CMAKE_SOURCE_DIR}/include/freeDiameter/libfdcore.h
+ ${CMAKE_SOURCE_DIR}/include/freeDiameter/libfdproto.h
+ lists.i
+ dictionary.i
+ sessions.i
+ routing.i
+ messages.i
+ dispatch.i
+ queues.i
+ peers.i
+ events.i
+ endpoints.i
+ posix.i
+ hooks.i
+ )
+SET_SOURCE_FILES_PROPERTIES(dbg_interactive.i PROPERTIES SWIG_MODULE_NAME fDpy)
+
+# The following code is inspired from SWIG_ADD_MODULE, but we do only what we need
+SWIG_MODULE_INITIALIZE(fDpy python)
+SWIG_ADD_SOURCE_TO_MODULE(fDpy swig_generated_sources "dbg_interactive.i")
+
+# In order to avoid shipping the python file that contains the shadow class definitions,
+# we transform this file in a C-style string and compile it within our software.
+# We use for this purpose xxd tool provided with vim package.
+FIND_PROGRAM(XXD_EXECUTABLE xxd)
+# To avoid the dependency, simply compile it if not provided
+if (NOT XXD_EXECUTABLE)
+ SET_SOURCE_FILES_PROPERTIES(helper/xxd.c PROPERTIES COMPILE_DEFINITIONS UNIX)
+ ADD_EXECUTABLE(xxd helper/xxd.c)
+ SET(XXD_EXECUTABLE xxd)
+endif (NOT XXD_EXECUTABLE)
+# And now the magic command
+ADD_CUSTOM_COMMAND(
+ OUTPUT "fDpy-inc.c"
+ COMMAND "${XXD_EXECUTABLE}"
+ ARGS "-i"
+ "fDpy.py"
+ "fDpy-inc.c"
+ MAIN_DEPENDENCY "${swig_extra_generated_files}"
+ COMMENT "Shadow definitions")
+
+# Ensure that the generated source files are removed
+GET_DIRECTORY_PROPERTY(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
+SET_DIRECTORY_PROPERTIES(PROPERTIES
+ ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources};fDpy-inc.c")
+
+
+#####
+# Extension that embeds the python interpreter
+FD_ADD_EXTENSION(dbg_interactive dbg_interactive.c ${swig_generated_sources} fDpy-inc.c)
+TARGET_LINK_LIBRARIES(dbg_interactive ${PYTHON_LIBRARIES})
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dbg_interactive
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
diff --git a/extensions/dbg_interactive/dbg_interactive.c b/extensions/dbg_interactive/dbg_interactive.c
new file mode 100644
index 0000000..d1347a2
--- /dev/null
+++ b/extensions/dbg_interactive/dbg_interactive.c
@@ -0,0 +1,140 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 <Python.h>
+#include <freeDiameter/extension.h>
+#include <unistd.h>
+
+/* wrapper generated by SWIG */
+#if PY_VERSION_HEX >= 0x03000000
+ extern void PyInit__fDpy(void);
+ #define WRAPPER_INIT PyInit__fDpy()
+#else /* PY_VERSION_HEX */
+ extern void init_fDpy(void);
+ #define WRAPPER_INIT init_fDpy()
+#endif /* PY_VERSION_HEX */
+
+/* The string created in the shadow proxy C string file */
+extern unsigned char fDpy_py[];
+extern unsigned int fDpy_py_len;
+
+/* Run an interactive interpreter in a separate thread */
+static pthread_t pyinterp = (pthread_t)NULL;
+static void * myinterp (void * arg)
+{
+ char * dum[3] = { "<dbg_interactive>", arg, NULL };
+
+ TRACE_ENTRY("%p", arg);
+
+ fd_log_threadname ( "fDpy" );
+
+ CHECK_FCT_DO(fd_core_waitstartcomplete(), goto end);
+
+ if (arg) {
+ fd_log_debug("Starting python interpreter with a script file [experimental].");
+ Py_Main(2, dum);
+ } else {
+ if (!isatty(fileno(stdin)) || !isatty(fileno(stdout))) {
+ TRACE_ERROR("[dbg_interactive]: this extension requires freeDiameter to be run from a console terminal!");
+ goto end;
+ }
+ printf("Starting interactive python interpreter [experimental].\n");
+ printf("Please use Ctrl-D to exit.\n");
+ printf("Example syntax:\n");
+ printf(" >>> print cvar.fd_g_config.cnf_diamid\n");
+ printf(" '%s'\n", fd_g_config->cnf_diamid);
+ Py_Main(1, dum);
+ printf("Python interpreter has exited...\n");
+ }
+
+end:
+ /* Upon exit, issue the order of terminating to fD, if the interpreter was started without a file */
+ if (!arg) {
+ (void)fd_core_shutdown();
+ }
+
+ return NULL;
+}
+
+/* Register the callbacks to the daemon */
+static int di_main(char * conffile)
+{
+ char * shadow_hlp = NULL;
+ int mustfree = 0;
+ TRACE_ENTRY("%p", conffile);
+
+ Py_InitializeEx(0);
+
+ WRAPPER_INIT;
+
+ /* Small hack to avoid duplicating the string, we replace the last char by a \0.
+ It works if the python file is terminated with several \n */
+ if ( (fDpy_py[fDpy_py_len - 2] == '\n')
+ && (fDpy_py[fDpy_py_len - 1] == '\n')) {
+ fDpy_py[fDpy_py_len - 1] = '\0';
+ shadow_hlp = (char *)&fDpy_py[0];
+ } else {
+ CHECK_MALLOC(shadow_hlp = malloc(fDpy_py_len + 1));
+ memcpy(shadow_hlp, fDpy_py, fDpy_py_len);
+ shadow_hlp[fDpy_py_len] = '\0';
+ mustfree=1;
+ }
+
+ PyRun_SimpleString("__file__ = \"\"\n");
+ PyRun_SimpleString(shadow_hlp);
+
+ if (mustfree)
+ free(shadow_hlp);
+
+ CHECK_POSIX( pthread_create(&pyinterp, NULL, myinterp, conffile) );
+
+ return 0;
+}
+
+/* Terminate the extension */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+ void * ret;
+
+ /* Cleanup the python interpreter */
+ Py_Finalize();
+ pthread_join(pyinterp, &ret);
+
+ return ;
+}
+
+/* Define the entry point function */
+EXTENSION_ENTRY("dbg_interactive", di_main);
diff --git a/extensions/dbg_interactive/dbg_interactive.i b/extensions/dbg_interactive/dbg_interactive.i
new file mode 100644
index 0000000..044584f
--- /dev/null
+++ b/extensions/dbg_interactive/dbg_interactive.i
@@ -0,0 +1,209 @@
+/* This interface file is processed by SWIG to create a python wrapper interface to freeDiameter framework. */
+%module fDpy
+%begin %{
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+%}
+
+%{
+/* This text is included in the generated wrapper verbatim */
+#define SWIG
+#include <freeDiameter/extension.h>
+%}
+
+
+/* Include standard types & functions used in freeDiameter headers */
+%include <stdint.i>
+//%include <cdata.i>
+%include <cstring.i>
+%include <typemaps.i>
+
+
+/* Inline functions seems to give problems to SWIG -- just remove the inline definition */
+%define __inline__
+%enddef
+
+
+/* Make some global-variables read-only (mainly to avoid warnings) */
+%immutable fd_g_config;
+%immutable peer_state_str;
+
+#pragma SWIG nowarn=451
+
+/*****************
+ * Exceptions *
+*****************/
+%{
+/* This is not thread-safe etc. but it should work /most of the time/. */
+static int wrapper_errno;
+static PyObject* wrapper_errno_py;
+static const char * wrapper_error_txt; /* if NULL, use strerror(errno) */
+#define DI_ERROR(code, pycode, str) { \
+ fd_log_debug("[dbg_interactive] ERROR: %s: %s", __PRETTY_FUNCTION__, str ? str : strerror(code)); \
+ wrapper_errno = code; \
+ wrapper_errno_py = pycode; \
+ wrapper_error_txt = str; \
+}
+
+#define DI_ERROR_MALLOC \
+ DI_ERROR(ENOMEM, PyExc_MemoryError, NULL)
+
+%}
+
+%exception {
+ /* reset the errno */
+ wrapper_errno = 0;
+ /* Call the function -- it will use DI_ERROR macro in case of error */
+ $action
+ /* Now, test for error */
+ if (wrapper_errno) {
+ const char * str = wrapper_error_txt ? wrapper_error_txt : strerror(wrapper_errno);
+ PyObject * exc = wrapper_errno_py;
+ if (!exc) {
+ switch (wrapper_errno) {
+ case ENOMEM: exc = PyExc_MemoryError; break;
+ case EINVAL: exc = PyExc_ValueError; break;
+ default: exc = PyExc_RuntimeError;
+ }
+ }
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ PyErr_SetString(exc, str);
+ SWIG_fail;
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ }
+}
+
+
+/***********************************
+ Some types & typemaps for usability
+ ***********************************/
+
+%apply (char *STRING, size_t LENGTH) { ( char * string, size_t len ) };
+%apply (char *STRING, size_t LENGTH) { ( uint8_t * string, size_t len ) };
+
+/* Generic typemap for functions that create something */
+%typemap(in, numinputs=0,noblock=1) SWIGTYPE ** OUTPUT (void *temp = NULL) {
+ $1 = (void *)&temp;
+}
+%typemap(argout,noblock=1) SWIGTYPE ** OUTPUT {
+ %append_output(SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
+}
+
+/* Case of the fd_*_dump functions */
+%typemap(in,noblock=1,numinputs=0) (char ** buf, size_t *len, size_t *offset) ($*1_ltype temp = NULL, $*2_ltype tempn = 0) {
+ $1 = &temp; $2 = &tempn; $3 = NULL;
+}
+%typemap(freearg,match="in") (char ** buf, size_t *len, size_t *offset) "";
+%typemap(argout,noblock=1,fragment="SWIG_FromCharPtr")(char ** buf, size_t *len, size_t *offset) {
+ if (*$1) {
+ %append_output(SWIG_FromCharPtr(*$1));
+ free(*$1);
+ }
+}
+
+/* Typemap to return a boolean value as output parameter */
+%typemap(in, numinputs=0,noblock=1) int * BOOL_OUT (int temp) {
+ $1 = &temp;
+}
+%typemap(argout,noblock=1) int * BOOL_OUT {
+ PyObject * r;
+ if (*$1)
+ r = Py_True;
+ else
+ r = Py_False;
+ Py_XINCREF(r);
+ %append_output(r);
+}
+
+/* To allow passing callback functions defined in python */
+%typemap(in) PyObject *PyCb {
+ if (!$input || ($input == Py_None)) {
+ $1 = NULL;
+ } else {
+ if (!PyCallable_Check($input)) {
+ PyErr_SetString(PyExc_TypeError, "Need a callable object!");
+ SWIG_fail;
+ }
+ $1 = $input;
+ }
+}
+
+%{
+/* Forward declaration for the peers module */
+static void fd_add_cb(struct peer_info *peer, void *data);
+
+/* This one gives problems when included from the header file */
+void fd_log_va( int, const char *, va_list);
+void fd_log_deprecated( int level, const char *format, ... ) MARK_DEPRECATED
+{
+ va_list ap;
+ va_start(ap, format);
+ fd_log_va(level, format, ap);
+ va_end(ap);
+}
+
+%}
+
+/* Overwrite declaration to apply typemaps */
+int fd_sess_fromsid ( uint8_t * string, size_t len, struct session ** OUTPUT, int * BOOL_OUT);
+
+
+
+/*********************************************************
+ Now, create wrappers for (almost) all objects from fD API
+ *********************************************************/
+%include "freeDiameter/freeDiameter-host.h"
+%include "freeDiameter/libfdproto.h"
+%include "freeDiameter/libfdcore.h"
+
+/* Most of the functions from the API are not directly usable "as is".
+See the specific following files and the dbg_interactive.py.sample file
+for more usable python-style versions.
+*/
+
+%include "lists.i"
+%include "dictionary.i"
+%include "sessions.i"
+%include "routing.i"
+%include "messages.i"
+%include "dispatch.i"
+%include "queues.i"
+
+%include "peers.i"
+%include "events.i"
+%include "endpoints.i"
+%include "hooks.i"
+
+%include "posix.i"
diff --git a/extensions/dbg_interactive/dictionary.i b/extensions/dbg_interactive/dictionary.i
new file mode 100644
index 0000000..41c9be8
--- /dev/null
+++ b/extensions/dbg_interactive/dictionary.i
@@ -0,0 +1,417 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** DICTIONARY *********/
+
+struct dictionary {
+};
+
+%extend dictionary {
+ dictionary() {
+ struct dictionary * r = NULL;
+ int ret = fd_dict_init(&r);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return r;
+ }
+ ~dictionary() {
+ struct dictionary *d = self;
+ int ret = fd_dict_fini(&d);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return;
+ }
+ void dump() {
+ char * buf = NULL;
+ size_t len;
+ printf("%s", fd_dict_dump(&buf, &len, NULL, $self));
+ free(buf);
+ }
+ PyObject * vendors_list() {
+ uint32_t *list = NULL, *li;
+ PyObject * ret;
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ ret = PyList_New(0);
+ list = fd_dict_get_vendorid_list($self);
+ for (li = list; *li != 0; li++) {
+ PyList_Append(ret, PyInt_FromLong((long)*li));
+ }
+ free(list);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return ret;
+ }
+ struct dict_object * new_obj(enum dict_object_type type, void * data, struct dict_object * parent = NULL) {
+ struct dict_object * obj = NULL;
+ int ret = fd_dict_new($self, type, data, parent, &obj);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return obj;
+ }
+ struct dict_object * search(enum dict_object_type type, int criteria, int what_by_val) {
+ struct dict_object * obj = NULL;
+ int ret = fd_dict_search ( $self, type, criteria, &what_by_val, &obj, ENOENT );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return obj;
+ }
+ struct dict_object * search(enum dict_object_type type, int criteria, char * what_by_string) {
+ struct dict_object * obj = NULL;
+ int ret = fd_dict_search ( $self, type, criteria, what_by_string, &obj, ENOENT );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return obj;
+ }
+ struct dict_object * search(enum dict_object_type type, int criteria, void * what) {
+ struct dict_object * obj = NULL;
+ int ret = fd_dict_search ( $self, type, criteria, what, &obj, ENOENT );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return obj;
+ }
+ struct dict_object * error_cmd() {
+ struct dict_object * obj = NULL;
+ int ret = fd_dict_get_error_cmd ( $self, &obj );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return obj;
+ }
+}
+
+%nodefaultctor dict_object;
+struct dict_object {
+};
+
+%extend dict_object {
+ void dump() {
+ char * buf = NULL;
+ size_t len;
+ printf("%s", fd_dict_dump_object(&buf, &len, NULL, $self));
+ free(buf);
+ }
+ enum dict_object_type gettype() {
+ enum dict_object_type t;
+ int ret = fd_dict_gettype ( $self, &t);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return 0;
+ }
+ return t;
+ }
+ struct dictionary * getdict() {
+ struct dictionary *d;
+ int ret = fd_dict_getdict ( $self, &d );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return d;
+ }
+ /* Since casting the pointer requires intelligence, we do it here instead of giving it to SWIG */
+ PyObject * getval() {
+ /* first, get the type */
+ enum dict_object_type t;
+ int ret = fd_dict_gettype ( $self, &t);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ switch (t) {
+%define %GETVAL_CASE(TYPE,STRUCT)
+ case TYPE: {
+ PyObject * v = NULL;
+ struct STRUCT * data = NULL;
+ data = malloc(sizeof(struct STRUCT));
+ if (!data) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ ret = fd_dict_getval($self, data);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ free(data);
+ return NULL;
+ }
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ v = SWIG_NewPointerObj((void *)data, SWIGTYPE_p_##STRUCT, SWIG_POINTER_OWN );
+ Py_XINCREF(v);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return v;
+ } break
+%enddef
+ %GETVAL_CASE( DICT_VENDOR, dict_vendor_data );
+ %GETVAL_CASE( DICT_APPLICATION, dict_application_data );
+ %GETVAL_CASE( DICT_TYPE, dict_type_data );
+ %GETVAL_CASE( DICT_ENUMVAL, dict_enumval_data );
+ %GETVAL_CASE( DICT_AVP, dict_avp_data );
+ %GETVAL_CASE( DICT_COMMAND, dict_cmd_data );
+ %GETVAL_CASE( DICT_RULE, dict_rule_data );
+ default:
+ DI_ERROR(EINVAL, PyExc_SystemError, "Internal error: Got invalid object type");
+ }
+ return NULL;
+ }
+}
+
+
+/* The following wrapper leaks memory each time an union avp_value is assigned an octet string.
+ TODO: fix this leak by better understanding SWIG...
+ -- the alternative is to uncomment the "free" statements below, but then it is easy to
+ create a segmentation fault by assigning first an integer, then an octetstring.
+ */
+%extend avp_value {
+ /* The following hack in the proxy file allows assigning the octet string directly like this:
+ avp_value.os = "blabla"
+ */
+ %pythoncode
+ {
+ __swig_setmethods__["os"] = _fDpy.avp_value_os_set
+ if _newclass:os = _swig_property(_fDpy.avp_value_os_get, _fDpy.avp_value_os_set)
+ }
+ void os_set(char *STRING, size_t LENGTH) {
+ /* free($self->os.data); -- do not free, in case the previous value was not an OS */
+ $self->os.data = malloc(LENGTH);
+ if (!$self->os.data) {
+ DI_ERROR_MALLOC;
+ return;
+ }
+ memcpy($self->os.data, STRING, LENGTH);
+ $self->os.len = LENGTH;
+ }
+ void os_set(avp_value_os * os) {
+ /* free($self->os.data); -- do not free, in case the previous value was not an OS */
+ $self->os.data = malloc(os->len);
+ if (!$self->os.data) {
+ DI_ERROR_MALLOC;
+ return;
+ }
+ memcpy($self->os.data, os->data, os->len);
+ $self->os.len = os->len;
+ }
+};
+
+%extend avp_value_os {
+ void dump() {
+ %#define LEN_MAX 20
+ int i, n=LEN_MAX;
+ if ($self->len < LEN_MAX)
+ n = $self->len;
+ fd_log_debug("l:%u, v:[", $self->len);
+ for (i=0; i < n; i++)
+ fd_log_debug("%02.2X", $self->data[i]);
+ fd_log_debug("] '%.*s%s'", n, $self->data, n == LEN_MAX ? "..." : "");
+ }
+ %cstring_output_allocate_size(char ** outbuffer, size_t * outlen, free(*$1));
+ void as_str ( char ** outbuffer, size_t * outlen ) {
+ char * b;
+ if (!$self->len) {
+ *outlen = 0;
+ *outbuffer = NULL;
+ return;
+ }
+ b = malloc($self->len);
+ if (!b) {
+ DI_ERROR_MALLOC;
+ return;
+ }
+ memcpy(b, $self->data, $self->len);
+ *outlen = $self->len;
+ *outbuffer = b;
+ }
+}
+
+
+/* Allow constructors with parameters for the dict_*_data */
+%extend dict_vendor_data {
+ dict_vendor_data(uint32_t id = 0, char * name = NULL) {
+ struct dict_vendor_data * d = (struct dict_vendor_data *)calloc(1, sizeof(struct dict_vendor_data));
+ if (!d) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ d->vendor_id = id;
+ if (name) {
+ d->vendor_name = strdup(name);
+ if (!d->vendor_name) {
+ DI_ERROR_MALLOC;
+ free(d);
+ return NULL;
+ }
+ }
+ return d;
+ }
+}
+
+%extend dict_application_data {
+ dict_application_data(uint32_t id = 0, char * name = NULL) {
+ struct dict_application_data * d = (struct dict_application_data *)calloc(1, sizeof(struct dict_application_data));
+ if (!d) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ d->application_id = id;
+ if (name) {
+ d->application_name = strdup(name);
+ if (!d->application_name) {
+ DI_ERROR_MALLOC;
+ free(d);
+ return NULL;
+ }
+ }
+ return d;
+ }
+}
+
+%extend dict_type_data {
+ dict_type_data(enum dict_avp_basetype base = 0, char * name = NULL) {
+ struct dict_type_data * d = (struct dict_type_data *)calloc(1, sizeof(struct dict_type_data));
+ if (!d) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ d->type_base = base;
+ if (name) {
+ d->type_name = strdup(name);
+ if (!d->type_name) {
+ DI_ERROR_MALLOC;
+ free(d);
+ return NULL;
+ }
+ }
+ return d;
+ }
+}
+
+%extend dict_enumval_data {
+ dict_enumval_data(char * name = NULL, uint32_t v = 0) {
+ struct dict_enumval_data * d = (struct dict_enumval_data *)calloc(1, sizeof(struct dict_enumval_data));
+ if (!d) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ if (name) {
+ d->enum_name = strdup(name);
+ if (!d->enum_name) {
+ DI_ERROR_MALLOC;
+ free(d);
+ return NULL;
+ }
+ }
+ d->enum_value.u32 = v;
+ return d;
+ }
+}
+
+%extend dict_avp_data {
+ dict_avp_data(uint32_t code = 0, char * name = NULL, enum dict_avp_basetype basetype = 0, uint32_t vendor = 0, int mandatory=0) {
+ struct dict_avp_data * d = (struct dict_avp_data *)calloc(1, sizeof(struct dict_avp_data));
+ if (!d) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ if (name) {
+ d->avp_name = strdup(name);
+ if (!d->avp_name) {
+ DI_ERROR_MALLOC;
+ free(d);
+ return NULL;
+ }
+ }
+ d->avp_code = code;
+ d->avp_basetype = basetype;
+ d->avp_vendor = vendor;
+ if (vendor) {
+ d->avp_flag_val |= AVP_FLAG_VENDOR;
+ d->avp_flag_mask |= AVP_FLAG_VENDOR;
+ }
+ d->avp_flag_mask |= AVP_FLAG_MANDATORY;
+ if (mandatory)
+ d->avp_flag_val |= AVP_FLAG_MANDATORY;
+ return d;
+ }
+}
+
+%extend dict_cmd_data {
+ dict_cmd_data(uint32_t code = 0, char * name = NULL, int request = 1) {
+ struct dict_cmd_data * d = (struct dict_cmd_data *)calloc(1, sizeof(struct dict_cmd_data));
+ if (!d) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ if (name) {
+ d->cmd_name = strdup(name);
+ if (!d->cmd_name) {
+ DI_ERROR_MALLOC;
+ free(d);
+ return NULL;
+ }
+ }
+ d->cmd_code = code;
+ d->cmd_flag_mask = CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE;
+ d->cmd_flag_val = CMD_FLAG_PROXIABLE | ( request ? CMD_FLAG_REQUEST : 0 );
+ return d;
+ }
+}
+
+%extend dict_rule_data {
+ dict_rule_data(struct dict_object *avp = NULL, enum rule_position pos = 0, int min = -1, int max = -1 ) {
+ struct dict_rule_data * d = (struct dict_rule_data *)calloc(1, sizeof(struct dict_rule_data));
+ if (!d) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ d->rule_avp = avp;
+ d->rule_position = pos;
+ d->rule_order = 1;
+ d->rule_min = min;
+ d->rule_max = max;
+ return d;
+ }
+}
+
diff --git a/extensions/dbg_interactive/dispatch.i b/extensions/dbg_interactive/dispatch.i
new file mode 100644
index 0000000..bc39251
--- /dev/null
+++ b/extensions/dbg_interactive/dispatch.i
@@ -0,0 +1,146 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** DISPATCH *********/
+
+
+%{
+/* call it (will be called from a different thread than the interpreter, when message arrives) */
+static int call_the_python_dispatch_callback(struct msg **msg, struct avp *avp, struct session *session, void * pycb, enum disp_action *action) {
+ PyObject *PyMsg, *PyAvp, *PySess;
+ PyObject *cb, *result = NULL;
+ int ret = 0;
+
+ if (!pycb) {
+ fd_log_debug("Internal error: missing the callback!");
+ return ENOTSUP;
+ }
+ cb = pycb;
+
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ /* Convert the arguments */
+ PyMsg = SWIG_NewPointerObj((void *)*msg, SWIGTYPE_p_msg, 0 );
+ PyAvp = SWIG_NewPointerObj((void *) avp, SWIGTYPE_p_avp, 0 );
+ PySess = SWIG_NewPointerObj((void *) session, SWIGTYPE_p_session, 0 );
+
+ /* Call the function */
+ result = PyObject_CallFunction(cb, "(OOO)", PyMsg, PyAvp, PySess);
+
+ /* The result is supposedly composed of: [ ret, *msg, *action ] */
+ if ((result == NULL) || (!PyList_Check(result)) || (PyList_Size(result) != 3)) {
+ fd_log_debug("Error: The Python callback did not return [ ret, msg, action ].");
+ ret = EINVAL;
+ goto out;
+ }
+
+ /* Convert the return values */
+ if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 0), &ret))) {
+ fd_log_debug("Error: Cannot convert the first return value to integer.");
+ ret = EINVAL;
+ goto out;
+ }
+ if (ret) {
+ TRACE_DEBUG(INFO, "The Python callback returned the error code %d (%s)", ret, strerror(ret));
+ goto out;
+ }
+
+ if (!SWIG_IsOK(SWIG_ConvertPtr(PyList_GetItem(result, 1), (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) {
+ fd_log_debug("Error: Cannot convert the second return value to message.");
+ ret = EINVAL;
+ goto out;
+ }
+
+ if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 2), (int *)action))) {
+ fd_log_debug("Error: Cannot convert the third return value to integer.");
+ ret = EINVAL;
+ goto out;
+ }
+
+ TRACE_DEBUG(FULL, "Python callback return: *action = %d", *action);
+out:
+ Py_XDECREF(result);
+
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return ret;
+}
+%}
+
+struct disp_hdl {
+};
+
+%nodefaultctor disp_hdl;
+%extend disp_hdl {
+ disp_hdl(PyObject * PyCb, enum disp_how how, struct disp_when * when) {
+ struct disp_hdl * hdl = NULL;
+ int ret;
+
+ Py_XINCREF(PyCb);
+
+ ret = fd_disp_register ( call_the_python_dispatch_callback, how, when, PyCb, &hdl );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return hdl;
+ }
+ ~disp_hdl() {
+ struct disp_hdl * hdl = self;
+ PyObject * cb = NULL;
+ int ret = fd_disp_unregister(&hdl, (void *)&cb);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ Py_XDECREF(cb);
+ return;
+ }
+}
+
+
+%extend disp_when {
+ disp_when(struct dict_object * app = NULL, struct dict_object * command = NULL, struct dict_object * avp = NULL, struct dict_object * value = NULL) {
+ struct disp_when * w = (struct disp_when *)calloc(1, sizeof(struct disp_when));
+ if (!w) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ w->app = app;
+ w->command = command;
+ w->avp = avp;
+ w->value = value;
+ return w;
+ }
+}
diff --git a/extensions/dbg_interactive/endpoints.i b/extensions/dbg_interactive/endpoints.i
new file mode 100644
index 0000000..329f379
--- /dev/null
+++ b/extensions/dbg_interactive/endpoints.i
@@ -0,0 +1,133 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** ENDPOINTS *********/
+
+%{
+
+#include <sys/socket.h>
+#include <netdb.h>
+
+%}
+
+%extend fd_endpoint {
+ fd_endpoint() {
+ struct fd_endpoint *np = (struct fd_endpoint *)calloc(1, sizeof(struct fd_endpoint));
+ if (!np) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ fd_list_init(&np->chain, np);
+ return np;
+ }
+
+ fd_endpoint(const char * endpoint, uint16_t port = 0, uint32_t flags = EP_FL_CONF) {
+ struct addrinfo hints;
+ struct addrinfo *ai = NULL;
+ int ret;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family= AF_UNSPEC;
+ hints.ai_flags = AI_NUMERICHOST;
+
+ ret = getaddrinfo(endpoint, NULL, &hints, &ai);
+ if (ret) {
+ DI_ERROR(ret, PyExc_ValueError, gai_strerror(ret));
+ return NULL;
+ }
+
+ if (port) {
+ switch (ai->ai_family) {
+ case AF_INET:
+ ((sSA4 *)ai->ai_addr)->sin_port = htons(port);
+ break;
+ case AF_INET6:
+ ((sSA6 *)ai->ai_addr)->sin6_port = htons(port);
+ break;
+ default:
+ DI_ERROR(EINVAL, PyExc_RuntimeError, "Unknown family returned by getaddrinfo");
+ return NULL;
+ }
+ }
+
+ struct fd_endpoint *np = (struct fd_endpoint *)calloc(1, sizeof(struct fd_endpoint));
+ if (!np) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ fd_list_init(&np->chain, np);
+
+ memcpy(&np->s.sa, ai->ai_addr, ai->ai_addrlen);
+
+ freeaddrinfo(ai);
+
+ np->flags = flags;
+
+ return np;
+ }
+
+ ~fd_endpoint() {
+ fd_list_unlink(&$self->chain);
+ free($self);
+ }
+
+ /* Merge to a list */
+ %delobject add_merge;
+ void add_merge(struct fd_list * eplist) {
+ int ret;
+
+ if (!eplist) {
+ DI_ERROR(EINVAL, NULL, NULL);
+ return;
+ }
+
+ ret = fd_ep_add_merge( eplist, &$self->s.sa, sSAlen(&$self->s.sa), $self->flags );
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ return;
+ }
+
+ return;
+ }
+
+ void dump() {
+ char * buf = NULL;
+ size_t len;
+ printf("%s", fd_ep_dump_one(&buf, &len, NULL, 1, $self));
+ free(buf);
+ }
+}
diff --git a/extensions/dbg_interactive/events.i b/extensions/dbg_interactive/events.i
new file mode 100644
index 0000000..a70c89e
--- /dev/null
+++ b/extensions/dbg_interactive/events.i
@@ -0,0 +1,73 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** EVENTS *********/
+
+%extend fd_event {
+ fd_event(int code, char *STRING, size_t LENGTH) {
+ struct fd_event * fd = calloc(1, sizeof(struct fd_event));
+ if (!fd) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ fd->code = code;
+ fd->data = os0dup(STRING, LENGTH);
+ if (!fd->data) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ };
+ fd->size = LENGTH;
+ return fd;
+ }
+
+ fd_event(int code, int value) {
+ struct fd_event * fd = calloc(1, sizeof(struct fd_event));
+ if (!fd) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ fd->code = code;
+ fd->data = malloc(sizeof(int));
+ if (!fd->data) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ };
+ *((int *)fd->data) = value;
+ fd->size = sizeof(int);
+ return fd;
+ }
+}
diff --git a/extensions/dbg_interactive/helper/xxd.c b/extensions/dbg_interactive/helper/xxd.c
new file mode 100644
index 0000000..490f571
--- /dev/null
+++ b/extensions/dbg_interactive/helper/xxd.c
@@ -0,0 +1,787 @@
+/* fD note: This source file comes from the VIM source package. All credits go to the original authors */
+
+/* xxd: my hexdump facility. jw
+ *
+ * 2.10.90 changed to word output
+ * 3.03.93 new indent style, dumb bug inserted and fixed.
+ * -c option, mls
+ * 26.04.94 better option parser, -ps, -l, -s added.
+ * 1.07.94 -r badly needs - as input file. Per default autoskip over
+ * consecutive lines of zeroes, as unix od does.
+ * -a shows them too.
+ * -i dump as c-style #include "file.h"
+ * 1.11.95 if "xxd -i" knows the filename, an 'unsigned char filename_bits[]'
+ * array is written in correct c-syntax.
+ * -s improved, now defaults to absolute seek, relative requires a '+'.
+ * -r improved, now -r -s -0x... is supported.
+ * change/suppress leading '\0' bytes.
+ * -l n improved: stops exactly after n bytes.
+ * -r improved, better handling of partial lines with trailing garbage.
+ * -r improved, now -r -p works again!
+ * -r improved, less flushing, much faster now! (that was silly)
+ * 3.04.96 Per repeated request of a single person: autoskip defaults to off.
+ * 15.05.96 -v added. They want to know the version.
+ * -a fixed, to show last line inf file ends in all zeros.
+ * -u added: Print upper case hex-letters, as preferred by unix bc.
+ * -h added to usage message. Usage message extended.
+ * Now using outfile if specified even in normal mode, aehem.
+ * No longer mixing of ints and longs. May help doze people.
+ * Added binify ioctl for same reason. (Enough Doze stress for 1996!)
+ * 16.05.96 -p improved, removed occasional superfluous linefeed.
+ * 20.05.96 -l 0 fixed. tried to read anyway.
+ * 21.05.96 -i fixed. now honours -u, and prepends __ to numeric filenames.
+ * compile -DWIN32 for NT or W95. George V. Reilly, * -v improved :-)
+ * support --gnuish-longhorn-options
+ * 25.05.96 MAC support added: CodeWarrior already uses ``outline'' in Types.h
+ * which is included by MacHeaders (Axel Kielhorn). Renamed to
+ * xxdline().
+ * 7.06.96 -i printed 'int' instead of 'char'. *blush*
+ * added Bram's OS2 ifdefs...
+ * 18.07.96 gcc -Wall @ SunOS4 is now slient.
+ * Added osver for MSDOS/DJGPP/WIN32.
+ * 29.08.96 Added size_t to strncmp() for Amiga.
+ * 24.03.97 Windows NT support (Phil Hanna). Clean exit for Amiga WB (Bram)
+ * 02.04.97 Added -E option, to have EBCDIC translation instead of ASCII
+ * (azc10@yahoo.com)
+ * 22.05.97 added -g (group octets) option (jcook@namerica.kla.com).
+ * 23.09.98 nasty -p -r misfeature fixed: slightly wrong output, when -c was
+ * missing or wrong.
+ * 26.09.98 Fixed: 'xxd -i infile outfile' did not truncate outfile.
+ * 27.10.98 Fixed: -g option parser required blank.
+ * option -b added: 01000101 binary output in normal format.
+ * 16.05.00 Added VAXC changes by Stephen P. Wall
+ * 16.05.00 Improved MMS file and merge for VMS by Zoltan Arpadffy
+ *
+ * (c) 1990-1998 by Juergen Weigert (jnweiger@informatik.uni-erlangen.de)
+ *
+ * Small changes made afterwards by Bram Moolenaar et al.
+ *
+ * Distribute freely and credit me,
+ * make money and share with me,
+ * lose money and don't ask me.
+ */
+
+/* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */
+#if _MSC_VER >= 1400
+# define _CRT_SECURE_NO_DEPRECATE
+# define _CRT_NONSTDC_NO_DEPRECATE
+#endif
+#if !defined(CYGWIN) && (defined(CYGWIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__))
+# define CYGWIN
+#endif
+
+#include <stdio.h>
+#ifdef VAXC
+# include <file.h>
+#else
+# include <fcntl.h>
+#endif
+#ifdef __TSC__
+# define MSDOS
+#endif
+#if !defined(OS2) && defined(__EMX__)
+# define OS2
+#endif
+#if defined(MSDOS) || defined(WIN32) || defined(OS2) || defined(__BORLANDC__) \
+ || defined(CYGWIN)
+# include <io.h> /* for setmode() */
+#else
+# ifdef UNIX
+# include <unistd.h>
+# endif
+#endif
+#include <stdlib.h>
+#include <string.h> /* for strncmp() */
+#include <ctype.h> /* for isalnum() */
+#if __MWERKS__ && !defined(BEBOX)
+# include <unix.h> /* for fdopen() on MAC */
+#endif
+
+#if defined(__BORLANDC__) && __BORLANDC__ <= 0x0410 && !defined(fileno)
+/* Missing define and prototype grabbed from the BC 4.0 <stdio.h> */
+# define fileno(f) ((f)->fd)
+FILE _FAR *_Cdecl _FARFUNC fdopen(int __handle, char _FAR *__type);
+#endif
+
+
+/* This corrects the problem of missing prototypes for certain functions
+ * in some GNU installations (e.g. SunOS 4.1.x).
+ * Darren Hiebert <darren@hmi.com> (sparc-sun-sunos4.1.3_U1/2.7.2.2)
+ */
+#if defined(__GNUC__) && defined(__STDC__)
+# ifndef __USE_FIXED_PROTOTYPES__
+# define __USE_FIXED_PROTOTYPES__
+# endif
+#endif
+
+#ifndef __USE_FIXED_PROTOTYPES__
+/*
+ * This is historic and works only if the compiler really has no prototypes:
+ *
+ * Include prototypes for Sun OS 4.x, when using an ANSI compiler.
+ * FILE is defined on OS 4.x, not on 5.x (Solaris).
+ * if __SVR4 is defined (some Solaris versions), don't include this.
+ */
+#if defined(sun) && defined(FILE) && !defined(__SVR4) && defined(__STDC__)
+# define __P(a) a
+/* excerpt from my sun_stdlib.h */
+extern int fprintf __P((FILE *, char *, ...));
+extern int fputs __P((char *, FILE *));
+extern int _flsbuf __P((unsigned char, FILE *));
+extern int _filbuf __P((FILE *));
+extern int fflush __P((FILE *));
+extern int fclose __P((FILE *));
+extern int fseek __P((FILE *, long, int));
+extern int rewind __P((FILE *));
+
+extern void perror __P((char *));
+# endif
+#endif
+
+extern long int strtol();
+extern long int ftell();
+
+char version[] = "xxd V1.10 27oct98 by Juergen Weigert";
+#ifdef WIN32
+char osver[] = " (Win32)";
+#else
+# ifdef DJGPP
+char osver[] = " (dos 32 bit)";
+# else
+# ifdef MSDOS
+char osver[] = " (dos 16 bit)";
+# else
+char osver[] = "";
+# endif
+# endif
+#endif
+
+#if defined(MSDOS) || defined(WIN32) || defined(OS2)
+# define BIN_READ(yes) ((yes) ? "rb" : "rt")
+# define BIN_WRITE(yes) ((yes) ? "wb" : "wt")
+# define BIN_CREAT(yes) ((yes) ? (O_CREAT|O_BINARY) : O_CREAT)
+# define BIN_ASSIGN(fp, yes) setmode(fileno(fp), (yes) ? O_BINARY : O_TEXT)
+# define PATH_SEP '\\'
+#elif defined(CYGWIN)
+# define BIN_READ(yes) ((yes) ? "rb" : "rt")
+# define BIN_WRITE(yes) ((yes) ? "wb" : "w")
+# define BIN_CREAT(yes) ((yes) ? (O_CREAT|O_BINARY) : O_CREAT)
+# define BIN_ASSIGN(fp, yes) ((yes) ? (void) setmode(fileno(fp), O_BINARY) : (void) (fp))
+# define PATH_SEP '/'
+#else
+# ifdef VMS
+# define BIN_READ(dummy) "r"
+# define BIN_WRITE(dummy) "w"
+# define BIN_CREAT(dummy) O_CREAT
+# define BIN_ASSIGN(fp, dummy) fp
+# define PATH_SEP ']'
+# define FILE_SEP '.'
+# else
+# define BIN_READ(dummy) "r"
+# define BIN_WRITE(dummy) "w"
+# define BIN_CREAT(dummy) O_CREAT
+# define BIN_ASSIGN(fp, dummy) fp
+# define PATH_SEP '/'
+# endif
+#endif
+
+/* open has only to arguments on the Mac */
+#if __MWERKS__
+# define OPEN(name, mode, umask) open(name, mode)
+#else
+# define OPEN(name, mode, umask) open(name, mode, umask)
+#endif
+
+#ifdef AMIGA
+# define STRNCMP(s1, s2, l) strncmp(s1, s2, (size_t)l)
+#else
+# define STRNCMP(s1, s2, l) strncmp(s1, s2, l)
+#endif
+
+#ifndef __P
+# if defined(__STDC__) || defined(MSDOS) || defined(WIN32) || defined(OS2) \
+ || defined(__BORLANDC__)
+# define __P(a) a
+# else
+# define __P(a) ()
+# endif
+#endif
+
+/* Let's collect some prototypes */
+/* CodeWarrior is really picky about missing prototypes */
+static void exit_with_usage __P((char *));
+static int huntype __P((FILE *, FILE *, FILE *, char *, int, int, long));
+static void xxdline __P((FILE *, char *, int));
+
+#define TRY_SEEK /* attempt to use lseek, or skip forward by reading */
+#define COLS 256 /* change here, if you ever need more columns */
+#define LLEN (11 + (9*COLS-1)/1 + COLS + 2)
+
+char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa;
+
+/* the different hextypes known by this program: */
+#define HEX_NORMAL 0
+#define HEX_POSTSCRIPT 1
+#define HEX_CINCLUDE 2
+#define HEX_BITS 3 /* not hex a dump, but bits: 01111001 */
+
+static void
+exit_with_usage(pname)
+char *pname;
+{
+ fprintf(stderr, "Usage:\n %s [options] [infile [outfile]]\n", pname);
+ fprintf(stderr, " or\n %s -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]]\n", pname);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -a toggle autoskip: A single '*' replaces nul-lines. Default off.\n");
+ fprintf(stderr, " -b binary digit dump (incompatible with -ps,-i,-r). Default hex.\n");
+ fprintf(stderr, " -c cols format <cols> octets per line. Default 16 (-i: 12, -ps: 30).\n");
+ fprintf(stderr, " -E show characters in EBCDIC. Default ASCII.\n");
+ fprintf(stderr, " -g number of octets per group in normal output. Default 2.\n");
+ fprintf(stderr, " -h print this summary.\n");
+ fprintf(stderr, " -i output in C include file style.\n");
+ fprintf(stderr, " -l len stop after <len> octets.\n");
+ fprintf(stderr, " -ps output in postscript plain hexdump style.\n");
+ fprintf(stderr, " -r reverse operation: convert (or patch) hexdump into binary.\n");
+ fprintf(stderr, " -r -s off revert with <off> added to file positions found in hexdump.\n");
+ fprintf(stderr, " -s %sseek start at <seek> bytes abs. %sinfile offset.\n",
+#ifdef TRY_SEEK
+ "[+][-]", "(or +: rel.) ");
+#else
+ "", "");
+#endif
+ fprintf(stderr, " -u use upper case hex letters.\n");
+ fprintf(stderr, " -v show version: \"%s%s\".\n", version, osver);
+ exit(1);
+}
+
+/*
+ * Max. cols binary characters are decoded from the input stream per line.
+ * Two adjacent garbage characters after evaluated data delimit valid data.
+ * Everything up to the next newline is discarded.
+ *
+ * The name is historic and came from 'undo type opt h'.
+ */
+static int
+huntype(fpi, fpo, fperr, pname, cols, hextype, base_off)
+FILE *fpi, *fpo, *fperr;
+char *pname;
+int cols, hextype;
+long base_off;
+{
+ int c, ign_garb = 1, n1 = -1, n2 = 0, n3, p = cols;
+ long have_off = 0, want_off = 0;
+
+ rewind(fpi);
+
+ while ((c = getc(fpi)) != EOF)
+ {
+ if (c == '\r') /* Doze style input file? */
+ continue;
+
+ /* Allow multiple spaces. This doesn't work when there is normal text
+ * after the hex codes in the last line that looks like hex, thus only
+ * use it for PostScript format. */
+ if (hextype == HEX_POSTSCRIPT && (c == ' ' || c == '\n' || c == '\t'))
+ continue;
+
+ n3 = n2;
+ n2 = n1;
+
+ if (c >= '0' && c <= '9')
+ n1 = c - '0';
+ else if (c >= 'a' && c <= 'f')
+ n1 = c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ n1 = c - 'A' + 10;
+ else
+ {
+ n1 = -1;
+ if (ign_garb)
+ continue;
+ }
+
+ ign_garb = 0;
+
+ if (p >= cols)
+ {
+ if (!hextype)
+ {
+ if (n1 < 0)
+ {
+ p = 0;
+ continue;
+ }
+ want_off = (want_off << 4) | n1;
+ continue;
+ }
+ else
+ p = 0;
+ }
+
+ if (base_off + want_off != have_off)
+ {
+ fflush(fpo);
+#ifdef TRY_SEEK
+ c = fseek(fpo, base_off + want_off - have_off, 1);
+ if (c >= 0)
+ have_off = base_off + want_off;
+#endif
+ if (base_off + want_off < have_off)
+ {
+ fprintf(fperr, "%s: sorry, cannot seek backwards.\n", pname);
+ return 5;
+ }
+ for (; have_off < base_off + want_off; have_off++)
+ putc(0, fpo);
+ }
+
+ if (n2 >= 0 && n1 >= 0)
+ {
+ putc((n2 << 4) | n1, fpo);
+ have_off++;
+ want_off++;
+ n1 = -1;
+ if ((++p >= cols) && !hextype)
+ {
+ /* skip rest of line as garbage */
+ want_off = 0;
+ while ((c = getc(fpi)) != '\n' && c != EOF)
+ ;
+ ign_garb = 1;
+ }
+ }
+ else if (n1 < 0 && n2 < 0 && n3 < 0)
+ {
+ /* already stumbled into garbage, skip line, wait and see */
+ if (!hextype)
+ want_off = 0;
+ while ((c = getc(fpi)) != '\n' && c != EOF)
+ ;
+ ign_garb = 1;
+ }
+ }
+ fflush(fpo);
+#ifdef TRY_SEEK
+ fseek(fpo, 0L, 2);
+#endif
+ fclose(fpo);
+ fclose(fpi);
+ return 0;
+}
+
+/*
+ * Print line l. If nz is false, xxdline regards the line a line of
+ * zeroes. If there are three or more consecutive lines of zeroes,
+ * they are replaced by a single '*' character.
+ *
+ * If the output ends with more than two lines of zeroes, you
+ * should call xxdline again with l being the last line and nz
+ * negative. This ensures that the last line is shown even when
+ * it is all zeroes.
+ *
+ * If nz is always positive, lines are never suppressed.
+ */
+static void
+xxdline(fp, l, nz)
+FILE *fp;
+char *l;
+int nz;
+{
+ static char z[LLEN+1];
+ static int zero_seen = 0;
+
+ if (!nz && zero_seen == 1)
+ strcpy(z, l);
+
+ if (nz || !zero_seen++)
+ {
+ if (nz)
+ {
+ if (nz < 0)
+ zero_seen--;
+ if (zero_seen == 2)
+ fputs(z, fp);
+ if (zero_seen > 2)
+ fputs("*\n", fp);
+ }
+ if (nz >= 0 || zero_seen > 0)
+ fputs(l, fp);
+ if (nz)
+ zero_seen = 0;
+ }
+}
+
+/* This is an EBCDIC to ASCII conversion table */
+/* from a proposed BTL standard April 16, 1979 */
+static unsigned char etoa64[] =
+{
+ 0040,0240,0241,0242,0243,0244,0245,0246,
+ 0247,0250,0325,0056,0074,0050,0053,0174,
+ 0046,0251,0252,0253,0254,0255,0256,0257,
+ 0260,0261,0041,0044,0052,0051,0073,0176,
+ 0055,0057,0262,0263,0264,0265,0266,0267,
+ 0270,0271,0313,0054,0045,0137,0076,0077,
+ 0272,0273,0274,0275,0276,0277,0300,0301,
+ 0302,0140,0072,0043,0100,0047,0075,0042,
+ 0303,0141,0142,0143,0144,0145,0146,0147,
+ 0150,0151,0304,0305,0306,0307,0310,0311,
+ 0312,0152,0153,0154,0155,0156,0157,0160,
+ 0161,0162,0136,0314,0315,0316,0317,0320,
+ 0321,0345,0163,0164,0165,0166,0167,0170,
+ 0171,0172,0322,0323,0324,0133,0326,0327,
+ 0330,0331,0332,0333,0334,0335,0336,0337,
+ 0340,0341,0342,0343,0344,0135,0346,0347,
+ 0173,0101,0102,0103,0104,0105,0106,0107,
+ 0110,0111,0350,0351,0352,0353,0354,0355,
+ 0175,0112,0113,0114,0115,0116,0117,0120,
+ 0121,0122,0356,0357,0360,0361,0362,0363,
+ 0134,0237,0123,0124,0125,0126,0127,0130,
+ 0131,0132,0364,0365,0366,0367,0370,0371,
+ 0060,0061,0062,0063,0064,0065,0066,0067,
+ 0070,0071,0372,0373,0374,0375,0376,0377
+};
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ FILE *fp, *fpo;
+ int c, e, p = 0, relseek = 1, negseek = 0, revert = 0;
+ int cols = 0, nonzero = 0, autoskip = 0, hextype = HEX_NORMAL;
+ int ebcdic = 0;
+ int octspergrp = -1; /* number of octets grouped in output */
+ int grplen; /* total chars per octet group */
+ long length = -1, n = 0, seekoff = 0;
+ char l[LLEN+1];
+ char *pname, *pp;
+
+#ifdef AMIGA
+ /* This program doesn't work when started from the Workbench */
+ if (argc == 0)
+ exit(1);
+#endif
+
+ pname = argv[0];
+ for (pp = pname; *pp; )
+ if (*pp++ == PATH_SEP)
+ pname = pp;
+#ifdef FILE_SEP
+ for (pp = pname; *pp; pp++)
+ if (*pp == FILE_SEP)
+ {
+ *pp = '\0';
+ break;
+ }
+#endif
+
+ while (argc >= 2)
+ {
+ pp = argv[1] + (!STRNCMP(argv[1], "--", 2) && argv[1][2]);
+ if (!STRNCMP(pp, "-a", 2)) autoskip = 1 - autoskip;
+ else if (!STRNCMP(pp, "-b", 2)) hextype = HEX_BITS;
+ else if (!STRNCMP(pp, "-u", 2)) hexx = hexxa + 16;
+ else if (!STRNCMP(pp, "-p", 2)) hextype = HEX_POSTSCRIPT;
+ else if (!STRNCMP(pp, "-i", 2)) hextype = HEX_CINCLUDE;
+ else if (!STRNCMP(pp, "-r", 2)) revert++;
+ else if (!STRNCMP(pp, "-E", 2)) ebcdic++;
+ else if (!STRNCMP(pp, "-v", 2))
+ {
+ fprintf(stderr, "%s%s\n", version, osver);
+ exit(0);
+ }
+ else if (!STRNCMP(pp, "-c", 2))
+ {
+ if (pp[2] && STRNCMP("ols", pp + 2, 3))
+ cols = (int)strtol(pp + 2, NULL, 0);
+ else
+ {
+ if (!argv[2])
+ exit_with_usage(pname);
+ cols = (int)strtol(argv[2], NULL, 0);
+ argv++;
+ argc--;
+ }
+ }
+ else if (!STRNCMP(pp, "-g", 2))
+ {
+ if (pp[2] && STRNCMP("group", pp + 2, 5))
+ octspergrp = (int)strtol(pp + 2, NULL, 0);
+ else
+ {
+ if (!argv[2])
+ exit_with_usage(pname);
+ octspergrp = (int)strtol(argv[2], NULL, 0);
+ argv++;
+ argc--;
+ }
+ }
+ else if (!STRNCMP(pp, "-s", 2))
+ {
+ relseek = 0;
+ negseek = 0;
+ if (pp[2] && STRNCMP("kip", pp+2, 3) && STRNCMP("eek", pp+2, 3))
+ {
+#ifdef TRY_SEEK
+ if (pp[2] == '+')
+ relseek++;
+ if (pp[2+relseek] == '-')
+ negseek++;
+#endif
+ seekoff = strtol(pp + 2+relseek+negseek, (char **)NULL, 0);
+ }
+ else
+ {
+ if (!argv[2])
+ exit_with_usage(pname);
+#ifdef TRY_SEEK
+ if (argv[2][0] == '+')
+ relseek++;
+ if (argv[2][relseek] == '-')
+ negseek++;
+#endif
+ seekoff = strtol(argv[2] + relseek+negseek, (char **)NULL, 0);
+ argv++;
+ argc--;
+ }
+ }
+ else if (!STRNCMP(pp, "-l", 2))
+ {
+ if (pp[2] && STRNCMP("en", pp + 2, 2))
+ length = strtol(pp + 2, (char **)NULL, 0);
+ else
+ {
+ if (!argv[2])
+ exit_with_usage(pname);
+ length = strtol(argv[2], (char **)NULL, 0);
+ argv++;
+ argc--;
+ }
+ }
+ else if (!strcmp(pp, "--")) /* end of options */
+ {
+ argv++;
+ argc--;
+ break;
+ }
+ else if (pp[0] == '-' && pp[1]) /* unknown option */
+ exit_with_usage(pname);
+ else
+ break; /* not an option */
+
+ argv++; /* advance to next argument */
+ argc--;
+ }
+
+ if (!cols)
+ switch (hextype)
+ {
+ case HEX_POSTSCRIPT: cols = 30; break;
+ case HEX_CINCLUDE: cols = 12; break;
+ case HEX_BITS: cols = 6; break;
+ case HEX_NORMAL:
+ default: cols = 16; break;
+ }
+
+ if (octspergrp < 0)
+ switch (hextype)
+ {
+ case HEX_BITS: octspergrp = 1; break;
+ case HEX_NORMAL: octspergrp = 2; break;
+ case HEX_POSTSCRIPT:
+ case HEX_CINCLUDE:
+ default: octspergrp = 0; break;
+ }
+
+ if (cols < 1 || ((hextype == HEX_NORMAL || hextype == HEX_BITS)
+ && (cols > COLS)))
+ {
+ fprintf(stderr, "%s: invalid number of columns (max. %d).\n", pname, COLS);
+ exit(1);
+ }
+
+ if (octspergrp < 1)
+ octspergrp = cols;
+
+ if (argc > 3)
+ exit_with_usage(pname);
+
+ if (argc == 1 || (argv[1][0] == '-' && !argv[1][1]))
+ BIN_ASSIGN(fp = stdin, !revert);
+ else
+ {
+ if ((fp = fopen(argv[1], BIN_READ(!revert))) == NULL)
+ {
+ fprintf(stderr,"%s: ", pname);
+ perror(argv[1]);
+ return 2;
+ }
+ }
+
+ if (argc < 3 || (argv[2][0] == '-' && !argv[2][1]))
+ BIN_ASSIGN(fpo = stdout, revert);
+ else
+ {
+ int fd;
+ int mode = revert ? O_WRONLY : (O_TRUNC|O_WRONLY);
+
+ if (((fd = OPEN(argv[2], mode | BIN_CREAT(revert), 0666)) < 0) ||
+ (fpo = fdopen(fd, BIN_WRITE(revert))) == NULL)
+ {
+ fprintf(stderr, "%s: ", pname);
+ perror(argv[2]);
+ return 3;
+ }
+ rewind(fpo);
+ }
+
+ if (revert)
+ {
+ if (hextype && (hextype != HEX_POSTSCRIPT))
+ {
+ fprintf(stderr, "%s: sorry, cannot revert this type of hexdump\n", pname);
+ return -1;
+ }
+ return huntype(fp, fpo, stderr, pname, cols, hextype,
+ negseek ? -seekoff : seekoff);
+ }
+
+ if (seekoff || negseek || !relseek)
+ {
+#ifdef TRY_SEEK
+ if (relseek)
+ e = fseek(fp, negseek ? -seekoff : seekoff, 1);
+ else
+ e = fseek(fp, negseek ? -seekoff : seekoff, negseek ? 2 : 0);
+ if (e < 0 && negseek)
+ {
+ fprintf(stderr, "%s: sorry cannot seek.\n", pname);
+ return 4;
+ }
+ if (e >= 0)
+ seekoff = ftell(fp);
+ else
+#endif
+ {
+ long s = seekoff;
+
+ while (s--)
+ (void)getc(fp);
+ }
+ }
+
+ if (hextype == HEX_CINCLUDE)
+ {
+ if (fp != stdin)
+ {
+ fprintf(fpo, "unsigned char %s", isdigit((int)argv[1][0]) ? "__" : "");
+ for (e = 0; (c = argv[1][e]) != 0; e++)
+ putc(isalnum(c) ? c : '_', fpo);
+ fputs("[] = {\n", fpo);
+ }
+
+ p = 0;
+ while ((length < 0 || p < length) && (c = getc(fp)) != EOF)
+ {
+ fprintf(fpo, (hexx == hexxa) ? "%s0x%02x" : "%s0X%02X",
+ (p % cols) ? ", " : ",\n "+2*!p, c);
+ p++;
+ }
+
+ if (p)
+ fputs("\n};\n"+3*(fp == stdin), fpo);
+
+ if (fp != stdin)
+ {
+ fprintf(fpo, "unsigned int %s", isdigit((int)argv[1][0]) ? "__" : "");
+ for (e = 0; (c = argv[1][e]) != 0; e++)
+ putc(isalnum(c) ? c : '_', fpo);
+ fprintf(fpo, "_len = %d;\n", p);
+ }
+
+ fclose(fp);
+ fclose(fpo);
+ return 0;
+ }
+
+ if (hextype == HEX_POSTSCRIPT)
+ {
+ p = cols;
+ while ((length < 0 || n < length) && (e = getc(fp)) != EOF)
+ {
+ putchar(hexx[(e >> 4) & 0xf]);
+ putchar(hexx[(e ) & 0xf]);
+ n++;
+ if (!--p)
+ {
+ putchar('\n');
+ p = cols;
+ }
+ }
+ if (p < cols)
+ putchar('\n');
+ fclose(fp);
+ fclose(fpo);
+ return 0;
+ }
+
+ /* hextype: HEX_NORMAL or HEX_BITS */
+
+ if (hextype == HEX_NORMAL)
+ grplen = octspergrp + octspergrp + 1; /* chars per octet group */
+ else /* hextype == HEX_BITS */
+ grplen = 8 * octspergrp + 1;
+
+ while ((length < 0 || n < length) && (e = getc(fp)) != EOF)
+ {
+ if (p == 0)
+ {
+ sprintf(l, "%07lx: ", n + seekoff);
+ for (c = 9; c < LLEN; l[c++] = ' ');
+ }
+ if (hextype == HEX_NORMAL)
+ {
+ l[c = (9 + (grplen * p) / octspergrp)] = hexx[(e >> 4) & 0xf];
+ l[++c] = hexx[ e & 0xf];
+ }
+ else /* hextype == HEX_BITS */
+ {
+ int i;
+
+ c = (9 + (grplen * p) / octspergrp) - 1;
+ for (i = 7; i >= 0; i--)
+ l[++c] = (e & (1 << i)) ? '1' : '0';
+ }
+ if (ebcdic)
+ e = (e < 64) ? '.' : etoa64[e-64];
+ /* When changing this update definition of LLEN above. */
+ l[11 + (grplen * cols - 1)/octspergrp + p] =
+#ifdef __MVS__
+ (e >= 64)
+#else
+ (e > 31 && e < 127)
+#endif
+ ? e : '.';
+ if (e)
+ nonzero++;
+ n++;
+ if (++p == cols)
+ {
+ l[c = (11 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
+ xxdline(fpo, l, autoskip ? nonzero : 1);
+ nonzero = 0;
+ p = 0;
+ }
+ }
+ if (p)
+ {
+ l[c = (11 + (grplen * cols - 1)/octspergrp + p)] = '\n'; l[++c] = '\0';
+ xxdline(fpo, l, 1);
+ }
+ else if (autoskip)
+ xxdline(fpo, l, -1); /* last chance to flush out suppressed lines */
+
+ fclose(fp);
+ fclose(fpo);
+ return 0;
+}
diff --git a/extensions/dbg_interactive/hooks.i b/extensions/dbg_interactive/hooks.i
new file mode 100644
index 0000000..98cbc58
--- /dev/null
+++ b/extensions/dbg_interactive/hooks.i
@@ -0,0 +1,190 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** HOOKS *********/
+
+
+/* Functions to handle the PMD */
+%{
+
+struct fd_hook_permsgdata {
+ PyObject *PyPML;
+};
+
+static void init_permsgdata (struct fd_hook_permsgdata * pmd) {
+ /* The PMD is None by default */
+ Py_INCREF(Py_None);
+ pmd->PyPML = Py_None;
+}
+
+static void fini_permsgdata (struct fd_hook_permsgdata * pmd) {
+ Py_DECREF(pmd->PyPML);
+}
+
+%}
+
+struct fd_hook_data_hdl {
+};
+
+%nodefaultctor fd_hook_data_hdl;
+%extend fd_hook_data_hdl {
+ fd_hook_data_hdl() {
+ struct fd_hook_data_hdl * hdl = NULL;
+ int ret;
+
+ ret = fd_hook_data_register ( sizeof(struct fd_hook_permsgdata), init_permsgdata, fini_permsgdata, &hdl );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return hdl;
+ }
+}
+
+
+/* Now the hook itself */
+%{
+static void call_the_python_hook_callback(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata) {
+ PyObject *cb, *result = NULL;
+ PyObject *PyType, *PyMsg, *PyPeer, *PyOther, *PyOldPmd;
+
+ if (!regdata) {
+ LOG_E("Internal error: missing the callback!");
+ return;
+ }
+ cb = regdata;
+
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ /* Convert the arguments */
+ PyType = PyLong_FromLong(type);
+ Py_INCREF(PyType);
+
+ PyMsg = SWIG_NewPointerObj((void *) msg, SWIGTYPE_p_msg, 0 );
+
+ PyPeer = SWIG_NewPointerObj((void *) peer, SWIGTYPE_p_peer_hdr, 0 );
+ if (other == NULL) {
+ PyOther=Py_None;
+ Py_INCREF(Py_None);
+ } else {
+ switch (type) {
+ case HOOK_DATA_RECEIVED:
+ PyOther= SWIG_NewPointerObj( other, SWIGTYPE_p_fd_cnx_rcvdata, 0 );
+ break;
+
+ case HOOK_MESSAGE_RECEIVED:
+ case HOOK_MESSAGE_ROUTING_ERROR:
+ case HOOK_MESSAGE_DROPPED:
+ case HOOK_PEER_CONNECT_FAILED:
+ PyOther= SWIG_NewPointerObj( other, SWIGTYPE_p_char, 0 );
+ break;
+
+ case HOOK_MESSAGE_PARSING_ERROR:
+ if (msg) {
+ PyOther= SWIG_NewPointerObj( other, SWIGTYPE_p_char, 0 );
+ } else {
+ PyOther= SWIG_NewPointerObj( other, SWIGTYPE_p_fd_cnx_rcvdata, 0 );
+ }
+ break;
+ default:
+ /* In other cases, other should be NULL */
+ LOG_E("Internal error: got a value of *other");
+ }
+
+ }
+
+ if (pmd == NULL) {
+ Py_INCREF(Py_None);
+ PyOldPmd=Py_None;
+ } else {
+ PyOldPmd=pmd->PyPML;
+ }
+
+ /* Call the function */
+ result = PyObject_CallFunction(cb, "(OOOOO)", PyType, PyMsg, PyPeer, PyOther, PyOldPmd);
+
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ if (pmd == NULL)
+ return;
+
+ Py_DECREF(pmd->PyPML);
+ Py_INCREF(result);
+ pmd->PyPML = result;
+}
+%}
+
+
+
+struct fd_hook_hdl {
+};
+
+%nodefaultctor fd_hook_hdl;
+%extend fd_hook_hdl {
+ fd_hook_hdl(uint32_t type_mask, PyObject * PyCb) {
+ struct fd_hook_hdl *hdl;
+ int ret;
+
+ Py_XINCREF(PyCb);
+
+ ret = fd_hook_register ( type_mask, call_the_python_hook_callback, PyCb, NULL, &hdl );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return hdl;
+ }
+ fd_hook_hdl(uint32_t type_mask, PyObject * PyCb, struct fd_hook_data_hdl *datahdl) {
+ struct fd_hook_hdl *hdl;
+ int ret;
+
+ Py_XINCREF(PyCb);
+
+ ret = fd_hook_register ( type_mask, call_the_python_hook_callback, PyCb, datahdl, &hdl );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return hdl;
+ }
+ ~fd_hook_hdl() {
+ struct fd_hook_hdl * hdl = self;
+ int ret = fd_hook_unregister(hdl);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return;
+ }
+}
diff --git a/extensions/dbg_interactive/lists.i b/extensions/dbg_interactive/lists.i
new file mode 100644
index 0000000..6ac26f2
--- /dev/null
+++ b/extensions/dbg_interactive/lists.i
@@ -0,0 +1,132 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** LISTS *********/
+
+%extend fd_list {
+ /* allow a parameter in the constructor, and perform the fd_list_init operation */
+ fd_list(void * o = NULL) {
+ struct fd_list * li;
+ li = (struct fd_list *) malloc(sizeof(struct fd_list));
+ if (!li) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ fd_list_init(li, o);
+ return li;
+ }
+ /* Unlink before freeing */
+ ~fd_list() {
+ fd_list_unlink($self);
+ free($self);
+ }
+ /* For debug, show the values of the list */
+ void dump() {
+ fd_log_debug("list: %p", $self);
+ fd_log_debug(" - next: %p", $self->next);
+ fd_log_debug(" - prev: %p", $self->prev);
+ fd_log_debug(" - head: %p", $self->head);
+ fd_log_debug(" - o : %p", $self->o);
+ }
+ /* Insert before/after wrapper */
+ void insert_prev(struct fd_list * li) {
+ fd_list_insert_before($self, li);
+ }
+ void insert_next(struct fd_list * li) {
+ fd_list_insert_after($self, li);
+ }
+ /* Test for emptyness */
+ PyObject * isempty() {
+ PyObject * ret;
+ if (FD_IS_LIST_EMPTY($self))
+ ret = Py_True;
+ else
+ ret = Py_False;
+ Py_XINCREF(ret);
+ return ret;
+ }
+ /* Concatenate two lists */
+ void concat(struct fd_list * li) {
+ fd_list_move_end($self, li);
+ }
+ /* Unlink without freeing */
+ void detach() {
+ fd_list_unlink($self);
+ }
+
+ /* Return the list as python list of elements */
+ PyObject * enum_as(char * type = NULL, int dont_use_o = 0) {
+ struct fd_list *li;
+ swig_type_info * desttype = NULL;
+ PyObject * rl;
+
+ if ($self->head != $self) {
+ DI_ERROR(EINVAL, NULL, "This method can only be called on the list sentinel.");
+ return NULL;
+ }
+
+ if (type) {
+ desttype = SWIG_TypeQuery(type);
+ if (!desttype) {
+ DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'");
+ return NULL;
+ }
+ }
+ if (desttype == NULL) {
+ /* fallback to fd_list */
+ desttype = SWIGTYPE_p_fd_list;
+ /* in this case, don't follow the 'o' link */
+ dont_use_o = 1;
+ }
+
+ rl = PyList_New(0);
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ for (li = $self->next; li != $self; li = li->next) {
+ void * obj = NULL;
+ if (dont_use_o || li->o == NULL)
+ obj = li;
+ else
+ obj = li->o;
+ PyList_Append(rl, SWIG_NewPointerObj(obj, desttype, 0 ));
+ }
+ Py_XINCREF(rl);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+
+ return rl;
+ }
+};
+
diff --git a/extensions/dbg_interactive/messages.i b/extensions/dbg_interactive/messages.i
new file mode 100644
index 0000000..3d13e5d
--- /dev/null
+++ b/extensions/dbg_interactive/messages.i
@@ -0,0 +1,615 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** MESSAGES *********/
+
+%{
+struct anscb_py_layer {
+ PyObject * cb;
+ PyObject * expcb;
+ PyObject * data;
+};
+
+/* If a python callback was provided, it is received in cbdata */
+static void anscb_python(void *cbdata, struct msg ** msg) {
+ /* The python callback is received in cbdata */
+ PyObject * result, *PyMsg;
+ struct anscb_py_layer * l = cbdata;
+
+ if (!l) {
+ fd_log_debug("Internal error! Python callback disappeared...");
+ return;
+ }
+
+ if (l->cb) {
+
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+
+ if (!msg || !*msg) {
+ PyMsg = Py_None;
+ } else {
+ PyMsg = SWIG_NewPointerObj((void *)*msg, SWIGTYPE_p_msg, 0 );
+ }
+
+ result = PyObject_CallFunction(l->cb, "(OO)", PyMsg, l->data);
+ Py_XDECREF(l->cb);
+ Py_XDECREF(l->expcb);
+ Py_XDECREF(l->data);
+ free(l);
+
+ /* The callback is supposed to return a message or NULL */
+ if (!SWIG_IsOK(SWIG_ConvertPtr(result, (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) {
+ fd_log_debug("Error: Cannot convert the return value to message.");
+ *msg = NULL;
+ }
+
+ Py_XDECREF(result);
+
+ SWIG_PYTHON_THREAD_END_BLOCK;
+
+ }
+ /* else */
+ /* Only the timeout was specified, without a callback */
+ /* in this case, just delete the message */
+ /* it actually happens automatically when we do nothing. */
+}
+
+static void expcb_python(void *cbdata, DiamId_t sentto, size_t senttolen, struct msg ** msg) {
+ /* The python callback is received in cbdata */
+ PyObject * result, *PyMsg;
+ struct anscb_py_layer * l = cbdata;
+
+ if (!l) {
+ fd_log_debug("Internal error! Python callback disappeared...");
+ return;
+ }
+
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+
+ if (!msg || !*msg) {
+ PyMsg = Py_None;
+ } else {
+ PyMsg = SWIG_NewPointerObj((void *)*msg, SWIGTYPE_p_msg, 0 );
+ }
+
+ result = PyObject_CallFunction(l->expcb, "(Os#O)", PyMsg, sentto, senttolen, l->data);
+ Py_XDECREF(l->cb);
+ Py_XDECREF(l->expcb);
+ Py_XDECREF(l->data);
+ free(l);
+
+ /* The callback is supposed to return a message or NULL */
+ if (!SWIG_IsOK(SWIG_ConvertPtr(result, (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) {
+ fd_log_debug("Error: Cannot convert the return value to message.");
+ *msg = NULL;
+ }
+
+ Py_XDECREF(result);
+
+ SWIG_PYTHON_THREAD_END_BLOCK;
+
+}
+
+
+
+%}
+
+struct msg {
+};
+
+%extend msg {
+ msg(struct dict_object * model=NULL, int flags = MSGFL_ALLOC_ETEID) {
+ struct msg * m = NULL;
+ int ret = fd_msg_new( model, flags, &m);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return m;
+ }
+ /* construct also from a binary buffer */
+ msg(char * STRING, size_t LENGTH) {
+ int ret;
+ struct msg * m = NULL;
+ /* First, copy the string */
+ unsigned char * buf = malloc(LENGTH);
+ if (buf == NULL) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ memcpy(buf, STRING, LENGTH);
+ ret = fd_msg_parse_buffer(&buf, LENGTH, &m);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ free(buf);
+ return NULL;
+ }
+ return m;
+ }
+ ~msg() {
+ int ret = fd_msg_free($self);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* SEND THE MESSAGE */
+ %delobject send; /* when this has been called, the msg must not be freed anymore */
+ void send(PyObject * PyCb = NULL, PyObject * data = NULL, PyObject * PyExpCb = NULL, unsigned int timeout = 0) {
+ int ret;
+ struct msg * m = $self;
+ struct anscb_py_layer * l = NULL;
+
+ if (PyCb || timeout) {
+ l = malloc(sizeof(struct anscb_py_layer));
+ if (!l) {
+ DI_ERROR_MALLOC;
+ return;
+ }
+
+ Py_XINCREF(PyCb);
+ Py_XINCREF(data);
+ Py_XINCREF(PyExpCb);
+ l->expcb = PyExpCb;
+ l->cb = PyCb;
+ l->data = data;
+ }
+
+ if (timeout) {
+ struct timespec ts;
+ (void) clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += timeout;
+ ret = fd_msg_send_timeout(&m, anscb_python, l, expcb_python, &ts);
+ } else {
+ ret = fd_msg_send(&m, PyCb ? anscb_python : NULL, l);
+ }
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Create an answer */
+ %delobject create_answer; /* when this has been called, the original msg should not be freed anymore */
+ struct msg * create_answer(struct dictionary * dict = NULL, int flags = 0) {
+ /* if dict is not provided, attempt to get it from the request model */
+ struct dictionary * d = dict;
+ struct msg * m = $self;
+ int ret;
+ if (!d) {
+ struct dict_object * mo = NULL;
+ ret = fd_msg_model($self, &mo);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, "Error retrieving query model.");
+ return NULL;
+ }
+ if (mo == NULL) {
+ /* use the fD dictionary by default */
+ d = fd_g_config->cnf_dict;
+ } else {
+ ret = fd_dict_getdict ( mo, &d );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, "Error retrieving query's dictionary.");
+ return NULL;
+ }
+ }
+ }
+ ret = fd_msg_new_answer_from_req(d, &m, flags);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, "Cannot guess the dictionary to use, please provide it as parameter.");
+ return NULL;
+ }
+
+ return m;
+ }
+ /* Return the first child AVP if any */
+ struct avp * first_child() {
+ struct avp * a = NULL;
+ int ret = fd_msg_browse($self, MSG_BRW_FIRST_CHILD, &a, NULL);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return a;
+ }
+
+ /* Enumerable list of children AVP */
+ %newobject children;
+ PyObject * children() {
+ struct avp * a = NULL;
+ PyObject * rl;
+ int ret = fd_msg_browse($self, MSG_BRW_FIRST_CHILD, &a, NULL);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ rl = PyList_New(0);
+ while (a) {
+ PyList_Append(rl, SWIG_NewPointerObj((void *)a, SWIGTYPE_p_avp, 0 /* do not own the AVPs */ ));
+ ret = fd_msg_browse(a, MSG_BRW_NEXT, &a, NULL);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ }
+ Py_XINCREF(rl);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return rl;
+ }
+
+ /* Add a new AVP */
+ void add_child(struct avp *DISOWN, int begin = 0) {
+ int ret = fd_msg_avp_add ( $self, begin ? MSG_BRW_FIRST_CHILD : MSG_BRW_LAST_CHILD, DISOWN);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Search an AVP */
+ struct avp * search(struct dict_object * what) {
+ struct avp * a = NULL;
+ int ret = fd_msg_search_avp($self, what, &a);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return a;
+ }
+
+ /* Dump */
+ void dump (int tree = 1) {
+ char * buf = NULL;
+ size_t len;
+ printf("%s", fd_msg_dump_treeview(&buf, &len, NULL, $self, NULL, 0, tree));
+ free(buf);
+ }
+
+ /* Model */
+ struct dict_object * model() {
+ struct dict_object * m = NULL;
+ int ret = fd_msg_model($self, &m);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return m;
+ }
+
+ /* Header */
+ struct msg_hdr * header() {
+ struct msg_hdr * h = NULL;
+ int ret = fd_msg_hdr($self, &h);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return h;
+ }
+
+ /* Get query if message is an answer */
+ struct msg * get_query() {
+ struct msg * q = NULL;
+ int ret = fd_msg_answ_getq($self, &q);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return q;
+ }
+
+ /* Get / Set routing data */
+ struct rt_data * get_rtd() {
+ struct rt_data * r = NULL;
+ int ret = fd_msg_rt_get($self, &r);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return r;
+ }
+ void set_rtd(struct rt_data *DISOWN) {
+ struct rt_data * r = DISOWN;
+ int ret = fd_msg_rt_associate($self, r);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return;
+ }
+
+ /* Is routable? */
+ PyObject * is_routable() {
+ PyObject * r;
+ if (fd_msg_is_routable($self))
+ r = Py_True;
+ else
+ r = Py_False;
+ Py_XINCREF(r);
+ return r;
+ }
+
+ /* Is request? (shortcut) */
+ PyObject * is_request() {
+ PyObject * r;
+ int ret;
+ struct msg_hdr * h;
+
+ ret = fd_msg_hdr($self, &h);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ if (h->msg_flags & CMD_FLAG_REQUEST)
+ r = Py_True;
+ else
+ r = Py_False;
+ Py_XINCREF(r);
+ return r;
+ }
+
+ /* Get the source */
+ %cstring_output_allocate_size(char ** outid, size_t * outlen, /* do not free */);
+ void source(char ** outid, size_t * outlen) {
+ int ret = fd_msg_source_get($self, outid, outlen);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return;
+ }
+ return;
+ }
+
+ /* Get the session */
+ %newobject get_session; /* it may be created or not, it is harmless because we only reclaim in ~session */
+ struct session *get_session(struct dictionary * dict = NULL) {
+ struct session *s = NULL;
+ struct dictionary * d = dict;
+ int ret = 0;
+ if (d == NULL)
+ d = fd_g_config->cnf_dict; /* default: use daemon's */
+ ret = fd_msg_sess_get(d, $self, &s, NULL);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return s;
+ }
+
+ /* Bufferize */
+ %cstring_output_allocate_size(char ** outbuffer, size_t * outlen, free(*$1));
+ void bufferize ( char ** outbuffer, size_t * outlen ) {
+ int ret = fd_msg_bufferize ( $self, (void *)outbuffer, outlen );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Dictionary parsing */
+ %newobject parse_dict;
+ struct fd_pei * parse_dict(struct dictionary * dict=NULL) {
+ int ret;
+ struct fd_pei pei, *e = NULL;
+ struct dictionary * d = dict;
+ memset(&pei, 0, sizeof(struct fd_pei));
+ if (d == NULL)
+ d = fd_g_config->cnf_dict; /* default: use daemon's */
+
+ ret = fd_msg_parse_dict ( $self, d, &pei );
+ if (ret != 0) {
+ e = malloc(sizeof(struct fd_pei));
+ if (!e) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ memcpy(e, &pei, sizeof(struct fd_pei));
+ }
+ return e; /* returns NULL when everything went OK */
+ }
+
+ /* Rules parsing */
+ %newobject parse_rules;
+ struct fd_pei * parse_rules(struct dictionary * dict=NULL) {
+ int ret;
+ struct fd_pei pei, *e = NULL;
+ struct dictionary * d = dict;
+ memset(&pei, 0, sizeof(struct fd_pei));
+ if (d == NULL)
+ d = fd_g_config->cnf_dict; /* default: use daemon's */
+
+ ret = fd_msg_parse_rules ( $self, d, &pei );
+ if (ret != 0) {
+ e = malloc(sizeof(struct fd_pei));
+ if (!e) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ memcpy(e, &pei, sizeof(struct fd_pei));
+ }
+ return e; /* returns NULL when everything went OK */
+ }
+
+ /* Update the length info in header */
+ void update_length() {
+ int ret = fd_msg_update_length ( $self );
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Set the result code */
+ void rescode_set(char * rescode = "DIAMETER_SUCCESS", char * errormsg = NULL, struct avp * optavp = NULL, int type_id = 0) {
+ int ret = fd_msg_rescode_set( $self, rescode, errormsg, optavp, type_id );
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Add the origin */
+ void add_origin(int osi = 0) {
+ int ret = fd_msg_add_origin( $self, osi );
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+}
+
+struct avp {
+};
+
+%extend avp {
+ avp(struct dict_object * model = NULL, int flags = 0) {
+ struct avp * a = NULL;
+ int ret = fd_msg_avp_new( model, flags, &a);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return a;
+ }
+ ~avp() {
+ int ret = fd_msg_free($self);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Return the first child AVP if any */
+ struct avp * first_child() {
+ struct avp * a = NULL;
+ int ret = fd_msg_browse($self, MSG_BRW_FIRST_CHILD, &a, NULL);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return a;
+ }
+
+ /* Enumerable list of children AVP */
+ %newobject children;
+ PyObject * children() {
+ struct avp * a = NULL;
+ PyObject * rl;
+ int ret = fd_msg_browse($self, MSG_BRW_FIRST_CHILD, &a, NULL);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ rl = PyList_New(0);
+ while (a) {
+ PyList_Append(rl, SWIG_NewPointerObj((void *)a, SWIGTYPE_p_avp, 0 /* the AVPs are not owned */ ));
+ ret = fd_msg_browse(a, MSG_BRW_NEXT, &a, NULL);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ }
+ Py_XINCREF(rl);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return rl;
+ }
+
+ /* Add a new AVP */
+ void add_next(struct avp *avp) {
+ int ret = fd_msg_avp_add ( $self, MSG_BRW_NEXT, avp);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void add_prev(struct avp *avp) {
+ int ret = fd_msg_avp_add ( $self, MSG_BRW_PREV, avp);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void add_child(struct avp *DISOWN, int begin = 0) {
+ int ret = fd_msg_avp_add ( $self, begin ? MSG_BRW_FIRST_CHILD : MSG_BRW_LAST_CHILD, DISOWN);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Get the next AVP at the same level */
+ struct avp * get_next() {
+ struct avp * a = NULL;
+ int ret = fd_msg_browse($self, MSG_BRW_NEXT, &a, NULL);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return a;
+ }
+
+ /* Dump */
+ void dump (int tree = 1) {
+ char * buf = NULL;
+ size_t len;
+ printf("%s", fd_msg_dump_treeview(&buf, &len, NULL, $self, NULL, 0, tree));
+ free(buf);
+ }
+
+ /* Model */
+ struct dict_object * model() {
+ struct dict_object * m = NULL;
+ int ret = fd_msg_model($self, &m);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return m;
+ }
+
+ /* Header */
+ struct avp_hdr * header() {
+ struct avp_hdr * h = NULL;
+ int ret = fd_msg_avp_hdr($self, &h);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return h;
+ }
+
+ /* set value */
+ void setval(union avp_value * val) {
+ int ret = fd_msg_avp_setvalue ( $self, val );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Update the length info in header */
+ void update_length() {
+ int ret = fd_msg_update_length ( $self );
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+}
diff --git a/extensions/dbg_interactive/peers.i b/extensions/dbg_interactive/peers.i
new file mode 100644
index 0000000..a256cf7
--- /dev/null
+++ b/extensions/dbg_interactive/peers.i
@@ -0,0 +1,227 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** PEERS *********/
+
+%{
+static void fd_add_cb(struct peer_info *peer, void *data) {
+ /* Callback called when the peer connection completes (or fails) */
+ PyObject *PyPeer, *PyFunc;
+ PyObject *result = NULL;
+
+ if (!data) {
+ TRACE_DEBUG(INFO, "Internal error: missing callback");
+ return;
+ }
+ PyFunc = data;
+
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+
+ /* Convert the argument */
+ PyPeer = SWIG_NewPointerObj((void *)peer, SWIGTYPE_p_peer_info, 0 );
+
+ /* Call the function */
+ result = PyObject_CallFunction(PyFunc, "(O)", PyPeer);
+
+ Py_XDECREF(result);
+ Py_XDECREF(PyFunc);
+
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return;
+}
+%}
+
+%extend peer_info {
+ peer_info () {
+ struct peer_info *np = (struct peer_info *)calloc(1, sizeof(struct peer_info));
+ if (!np) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+
+ fd_list_init(&np->pi_endpoints, NULL);
+
+ return np;
+ }
+
+ /* Wrapper around fd_peer_add to allow calling the python callback */
+ %delobject add;
+ void add(PyObject * PyCb=NULL) {
+ int ret;
+
+ if (PyCb) {
+ Py_XINCREF(PyCb);
+ ret = fd_peer_add ( $self, "dbg_interactive", fd_add_cb, PyCb );
+ } else {
+ ret = fd_peer_add ( $self, "dbg_interactive", NULL, NULL );
+ }
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+}
+
+%inline %{
+static struct peer_hdr * peer_search(char *STRING, size_t LENGTH) {
+ struct peer_hdr *r = NULL;
+ int ret = fd_peer_getbyid( STRING, LENGTH, 0, &r );
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return r;
+}
+%}
+
+%{
+static PyObject * validate_cb_py = NULL;
+static PyObject * validate_cb2_py = NULL;
+
+/* C wrapper that calls validate_cb2_py */
+int call_the_python_validate_callback2(struct peer_info * info) {
+ PyObject *PyInfo;
+ PyObject *result = NULL;
+ int ret = 0;
+
+ if (!validate_cb2_py) {
+ fd_log_debug("Internal error: missing the callback2!");
+ return ENOTSUP;
+ }
+
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ /* Convert the arguments */
+ PyInfo = SWIG_NewPointerObj((void *)info, SWIGTYPE_p_peer_info, 0 );
+
+ /* Call the function */
+ result = PyObject_CallFunction(validate_cb2_py, "(O)", PyInfo);
+
+ /* The result is an integer */
+ if ((result == NULL) || !SWIG_IsOK(SWIG_AsVal_int(result, &ret))) {
+ fd_log_debug("Error: The Python callback did not return an integer.");
+ ret = EINVAL;
+ goto out;
+ }
+
+out:
+ Py_XDECREF(result);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return ret;
+}
+
+/* C wrapper that calls validate_cb_py */
+int call_the_python_validate_callback(struct peer_info * info, int * auth, int (**cb2)(struct peer_info *)) {
+ PyObject *PyInfo;
+ PyObject *result = NULL;
+ int ret = 0;
+
+ if (!validate_cb_py) {
+ fd_log_debug("Internal error: missing the callback!");
+ return ENOTSUP;
+ }
+
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ /* Convert the arguments */
+ PyInfo = SWIG_NewPointerObj((void *)info, SWIGTYPE_p_peer_info, 0 );
+
+ /* Call the function */
+ result = PyObject_CallFunction(validate_cb_py, "(O)", PyInfo);
+
+ /* The result is supposedly -1, 1, or a cb2 */
+ if (result == NULL) {
+ fd_log_debug("Error: The Python callback did not return a value.");
+ ret = EINVAL;
+ goto out;
+ }
+
+ if (PyCallable_Check(result)) {
+ if (cb2) {
+ if (validate_cb2_py && (validate_cb2_py != result)) {
+ fd_log_debug("Only 1 register callback2 is supported currently");
+ ret = ENOTSUP;
+ goto out;
+ }
+ validate_cb2_py = result;
+ *cb2 = call_the_python_validate_callback2;
+ *auth = 1;
+ goto out_nodec;
+ } else {
+ *auth = 1;
+ goto out; /* ignore the callback since it won't be used */
+ }
+ } else { /* In this case, the return value must be -1, 0, or 1 */
+ if (!SWIG_IsOK(SWIG_AsVal_int(result, auth))) {
+ fd_log_debug("Error: Cannot convert the return value to integer.");
+ ret = EINVAL;
+ goto out;
+ }
+ }
+
+out:
+ Py_XDECREF(result);
+out_nodec:
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ TRACE_DEBUG(FULL, "ret=%d, *auth=%d, cb2=%p, *cb2=%p", ret, *auth, cb2, cb2 ? *cb2 : NULL);
+ return ret;
+}
+
+%}
+
+%inline %{
+static void peer_validate_register(PyObject * PyCb) {
+ int ret ;
+
+ if (!PyCb) {
+ DI_ERROR(EINVAL, NULL, "The callback must be provided");
+ return;
+ }
+
+ if (validate_cb_py) {
+ if (PyCb != validate_cb_py) {
+ DI_ERROR(ENOTSUP, PyExc_RuntimeError, "Only 1 register callback is supported currently");
+ return;
+ }
+ } else {
+ validate_cb_py = PyCb;
+ Py_XINCREF(PyCb);
+ }
+
+ ret = fd_peer_validate_register ( call_the_python_validate_callback );
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+}
+%}
diff --git a/extensions/dbg_interactive/posix.i b/extensions/dbg_interactive/posix.i
new file mode 100644
index 0000000..ceafeb6
--- /dev/null
+++ b/extensions/dbg_interactive/posix.i
@@ -0,0 +1,194 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2012, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** POSIX wrappers around useful functions for fD *********/
+
+/**** MUTEX ****/
+typedef struct {
+} pthread_mutex_t;
+
+%extend pthread_mutex_t {
+ pthread_mutex_t() {
+ int ret = 0;
+ pthread_mutex_t * r = calloc(1, sizeof(pthread_mutex_t));
+ if (!r) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ ret = pthread_mutex_init(r, NULL);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ free(r);
+ return NULL;
+ }
+ return r;
+ }
+ ~pthread_mutex_t() {
+ int ret = 0;
+ ret = pthread_mutex_destroy($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ return;
+ }
+ free($self);
+ return;
+ }
+ void lock() {
+ int ret = pthread_mutex_lock($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void unlock() {
+ int ret = pthread_mutex_unlock($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+}
+
+/**** CONDVAR ****/
+typedef struct {
+} pthread_cond_t;
+
+%extend pthread_cond_t {
+ pthread_cond_t() {
+ int ret = 0;
+ pthread_cond_t * r = calloc(1, sizeof(pthread_cond_t));
+ if (!r) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ ret = pthread_cond_init(r, NULL);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ free(r);
+ return NULL;
+ }
+ return r;
+ }
+ ~pthread_cond_t() {
+ int ret = 0;
+ ret = pthread_cond_destroy($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ return;
+ }
+ free($self);
+ return;
+ }
+ void signal() {
+ int ret = pthread_cond_signal($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void broadcast() {
+ int ret = pthread_cond_broadcast($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void wait(pthread_mutex_t * mutex) {
+ int ret = pthread_cond_wait($self, mutex);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void timedwait(pthread_mutex_t * mutex, long seconds) {
+ struct timespec ts;
+ int ret;
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += seconds;
+
+ ret = pthread_cond_timedwait($self, mutex, &ts);
+ if (ret && (ret != ETIMEDOUT)) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+}
+
+/**** RWLOCK ****/
+typedef struct {
+} pthread_rwlock_t;
+
+%extend pthread_rwlock_t {
+ pthread_rwlock_t() {
+ int ret = 0;
+ pthread_rwlock_t * r = calloc(1, sizeof(pthread_rwlock_t));
+ if (!r) {
+ DI_ERROR_MALLOC;
+ return NULL;
+ }
+ ret = pthread_rwlock_init(r, NULL);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ free(r);
+ return NULL;
+ }
+ return r;
+ }
+ ~pthread_rwlock_t() {
+ int ret = 0;
+ ret = pthread_rwlock_destroy($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ return;
+ }
+ free($self);
+ return;
+ }
+ void rdlock() {
+ int ret = pthread_rwlock_rdlock($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void wrlock() {
+ int ret = pthread_rwlock_wrlock($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void unlock() {
+ int ret = pthread_rwlock_unlock($self);
+ if (ret) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+}
diff --git a/extensions/dbg_interactive/queues.i b/extensions/dbg_interactive/queues.i
new file mode 100644
index 0000000..ff1728d
--- /dev/null
+++ b/extensions/dbg_interactive/queues.i
@@ -0,0 +1,198 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** FIFO QUEUES *********/
+
+struct fifo {
+};
+
+%extend fifo {
+ fifo(int max = 0) {
+ struct fifo * q = NULL;
+ int ret = fd_fifo_new(&q, max);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return q;
+ }
+ ~fifo() {
+ struct fifo *q = self;
+ fd_fifo_del(&q);
+ }
+
+ /* Move all elements to another queue */
+ void move(struct fifo * to) {
+ int ret = fd_fifo_move($self, to, NULL);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Get the length of the queue (nb elements) */
+ int length() {
+ return fd_fifo_length ( $self ) ;
+ }
+
+ /* Is the threashold function useful here? TODO... */
+
+ /* Post an item */
+ void post(PyObject * item, char * type = NULL) {
+ int ret;
+ if (type) {
+ void * real_obj = NULL;
+ swig_type_info * desttype = NULL;
+ desttype = SWIG_TypeQuery(type);
+ if (!desttype) {
+ DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'");
+ return;
+ }
+ /* Now, get the "real" value under the shadow umbrella */
+ ret = SWIG_ConvertPtr(item, &real_obj, desttype, SWIG_POINTER_DISOWN );
+ if (!SWIG_IsOK(ret)) {
+ DI_ERROR(EINVAL, SWIG_ErrorType(ret), "Unable to convert the item to given type");
+ return;
+ }
+ ret = fd_fifo_post($self, &real_obj);
+ } else {
+ PyObject * i = item;
+ Py_XINCREF(i);
+ ret = fd_fifo_post($self, &i);
+ }
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+
+ /* Get (blocking) */
+ PyObject * get(char * type = NULL) {
+ int ret;
+ PyObject * i = NULL;
+ void * obj = NULL;
+ swig_type_info * desttype = NULL;
+ if (type) {
+ desttype = SWIG_TypeQuery(type);
+ if (!desttype) {
+ DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'");
+ return NULL;
+ }
+ }
+
+ ret = fd_fifo_get($self, &obj);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+
+ if (type) {
+ return SWIG_NewPointerObj(obj, desttype, 0 );
+ } else {
+ i = obj;
+ return i;
+ }
+ }
+
+ /* TryGet (non-blocking, returns None on empty queue) */
+ PyObject * tryget(char * type = NULL) {
+ int ret;
+ PyObject * i = NULL;
+ void * obj = NULL;
+ swig_type_info * desttype = NULL;
+ if (type) {
+ desttype = SWIG_TypeQuery(type);
+ if (!desttype) {
+ DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'");
+ return NULL;
+ }
+ }
+
+ ret = fd_fifo_tryget($self, &obj);
+ if (ret == EWOULDBLOCK) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+
+ if (type) {
+ return SWIG_NewPointerObj(obj, desttype, 0 );
+ } else {
+ i = obj;
+ return i;
+ }
+ }
+
+ /* TimedGet (blocking for a while) */
+ PyObject * timedget(long seconds, char * type = NULL) {
+ int ret;
+ PyObject * i = NULL;
+ struct timespec ts;
+ void * obj = NULL;
+ swig_type_info * desttype = NULL;
+ if (type) {
+ desttype = SWIG_TypeQuery(type);
+ if (!desttype) {
+ DI_ERROR(EINVAL, NULL, "Unable to resolve this type. Please check the form: 'struct blahbla *'");
+ return NULL;
+ }
+ }
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += seconds;
+
+ ret = fd_fifo_timedget($self, &obj, &ts);
+ if (ret == ETIMEDOUT) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+
+ if (type) {
+ return SWIG_NewPointerObj(obj, desttype, 0 );
+ } else {
+ i = obj;
+ return i;
+ }
+ }
+
+}
+
+
+
+
diff --git a/extensions/dbg_interactive/routing.i b/extensions/dbg_interactive/routing.i
new file mode 100644
index 0000000..324674f
--- /dev/null
+++ b/extensions/dbg_interactive/routing.i
@@ -0,0 +1,251 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** ROUTING *********/
+
+struct rt_data {
+};
+
+%extend rt_data {
+ rt_data() {
+ struct rt_data * r = NULL;
+ int ret = fd_rtd_init(&r);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return r;
+ }
+ ~rt_data() {
+ struct rt_data *r = self;
+ fd_rtd_free(&r);
+ }
+ %apply (char *STRING, int LENGTH) { (char * peerid, size_t peeridlen) };
+ %apply (char *STRING, int LENGTH) { (char * realm, size_t realmlen) };
+ void add(char * peerid, size_t peeridlen, char * realm, size_t realmlen) {
+ int ret = fd_rtd_candidate_add($self, peerid, peeridlen, realm, realmlen);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void remove(char * STRING, size_t LENGTH) {
+ fd_rtd_candidate_del($self, (os0_t)STRING, LENGTH);
+ }
+ int error(char * peerid, size_t peeridlen, char * STRING, size_t LENGTH, uint32_t rcode) {
+ int n;
+ int ret = fd_rtd_error_add($self, peerid, peeridlen, (os0_t)STRING, LENGTH, rcode, NULL, &n);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return n;
+ }
+ struct fd_list * extract(int score = 0) {
+ struct fd_list * li = NULL;
+ fd_rtd_candidate_extract($self, &li, score);
+ return li;
+ }
+}
+
+
+
+%extend rtd_candidate {
+ void dump() {
+ fd_log_debug("candidate %p", $self);
+ fd_log_debug(" id : %s", $self->diamid);
+ fd_log_debug(" rlm: %s", $self->realm);
+ fd_log_debug(" sc : %d", $self->score);
+ }
+}
+
+
+%{
+/* call it (will be called from a different thread than the interpreter, when message arrives) */
+static int call_the_python_rt_fwd_callback(void * pycb, struct msg **msg) {
+ PyObject *PyMsg;
+ PyObject *cb, *result = NULL;
+ int ret = 0;
+
+ if (!pycb) {
+ fd_log_debug("Internal error: missing the callback!");
+ return ENOTSUP;
+ }
+ cb = pycb;
+
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ /* Convert the arguments */
+ PyMsg = SWIG_NewPointerObj((void *)*msg, SWIGTYPE_p_msg, 0 );
+
+ /* Call the function */
+ result = PyObject_CallFunction(cb, "(O)", PyMsg);
+
+ /* The result is supposedly composed of: [ ret, *msg ] */
+ if ((result == NULL) || (!PyList_Check(result)) || (PyList_Size(result) != 2)) {
+ fd_log_debug("Error: The Python callback did not return [ ret, msg ].");
+ ret = EINVAL;
+ goto out;
+ }
+
+ /* Convert the return values */
+ if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 0), &ret))) {
+ fd_log_debug("Error: Cannot convert the first return value to integer.");
+ ret = EINVAL;
+ goto out;
+ }
+ if (ret) {
+ TRACE_DEBUG(INFO, "The Python callback returned the error code %d (%s)", ret, strerror(ret));
+ goto out;
+ }
+
+ if (!SWIG_IsOK(SWIG_ConvertPtr(PyList_GetItem(result, 1), (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) {
+ fd_log_debug("Error: Cannot convert the second return value to message.");
+ ret = EINVAL;
+ goto out;
+ }
+
+out:
+ Py_XDECREF(result);
+
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return ret;
+}
+%}
+
+
+struct fd_rt_fwd_hdl {
+};
+
+%extend fd_rt_fwd_hdl{
+ fd_rt_fwd_hdl(PyObject * PyCb, enum fd_rt_fwd_dir dir) {
+ struct fd_rt_fwd_hdl * r = NULL;
+ int ret;
+
+ Py_XINCREF(PyCb);
+
+ ret = fd_rt_fwd_register( call_the_python_rt_fwd_callback, PyCb, dir, &r );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return r;
+ }
+
+ ~fd_rt_fwd_hdl() {
+ PyObject * func;
+ int ret = fd_rt_fwd_unregister ( $self, (void *) &func );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return;
+ }
+ Py_XDECREF(func);
+ return;
+ }
+}
+
+
+%{
+/* call it (will be called from a different thread than the interpreter, when message arrives) */
+static int call_the_python_rt_out_callback(void * pycb, struct msg **msg, struct fd_list * candidates) {
+ PyObject *PyMsg, *PyCands;
+ PyObject *cb, *result = NULL;
+ int ret = 0;
+
+ if (!pycb) {
+ fd_log_debug("Internal error: missing the callback!");
+ return ENOTSUP;
+ }
+ cb = pycb;
+
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ /* Convert the arguments */
+ PyMsg = SWIG_NewPointerObj((void *)*msg, SWIGTYPE_p_msg, 0 );
+ PyCands = SWIG_NewPointerObj((void *)candidates, SWIGTYPE_p_fd_list, 0 );
+
+ /* Call the function */
+ result = PyObject_CallFunction(cb, "(OO)", PyMsg, PyCands);
+
+ /* The result is supposedly composed of: [ ret, *msg ] */
+ if (result == NULL){
+ fd_log_debug("Error: The Python callback raised an exception.");
+ ret = EINVAL;
+ goto out;
+ }
+
+ /* Convert the return values */
+ if (!SWIG_IsOK(SWIG_AsVal_int(result, &ret))) {
+ fd_log_debug("Error: Cannot convert the return value to integer.");
+ ret = EINVAL;
+ goto out;
+ }
+out:
+ Py_XDECREF(result);
+
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return ret;
+}
+%}
+
+
+struct fd_rt_out_hdl {
+};
+
+%extend fd_rt_out_hdl{
+ fd_rt_out_hdl(PyObject * PyCb, int priority = 0) {
+ struct fd_rt_out_hdl * r = NULL;
+ int ret;
+
+ Py_XINCREF(PyCb);
+
+ ret = fd_rt_out_register( call_the_python_rt_out_callback, PyCb, priority, &r );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return r;
+ }
+
+ ~fd_rt_out_hdl() {
+ PyObject * func;
+ int ret = fd_rt_out_unregister ( $self, (void *) &func );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return;
+ }
+ Py_XDECREF(func);
+ return;
+ }
+}
+
diff --git a/extensions/dbg_interactive/sessions.i b/extensions/dbg_interactive/sessions.i
new file mode 100644
index 0000000..180a150
--- /dev/null
+++ b/extensions/dbg_interactive/sessions.i
@@ -0,0 +1,210 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Do not include this directly, use dbg_interactive.i instead */
+
+/****** SESSIONS *********/
+
+%{
+struct sess_state {
+ PyObject * pystate;
+};
+
+/* call it (might be called from a different thread than the interpreter, when session times out) */
+static void call_the_python_cleanup_callback(struct sess_state * state, os0_t sid, void * cb) {
+ PyObject *result;
+ if (!cb) {
+ fd_log_debug("Internal error: missing callback object!");
+ return;
+ }
+
+ /* Call the function */
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ result = PyObject_CallFunction((PyObject *)cb, "(Os)", state, sid);
+ Py_XDECREF(result);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+ return;
+}
+%}
+
+struct session_handler {
+};
+
+%nodefaultctor session_handler;
+%extend session_handler {
+ session_handler(PyObject * PyCb) {
+ struct session_handler * hdl = NULL;
+ int ret;
+
+ Py_XINCREF(PyCb);
+
+ ret = fd_sess_handler_create ( &hdl, call_the_python_cleanup_callback, NULL, PyCb );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return hdl;
+ }
+ ~session_handler() {
+ struct session_handler * hdl = self;
+ PyObject * cb = NULL;
+
+ int ret = fd_sess_handler_destroy(&hdl, (void *)&cb);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ /* Now free the callback */
+ Py_XDECREF(cb);
+ return;
+ }
+ void dump() {
+ char * buf = NULL;
+ size_t len;
+ printf("%s", fd_sess_dump_hdl(&buf, &len, NULL, $self));
+ free(buf);
+ }
+}
+
+
+struct session {
+};
+
+%extend session {
+ /* The first two versions create a new session string. The third one allow to use an existing string. */
+ session() {
+ int ret;
+ struct session * s = NULL;
+ ret = fd_sess_new(&s, fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len, (os0_t)"dbg_interactive", CONSTSTRLEN("dbg_interactive"));
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return s;
+ }
+ session(char * diamid, char * STRING, size_t LENGTH) {
+ int ret;
+ struct session * s = NULL;
+ ret = fd_sess_new(&s, diamid, 0, (os0_t)STRING, LENGTH);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ return s;
+ }
+ session(char * STRING, size_t LENGTH) {
+ int ret, n;
+ struct session * s = NULL;
+ ret = fd_sess_fromsid((os0_t)STRING, LENGTH, &s, &n);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ /* When defining n as OUTPUT parameter, we get something strange... Use fd_sess_fromsid if you need it */
+ #if 0
+ if (n) {
+ fd_log_debug("A new session has been created");
+ } else {
+ fd_log_debug("A session with same id already existed");
+ }
+ #endif /* 0 */
+
+ return s;
+ }
+ ~session() {
+ struct session * s = self;
+ int ret = fd_sess_reclaim(&s);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ return;
+ }
+
+ %cstring_output_allocate_size(char ** outsid, size_t * sidlen, /* do not free */);
+ void getsid(char ** outsid, size_t * sidlen) {
+ int ret;
+ ret = fd_sess_getsid( $self, (void *)outsid, sidlen);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return;
+ }
+ return;
+ }
+ void settimeout(long seconds) {
+ struct timespec timeout;
+ int ret;
+ clock_gettime(CLOCK_REALTIME, &timeout);
+ timeout.tv_sec += seconds;
+ ret = fd_sess_settimeout( $self, &timeout );
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ void dump() {
+ char * buf = NULL;
+ size_t len = 0;
+ printf("%s", fd_sess_dump(&buf, &len, NULL, $self, 1) );
+ free(buf);
+ }
+ void store(struct session_handler * handler, PyObject * DISOWN) {
+ int ret;
+ struct sess_state * st = NULL;
+ st = malloc(sizeof(struct sess_state));
+ st->pystate = DISOWN;
+ Py_XINCREF(DISOWN);
+ ret = fd_sess_state_store(handler, $self, (void *) &st);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ }
+ }
+ %newobject retrieve;
+ PyObject * retrieve(struct session_handler * handler) {
+ int ret;
+ struct sess_state * st = NULL;
+ PyObject * state = NULL;
+ ret = fd_sess_state_retrieve(handler, $self, (void *) &st);
+ if (ret != 0) {
+ DI_ERROR(ret, NULL, NULL);
+ return NULL;
+ }
+ if (st == NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ state = st->pystate;
+ free(st);
+ return state;
+ }
+}
+
diff --git a/extensions/dbg_monitor/CMakeLists.txt b/extensions/dbg_monitor/CMakeLists.txt
new file mode 100644
index 0000000..ddc8df7
--- /dev/null
+++ b/extensions/dbg_monitor/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Monitoring extension
+PROJECT("Monitor extension" C)
+FD_ADD_EXTENSION(dbg_monitor dbg_monitor.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dbg_monitor
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
+
diff --git a/extensions/dbg_monitor/dbg_monitor.c b/extensions/dbg_monitor/dbg_monitor.c
new file mode 100644
index 0000000..de7c13a
--- /dev/null
+++ b/extensions/dbg_monitor/dbg_monitor.c
@@ -0,0 +1,170 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Monitoring extension:
+ - periodically display queues and peers information
+ - upon SIGUSR2, display additional debug information
+ */
+
+#include <freeDiameter/extension.h>
+#include <signal.h>
+
+#ifndef MONITOR_SIGNAL
+#define MONITOR_SIGNAL SIGUSR2
+#endif /* MONITOR_SIGNAL */
+
+static int monitor_main(char * conffile);
+
+EXTENSION_ENTRY("dbg_monitor", monitor_main);
+
+
+
+/* Display information about a queue */
+static void display_info(char * queue_desc, char * peer, int current_count, int limit_count, int highest_count, long long total_count,
+ struct timespec * total, struct timespec * blocking, struct timespec * last)
+{
+ long long us = (total->tv_sec * 1000000) + (total->tv_nsec / 1000);
+ long double throughput = (long double)total_count * 1000000;
+ throughput /= us;
+ if (peer) {
+ TRACE_DEBUG(INFO, "'%s'@'%s': cur:%d/%d, h:%d, T:%lld in %ld.%06lds (%.2LFitems/s), blocked:%ld.%06lds, last processing:%ld.%06lds",
+ queue_desc, peer, current_count, limit_count, highest_count,
+ total_count, total->tv_sec, total->tv_nsec/1000, throughput,
+ blocking->tv_sec, blocking->tv_nsec/1000, last->tv_sec, last->tv_nsec/1000);
+ } else {
+ TRACE_DEBUG(INFO, "Global '%s': cur:%d/%d, h:%d, T:%lld in %ld.%06lds (%.2LFitems/s), blocked:%ld.%06lds, last processing:%ld.%06lds",
+ queue_desc, current_count, limit_count, highest_count,
+ total_count, total->tv_sec, total->tv_nsec/1000, throughput,
+ blocking->tv_sec, blocking->tv_nsec/1000, last->tv_sec, last->tv_nsec/1000);
+ }
+}
+
+/* Thread to display periodical debug information */
+static pthread_t thr;
+static void * mn_thr(void * arg)
+{
+ int i = 0;
+ fd_log_threadname("Monitor thread");
+ char * buf = NULL;
+ size_t len;
+
+ /* Loop */
+ while (1) {
+ int current_count, limit_count, highest_count;
+ long long total_count;
+ struct timespec total, blocking, last;
+ struct fd_list * li;
+
+ #ifdef DEBUG
+ for (i++; i % 30; i++) {
+ fd_log_debug("[dbg_monitor] %ih%*im%*is", i/3600, 2, (i/60) % 60 , 2, i%60); /* This makes it easier to detect inactivity periods in the log file */
+ sleep(1);
+ }
+ #else /* DEBUG */
+ sleep(3599); /* 1 hour */
+ #endif /* DEBUG */
+ TRACE_DEBUG(INFO, "[dbg_monitor] Dumping queues statistics");
+
+ CHECK_FCT_DO( fd_stat_getstats(STAT_G_LOCAL, NULL, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), );
+ display_info("Local delivery", NULL, current_count, limit_count, highest_count, total_count, &total, &blocking, &last);
+
+ CHECK_FCT_DO( fd_stat_getstats(STAT_G_INCOMING, NULL, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), );
+ display_info("Total received", NULL, current_count, limit_count, highest_count, total_count, &total, &blocking, &last);
+
+ CHECK_FCT_DO( fd_stat_getstats(STAT_G_OUTGOING, NULL, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), );
+ display_info("Total sending", NULL, current_count, limit_count, highest_count, total_count, &total, &blocking, &last);
+
+
+ CHECK_FCT_DO( pthread_rwlock_rdlock(&fd_g_peers_rw), /* continue */ );
+
+ for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
+ struct peer_hdr * p = (struct peer_hdr *)li->o;
+
+ TRACE_DEBUG(INFO, "%s", fd_peer_dump(&buf, &len, NULL, p, 1));
+
+ CHECK_FCT_DO( fd_stat_getstats(STAT_P_PSM, p, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), );
+ display_info("Events, incl. recept", p->info.pi_diamid, current_count, limit_count, highest_count, total_count, &total, &blocking, &last);
+
+ CHECK_FCT_DO( fd_stat_getstats(STAT_P_TOSEND, p, ¤t_count, &limit_count, &highest_count, &total_count, &total, &blocking, &last), );
+ display_info("Outgoing", p->info.pi_diamid, current_count, limit_count, highest_count, total_count, &total, &blocking, &last);
+
+ }
+
+ CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ );
+
+ TRACE_DEBUG(INFO, "[dbg_monitor] Dumping servers information");
+ TRACE_DEBUG(INFO, "%s", fd_servers_dump(&buf, &len, NULL, 1));
+
+ sleep(1);
+ }
+
+ free(buf);
+ return NULL;
+}
+
+/* Function called on receipt of MONITOR_SIGNAL */
+static void got_sig()
+{
+ char * buf = NULL;
+ size_t len;
+ TRACE_DEBUG(INFO, "[dbg_monitor] Dumping config information");
+ TRACE_DEBUG(INFO, "%s", fd_conf_dump(&buf, &len, NULL));
+ TRACE_DEBUG(INFO, "[dbg_monitor] Dumping extensions information");
+ TRACE_DEBUG(INFO, "%s", fd_ext_dump(&buf, &len, NULL));
+ TRACE_DEBUG(INFO, "[dbg_monitor] Dumping dictionary information");
+ TRACE_DEBUG(INFO, "%s", fd_dict_dump(&buf, &len, NULL, fd_g_config->cnf_dict));
+ free(buf);
+}
+
+/* Entry point */
+static int monitor_main(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* Catch signal SIGUSR1 */
+ CHECK_FCT( fd_event_trig_regcb(MONITOR_SIGNAL, "dbg_monitor", got_sig));
+
+ CHECK_POSIX( pthread_create( &thr, NULL, mn_thr, NULL ) );
+ return 0;
+}
+
+/* Cleanup */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+ CHECK_FCT_DO( fd_thr_term(&thr), /* continue */ );
+ return ;
+}
+
diff --git a/extensions/dbg_msg_dumps/CMakeLists.txt b/extensions/dbg_msg_dumps/CMakeLists.txt
new file mode 100644
index 0000000..3348ac9
--- /dev/null
+++ b/extensions/dbg_msg_dumps/CMakeLists.txt
@@ -0,0 +1,11 @@
+PROJECT("Messages dump extension" C)
+FD_ADD_EXTENSION(dbg_msg_dumps dbg_msg_dumps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dbg_msg_dumps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
+
diff --git a/extensions/dbg_msg_dumps/dbg_msg_dumps.c b/extensions/dbg_msg_dumps/dbg_msg_dumps.c
new file mode 100644
index 0000000..a26b14c
--- /dev/null
+++ b/extensions/dbg_msg_dumps/dbg_msg_dumps.c
@@ -0,0 +1,415 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2015, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* This extension uses the hooks mechanism to display the full content of received and sent messages, for
+ learning & debugging purpose.
+ Do NOT use this extension in production environment because it will slow down all operation. */
+
+/* You can add a configuration parameter on the LoadExtension line, e.g.
+LoadExtension="dbg_msg_dump.fdx":"0x149";
+The value is an hexadecimal value with the following bits meaning: */
+#define HK_ERRORS_QUIET 0x0001 /* errors are not dumped -- removes the default handling as well */
+#define HK_ERRORS_COMPACT 0x0002 /* errors in compact mode */
+#define HK_ERRORS_FULL 0x0004 /* errors in full mode (1 line with all the data) */
+#define HK_ERRORS_TREE 0x0008 /* errors in treeview mode (message split over multiple lines) */
+
+#define HK_SNDRCV_QUIET 0x0010 /* send+rcv are not dumped -- removes the default handling as well */
+#define HK_SNDRCV_COMPACT 0x0020 /* send+rcv in compact mode */
+#define HK_SNDRCV_FULL 0x0040 /* send+rcv in full mode */
+#define HK_SNDRCV_TREE 0x0080 /* send+rcv in tree mode */
+
+#define HK_ROUTING_QUIET 0x0100 /* routing decisions are not dumped -- removes the default handling as well */
+#define HK_ROUTING_COMPACT 0x0200 /* routing decisions in compact mode */
+#define HK_ROUTING_FULL 0x0400 /* routing decisions in full mode */
+#define HK_ROUTING_TREE 0x0800 /* routing decisions in tree mode */
+
+#define HK_PEERS_QUIET 0x1000 /* peers connections events are not dumped -- removes the default handling as well */
+#define HK_PEERS_COMPACT 0x2000 /* peers connections events in compact mode */
+#define HK_PEERS_FULL 0x4000 /* peers connections events in full mode */
+#define HK_PEERS_TREE 0x8000 /* peers connections events in tree mode */
+/*
+Default value is HK_ERRORS_TREE + HK_SNDRCV_TREE + HK_PEERS_TREE
+*/
+
+#include <freeDiameter/extension.h>
+
+static struct fd_hook_hdl *md_hdl[4] = {NULL,NULL,NULL,NULL};
+static uint32_t dump_level = HK_ERRORS_TREE | HK_SNDRCV_TREE | HK_PEERS_TREE; /* default */
+static char * buf = NULL;
+static size_t len;
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+
+/* The callback called when messages are received and sent */
+static void md_hook_cb_tree(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata)
+{
+ char * peer_name = peer ? peer->info.pi_diamid : "<unknown peer>";
+
+ CHECK_POSIX_DO( pthread_mutex_lock(&mtx), );
+
+ if (msg) {
+ CHECK_MALLOC_DO( fd_msg_dump_treeview(&buf, &len, NULL, msg, fd_g_config->cnf_dict, (type == HOOK_MESSAGE_PARSING_ERROR) ? 0 : 1, 1),
+ { LOG_E("Error while dumping a message"); pthread_mutex_unlock(&mtx); return; } );
+ }
+
+ switch (type) {
+/* errors */
+ case HOOK_MESSAGE_FAILOVER:
+ LOG_E("FAILOVER from '%s':", peer_name);
+ LOG_SPLIT(FD_LOG_ERROR, " ", buf, NULL);
+ break;
+ case HOOK_MESSAGE_PARSING_ERROR:
+ if (msg) {
+ DiamId_t id = NULL;
+ if (fd_msg_source_get( msg, &id, NULL ))
+ id = (DiamId_t)"<error getting source>";
+ if (!id)
+ id = (DiamId_t)"<local>";
+ LOG_E("PARSING ERROR: '%s' from '%s': ", (char *)other, (char *)id);
+ LOG_SPLIT(FD_LOG_ERROR, " ", buf, NULL);
+ } else {
+ struct fd_cnx_rcvdata *rcv_data = other;
+ CHECK_MALLOC_DO(fd_dump_extend_hexdump(&buf, &len, NULL, rcv_data->buffer, rcv_data->length, 0, 0), break);
+ LOG_E("PARSING ERROR: %zdB msg from '%s': %s", rcv_data->length, peer_name, buf);
+ }
+ break;
+ case HOOK_MESSAGE_PARSING_ERROR2:
+ LOG_E("PARSING ERROR, returning:");
+ LOG_SPLIT(FD_LOG_ERROR, " ", buf, NULL);
+ break;
+ case HOOK_MESSAGE_ROUTING_ERROR:
+ LOG_E("ROUTING ERROR '%s' for: ", (char *)other);
+ LOG_SPLIT(FD_LOG_ERROR, " ", buf, NULL);
+ break;
+ case HOOK_MESSAGE_DROPPED:
+ LOG_E("DROPPED '%s'", (char *)other);
+ LOG_SPLIT(FD_LOG_ERROR, " ", buf, NULL);
+ break;
+
+/* send receive */
+ case HOOK_MESSAGE_RECEIVED:
+ LOG_N("RCV from '%s':", peer_name);
+ LOG_SPLIT(FD_LOG_NOTICE, " ", buf, NULL);
+ break;
+ case HOOK_MESSAGE_SENDING:
+ LOG_N("SNDING to '%s':", peer_name);
+ LOG_SPLIT(FD_LOG_NOTICE, " ", buf, NULL);
+ break;
+ case HOOK_MESSAGE_SENT:
+ LOG_N("SND to '%s':", peer_name);
+ LOG_SPLIT(FD_LOG_NOTICE, " ", buf, NULL);
+ break;
+
+/* routing */
+ case HOOK_MESSAGE_LOCAL:
+ LOG_N("ISSUED:");
+ LOG_SPLIT(FD_LOG_NOTICE, " ", buf, NULL);
+ break;
+ case HOOK_MESSAGE_ROUTING_FORWARD:
+ LOG_N("FORWARDING: %s", buf);
+ LOG_SPLIT(FD_LOG_NOTICE, " ", buf, NULL);
+ break;
+ case HOOK_MESSAGE_ROUTING_LOCAL:
+ LOG_N("DISPATCHING: %s", buf);
+ LOG_SPLIT(FD_LOG_NOTICE, " ", buf, NULL);
+ break;
+
+/* peers */
+ case HOOK_PEER_CONNECT_FAILED:
+ LOG_N("CONNECT FAILED to %s: %s", peer_name, (char *)other);
+ break;
+ case HOOK_PEER_CONNECT_SUCCESS:
+ {
+ char protobuf[40];
+ if (peer) {
+ CHECK_FCT_DO(fd_peer_cnx_proto_info(peer, protobuf, sizeof(protobuf)), break );
+ } else {
+ protobuf[0] = '-';
+ protobuf[1] = '\0';
+ }
+ LOG_N("CONNECTED TO '%s' (%s):", peer_name, protobuf);
+ LOG_SPLIT(FD_LOG_NOTICE, " ", buf, NULL);
+ }
+ break;
+
+/* Not handled */
+ case HOOK_DATA_RECEIVED:
+ break;
+ }
+
+ CHECK_POSIX_DO( pthread_mutex_unlock(&mtx), );
+}
+
+static void md_hook_cb_full(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata)
+{
+ char * peer_name = peer ? peer->info.pi_diamid : "<unknown peer>";
+
+ CHECK_POSIX_DO( pthread_mutex_lock(&mtx), );
+
+ if (msg) {
+ CHECK_MALLOC_DO( fd_msg_dump_full(&buf, &len, NULL, msg, fd_g_config->cnf_dict, (type == HOOK_MESSAGE_PARSING_ERROR) ? 0 : 1, 1),
+ { LOG_E("Error while dumping a message"); pthread_mutex_unlock(&mtx); return; } );
+ }
+
+ switch (type) {
+/* errors */
+ case HOOK_MESSAGE_FAILOVER:
+ LOG_E("FAILOVER from '%s': %s", peer_name, buf);
+ break;
+ case HOOK_MESSAGE_PARSING_ERROR:
+ if (msg) {
+ DiamId_t id = NULL;
+ if (fd_msg_source_get( msg, &id, NULL ))
+ id = (DiamId_t)"<error getting source>";
+ if (!id)
+ id = (DiamId_t)"<local>";
+ LOG_E("PARSING ERROR: '%s' from '%s': %s", (char *)other, (char *)id, buf);
+ } else {
+ struct fd_cnx_rcvdata *rcv_data = other;
+ CHECK_MALLOC_DO(fd_dump_extend_hexdump(&buf, &len, NULL, rcv_data->buffer, rcv_data->length, 0, 0), break);
+ LOG_E("PARSING ERROR: %zdB msg from '%s': %s", rcv_data->length, peer_name, buf);
+ }
+ break;
+ case HOOK_MESSAGE_PARSING_ERROR2:
+ LOG_E("PARSING ERROR, returning: %s", buf);
+ break;
+ case HOOK_MESSAGE_ROUTING_ERROR:
+ LOG_E("ROUTING ERROR '%s' for: %s", (char *)other, buf);
+ break;
+ case HOOK_MESSAGE_DROPPED:
+ LOG_E("DROPPED '%s' %s", (char *)other, buf);
+ break;
+
+/* send receive */
+ case HOOK_MESSAGE_RECEIVED:
+ LOG_N("RCV from '%s': %s", peer_name, buf);
+ break;
+ case HOOK_MESSAGE_SENDING:
+ LOG_N("SNDING to '%s': %s", peer_name, buf);
+ break;
+ case HOOK_MESSAGE_SENT:
+ LOG_N("SND to '%s': %s", peer_name, buf);
+ break;
+
+/* routing */
+ case HOOK_MESSAGE_LOCAL:
+ LOG_N("ISSUED: %s", buf);
+ break;
+ case HOOK_MESSAGE_ROUTING_FORWARD:
+ LOG_N("FORWARDING: %s", buf);
+ break;
+ case HOOK_MESSAGE_ROUTING_LOCAL:
+ LOG_N("DISPATCHING: %s", buf);
+ break;
+
+/* peers */
+ case HOOK_PEER_CONNECT_FAILED:
+ LOG_N("CONNECT FAILED to %s: %s", peer_name, (char *)other);
+ break;
+ case HOOK_PEER_CONNECT_SUCCESS: {
+ char protobuf[40];
+ if (peer) {
+ CHECK_FCT_DO(fd_peer_cnx_proto_info(peer, protobuf, sizeof(protobuf)), break );
+ } else {
+ protobuf[0] = '-';
+ protobuf[1] = '\0';
+ }
+ LOG_N("CONNECTED TO '%s' (%s): %s", peer_name, protobuf, buf);
+ }
+ break;
+/* Not handled */
+ case HOOK_DATA_RECEIVED:
+ break;
+ }
+
+ CHECK_POSIX_DO( pthread_mutex_unlock(&mtx), );
+}
+
+static void md_hook_cb_compact(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata)
+{
+ char * peer_name = peer ? peer->info.pi_diamid : "<unknown peer>";
+
+ CHECK_POSIX_DO( pthread_mutex_lock(&mtx), );
+
+ if (msg) {
+ CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, fd_g_config->cnf_dict, 0, 0),
+ { LOG_E("Error while dumping a message"); pthread_mutex_unlock(&mtx); return; } );
+ }
+
+ switch (type) {
+/* errors */
+ case HOOK_MESSAGE_FAILOVER:
+ LOG_E("FAILOVER from '%s': %s", peer_name, buf);
+ break;
+ case HOOK_MESSAGE_PARSING_ERROR:
+ if (msg) {
+ DiamId_t id = NULL;
+ if (fd_msg_source_get( msg, &id, NULL ))
+ id = (DiamId_t)"<error getting source>";
+ if (!id)
+ id = (DiamId_t)"<local>";
+ LOG_E("PARSING ERROR: '%s' from '%s': %s", (char *)other, (char *)id, buf);
+ } else {
+ struct fd_cnx_rcvdata *rcv_data = other;
+ CHECK_MALLOC_DO(fd_dump_extend_hexdump(&buf, &len, NULL, rcv_data->buffer, rcv_data->length, 0, 0), break);
+ LOG_E("PARSING ERROR: %zdB msg from '%s': %s", rcv_data->length, peer_name, buf);
+ }
+ break;
+ case HOOK_MESSAGE_PARSING_ERROR2:
+ LOG_E("PARSING ERROR, returning: %s", buf);
+ break;
+ case HOOK_MESSAGE_ROUTING_ERROR:
+ LOG_E("ROUTING ERROR '%s' for: %s", (char *)other, buf);
+ break;
+ case HOOK_MESSAGE_DROPPED:
+ LOG_E("DROPPED '%s' %s", (char *)other, buf);
+ break;
+
+/* send receive */
+ case HOOK_MESSAGE_RECEIVED:
+ LOG_N("RCV from '%s': %s", peer_name, buf);
+ break;
+ case HOOK_MESSAGE_SENDING:
+ LOG_N("SNDING to '%s': %s", peer_name, buf);
+ break;
+ case HOOK_MESSAGE_SENT:
+ LOG_N("SND to '%s': %s", peer_name, buf);
+ break;
+
+/* routing */
+ case HOOK_MESSAGE_LOCAL:
+ LOG_N("ISSUED: %s", buf);
+ break;
+ case HOOK_MESSAGE_ROUTING_FORWARD:
+ LOG_N("FORWARDING: %s", buf);
+ break;
+ case HOOK_MESSAGE_ROUTING_LOCAL:
+ LOG_N("DISPATCHING: %s", buf);
+ break;
+
+/* peers */
+ case HOOK_PEER_CONNECT_FAILED:
+ LOG_N("CONNECT FAILED to %s: %s", peer_name, (char *)other);
+ break;
+ case HOOK_PEER_CONNECT_SUCCESS: {
+ char protobuf[40];
+ if (peer) {
+ CHECK_FCT_DO(fd_peer_cnx_proto_info(peer, protobuf, sizeof(protobuf)), break );
+ } else {
+ protobuf[0] = '-';
+ protobuf[1] = '\0';
+ }
+ LOG_N("CONNECTED TO '%s' (%s)", peer_name, protobuf);
+ }
+ break;
+/* Not handled */
+ case HOOK_DATA_RECEIVED:
+ break;
+ }
+
+ CHECK_POSIX_DO( pthread_mutex_unlock(&mtx), );
+}
+
+static void md_hook_cb_quiet(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata)
+{
+}
+
+/* Entry point */
+static int md_main(char * conffile)
+{
+ uint32_t mask_errors, mask_sndrcv, mask_routing, mask_peers;
+ uint32_t mask_quiet, mask_compact, mask_full, mask_tree;
+ TRACE_ENTRY("%p", conffile);
+
+ if (conffile != NULL) {
+ char * endp;
+ dump_level = (uint32_t)strtoul(conffile, &endp, 16);
+ CHECK_PARAMS_DO( *endp == '\0', {
+ LOG_E("Configuration parameter must be in the form \"0xNNNN\"");
+ return EINVAL; });
+ }
+
+ mask_errors = HOOK_MASK( HOOK_MESSAGE_FAILOVER, HOOK_MESSAGE_PARSING_ERROR, HOOK_MESSAGE_PARSING_ERROR2, HOOK_MESSAGE_ROUTING_ERROR, HOOK_MESSAGE_DROPPED );
+ mask_sndrcv = HOOK_MASK( HOOK_MESSAGE_RECEIVED, HOOK_MESSAGE_SENT ); /* We don t access SENDING hook here */
+ mask_routing= HOOK_MASK( HOOK_MESSAGE_LOCAL, HOOK_MESSAGE_ROUTING_FORWARD, HOOK_MESSAGE_ROUTING_LOCAL );
+ mask_peers = HOOK_MASK( HOOK_PEER_CONNECT_FAILED, HOOK_PEER_CONNECT_SUCCESS );
+
+ mask_quiet = (dump_level & HK_ERRORS_QUIET) ? mask_errors : 0;
+ mask_quiet |= (dump_level & HK_SNDRCV_QUIET) ? mask_sndrcv : 0;
+ mask_quiet |= (dump_level & HK_ROUTING_QUIET) ? mask_routing : 0;
+ mask_quiet |= (dump_level & HK_PEERS_QUIET) ? mask_peers : 0;
+
+ mask_compact = (dump_level & HK_ERRORS_COMPACT) ? mask_errors : 0;
+ mask_compact |= (dump_level & HK_SNDRCV_COMPACT) ? mask_sndrcv : 0;
+ mask_compact |= (dump_level & HK_ROUTING_COMPACT) ? mask_routing : 0;
+ mask_compact |= (dump_level & HK_PEERS_COMPACT) ? mask_peers : 0;
+
+ mask_full = (dump_level & HK_ERRORS_FULL) ? mask_errors : 0;
+ mask_full |= (dump_level & HK_SNDRCV_FULL) ? mask_sndrcv : 0;
+ mask_full |= (dump_level & HK_ROUTING_FULL) ? mask_routing : 0;
+ mask_full |= (dump_level & HK_PEERS_FULL) ? mask_peers : 0;
+
+ mask_tree = (dump_level & HK_ERRORS_TREE) ? mask_errors : 0;
+ mask_tree |= (dump_level & HK_SNDRCV_TREE) ? mask_sndrcv : 0;
+ mask_tree |= (dump_level & HK_ROUTING_TREE) ? mask_routing : 0;
+ mask_tree |= (dump_level & HK_PEERS_TREE) ? mask_peers : 0;
+
+ if (mask_quiet) {
+ CHECK_FCT( fd_hook_register( mask_quiet, md_hook_cb_quiet, NULL, NULL, &md_hdl[0]) );
+ }
+ if (mask_compact) {
+ CHECK_FCT( fd_hook_register( mask_compact, md_hook_cb_compact, NULL, NULL, &md_hdl[1]) );
+ }
+ if (mask_full) {
+ CHECK_FCT( fd_hook_register( mask_full, md_hook_cb_full, NULL, NULL, &md_hdl[2]) );
+ }
+ if (mask_tree) {
+ CHECK_FCT( fd_hook_register( mask_tree, md_hook_cb_tree, NULL, NULL, &md_hdl[3]) );
+ }
+
+ return 0;
+}
+
+/* Cleanup */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+ if (md_hdl[0]) { CHECK_FCT_DO( fd_hook_unregister( md_hdl[0] ), ); }
+ if (md_hdl[1]) { CHECK_FCT_DO( fd_hook_unregister( md_hdl[1] ), ); }
+ if (md_hdl[2]) { CHECK_FCT_DO( fd_hook_unregister( md_hdl[2] ), ); }
+ if (md_hdl[2]) { CHECK_FCT_DO( fd_hook_unregister( md_hdl[3] ), ); }
+ return ;
+}
+
+EXTENSION_ENTRY("dbg_msg_dumps", md_main);
diff --git a/extensions/dbg_msg_timings/CMakeLists.txt b/extensions/dbg_msg_timings/CMakeLists.txt
new file mode 100644
index 0000000..338a3e0
--- /dev/null
+++ b/extensions/dbg_msg_timings/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Messages timing extension
+PROJECT("Messages timing extension" C)
+FD_ADD_EXTENSION(dbg_msg_timings dbg_msg_timings.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dbg_msg_timings
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
+
diff --git a/extensions/dbg_msg_timings/dbg_msg_timings.c b/extensions/dbg_msg_timings/dbg_msg_timings.c
new file mode 100644
index 0000000..6c66069
--- /dev/null
+++ b/extensions/dbg_msg_timings/dbg_msg_timings.c
@@ -0,0 +1,133 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* This extension uses the hooks mechanism to compute some timing information related to messages */
+
+#include <freeDiameter/extension.h>
+
+struct fd_hook_permsgdata {
+ struct timespec received_on;
+ struct timespec sent_on;
+};
+
+static struct fd_hook_data_hdl *mt_data_hdl = NULL;
+static struct fd_hook_hdl *mt_hdl = NULL;
+
+/* The callback called when messages are received and sent */
+static void mt_hook_cb(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata)
+{
+ struct msg_hdr * hdr;
+ char * buf = NULL;
+ size_t len;
+
+ ASSERT(pmd);
+
+ if (type == HOOK_DATA_RECEIVED) {
+ /* We just store the timestamp it was received on */
+ (void)clock_gettime(CLOCK_REALTIME, &pmd->received_on);
+ return;
+ }
+
+ ASSERT(msg);
+
+ /* Check if this message is request or answer */
+ CHECK_FCT_DO( fd_msg_hdr(msg, &hdr), return);
+
+ if (type == HOOK_MESSAGE_RECEIVED) {
+ ASSERT(pmd->received_on.tv_sec); /* otherwise it means the HOOK_DATA_RECEIVED hook was not trigged for this message */
+ if (hdr->msg_flags & CMD_FLAG_REQUEST) {
+ /* We have received a new request, nothing special to do */
+ } else {
+ /* This is an answer, check how long it took to get it */
+ struct fd_hook_permsgdata *qpmd = fd_hook_get_request_pmd(mt_data_hdl, msg);
+ struct timespec delay;
+ ASSERT(qpmd); /* If we do not have it, we must find out why */
+ ASSERT(qpmd->sent_on.tv_sec); /* same, would mean the HOOK_MESSAGE_SENT hook was not trigged */
+ TS_DIFFERENCE( &delay, &qpmd->sent_on, &pmd->received_on );
+ CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), return );
+ LOG_N("[TIMING] RCV ANS %ld.%06ld sec <-'%s': %s", (long)delay.tv_sec, delay.tv_nsec / 1000, peer ? peer->info.pi_diamid : "<unidentified>", buf);
+ }
+ } else if (type == HOOK_MESSAGE_SENT) {
+ DiamId_t source = NULL;
+
+ (void)clock_gettime(CLOCK_REALTIME, &pmd->sent_on);
+
+ /* Is this a forwarded message ? */
+ CHECK_FCT_DO( fd_msg_source_get(msg, &source, NULL), return );
+ if (source) {
+ struct timespec delay;
+ ASSERT(pmd->received_on.tv_sec);
+ TS_DIFFERENCE( &delay, &pmd->received_on, &pmd->sent_on );
+ CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), return );
+ LOG_N("[TIMING] FWD %ld.%06ld sec '%s'->'%s': %s", (long)delay.tv_sec, delay.tv_nsec / 1000, source, peer ? peer->info.pi_diamid : "<unidentified>", buf);
+ } else if (hdr->msg_flags & CMD_FLAG_REQUEST) {
+ /* We are sending a request issued locally, nothing special to log */
+ } else {
+ /* We have generated an anwer, log the time it took since the corresponding request was received */
+ struct fd_hook_permsgdata *qpmd = fd_hook_get_request_pmd(mt_data_hdl, msg);
+ if (qpmd->received_on.tv_sec) {
+ struct timespec delay;
+ TS_DIFFERENCE( &delay, &qpmd->received_on, &pmd->sent_on );
+ CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), return );
+ LOG_N("[TIMING] ANS %ld.%06ld sec ->'%s': %s", (long)delay.tv_sec, delay.tv_nsec / 1000, peer ? peer->info.pi_diamid : "<unidentified>", buf);
+ }
+ }
+ }
+
+ free(buf);
+}
+
+/* Entry point */
+static int mt_main(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ CHECK_FCT( fd_hook_data_register( sizeof(struct fd_hook_permsgdata), NULL, NULL, &mt_data_hdl ) );
+
+ CHECK_FCT( fd_hook_register( HOOK_MASK( HOOK_MESSAGE_RECEIVED, HOOK_MESSAGE_SENT, HOOK_DATA_RECEIVED ),
+ mt_hook_cb, NULL, mt_data_hdl, &mt_hdl) );
+
+ return 0;
+}
+
+/* Cleanup */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+ CHECK_FCT_DO( fd_hook_unregister( mt_hdl ), );
+ return ;
+}
+
+EXTENSION_ENTRY("dbg_msg_timing", mt_main);
diff --git a/extensions/dbg_rt/CMakeLists.txt b/extensions/dbg_rt/CMakeLists.txt
new file mode 100644
index 0000000..6ce7084
--- /dev/null
+++ b/extensions/dbg_rt/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The rt_debug extension
+PROJECT("Routing module debug extension" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dbg_rt dbg_rt.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dbg_rt
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
diff --git a/extensions/dbg_rt/dbg_rt.c b/extensions/dbg_rt/dbg_rt.c
new file mode 100644
index 0000000..906e18e
--- /dev/null
+++ b/extensions/dbg_rt/dbg_rt.c
@@ -0,0 +1,106 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * Debug-only extension for routing module;
+ * displays state information at the end of routing information process.
+ */
+#include <freeDiameter/extension.h>
+
+static struct fd_rt_fwd_hdl * fwd_hdl = NULL;
+static struct fd_rt_out_hdl * out_hdl = NULL;
+
+/* Proxying debug callback */
+static int dbgrt_fwd_cb(void * cbdata, struct msg ** msg)
+{
+ char * buf = NULL; size_t buflen;
+ TRACE_ENTRY("%p %p", cbdata, msg);
+
+ LOG_D("[dbg_rt] FWD routing message: %p", msg ? *msg : NULL);
+ if (msg) {
+ CHECK_MALLOC( fd_msg_dump_treeview(&buf, &buflen, NULL, *msg, NULL, 0, 1) );
+ LOG_D("%s", buf);
+ }
+ free(buf);
+ return 0;
+}
+
+/* Path selection debug callback */
+static int dbgrt_out_cb(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
+{
+ struct fd_list * li;
+ struct msg * msg = *pmsg;
+ char * buf = NULL; size_t buflen;
+
+ TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
+
+ LOG_D("[dbg_rt] OUT routing message: %p", msg);
+ CHECK_MALLOC( fd_msg_dump_treeview(&buf, &buflen, NULL, msg, NULL, 0, 1) );
+ LOG_D("%s", buf);
+ LOG_D("[dbg_rt] Current list of candidates (%p): (score - id)", msg);
+
+ for (li = candidates->next; li != candidates; li = li->next) {
+ struct rtd_candidate *c = (struct rtd_candidate *) li;
+ LOG_D("[dbg_rt] %d -\t%s", c->score, c->diamid);
+ }
+
+ return 0;
+}
+
+/* Register the callbacks to the daemon */
+static int dbgrt_main(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ CHECK_FCT( fd_rt_fwd_register ( dbgrt_fwd_cb, NULL, RT_FWD_ALL, &fwd_hdl ) );
+ CHECK_FCT( fd_rt_out_register ( dbgrt_out_cb, NULL, -1 /* so that it is called late */, &out_hdl ) );
+
+ return 0;
+}
+
+/* Cleanup the callbacks */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+
+ /* Unregister the modules */
+ CHECK_FCT_DO( fd_rt_fwd_unregister ( fwd_hdl, NULL ), /* continue */ );
+ CHECK_FCT_DO( fd_rt_out_unregister ( out_hdl, NULL ), /* continue */ );
+
+ return ;
+}
+
+/* Define the entry point function */
+EXTENSION_ENTRY("dbg_rt", dbgrt_main);
diff --git a/extensions/dict_3gpp2_avps/3gpp2_avps.did b/extensions/dict_3gpp2_avps/3gpp2_avps.did
new file mode 100644
index 0000000..7c1da3c
--- /dev/null
+++ b/extensions/dict_3gpp2_avps/3gpp2_avps.did
@@ -0,0 +1 @@
+dict_3gpp2_avps
diff --git a/extensions/dict_3gpp2_avps/CMakeLists.txt b/extensions/dict_3gpp2_avps/CMakeLists.txt
new file mode 100644
index 0000000..ceda190
--- /dev/null
+++ b/extensions/dict_3gpp2_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_3gpp2_avps extension
+PROJECT("dict_3gpp2_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_3gpp2_avps dict_3gpp2_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_3gpp2_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-3GPP2_AVPS)
+
+
+
diff --git a/extensions/dict_3gpp2_avps/dict_3gpp2_avps.c b/extensions/dict_3gpp2_avps/dict_3gpp2_avps.c
new file mode 100644
index 0000000..a03b51c
--- /dev/null
+++ b/extensions/dict_3gpp2_avps/dict_3gpp2_avps.c
@@ -0,0 +1,184 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in 3gpp2_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697184.91
+
+const char *_3gpp2_avps_proto_ver = PROTO_VER;
+const double _3gpp2_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_3gpp2_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 5535, "3GPP2" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* 3GPP2-BSID */
+ {
+ struct dict_avp_data data = {
+ 9010, /* Code */
+ 5535, /* Vendor */
+ "3GPP2-BSID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_3gpp2_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for 3gpp2_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_3gpp2_avps_load_defs(conffile);
+ return dict_3gpp2_avps_load_rules(conffile);
+}
+
+const char* dict_3gpp2_avps_proto_ver(char * conffile) {
+ return _3gpp2_avps_proto_ver;
+}
+
+const double dict_3gpp2_avps_gen_ts(char * conffile) {
+ return _3gpp2_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_3gpp2_avps", dict_3gpp2_avps_load_defs, dict_3gpp2_avps_load_rules);
+
+
+
diff --git a/extensions/dict_CreditControl/CMakeLists.txt b/extensions/dict_CreditControl/CMakeLists.txt
new file mode 100644
index 0000000..6ae7d43
--- /dev/null
+++ b/extensions/dict_CreditControl/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_CreditControl extension
+PROJECT("dict_CreditControl library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_CreditControl dict_CreditControl.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_CreditControl
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-CREDITCONTROL)
+
+
+
diff --git a/extensions/dict_CreditControl/CreditControl.did b/extensions/dict_CreditControl/CreditControl.did
new file mode 100644
index 0000000..668abaa
--- /dev/null
+++ b/extensions/dict_CreditControl/CreditControl.did
@@ -0,0 +1,5 @@
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_CreditControl
diff --git a/extensions/dict_CreditControl/dict_CreditControl.c b/extensions/dict_CreditControl/dict_CreditControl.c
new file mode 100644
index 0000000..3d3ba7c
--- /dev/null
+++ b/extensions/dict_CreditControl/dict_CreditControl.c
@@ -0,0 +1,286 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in CreditControl (rfc4006bis).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "rfc4006bis"
+#define GEN_DATE 1506697121.72
+
+const char *creditcontrol_proto_ver = PROTO_VER;
+const double creditcontrol_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_creditcontrol_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id4;
+
+ /* Application Section */
+ {
+ {
+ struct dict_application_data data = { 4, "CreditControl" };
+ CHECK_dict_new( DICT_APPLICATION, &data, NULL, &app_id4)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "is", { .u32=10 }};
+ struct dict_enumval_data t_2 = { "Services", { .u32=3 }};
+ struct dict_enumval_data t_3 = { "KS", { .u32=66251 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* Credit-Control-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 272, /* Code */
+ "Credit-Control-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id4, &cmd)
+ }
+ /* Credit-Control-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 272, /* Code */
+ "Credit-Control-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id4, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_creditcontrol_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Credit-Control-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Context-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Multi-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id-Extension"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Termination-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Requested-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Requested-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Used-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Multiple-Services-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Multiple-Services-Credit-Control"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Parameter-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Correlation-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info-Extension"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Credit-Control-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Session-Failover"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Multi-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Granted-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Multiple-Services-Credit-Control"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Cost-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Final-Unit-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "QoS-Final-Unit-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Check-Balance-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Credit-Control-Failure-Handling"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Direct-Debiting-Failure-Handling"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Validity-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for CreditControl (rfc4006bis)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_creditcontrol_load_defs(conffile);
+ return dict_creditcontrol_load_rules(conffile);
+}
+
+const char* dict_creditcontrol_proto_ver(char * conffile) {
+ return creditcontrol_proto_ver;
+}
+
+const double dict_creditcontrol_gen_ts(char * conffile) {
+ return creditcontrol_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_creditcontrol", dict_creditcontrol_load_defs, dict_creditcontrol_load_rules, "dict_rfc4006bis_avps", "dict_rfc7155_avps", "dict_rfc5777_avps");
+
+
+
diff --git a/extensions/dict_CxDx/CMakeLists.txt b/extensions/dict_CxDx/CMakeLists.txt
new file mode 100644
index 0000000..ea6c136
--- /dev/null
+++ b/extensions/dict_CxDx/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_CxDx extension
+PROJECT("dict_CxDx library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_CxDx dict_CxDx.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_CxDx
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-CXDX)
+
+
+
diff --git a/extensions/dict_CxDx/CxDx.did b/extensions/dict_CxDx/CxDx.did
new file mode 100644
index 0000000..c6407fb
--- /dev/null
+++ b/extensions/dict_CxDx/CxDx.did
@@ -0,0 +1,9 @@
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_CxDx
diff --git a/extensions/dict_CxDx/dict_CxDx.c b/extensions/dict_CxDx/dict_CxDx.c
new file mode 100644
index 0000000..8fc87f2
--- /dev/null
+++ b/extensions/dict_CxDx/dict_CxDx.c
@@ -0,0 +1,656 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in CxDx (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697212.25
+
+const char *cxdx_proto_ver = PROTO_VER;
+const double cxdx_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_cxdx_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777216;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777216, "CxDx" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777216)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "Discovery_of_supported_interface_versions", { .u32=1 }};
+ struct dict_enumval_data t_2 = { "Supported_features", { .u32=2 }};
+ struct dict_enumval_data t_3 = { "Interface_versions", { .u32=3 }};
+ struct dict_enumval_data t_4 = { "Application_ID_value", { .u32=4 }};
+ struct dict_enumval_data t_5 = { "Special_Requirements", { .u32=7 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* User-Authorization-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 300, /* Code */
+ "User-Authorization-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* User-Authorization-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 300, /* Code */
+ "User-Authorization-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Server-Assignment-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 301, /* Code */
+ "Server-Assignment-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Server-Assignment-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 301, /* Code */
+ "Server-Assignment-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Location-Info-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 302, /* Code */
+ "Location-Info-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Location-Info-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 302, /* Code */
+ "Location-Info-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Multimedia-Auth-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 303, /* Code */
+ "Multimedia-Auth-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Multimedia-Auth-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 303, /* Code */
+ "Multimedia-Auth-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Registration-Termination-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 304, /* Code */
+ "Registration-Termination-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Registration-Termination-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 304, /* Code */
+ "Registration-Termination-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Push-Profile-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 305, /* Code */
+ "Push-Profile-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+ /* Push-Profile-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 305, /* Code */
+ "Push-Profile-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777216, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_cxdx_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* User-Authorization-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "User-Authorization-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Public-Identity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-Network-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Authorization-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UAR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* User-Authorization-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "User-Authorization-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Capabilities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Server-Assignment-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Server-Assignment-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Assignment-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Data-Already-Available"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCSCF-Restoration-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Multiple-Registration-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SAR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Server-Assignment-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Server-Assignment-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Associated-Identities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Loose-Route-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCSCF-Restoration-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Associated-Registered-Identities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Priviledged-Sender-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Allowed-WAF-WWSF-Identities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Location-Info-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Originating-Request"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Public-Identity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Authorization-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Location-Info-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Location-Info-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Capabilities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LIA-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Multimedia-Auth-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Multimedia-Auth-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Public-Identity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Auth-Data-Item"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Number-Auth-Items"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Multimedia-Auth-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Multimedia-Auth-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Number-Auth-Items"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Auth-Data-Item"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Registration-Termination-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Associated-Identities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Deregistration-Reason"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Registration-Termination-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Associated-Identities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Identity-with-Emergency-Registration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Push-Profile-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Push-Profile-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Auth-Data-Item"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Allowed-WAF-WWSF-Identities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Push-Profile-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Push-Profile-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for CxDx (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_cxdx_load_defs(conffile);
+ return dict_cxdx_load_rules(conffile);
+}
+
+const char* dict_cxdx_proto_ver(char * conffile) {
+ return cxdx_proto_ver;
+}
+
+const double dict_cxdx_gen_ts(char * conffile) {
+ return cxdx_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_cxdx", dict_cxdx_load_defs, dict_cxdx_load_rules, "dict_ts29229_avps", "dict_draftload_avps", "dict_rfc4590_avps", "dict_rfc7683_avps", "dict_rfc7155_avps", "dict_etsi283034_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_Gx/CMakeLists.txt b/extensions/dict_Gx/CMakeLists.txt
new file mode 100644
index 0000000..e04526e
--- /dev/null
+++ b/extensions/dict_Gx/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_Gx extension
+PROJECT("dict_Gx library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_Gx dict_Gx.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_Gx
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-GX)
+
+
+
diff --git a/extensions/dict_Gx/Gx.did b/extensions/dict_Gx/Gx.did
new file mode 100644
index 0000000..33d3e5f
--- /dev/null
+++ b/extensions/dict_Gx/Gx.did
@@ -0,0 +1,39 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_ts29212_avps
+dict_CreditControl
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_Gx
diff --git a/extensions/dict_Gx/dict_Gx.c b/extensions/dict_Gx/dict_Gx.c
new file mode 100644
index 0000000..c0f5990
--- /dev/null
+++ b/extensions/dict_Gx/dict_Gx.c
@@ -0,0 +1,437 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in Gx (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697205.07
+
+const char *gx_proto_ver = PROTO_VER;
+const double gx_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_gx_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777224;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777224, "Gx" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777224)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "DIAMETER_USER_UNKNOWN", { .u32=5030 }};
+ struct dict_enumval_data t_2 = { "DIAMETER_ERROR_LATE_OVERLAPPING_REQUEST", { .u32=5453 }};
+ struct dict_enumval_data t_3 = { "DIAMETER_ERROR_TIMED_OUT_REQUEST", { .u32=5454 }};
+ struct dict_enumval_data t_4 = { "DIAMETER_ERROR_INITIAL_PARAMETERS", { .u32=5140 }};
+ struct dict_enumval_data t_5 = { "DIAMETER_ERROR_TRIGGER_EVENT", { .u32=5141 }};
+ struct dict_enumval_data t_6 = { "DIAMETER_PCC_RULE_EVENT", { .u32=5142 }};
+ struct dict_enumval_data t_7 = { "DIAMETER_ERROR_BEARER_NOT_AUTHORIZED", { .u32=5143 }};
+ struct dict_enumval_data t_8 = { "DIAMETER_ERROR_TRAFFIC_MAPPING_INFO_REJECTED", { .u32=5144 }};
+ struct dict_enumval_data t_9 = { "DIAMETER_ERROR_CONFLICTING_REQUEST", { .u32=5147 }};
+ struct dict_enumval_data t_10 = { "DIAMETER_ADC_RULE_EVENT", { .u32=5148 }};
+ struct dict_enumval_data t_11 = { "DIAMETER_ERROR_NBIFOM_NOT_AUTHORIZED", { .u32=5149 }};
+ struct dict_enumval_data t_12 = { "DIAMETER_PCC_BEARER_EVENT", { .u32=4141 }};
+ struct dict_enumval_data t_13 = { "DIAMETER_AN_GW_FAILED", { .u32=4143 }};
+ struct dict_enumval_data t_14 = { "DIAMETER_PENDING_TRANSACTION", { .u32=4144 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_gx_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Credit-Control-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Credit-Management-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TDF-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Network-Request-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Operation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Operation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Dynamic-Address-Flag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Dynamic-Address-Flag-Extension"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Connection-Charging-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-Trusted"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Termination-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Negotiation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Upgrade"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-EPS-Bearer-QoS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-GGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-GGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Selection-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Fixed-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Location-Info-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAN-NAS-Release-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Connection-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Online"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Offline"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TFT-Packet-Filter-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Detection-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier-Gx"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CoA-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-Access"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Origination-Time-Stamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-Wait-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Availability-Change-Reason"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "HeNB-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UDP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Logical-Access-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Physical-Access-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-PS-Data-Off-Status"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Credit-Control-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Control-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Online"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Offline"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Revalidation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-EPS-Bearer-QoS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CSG-Information-Reporting"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PRA-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PRA-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Release-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-Access"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAN-Rule-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Conditional-Policy-Information"}, RULE_OPTIONAL, 0, 4 },
+ { { .avp_vendor = 10415, .avp_name = "Removal-Of-Access"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Re-Auth-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Release-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-EPS-Bearer-QoS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Revalidation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PCSCF-Restoration-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Conditional-Policy-Information"}, RULE_OPTIONAL, 0, 4 },
+ { { .avp_vendor = 10415, .avp_name = "Removal-Of-Access"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PRA-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PRA-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-Trusted"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Location-Info-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NetLoc-Access-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for Gx (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_gx_load_defs(conffile);
+ return dict_gx_load_rules(conffile);
+}
+
+const char* dict_gx_proto_ver(char * conffile) {
+ return gx_proto_ver;
+}
+
+const double dict_gx_gen_ts(char * conffile) {
+ return gx_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_gx", dict_gx_load_defs, dict_gx_load_rules, "dict_ts32299_avps", "dict_ts29212_avps", "dict_ts29273_avps", "dict_ts29214_avps", "dict_ts29272_avps", "dict_ts29229_avps", "dict_ts29061_avps", "dict_CreditControl", "dict_rfc4006bis_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7155_avps", "dict_etsi283034_avps", "dict_3gpp2_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_NAS/CMakeLists.txt b/extensions/dict_NAS/CMakeLists.txt
new file mode 100644
index 0000000..ace49ff
--- /dev/null
+++ b/extensions/dict_NAS/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_NAS extension
+PROJECT("dict_NAS library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_NAS dict_NAS.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_NAS
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-dict_NAS)
+
+
+
diff --git a/extensions/dict_NAS/NAS.did b/extensions/dict_NAS/NAS.did
new file mode 100644
index 0000000..5e6af9e
--- /dev/null
+++ b/extensions/dict_NAS/NAS.did
@@ -0,0 +1,3 @@
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_NAS
diff --git a/extensions/dict_NAS/dict_NAS.c b/extensions/dict_NAS/dict_NAS.c
new file mode 100644
index 0000000..eeaa8c0
--- /dev/null
+++ b/extensions/dict_NAS/dict_NAS.c
@@ -0,0 +1,555 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in NAS.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697121.58
+
+const char *nas_proto_ver = PROTO_VER;
+const double nas_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_nas_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id0;
+ struct dict_object * app_id1;
+
+ /* Application Section */
+ {
+ {
+ struct dict_application_data data = { 0, "NAS-app0" };
+ CHECK_dict_new( DICT_APPLICATION, &data, NULL, &app_id0)
+ }
+ {
+ struct dict_application_data data = { 1, "NAS" };
+ CHECK_dict_new( DICT_APPLICATION, &data, NULL, &app_id1)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "Bangkok", { .u32=10260 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* AA-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 265, /* Code */
+ "AA-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id1, &cmd)
+ }
+ /* AA-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 265, /* Code */
+ "AA-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id1, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_nas_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* AA-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "AA-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IPv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-AAA-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Port-Limit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Password"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "State"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Authorization-Lifetime"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Grace-Period"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Callback-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Calling-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Originating-Line-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Connect-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CHAP-Auth"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CHAP-Challenge"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Compression"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Interface-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Netmask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-MTU"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "ARAP-Password"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* AA-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "AA-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Re-Auth-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-AAA-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IPv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-AAA-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Configuration-Token"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Idle-Timeout"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Authorization-Lifetime"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Grace-Period"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Re-Auth-Request-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "State"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Reply-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Prompt"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Abort-Session-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Abort-Session-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-AAA-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IPv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Interface-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Abort-Session-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Abort-Session-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-AAA-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "State"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Session-Termination-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Termination-Cause"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-AAA-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Session-Termination-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-AAA-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Accounting-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Accounting-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Record-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Record-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Multi-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-AAA-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Delay-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IPv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Termination-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Input-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Input-Packets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Output-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Output-Packets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Authentic"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Auth-Method"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Link-Count"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Session-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Tunnel-Connection"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Tunnel-Packets-Lost"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Callback-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Callback-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Calling-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Connect-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Originating-Line-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Authorization-Lifetime"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Session-Timeout"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Idle-Timeout"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Port-Limit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Realtime-Required"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Interim-Interval"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Filter-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Filter-Rule"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "QoS-Filter-Rule"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Appletalk-Link"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Appletalk-Network"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Appletalk-Zone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Compression"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Interface-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Netmask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Pool"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Route"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPX-Network"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-MTU"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Pool"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Route"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Routing"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Login-IP-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Login-IPv6-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Login-LAT-Group"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Login-LAT-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Login-LAT-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Login-LAT-Service"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Login-Service"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Login-TCP-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunneling"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Accounting-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Accounting-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Record-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Record-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Multi-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-AAA-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-IPv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "NAS-Port-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Termination-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Realtime-Required"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for NAS (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_nas_load_defs(conffile);
+ return dict_nas_load_rules(conffile);
+}
+
+const char* dict_nas_proto_ver(char * conffile) {
+ return nas_proto_ver;
+}
+
+const double dict_nas_gen_ts(char * conffile) {
+ return nas_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_nas", dict_nas_load_defs, dict_nas_load_rules, "dict_rfc7155_avps");
+
+
+
diff --git a/extensions/dict_Rf/CMakeLists.txt b/extensions/dict_Rf/CMakeLists.txt
new file mode 100644
index 0000000..6073671
--- /dev/null
+++ b/extensions/dict_Rf/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_Rf extension
+PROJECT("dict_Rf library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_Rf dict_Rf.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_Rf
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RF)
+
+
+
diff --git a/extensions/dict_Rf/Rf.did b/extensions/dict_Rf/Rf.did
new file mode 100644
index 0000000..72ff4f6
--- /dev/null
+++ b/extensions/dict_Rf/Rf.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_ts29337_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29173_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc5447_avps
+dict_rfc5778_avps
+dict_rfc5777_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_3gpp2_avps
+dict_Rf
diff --git a/extensions/dict_Rf/dict_Rf.c b/extensions/dict_Rf/dict_Rf.c
new file mode 100644
index 0000000..4edee61
--- /dev/null
+++ b/extensions/dict_Rf/dict_Rf.c
@@ -0,0 +1,235 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in Rf (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697125.6
+
+const char *rf_proto_ver = PROTO_VER;
+const double rf_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rf_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id3;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 3, "Rf" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id3)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rf_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Accounting-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Accounting-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Record-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Record-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Multi-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Interim-Interval"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Realtime-Required"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Context-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Accounting-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Accounting-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Record-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Record-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Multi-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Interim-Interval"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Realtime-Required"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for Rf (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rf_load_defs(conffile);
+ return dict_rf_load_rules(conffile);
+}
+
+const char* dict_rf_proto_ver(char * conffile) {
+ return rf_proto_ver;
+}
+
+const double dict_rf_gen_ts(char * conffile) {
+ return rf_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rf", dict_rf_load_defs, dict_rf_load_rules, "dict_ts32299_avps", "dict_ts29272_avps", "dict_ts29273_avps", "dict_ts29212_avps", "dict_ts29336_avps", "dict_ts29128_avps", "dict_ts29214_avps", "dict_ts29345_avps", "dict_ts29337_avps", "dict_ts29344_avps", "dict_ts29368_avps", "dict_ts29217_avps", "dict_ts29229_avps", "dict_ts29338_avps", "dict_ts29468_avps", "dict_ts29329_avps", "dict_ts29061_avps", "dict_rfc5778_avps", "dict_ts29173_avps", "dict_rfc4006bis_avps", "dict_ts29343_avps", "dict_rfc7155_avps", "dict_rfc5447_avps", "dict_rfc7683_avps", "dict_rfc4590_avps", "dict_draftload_avps", "dict_rfc4004_avps", "dict_rfc5777_avps", "dict_etsi283034_avps", "dict_3gpp2_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_Ro/CMakeLists.txt b/extensions/dict_Ro/CMakeLists.txt
new file mode 100644
index 0000000..a37c7de
--- /dev/null
+++ b/extensions/dict_Ro/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_Ro extension
+PROJECT("dict_Ro library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_Ro dict_Ro.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_Ro
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RO)
+
+
+
diff --git a/extensions/dict_Ro/Ro.did b/extensions/dict_Ro/Ro.did
new file mode 100644
index 0000000..1600d85
--- /dev/null
+++ b/extensions/dict_Ro/Ro.did
@@ -0,0 +1,39 @@
+dict_CreditControl
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_ts29337_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29173_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc5447_avps
+dict_rfc5778_avps
+dict_rfc5777_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_3gpp2_avps
+dict_Ro
diff --git a/extensions/dict_Ro/dict_Ro.c b/extensions/dict_Ro/dict_Ro.c
new file mode 100644
index 0000000..a8799f7
--- /dev/null
+++ b/extensions/dict_Ro/dict_Ro.c
@@ -0,0 +1,310 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in Ro (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697129.62
+
+const char *ro_proto_ver = PROTO_VER;
+const double ro_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ro_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id3;
+ struct dict_object * app_id4;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 3, "Ro-app3" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id3)
+ }
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 4, "Ro" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id4)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ro_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Credit-Control-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Context-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Multi-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Termination-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Requested-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Requested-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Used-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AoC-Request-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Multiple-Services-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Multiple-Services-Credit-Control"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Parameter-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Correlation-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Credit-Control-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Session-Failover"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Multi-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Granted-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Multiple-Services-Credit-Control"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Cost-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Low-Balance-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Remaining-Balance"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Final-Unit-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Check-Balance-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Credit-Control-Failure-Handling"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Direct-Debiting-Failure-Handling"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Validity-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Re-Auth-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "G-S-U-Pool-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Rating-Group"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Sub-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "G-S-U-Pool-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Rating-Group"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for Ro (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ro_load_defs(conffile);
+ return dict_ro_load_rules(conffile);
+}
+
+const char* dict_ro_proto_ver(char * conffile) {
+ return ro_proto_ver;
+}
+
+const double dict_ro_gen_ts(char * conffile) {
+ return ro_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ro", dict_ro_load_defs, dict_ro_load_rules, "dict_ts32299_avps", "dict_ts29272_avps", "dict_ts29273_avps", "dict_ts29212_avps", "dict_ts29336_avps", "dict_ts29128_avps", "dict_ts29214_avps", "dict_ts29345_avps", "dict_ts29337_avps", "dict_ts29344_avps", "dict_ts29368_avps", "dict_ts29217_avps", "dict_ts29229_avps", "dict_ts29338_avps", "dict_ts29468_avps", "dict_ts29329_avps", "dict_ts29061_avps", "dict_rfc5778_avps", "dict_ts29173_avps", "dict_CreditControl", "dict_rfc4006bis_avps", "dict_ts29343_avps", "dict_rfc7155_avps", "dict_rfc5447_avps", "dict_rfc7683_avps", "dict_rfc4590_avps", "dict_draftload_avps", "dict_rfc4004_avps", "dict_rfc5777_avps", "dict_etsi283034_avps", "dict_3gpp2_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_Rx/CMakeLists.txt b/extensions/dict_Rx/CMakeLists.txt
new file mode 100644
index 0000000..8ac999c
--- /dev/null
+++ b/extensions/dict_Rx/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_Rx extension
+PROJECT("dict_Rx library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_Rx dict_Rx.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_Rx
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RX)
+
+
+
diff --git a/extensions/dict_Rx/Rx.did b/extensions/dict_Rx/Rx.did
new file mode 100644
index 0000000..8e16935
--- /dev/null
+++ b/extensions/dict_Rx/Rx.did
@@ -0,0 +1,39 @@
+dict_NAS
+dict_rfc6942_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc5778_avps
+dict_ts29338_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_rfc4072_avps
+dict_rfc5447_avps
+dict_ts29273_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc7944_avps
+dict_Rx
diff --git a/extensions/dict_Rx/dict_Rx.c b/extensions/dict_Rx/dict_Rx.c
new file mode 100644
index 0000000..19ad57d
--- /dev/null
+++ b/extensions/dict_Rx/dict_Rx.c
@@ -0,0 +1,471 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in Rx (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697208.6
+
+const char *rx_proto_ver = PROTO_VER;
+const double rx_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rx_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777224;
+ struct dict_object * app_id16777229;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777224, "Rx" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777224)
+ }
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777229, "Rx-app16777229" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777229)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "REQUESTED_SERVICE_TEMPORARILY_NOT_AUTHORIZED", { .u32=4261 }};
+ struct dict_enumval_data t_2 = { "INVALID_SERVICE_INFORMATION", { .u32=5061 }};
+ struct dict_enumval_data t_3 = { "FILTER_RESTRICTIONS", { .u32=5062 }};
+ struct dict_enumval_data t_4 = { "REQUESTED_SERVICE_NOT_AUTHORIZED", { .u32=5063 }};
+ struct dict_enumval_data t_5 = { "DUPLICATED_AF_SESSION", { .u32=5064 }};
+ struct dict_enumval_data t_6 = { "IP-CAN_SESSION_NOT_AVAILABLE", { .u32=5065 }};
+ struct dict_enumval_data t_7 = { "UNAUTHORIZED_NON_EMERGENCY_SESSION", { .u32=5066 }};
+ struct dict_enumval_data t_8 = { "UNAUTHORIZED_SPONSORED_DATA_CONNECTIVITY", { .u32=5067 }};
+ struct dict_enumval_data t_9 = { "TEMPORARY_NETWORK_FAILURE", { .u32=5068 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rx_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* AA-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "AA-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-Domain-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AF-Application-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Media-Component-Description"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Info-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AF-Charging-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Forking-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Specific-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Reservation-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-URN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sponsored-Connectivity-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MPS-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GCS-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MCPTT-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rx-Request-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Required-Access-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AF-Requested-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reference-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Pre-emption-Control-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* AA-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "AA-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Acceptable-Service-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-Trusted"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Authorization-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NetLoc-Access-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flows"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Retry-Interval"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Specific-Action"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-Trusted"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flows"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Abort-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NetLoc-Access-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sponsored-Connectivity-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Location-Info-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAN-NAS-Release-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TCP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UDP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Media-Component-Description"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-URN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Session-Termination-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Termination-Cause"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Required-Access-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Session-Termination-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sponsored-Connectivity-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Location-Info-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAN-NAS-Release-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TCP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UDP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NetLoc-Access-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Abort-Session-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Abort-Session-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Abort-Cause"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Abort-Session-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Abort-Session-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for Rx (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rx_load_defs(conffile);
+ return dict_rx_load_rules(conffile);
+}
+
+const char* dict_rx_proto_ver(char * conffile) {
+ return rx_proto_ver;
+}
+
+const double dict_rx_gen_ts(char * conffile) {
+ return rx_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rx", dict_rx_load_defs, dict_rx_load_rules, "dict_ts32299_avps", "dict_ts29214_avps", "dict_ts29212_avps", "dict_ts29273_avps", "dict_ts29229_avps", "dict_ts29154_avps", "dict_ts29061_avps", "dict_NAS", "dict_rfc4006bis_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7155_avps", "dict_etsi283034_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_S6as6d/CMakeLists.txt b/extensions/dict_S6as6d/CMakeLists.txt
new file mode 100644
index 0000000..828900d
--- /dev/null
+++ b/extensions/dict_S6as6d/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_S6as6d extension
+PROJECT("dict_S6as6d library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_S6as6d dict_S6as6d.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_S6as6d
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-S6AS6D)
+
+
+
diff --git a/extensions/dict_S6as6d/S6as6d.did b/extensions/dict_S6as6d/S6as6d.did
new file mode 100644
index 0000000..b4bdb34
--- /dev/null
+++ b/extensions/dict_S6as6d/S6as6d.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29337_avps
+dict_3gpp2_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_ts29338_avps
+dict_ts29173_avps
+dict_ts29336_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_draftload_avps
+dict_etsi283034_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_rfc7155_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc4004_avps
+dict_rfc5447_avps
+dict_S6as6d
diff --git a/extensions/dict_S6as6d/dict_S6as6d.c b/extensions/dict_S6as6d/dict_S6as6d.c
new file mode 100644
index 0000000..c39b75d
--- /dev/null
+++ b/extensions/dict_S6as6d/dict_S6as6d.c
@@ -0,0 +1,722 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in S6as6d (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697194.55
+
+const char *s6as6d_proto_ver = PROTO_VER;
+const double s6as6d_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_s6as6d_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777251;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777251, "S6as6d" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777251)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "General", { .u32=1 }};
+ struct dict_enumval_data t_2 = { "HSS_behaviour", { .u32=2 }};
+ struct dict_enumval_data t_3 = { "MME_SGSN_behaviour", { .u32=3 }};
+ struct dict_enumval_data t_4 = { "Transient_Failures", { .u32=4 }};
+ struct dict_enumval_data t_5 = { "User_identity_to_HSS_resolution", { .u32=8 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* Update-Location-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 316, /* Code */
+ "Update-Location-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Update-Location-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 316, /* Code */
+ "Update-Location-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Cancel-Location-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 317, /* Code */
+ "Cancel-Location-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Cancel-Location-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 317, /* Code */
+ "Cancel-Location-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Authentication-Information-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 318, /* Code */
+ "Authentication-Information-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Authentication-Information-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 318, /* Code */
+ "Authentication-Information-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Insert-Subscriber-Data-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 319, /* Code */
+ "Insert-Subscriber-Data-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Insert-Subscriber-Data-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 319, /* Code */
+ "Insert-Subscriber-Data-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Delete-Subscriber-Data-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 320, /* Code */
+ "Delete-Subscriber-Data-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Delete-Subscriber-Data-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 320, /* Code */
+ "Delete-Subscriber-Data-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Purge-UE-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 321, /* Code */
+ "Purge-UE-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Purge-UE-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 321, /* Code */
+ "Purge-UE-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Reset-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 322, /* Code */
+ "Reset-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+ /* Reset-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 322, /* Code */
+ "Reset-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777251, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_s6as6d_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Update-Location-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Update-Location-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Terminal-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ULR-Flags"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-SRVCC-Capability"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GMLC-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Active-APN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Equivalent-PLMN-List"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Number-for-MT-SMS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMS-Register-Request"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGs-MME-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Coupled-Node-Diameter-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Adjacent-PLMNs"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Services"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Update-Location-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Update-Location-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Error-Diagnostic"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ULA-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subscription-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reset-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Cancel-Location-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Cancel-Location-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Cancellation-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CLR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Cancel-Location-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Cancel-Location-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Authentication-Information-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Authentication-Information-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requested-EUTRAN-Authentication-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requested-UTRAN-GERAN-Authentication-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AIR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Authentication-Information-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Authentication-Information-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Error-Diagnostic"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Authentication-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Usage-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Insert-Subscriber-Data-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Insert-Subscriber-Data-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subscription-Data"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IDR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reset-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Insert-Subscriber-Data-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Insert-Subscriber-Data-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Voice-Over-PS-Sessions-Supported"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Last-UE-Activity-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IDA-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "EPS-User-State"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "EPS-Location-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Local-Time-Zone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Services"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Config-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Delete-Subscriber-Data-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Delete-Subscriber-Data-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DSR-Flags"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Context-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Reference"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TS-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SS-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Delete-Subscriber-Data-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Delete-Subscriber-Data-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DSA-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Purge-UE-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PUR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "EPS-Location-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Purge-UE-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Purge-UE-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PUA-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Reset-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Reset-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reset-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subscription-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subscription-Data-Deletion"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Reset-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Reset-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for S6as6d (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_s6as6d_load_defs(conffile);
+ return dict_s6as6d_load_rules(conffile);
+}
+
+const char* dict_s6as6d_proto_ver(char * conffile) {
+ return s6as6d_proto_ver;
+}
+
+const double dict_s6as6d_gen_ts(char * conffile) {
+ return s6as6d_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_s6as6d", dict_s6as6d_load_defs, dict_s6as6d_load_rules, "dict_ts29272_avps", "dict_ts32299_avps", "dict_ts29273_avps", "dict_ts29336_avps", "dict_ts29212_avps", "dict_ts29214_avps", "dict_ts29344_avps", "dict_ts29338_avps", "dict_ts29217_avps", "dict_ts29173_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_rfc5778_avps", "dict_ts29061_avps", "dict_rfc5447_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc4004_avps", "dict_rfc5777_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_S6c/CMakeLists.txt b/extensions/dict_S6c/CMakeLists.txt
new file mode 100644
index 0000000..469e515
--- /dev/null
+++ b/extensions/dict_S6c/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The S6c extension
+PROJECT("S6c library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_S6c dict_S6c.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_S6c
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-S6C)
+
+
+
diff --git a/extensions/dict_S6c/S6c.did b/extensions/dict_S6c/S6c.did
new file mode 100644
index 0000000..1dbb9db
--- /dev/null
+++ b/extensions/dict_S6c/S6c.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_rfc7944_avps
+dict_S6c
diff --git a/extensions/dict_S6c/dict_S6c.c b/extensions/dict_S6c/dict_S6c.c
new file mode 100644
index 0000000..6e06b83
--- /dev/null
+++ b/extensions/dict_S6c/dict_S6c.c
@@ -0,0 +1,413 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in S6c (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697121.53
+
+const char *s6c_proto_ver = PROTO_VER;
+const double s6c_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_s6c_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777312;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777312, "S6c" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777312)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "General", { .u32=1 }};
+ struct dict_enumval_data t_2 = { "Permanent_Failures", { .u32=3 }};
+ struct dict_enumval_data t_3 = { "Transient_Failures", { .u32=4 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* Send-Routing-Info-for-SM-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388647, /* Code */
+ "Send-Routing-Info-for-SM-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777312, &cmd)
+ }
+ /* Send-Routing-Info-for-SM-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388647, /* Code */
+ "Send-Routing-Info-for-SM-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777312, &cmd)
+ }
+ /* Alert-Service-Centre-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388648, /* Code */
+ "Alert-Service-Centre-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777312, &cmd)
+ }
+ /* Alert-Service-Centre-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388648, /* Code */
+ "Alert-Service-Centre-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777312, &cmd)
+ }
+ /* Report-SM-Delivery-Status-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388649, /* Code */
+ "Report-SM-Delivery-Status-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777312, &cmd)
+ }
+ /* Report-SM-Delivery-Status-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388649, /* Code */
+ "Report-SM-Delivery-Status-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777312, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_s6c_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Send-Routing-Info-for-SM-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Send-Routing-Info-for-SM-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMSMI-Correlation-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SC-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-RP-MTI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-RP-SMEA"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SRR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Not-Intended"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Send-Routing-Info-for-SM-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Send-Routing-Info-for-SM-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Additional-Serving-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LMSI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MWD-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Absent-User-Diagnostic-SM"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSC-Absent-User-Diagnostic-SM"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Absent-User-Diagnostic-SM"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Alert-Service-Centre-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Alert-Service-Centre-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SC-Address"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMSMI-Correlation-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-UE-Availability-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMS-GMSC-Alert-Event"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Alert-Service-Centre-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Alert-Service-Centre-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Report-SM-Delivery-Status-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Report-SM-Delivery-Status-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMSMI-Correlation-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SC-Address"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Outcome"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RDR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Report-SM-Delivery-Status-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Report-SM-Delivery-Status-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for S6c (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_s6c_load_defs(conffile);
+ return dict_s6c_load_rules(conffile);
+}
+
+const char* dict_s6c_proto_ver(char * conffile) {
+ return s6c_proto_ver;
+}
+
+const double dict_s6c_gen_ts(char * conffile) {
+ return s6c_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_s6c", dict_s6c_load_defs, dict_s6c_load_rules, "dict_ts29338_avps", "dict_ts29272_avps", "dict_ts29336_avps", "dict_ts29173_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_S6mS6n/CMakeLists.txt b/extensions/dict_S6mS6n/CMakeLists.txt
new file mode 100644
index 0000000..2df2008
--- /dev/null
+++ b/extensions/dict_S6mS6n/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_S6mS6n extension
+PROJECT("dict_S6mS6n library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_S6mS6n dict_S6mS6n.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_S6mS6n
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-S6MS6N)
+
+
+
diff --git a/extensions/dict_S6mS6n/S6mS6n.did b/extensions/dict_S6mS6n/S6mS6n.did
new file mode 100644
index 0000000..07aba84
--- /dev/null
+++ b/extensions/dict_S6mS6n/S6mS6n.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29337_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29173_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc5447_avps
+dict_rfc5778_avps
+dict_rfc5777_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_S6mS6n
diff --git a/extensions/dict_S6mS6n/dict_S6mS6n.c b/extensions/dict_S6mS6n/dict_S6mS6n.c
new file mode 100644
index 0000000..94b38c7
--- /dev/null
+++ b/extensions/dict_S6mS6n/dict_S6mS6n.c
@@ -0,0 +1,250 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in S6mS6n (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697197.86
+
+const char *s6ms6n_proto_ver = PROTO_VER;
+const double s6ms6n_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_s6ms6n_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777310;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777310, "S6mS6n" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777310)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* Subscriber-Information-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388641, /* Code */
+ "Subscriber-Information-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777310, &cmd)
+ }
+ /* Subscriber-Information-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388641, /* Code */
+ "Subscriber-Information-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777310, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_s6ms6n_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Subscriber-Information-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Subscriber-Information-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCS-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Parameters"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIR-Flags"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Subscriber-Information-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Subscriber-Information-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for S6mS6n (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_s6ms6n_load_defs(conffile);
+ return dict_s6ms6n_load_rules(conffile);
+}
+
+const char* dict_s6ms6n_proto_ver(char * conffile) {
+ return s6ms6n_proto_ver;
+}
+
+const double dict_s6ms6n_gen_ts(char * conffile) {
+ return s6ms6n_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_s6ms6n", dict_s6ms6n_load_defs, dict_s6ms6n_load_rules, "dict_ts32299_avps", "dict_ts29336_avps", "dict_ts29272_avps", "dict_ts29338_avps", "dict_ts29368_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_ts29217_avps", "dict_ts29173_avps", "dict_rfc5778_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc5777_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_S6t/CMakeLists.txt b/extensions/dict_S6t/CMakeLists.txt
new file mode 100644
index 0000000..45782e2
--- /dev/null
+++ b/extensions/dict_S6t/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_S6t extension
+PROJECT("dict_S6t library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_S6t dict_S6t.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_S6t
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-S6T)
+
+
+
diff --git a/extensions/dict_S6t/S6t.did b/extensions/dict_S6t/S6t.did
new file mode 100644
index 0000000..c1d6a5b
--- /dev/null
+++ b/extensions/dict_S6t/S6t.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29337_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29173_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc5447_avps
+dict_rfc5778_avps
+dict_rfc5777_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_S6t
diff --git a/extensions/dict_S6t/dict_S6t.c b/extensions/dict_S6t/dict_S6t.c
new file mode 100644
index 0000000..33bce71
--- /dev/null
+++ b/extensions/dict_S6t/dict_S6t.c
@@ -0,0 +1,397 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in S6t (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1508010210.19
+
+const char *s6t_proto_ver = PROTO_VER;
+const double s6t_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_s6t_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777345;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777345, "S6t" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777345)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* Configuration-Information-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388718, /* Code */
+ "Configuration-Information-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777345, &cmd)
+ }
+ /* Configuration-Information-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388718, /* Code */
+ "Configuration-Information-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777345, &cmd)
+ }
+ /* Reporting-Information-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388719, /* Code */
+ "Reporting-Information-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777345, &cmd)
+ }
+ /* Reporting-Information-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388719, /* Code */
+ "Reporting-Information-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777345, &cmd)
+ }
+ /* NIDD-Information-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388726, /* Code */
+ "NIDD-Information-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777345, &cmd)
+ }
+ /* NIDD-Information-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388726, /* Code */
+ "NIDD-Information-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777345, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_s6t_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Configuration-Information-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Configuration-Information-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Configuration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CIR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AESE-Communication-Pattern"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Enhanced-Coverage-Restriction"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Group-Reporting-Guard-Timer"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Configuration-Information-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Configuration-Information-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Config-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AESE-Communication-Pattern-Config-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Services"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "S6t-HSS-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Enhanced-Coverage-Restriction-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CIA-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Reporting-Information-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Reporting-Information-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Group-Monitoring-Event-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RIR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Services"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Reporting-Information-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Reporting-Information-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* NIDD-Information-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "NIDD-Information-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NIDD-Authorization-Request"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NIDD-Authorization-Update"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* NIDD-Information-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "NIDD-Information-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NIDD-Authorization-Response"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for S6t (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_s6t_load_defs(conffile);
+ return dict_s6t_load_rules(conffile);
+}
+
+const char* dict_proto_ver(char * conffile) {
+ return s6t_proto_ver;
+}
+
+const double dict_gen_ts(char * conffile) {
+ return s6t_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_s6t", dict_s6t_load_defs, dict_s6t_load_rules, "dict_ts32299_avps", "dict_ts29336_avps", "dict_ts29272_avps", "dict_ts29338_avps", "dict_ts29368_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_ts29217_avps", "dict_ts29173_avps", "dict_rfc5778_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc5777_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_S9/CMakeLists.txt b/extensions/dict_S9/CMakeLists.txt
new file mode 100644
index 0000000..af524de
--- /dev/null
+++ b/extensions/dict_S9/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_S9 extension
+PROJECT("dict_S9 library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_S9 dict_S9.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_S9
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-S9)
+
+
+
diff --git a/extensions/dict_S9/S9.did b/extensions/dict_S9/S9.did
new file mode 100644
index 0000000..64f69d1
--- /dev/null
+++ b/extensions/dict_S9/S9.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc5778_avps
+dict_ts29338_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_rfc4072_avps
+dict_rfc5447_avps
+dict_ts29273_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc7944_avps
+dict_S9
diff --git a/extensions/dict_S9/dict_S9.c b/extensions/dict_S9/dict_S9.c
new file mode 100644
index 0000000..5a93c8c
--- /dev/null
+++ b/extensions/dict_S9/dict_S9.c
@@ -0,0 +1,471 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in S9 (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697117.57
+
+const char *s9_proto_ver = PROTO_VER;
+const double s9_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_s9_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777267;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777267, "S9" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777267)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "DIAMETER_USER_UNKNOWN", { .u32=5030 }};
+ struct dict_enumval_data t_2 = { "DIAMETER_ERROR_LATE_OVERLAPPING_REQUEST", { .u32=5453 }};
+ struct dict_enumval_data t_3 = { "DIAMETER_ERROR_TIMED_OUT_REQUEST", { .u32=5454 }};
+ struct dict_enumval_data t_4 = { "DIAMETER_ERROR_INITIAL_PARAMETERS", { .u32=5140 }};
+ struct dict_enumval_data t_5 = { "DIAMETER_ERROR_TRIGGER_EVENT", { .u32=5141 }};
+ struct dict_enumval_data t_6 = { "DIAMETER_PCC_RULE_EVENT", { .u32=5142 }};
+ struct dict_enumval_data t_7 = { "DIAMETER_ERROR_BEARER_NOT_AUTHORIZED", { .u32=5143 }};
+ struct dict_enumval_data t_8 = { "DIAMETER_ERROR_TRAFFIC_MAPPING_INFO_REJECTED", { .u32=5144 }};
+ struct dict_enumval_data t_9 = { "DIAMETER_ERROR_CONFLICTING_REQUEST", { .u32=5147 }};
+ struct dict_enumval_data t_10 = { "DIAMETER_ADC_RULE_EVENT", { .u32=5148 }};
+ struct dict_enumval_data t_11 = { "DIAMETER_ERROR_NBIFOM_NOT_AUTHORIZED", { .u32=5149 }};
+ struct dict_enumval_data t_12 = { "DIAMETER_ERROR_SUBSESSION", { .u32=5470 }};
+ struct dict_enumval_data t_13 = { "DIAMETER_ERROR_ONGOING_SESSION_ESTABLISHMENT", { .u32=5471 }};
+ struct dict_enumval_data t_14 = { "DIAMETER_PCC_BEARER_EVENT", { .u32=4141 }};
+ struct dict_enumval_data t_15 = { "DIAMETER_AN_GW_FAILED", { .u32=4143 }};
+ struct dict_enumval_data t_16 = { "DIAMETER_PENDING_TRANSACTION", { .u32=4144 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* Re-Authorization-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 258, /* Code */
+ "Re-Authorization-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777267, &cmd)
+ }
+ /* Re-Authorization-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 258, /* Code */
+ "Re-Authorization-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777267, &cmd)
+ }
+ /* Trigger-Establishment-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388656, /* Code */
+ "Trigger-Establishment-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777267, &cmd)
+ }
+ /* Trigger-Establishment-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388656, /* Code */
+ "Trigger-Establishment-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777267, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_s9_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* CC-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "CC-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "Network-Request-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Operation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subsession-Enforcement-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Termination-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Negotiation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Upgrade"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 5535, .avp_name = "3GPP2-BSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Multiple-BBERF-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* CC-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "CC-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Control-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subsession-Decision-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CSG-Information-Reporting"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Authorization-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Authorization-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Re-Auth-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subsession-Decision-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Release-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "HeNB-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UDP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Authorization-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Authorization-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 5535, .avp_name = "3GPP2-BSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "Subsession-Enforcement-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Trigger-Establishment-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Trigger-Establishment-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "HeNB-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DRA-Binding"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UDP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Trigger-Establishment-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Trigger-Establishment-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DRA-Deployment"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for S9 (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_s9_load_defs(conffile);
+ return dict_s9_load_rules(conffile);
+}
+
+const char* dict_s9_proto_ver(char * conffile) {
+ return s9_proto_ver;
+}
+
+const double dict_s9_gen_ts(char * conffile) {
+ return s9_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_s9", dict_s9_load_defs, dict_s9_load_rules, "dict_ts32299_avps", "dict_ts29212_avps", "dict_ts29215_avps", "dict_ts29273_avps", "dict_ts29214_avps", "dict_ts29272_avps", "dict_ts29229_avps", "dict_ts29061_avps", "dict_rfc4006bis_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7155_avps", "dict_etsi283034_avps", "dict_3gpp2_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_SGd/CMakeLists.txt b/extensions/dict_SGd/CMakeLists.txt
new file mode 100644
index 0000000..3bc5901
--- /dev/null
+++ b/extensions/dict_SGd/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_SGd extension
+PROJECT("dict_SGd library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_SGd dict_SGd.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_SGd
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-SGD)
+
+
+
diff --git a/extensions/dict_SGd/SGd.did b/extensions/dict_SGd/SGd.did
new file mode 100644
index 0000000..3ffdde6
--- /dev/null
+++ b/extensions/dict_SGd/SGd.did
@@ -0,0 +1,39 @@
+dict_S6c
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_rfc7944_avps
+dict_SGd
diff --git a/extensions/dict_SGd/dict_SGd.c b/extensions/dict_SGd/dict_SGd.c
new file mode 100644
index 0000000..77928ad
--- /dev/null
+++ b/extensions/dict_SGd/dict_SGd.c
@@ -0,0 +1,385 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in SGd (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697222.84
+
+const char *sgd_proto_ver = PROTO_VER;
+const double sgd_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_sgd_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777312;
+ struct dict_object * app_id16777313;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777312, "SGd-app16777312" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777312)
+ }
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777313, "SGd" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777313)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "General", { .u32=1 }};
+ struct dict_enumval_data t_2 = { "Permanent_Failures", { .u32=3 }};
+ struct dict_enumval_data t_3 = { "Transient_Failures", { .u32=4 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* MO-Forward-Short-Message-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388645, /* Code */
+ "MO-Forward-Short-Message-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777313, &cmd)
+ }
+ /* MO-Forward-Short-Message-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388645, /* Code */
+ "MO-Forward-Short-Message-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777313, &cmd)
+ }
+ /* MT-Forward-Short-Message-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388646, /* Code */
+ "MT-Forward-Short-Message-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777313, &cmd)
+ }
+ /* MT-Forward-Short-Message-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388646, /* Code */
+ "MT-Forward-Short-Message-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777313, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_sgd_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* MO-Forward-Short-Message-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "MO-Forward-Short-Message-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SC-Address"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "OFR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-RP-UI"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMSMI-Correlation-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Outcome"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* MO-Forward-Short-Message-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "MO-Forward-Short-Message-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* MT-Forward-Short-Message-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "MT-Forward-Short-Message-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMSMI-Correlation-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SC-Address"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-RP-UI"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Number-for-MT-SMS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TFR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Timer"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Start-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-Retransmission-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMS-GMSC-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* MT-Forward-Short-Message-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "MT-Forward-Short-Message-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Absent-User-Diagnostic-SM"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Alert-Service-Centre-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Alert-Service-Centre-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SC-Address"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMSMI-Correlation-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-UE-Availability-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMS-GMSC-Alert-Event"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Alert-Service-Centre-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Alert-Service-Centre-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for SGd (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_sgd_load_defs(conffile);
+ return dict_sgd_load_rules(conffile);
+}
+
+const char* dict_sgd_proto_ver(char * conffile) {
+ return sgd_proto_ver;
+}
+
+const double dict_sgd_gen_ts(char * conffile) {
+ return sgd_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_sgd", dict_sgd_load_defs, dict_sgd_load_rules, "dict_S6c", "dict_ts29338_avps", "dict_ts29272_avps", "dict_ts29336_avps", "dict_ts29173_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_SLh/CMakeLists.txt b/extensions/dict_SLh/CMakeLists.txt
new file mode 100644
index 0000000..a9d18b1
--- /dev/null
+++ b/extensions/dict_SLh/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_SLh extension
+PROJECT("dict_SLh library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_SLh dict_SLh.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_SLh
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-SLH)
+
+
+
diff --git a/extensions/dict_SLh/SLh.did b/extensions/dict_SLh/SLh.did
new file mode 100644
index 0000000..204faff
--- /dev/null
+++ b/extensions/dict_SLh/SLh.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc5778_avps
+dict_ts29338_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_rfc7155_avps
+dict_rfc4072_avps
+dict_rfc4004_avps
+dict_rfc5447_avps
+dict_ts29273_avps
+dict_SLh
diff --git a/extensions/dict_SLh/dict_SLh.c b/extensions/dict_SLh/dict_SLh.c
new file mode 100644
index 0000000..edd54bb
--- /dev/null
+++ b/extensions/dict_SLh/dict_SLh.c
@@ -0,0 +1,250 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in SLh (e00).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e00"
+#define GEN_DATE 1506697215.67
+
+const char *slh_proto_ver = PROTO_VER;
+const double slh_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_slh_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777291;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777291, "SLh" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777291)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* LCS-Routing-Info-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388622, /* Code */
+ "LCS-Routing-Info-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777291, &cmd)
+ }
+ /* LCS-Routing-Info-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388622, /* Code */
+ "LCS-Routing-Info-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777291, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_slh_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* LCS-Routing-Info-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "LCS-Routing-Info-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GMLC-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* LCS-Routing-Info-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "LCS-Routing-Info-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LMSI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Additional-Serving-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GMLC-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PPR-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RIA-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for SLh (e00)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_slh_load_defs(conffile);
+ return dict_slh_load_rules(conffile);
+}
+
+const char* dict_slh_proto_ver(char * conffile) {
+ return slh_proto_ver;
+}
+
+const double dict_slh_gen_ts(char * conffile) {
+ return slh_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_slh", dict_slh_load_defs, dict_slh_load_rules, "dict_ts29272_avps", "dict_ts29173_avps", "dict_ts29273_avps", "dict_ts29329_avps", "dict_ts29229_avps");
+
+
+
diff --git a/extensions/dict_Sd/CMakeLists.txt b/extensions/dict_Sd/CMakeLists.txt
new file mode 100644
index 0000000..3fd2ef0
--- /dev/null
+++ b/extensions/dict_Sd/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_Sd extension
+PROJECT("dict_Sd library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_Sd dict_Sd.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_Sd
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-SD)
+
+
+
diff --git a/extensions/dict_Sd/Sd.did b/extensions/dict_Sd/Sd.did
new file mode 100644
index 0000000..0f6f67d
--- /dev/null
+++ b/extensions/dict_Sd/Sd.did
@@ -0,0 +1,39 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_ts29212_avps
+dict_CreditControl
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_Sd
diff --git a/extensions/dict_Sd/dict_Sd.c b/extensions/dict_Sd/dict_Sd.c
new file mode 100644
index 0000000..c5dd8eb
--- /dev/null
+++ b/extensions/dict_Sd/dict_Sd.c
@@ -0,0 +1,432 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in Sd (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697212.17
+
+const char *sd_proto_ver = PROTO_VER;
+const double sd_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_sd_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777303;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777303, "Sd" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777303)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "PCEF_Initiated_IP_CAN_Session_Modification", { .u32=1 }};
+ struct dict_enumval_data t_2 = { "PCRF_Initiated_IP_CAN_Session_Modification", { .u32=2 }};
+ struct dict_enumval_data t_3 = { "IP_CAN_Session_Termination", { .u32=3 }};
+ struct dict_enumval_data t_4 = { "IP_CAN_Session_Modification", { .u32=4 }};
+ struct dict_enumval_data t_5 = { "ADC_rule", { .u32=5 }};
+ struct dict_enumval_data t_6 = { "Subscriber_Identifier", { .u32=6 }};
+ struct dict_enumval_data t_7 = { "Default_QoS_control", { .u32=7 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* TS-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388637, /* Code */
+ "TS-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777303, &cmd)
+ }
+ /* TS-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388637, /* Code */
+ "TS-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777303, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_sd_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* TS-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "TS-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-Trusted"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-GGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-GGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Selection-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Dynamic-Address-Flag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Dynamic-Address-Flag-Extension"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Connection-Charging-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Fixed-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Online"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Offline"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Revalidation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CSG-Information-Reporting"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Logical-Access-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Physical-Access-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 5535, .avp_name = "3GPP2-BSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* TS-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "TS-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Credit-Control-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Credit-Management-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Detection-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Credit-Control-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Request-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Revalidation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Re-Auth-Request-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Release-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Revalidation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Re-Auth-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for Sd (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_sd_load_defs(conffile);
+ return dict_sd_load_rules(conffile);
+}
+
+const char* dict_sd_proto_ver(char * conffile) {
+ return sd_proto_ver;
+}
+
+const double dict_sd_gen_ts(char * conffile) {
+ return sd_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_sd", dict_sd_load_defs, dict_sd_load_rules, "dict_ts32299_avps", "dict_ts29212_avps", "dict_ts29273_avps", "dict_ts29214_avps", "dict_ts29272_avps", "dict_ts29229_avps", "dict_ts29061_avps", "dict_CreditControl", "dict_rfc4006bis_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7155_avps", "dict_etsi283034_avps", "dict_3gpp2_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_Sh/CMakeLists.txt b/extensions/dict_Sh/CMakeLists.txt
new file mode 100644
index 0000000..765e6cb
--- /dev/null
+++ b/extensions/dict_Sh/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_Sh extension
+PROJECT("dict_Sh library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_Sh dict_Sh.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_Sh
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-SH)
+
+
+
diff --git a/extensions/dict_Sh/Sh.did b/extensions/dict_Sh/Sh.did
new file mode 100644
index 0000000..0e2b2ac
--- /dev/null
+++ b/extensions/dict_Sh/Sh.did
@@ -0,0 +1,10 @@
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_ts29329_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_Sh
diff --git a/extensions/dict_Sh/dict_Sh.c b/extensions/dict_Sh/dict_Sh.c
new file mode 100644
index 0000000..287de2b
--- /dev/null
+++ b/extensions/dict_Sh/dict_Sh.c
@@ -0,0 +1,516 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in Sh (e20).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e20"
+#define GEN_DATE 1506697212.31
+
+const char *sh_proto_ver = PROTO_VER;
+const double sh_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_sh_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777217;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777217, "Sh" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777217)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "used_in_Sh", { .u32=1 }};
+ struct dict_enumval_data t_2 = { "Command_Code_values", { .u32=3 }};
+ struct dict_enumval_data t_3 = { "Application_ID_value", { .u32=4 }};
+ struct dict_enumval_data t_4 = { "Special_Requirements", { .u32=7 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* User-Data-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 306, /* Code */
+ "User-Data-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777217, &cmd)
+ }
+ /* User-Data-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 306, /* Code */
+ "User-Data-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777217, &cmd)
+ }
+ /* Profile-Update-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 307, /* Code */
+ "Profile-Update-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777217, &cmd)
+ }
+ /* Profile-Update-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 307, /* Code */
+ "Profile-Update-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777217, &cmd)
+ }
+ /* Subscribe-Notifications-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 308, /* Code */
+ "Subscribe-Notifications-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777217, &cmd)
+ }
+ /* Subscribe-Notifications-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 308, /* Code */
+ "Subscribe-Notifications-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777217, &cmd)
+ }
+ /* Push-Notification-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 309, /* Code */
+ "Push-Notification-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777217, &cmd)
+ }
+ /* Push-Notification-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 309, /* Code */
+ "Push-Notification-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777217, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_sh_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* User-Data-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "User-Data-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-IMPU"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Data-Reference"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Identity-Set"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requested-Domain"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Current-Location"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DSAI-Tag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requested-Nodes"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-Node-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Pre-paging-Supported"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Local-Time-Zone-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UDR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Call-Reference-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* User-Data-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "User-Data-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-IMPU"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Profile-Update-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Profile-Update-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-IMPU"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Data-Reference"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Data"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Profile-Update-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Profile-Update-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-IMPU"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Repository-Data-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Data-Reference"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Subscribe-Notifications-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Subscribe-Notifications-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-IMPU"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Send-Data-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subs-Req-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Data-Reference"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Identity-Set"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Expiry-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DSAI-Tag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "One-Time-Notification"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Subscribe-Notifications-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Subscribe-Notifications-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-IMPU"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Expiry-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Push-Notification-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Push-Notification-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Wildcarded-IMPU"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Data"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Push-Notification-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Push-Notification-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for Sh (e20)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_sh_load_defs(conffile);
+ return dict_sh_load_rules(conffile);
+}
+
+const char* dict_sh_proto_ver(char * conffile) {
+ return sh_proto_ver;
+}
+
+const double dict_sh_gen_ts(char * conffile) {
+ return sh_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_sh", dict_sh_load_defs, dict_sh_load_rules, "dict_ts29329_avps", "dict_ts29229_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_T4/CMakeLists.txt b/extensions/dict_T4/CMakeLists.txt
new file mode 100644
index 0000000..813b8bf
--- /dev/null
+++ b/extensions/dict_T4/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_T4 extension
+PROJECT("dict_T4 library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_T4 dict_T4.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_T4
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-dict_T4)
+
+
+
diff --git a/extensions/dict_T4/T4.did b/extensions/dict_T4/T4.did
new file mode 100644
index 0000000..2ad7fcb
--- /dev/null
+++ b/extensions/dict_T4/T4.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29337_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29173_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc5447_avps
+dict_rfc5778_avps
+dict_rfc5777_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_T4
diff --git a/extensions/dict_T4/dict_T4.c b/extensions/dict_T4/dict_T4.c
new file mode 100644
index 0000000..e02df57
--- /dev/null
+++ b/extensions/dict_T4/dict_T4.c
@@ -0,0 +1,338 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in T4 (e00).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e00"
+#define GEN_DATE 1506697219.31
+
+const char *t4_proto_ver = PROTO_VER;
+const double t4_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_t4_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777311;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777311, "T4" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777311)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "General", { .u32=1 }};
+ struct dict_enumval_data t_2 = { "SMS_SC_and_MTC_IWF_behaviour", { .u32=2 }};
+ struct dict_enumval_data t_3 = { "Permanent_Failures", { .u32=3 }};
+ struct dict_enumval_data t_4 = { "Void", { .u32=4 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* Device-Trigger-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388643, /* Code */
+ "Device-Trigger-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777311, &cmd)
+ }
+ /* Device-Trigger-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388643, /* Code */
+ "Device-Trigger-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777311, &cmd)
+ }
+ /* Delivery-Report-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388644, /* Code */
+ "Delivery-Report-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777311, &cmd)
+ }
+ /* Delivery-Report-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388644, /* Code */
+ "Delivery-Report-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777311, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_t4_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Device-Trigger-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Device-Trigger-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-RP-SMEA"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Payload"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Additional-Serving-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reference-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Validity-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Priority-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Port-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Old-Reference-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trigger-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Device-Trigger-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Device-Trigger-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MTC-Error-Diagnostic"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Old-Reference-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trigger-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Delivery-Report-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Delivery-Report-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-RP-SMEA"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Outcome-T4"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Absent-Subscriber-Diagnostic-T4"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reference-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Delivery-Report-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Delivery-Report-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for T4 (e00)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_t4_load_defs(conffile);
+ return dict_t4_load_rules(conffile);
+}
+
+const char* dict_t4_proto_ver(char * conffile) {
+ return t4_proto_ver;
+}
+
+const double dict_t4_gen_ts(char * conffile) {
+ return t4_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_t4", dict_t4_load_defs, dict_t4_load_rules, "dict_ts29337_avps", "dict_ts29336_avps", "dict_ts29338_avps", "dict_ts29272_avps", "dict_ts29368_avps", "dict_ts29173_avps", "dict_ts29229_avps", "dict_ts29329_avps", "dict_rfc4006bis_avps", "dict_rfc7155_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_T6aT6bT7/CMakeLists.txt b/extensions/dict_T6aT6bT7/CMakeLists.txt
new file mode 100644
index 0000000..eb55e44
--- /dev/null
+++ b/extensions/dict_T6aT6bT7/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_T6aT6bT7 extension
+PROJECT("dict_T6aT6bT7 library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_T6aT6bT7 dict_T6aT6bT7.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_T6aT6bT7
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-T6AT6BT7)
+
+
+
diff --git a/extensions/dict_T6aT6bT7/T6aT6bT7.did b/extensions/dict_T6aT6bT7/T6aT6bT7.did
new file mode 100644
index 0000000..ca39ad5
--- /dev/null
+++ b/extensions/dict_T6aT6bT7/T6aT6bT7.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29212_avps
+dict_T6aT6bT7
diff --git a/extensions/dict_T6aT6bT7/dict_T6aT6bT7.c b/extensions/dict_T6aT6bT7/dict_T6aT6bT7.c
new file mode 100644
index 0000000..e137a4a
--- /dev/null
+++ b/extensions/dict_T6aT6bT7/dict_T6aT6bT7.c
@@ -0,0 +1,485 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in T6aT6bT7 (e20).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e20"
+#define GEN_DATE 1506697230.23
+
+const char *t6at6bt7_proto_ver = PROTO_VER;
+const double t6at6bt7_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_t6at6bt7_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777346;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777346, "T6aT6bT7" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777346)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* Connection-Management-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388732, /* Code */
+ "Connection-Management-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777346, &cmd)
+ }
+ /* Connection-Management-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388732, /* Code */
+ "Connection-Management-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777346, &cmd)
+ }
+ /* MO-Data-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388733, /* Code */
+ "MO-Data-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777346, &cmd)
+ }
+ /* MO-Data-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388733, /* Code */
+ "MO-Data-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777346, &cmd)
+ }
+ /* MT-Data-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388734, /* Code */
+ "MT-Data-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777346, &cmd)
+ }
+ /* MT-Data-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388734, /* Code */
+ "MT-Data-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777346, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_t6at6bt7_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Configuration-Information-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Configuration-Information-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Configuration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Configuration-Information-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Configuration-Information-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Config-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Reporting-Information-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Reporting-Information-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Report"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Reporting-Information-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Reporting-Information-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Connection-Management-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Connection-Management-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Identifier"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CMR-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-UE-Availability-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Connection-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Selection"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-PLMN-Rate-Control"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Extended-PCO"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Terminal-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Connection-Management-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Connection-Management-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Connection-Charging-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Extended-PCO"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* MO-Data-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "MO-Data-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Identifier"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Non-IP-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RRC-Cause-Counter"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* MO-Data-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "MO-Data-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* MT-Data-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "MT-Data-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Identifier"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Non-IP-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Wait-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-Retransmission-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* MT-Data-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "MT-Data-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "DRMP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-OLR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requested-Retransmission-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for T6aT6bT7 (e20)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_t6at6bt7_load_defs(conffile);
+ return dict_t6at6bt7_load_rules(conffile);
+}
+
+const char* dict_t6at6bt7_proto_ver(char * conffile) {
+ return t6at6bt7_proto_ver;
+}
+
+const double dict_t6at6bt7_gen_ts(char * conffile) {
+ return t6at6bt7_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_t6at6bt7", dict_t6at6bt7_load_defs, dict_t6at6bt7_load_rules, "dict_ts32299_avps", "dict_ts29272_avps", "dict_ts29128_avps", "dict_S6t", "dict_ts29336_avps", "dict_ts29212_avps", "dict_ts29217_avps", "dict_ts29338_avps", "dict_ts29229_avps", "dict_ts29061_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc5778_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_Tsp/CMakeLists.txt b/extensions/dict_Tsp/CMakeLists.txt
new file mode 100644
index 0000000..44eda5b
--- /dev/null
+++ b/extensions/dict_Tsp/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_Tsp extension
+PROJECT("dict_Tsp library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_Tsp dict_Tsp.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_Tsp
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TSP)
+
+
+
diff --git a/extensions/dict_Tsp/Tsp.did b/extensions/dict_Tsp/Tsp.did
new file mode 100644
index 0000000..75b325f
--- /dev/null
+++ b/extensions/dict_Tsp/Tsp.did
@@ -0,0 +1,38 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29337_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29173_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc5447_avps
+dict_rfc5778_avps
+dict_rfc5777_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_Tsp
diff --git a/extensions/dict_Tsp/dict_Tsp.c b/extensions/dict_Tsp/dict_Tsp.c
new file mode 100644
index 0000000..d1eed0f
--- /dev/null
+++ b/extensions/dict_Tsp/dict_Tsp.c
@@ -0,0 +1,334 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in Tsp (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697226.2
+
+const char *tsp_proto_ver = PROTO_VER;
+const double tsp_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_tsp_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ struct dict_object * app_id16777309;
+
+ /* Application Section */
+ {
+ {
+ struct dict_object * vendor;
+ CHECK_dict_search(DICT_VENDOR, VENDOR_BY_NAME, "3GPP", &vendor)
+ struct dict_application_data data = { 16777309, "Tsp" };
+ CHECK_dict_new( DICT_APPLICATION, &data, vendor, &app_id16777309)
+ }
+ /* Result codes */
+ {
+ struct dict_object *type;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)",&type);
+ struct dict_enumval_data t_1 = { "General", { .u32=1 }};
+ struct dict_enumval_data t_2 = { "SCS_behaviour", { .u32=2 }};
+ struct dict_enumval_data t_3 = { "MTC_IWF_behaviour", { .u32=3 }};
+ struct dict_enumval_data t_4 = { "Replace_Failure", { .u32=4 }};
+ struct dict_enumval_data t_5 = { "Delivery_of_a_MSISDN_less_MO_SMS", { .u32=9 }};
+
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ }
+
+ /* Commands section */
+ {
+ /* Device-Action-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388639, /* Code */
+ "Device-Action-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777309, &cmd)
+ }
+ /* Device-Action-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388639, /* Code */
+ "Device-Action-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777309, &cmd)
+ }
+ /* Device-Notification-Request */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388640, /* Code */
+ "Device-Notification-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777309, &cmd)
+ }
+ /* Device-Notification-Answer */
+ {
+ struct dict_object* cmd;
+ struct dict_cmd_data data = {
+ 8388640, /* Code */
+ "Device-Notification-Answer", /* Name */
+ CMD_FLAG_REQUEST, /* Fixed flags */
+ CMD_FLAG_PROXIABLE, /* Fixed flag values */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , app_id16777309, &cmd)
+ }
+
+ }
+
+ return 0;
+}
+
+static int dict_tsp_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+ /* Device-Action-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Device-Action-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Device-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Device-Action-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Device-Action-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Device-Notification"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Supported-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Feature-Supported-In-Final-Target"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Device-Notification-Request */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Device-Notification-Request", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Destination-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Device-Notification"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Route-Record"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+ /* Device-Notification-Answer */
+ {
+ struct dict_object* cmd;
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Device-Notification-Answer", &cmd)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Session-Id"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Auth-Session-State"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-State-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Message"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Error-Reporting-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Host-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Max-Cache-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Failed-AVP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Proxy-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules(rules, cmd);
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for Tsp (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_tsp_load_defs(conffile);
+ return dict_tsp_load_rules(conffile);
+}
+
+const char* dict_tsp_proto_ver(char * conffile) {
+ return tsp_proto_ver;
+}
+
+const double dict_tsp_gen_ts(char * conffile) {
+ return tsp_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_tsp", dict_tsp_load_defs, dict_tsp_load_rules, "dict_ts29368_avps", "dict_ts29337_avps", "dict_ts29336_avps", "dict_ts29338_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_draftload_avps", "dict_rfc4006bis_avps");
+
+
+
diff --git a/extensions/dict_dcca/CMakeLists.txt b/extensions/dict_dcca/CMakeLists.txt
new file mode 100644
index 0000000..62ab6b9
--- /dev/null
+++ b/extensions/dict_dcca/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The dict_dcca extension
+PROJECT("Diameter DCCA (Diameter Credit Control Application ) dictionary definitions" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_dcca dict_dcca.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_dcca
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-rfc4006)
diff --git a/extensions/dict_dcca/dict_dcca.c b/extensions/dict_dcca/dict_dcca.c
new file mode 100644
index 0000000..5d94603
--- /dev/null
+++ b/extensions/dict_dcca/dict_dcca.c
@@ -0,0 +1,1487 @@
+/****************
+ Contributed by: Konstantin Chekushin <koch@lmt.lv> and Thomas Klausner <tk@giga.or.at>
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in DCCA (rfc4006).
+ */
+#include <freeDiameter/extension.h>
+
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+ CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ char *avp_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME, \
+ (_rulearray)[__ar].avp_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
+ return ENOENT; \
+ } \
+ CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
+ { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_name ); \
+ return EINVAL; \
+ } ); \
+ } \
+ }
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_dcca_entry(char * conffile)
+{
+ struct dict_object * dcca;
+ TRACE_ENTRY("%p", conffile);
+
+ /* Applications section */
+ {
+ /* DCCA */
+ {
+ struct dict_application_data data = { 4, "Diameter Credit Control Application" };
+ CHECK_dict_new( DICT_APPLICATION, &data, NULL, &dcca);
+ }
+ }
+
+ /* Result codes */
+ {
+ struct dict_object *ResultCodeType;
+ CHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "Enumerated(Result-Code)", &ResultCodeType);
+
+ {
+ struct dict_enumval_data error_code = {"END_USER_SERVICE_DENIED",
+ { .u32 = 4010}};
+ CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL);
+ }
+ {
+ struct dict_enumval_data error_code = {"CREDIT_CONTROL_NOT_APPLICABLE",
+ { .u32 = 4011}};
+ CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL);
+ }
+ {
+ struct dict_enumval_data error_code = {"CREDIT_LIMIT_REACHED",
+ { .u32 = 4012}};
+ CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL);
+ }
+ {
+ struct dict_enumval_data error_code = {"USER_UNKNOWN",
+ { .u32 = 5030}};
+ CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL);
+ }
+ {
+ struct dict_enumval_data error_code = {"RATING_FAILED",
+ { .u32 = 5031}};
+ CHECK_dict_new(DICT_ENUMVAL, &error_code, ResultCodeType, NULL);
+ }
+
+ }
+
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+
+
+ /* CC-Correlation-Id */
+ {
+ /*
+ OctetString.
+ */
+ struct dict_avp_data data = {
+ 411, /* Code */
+ 0, /* Vendor */
+ "CC-Correlation-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* CC-Input-Octets */
+ {
+ /*
+ Unsigned64.
+ */
+ struct dict_avp_data data = {
+ 412, /* Code */
+ 0, /* Vendor */
+ "CC-Input-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* CC-Output-Octets */
+ {
+ /*
+ Unsigned64.
+ */
+ struct dict_avp_data data = {
+ 414, /* Code */
+ 0, /* Vendor */
+ "CC-Output-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* CC-Request-Number */
+ {
+ /*
+ Unsigned32.
+ */
+ struct dict_avp_data data = {
+ 415, /* Code */
+ 0, /* Vendor */
+ "CC-Request-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* CC-Request-Type */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CC-Request-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "INITIAL_REQUEST", { .i32 = 1 }};
+ struct dict_enumval_data t_2 = { "UPDATE_REQUEST", { .i32 = 2 }};
+ struct dict_enumval_data t_3 = { "TERMINATION_REQUEST", { .i32 = 3 }};
+ struct dict_enumval_data t_4 = { "EVENT_REQUEST", { .i32 = 4 }};
+
+
+ struct dict_avp_data data = {
+ 416, /* Code */
+ 0, /* Vendor */
+ "CC-Request-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+
+ /* CC-Service-Specific-Units */
+ {
+ /*
+ Unsigned64.
+ */
+ struct dict_avp_data data = {
+ 417, /* Code */
+ 0, /* Vendor */
+ "CC-Service-Specific-Units", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* CC-Session-Failover */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CC-Session-Failover)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "FAILOVER_NOT_SUPPORTED", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "FAILOVER_SUPPORTED", { .i32 = 1 }};
+
+
+ struct dict_avp_data data = {
+ 418, /* Code */
+ 0, /* Vendor */
+ "CC-Session-Failover", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* CC-Sub-Session-Id */
+ {
+ /*
+ Unsigned64.
+ */
+ struct dict_avp_data data = {
+ 419, /* Code */
+ 0, /* Vendor */
+ "CC-Sub-Session-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* CC-Time */
+ {
+ /*
+ Unsigned32.
+ */
+ struct dict_avp_data data = {
+ 420, /* Code */
+ 0, /* Vendor */
+ "CC-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* CC-Total-Octets */
+ {
+ /*
+ Unsigned64.
+ */
+ struct dict_avp_data data = {
+ 421, /* Code */
+ 0, /* Vendor */
+ "CC-Total-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* CC-Unit-Type */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CC-Unit-Type)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TIME", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "MONEY", { .i32 = 1 }};
+ struct dict_enumval_data t_3 = { "TOTAL-OCTETS", { .i32 = 2 }};
+ struct dict_enumval_data t_4 = { "INPUT-OCTETS", { .i32 = 3 }};
+ struct dict_enumval_data t_5 = { "OUTPUT-OCTETS", { .i32 = 4 }};
+ struct dict_enumval_data t_6 = { "SERVICE-SPECIFIC-UNITS", { .i32 = 5 }};
+
+
+ struct dict_avp_data data = {
+ 454, /* Code */
+ 0, /* Vendor */
+ "CC-Unit-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Check-Balance-Result */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Check-Balance-Result)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ENOUGH_CREDIT", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "NO_CREDIT", { .i32 = 1 }};
+
+
+ struct dict_avp_data data = {
+ 422, /* Code */
+ 0, /* Vendor */
+ "Check-Balance-Result", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Cost-Unit */
+ {
+ /*
+ UTF8String.
+ */
+ struct dict_avp_data data = {
+ 424, /* Code */
+ 0, /* Vendor */
+ "Cost-Unit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Credit-Control */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Credit-Control)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CREDIT_AUTHORIZATION", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "RE_AUTHORIZATION", { .i32 = 1 }};
+
+ struct dict_avp_data data = {
+ 426, /* Code */
+ 0, /* Vendor */
+ "Credit-Control", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Credit-Control-Failure-Handling */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Credit-Control-Failure-Handling)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TERMINATE", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "CONTINUE", { .i32 = 1 }};
+ struct dict_enumval_data t_3 = { "RETRY_AND_TERMINATE", { .i32 = 2 }};
+
+ struct dict_avp_data data = {
+ 427, /* Code */
+ 0, /* Vendor */
+ "Credit-Control-Failure-Handling", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Currency-Code */
+ {
+ /*
+ Unsigned32.
+ */
+ struct dict_avp_data data = {
+ 425, /* Code */
+ 0, /* Vendor */
+ "Currency-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Direct-Debiting-Failure-Handling */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Direct-Debiting-Failure-Handling)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TERMINATE_OR_BUFFER", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "CONTINUE", { .i32 = 1 }};
+
+ struct dict_avp_data data = {
+ 428, /* Code */
+ 0, /* Vendor */
+ "Direct-Debiting-Failure-Handling", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Exponent */
+ {
+ /*
+ Integer32.
+ */
+ struct dict_avp_data data = {
+ 429, /* Code */
+ 0, /* Vendor */
+ "Exponent", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Final-Unit-Action */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Final-Unit-Action)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TERMINATE", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "REDIRECT", { .i32 = 1 }};
+ struct dict_enumval_data t_3 = { "RESTRICT_ACCESS", { .i32 = 2 }};
+
+ struct dict_avp_data data = {
+ 449, /* Code */
+ 0, /* Vendor */
+ "Final-Unit-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* G-S-U-Pool-Identifier */
+ {
+ /*
+ Unsigned32.
+ */
+ struct dict_avp_data data = {
+ 453, /* Code */
+ 0, /* Vendor */
+ "G-S-U-Pool-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Multiple-Services-Indicator */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Multiple-Services-Indicator)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MULTIPLE_SERVICES_NOT_SUPPORTED", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "MULTIPLE_SERVICES_SUPPORTED", { .i32 = 1 }};
+
+ struct dict_avp_data data = {
+ 455, /* Code */
+ 0, /* Vendor */
+ "Multiple-Services-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Rating-Group */
+ {
+ /*
+ Unsigned32.
+ */
+ struct dict_avp_data data = {
+ 432, /* Code */
+ 0, /* Vendor */
+ "Rating-Group", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Redirect-Address-Type */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Redirect-Address-Type)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "IPV4_ADDRESS", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "IPV6_ADDRESS", { .i32 = 1 }};
+ struct dict_enumval_data t_3 = { "URL", { .i32 = 2 }};
+ struct dict_enumval_data t_4 = { "SIP_URI", { .i32 = 3 }};
+
+ struct dict_avp_data data = {
+ 433, /* Code */
+ 0, /* Vendor */
+ "Redirect-Address-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Redirect-Server-Address */
+ {
+ /*
+ UTF8String.
+ */
+ struct dict_avp_data data = {
+ 435, /* Code */
+ 0, /* Vendor */
+ "Redirect-Server-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Requested-Action */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Requested-Action)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DIRECT_DEBITING", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "REFUND_ACCOUNT", { .i32 = 1 }};
+ struct dict_enumval_data t_3 = { "CHECK_BALANCE", { .i32 = 2 }};
+ struct dict_enumval_data t_4 = { "PRICE_ENQUIRY", { .i32 = 3 }};
+
+ struct dict_avp_data data = {
+ 436, /* Code */
+ 0, /* Vendor */
+ "Requested-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Restriction-Filter-Rule */
+ {
+ /*
+ IPFiltrRule.
+ */
+ struct dict_avp_data data = {
+ 438, /* Code */
+ 0, /* Vendor */
+ "Restriction-Filter-Rule", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , IPFilterRule_type, NULL);
+ }
+ /*Service-Context-Id */
+ {
+ /*
+ UTF8String.
+ */
+ struct dict_avp_data data = {
+ 461, /* Code */
+ 0, /* Vendor */
+ "Service-Context-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Service-Identifier */
+ {
+ /*
+ Unsigned32.
+ */
+ struct dict_avp_data data = {
+ 439, /* Code */
+ 0, /* Vendor */
+ "Service-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Service-Parameter-Type */
+ {
+ /*
+ Unsigned32.
+ */
+ struct dict_avp_data data = {
+ 441, /* Code */
+ 0, /* Vendor */
+ "Service-Parameter-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Service-Parameter-Value */
+ {
+ /*
+ OctetString.
+ */
+ struct dict_avp_data data = {
+ 442, /* Code */
+ 0, /* Vendor */
+ "Service-Parameter-Value", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Subscription-Id-Data */
+ {
+ /*
+ UTF8String.
+ */
+ struct dict_avp_data data = {
+ 444, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Subscription-Id-Type */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Subscription-Id-Type)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "END_USER_E164", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "END_USER_IMSI", { .i32 = 1 }};
+ struct dict_enumval_data t_3 = { "END_USER_SIP_URI", { .i32 = 2 }};
+ struct dict_enumval_data t_4 = { "END_USER_NAI", { .i32 = 3 }};
+
+ struct dict_avp_data data = {
+ 450, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Tariff-Change-Usage */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Tariff-Change-Usage)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UNIT_BEFORE_TARIFF_CHANGE", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "UNIT_AFTER_TARIFF_CHANGE", { .i32 = 1 }};
+ struct dict_enumval_data t_3 = { "UNIT_INDETERMINATE", { .i32 = 2 }};
+
+ struct dict_avp_data data = {
+ 452, /* Code */
+ 0, /* Vendor */
+ "Tariff-Change-Usage", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Tariff-Time-Change */
+ {
+ /*
+ Time.
+ */
+ struct dict_avp_data data = {
+ 451, /* Code */
+ 0, /* Vendor */
+ "Tariff-Time-Change", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , Time_type, NULL);
+ }
+
+ /* User-Equipment-Info-Type */
+ {
+ /*
+ Enumerated.
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(User-Equipment-Info-Type)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "IMEISV", { .i32 = 0 }};
+ struct dict_enumval_data t_2 = { "MAC", { .i32 = 1 }};
+ struct dict_enumval_data t_3 = { "EUI64", { .i32 = 2 }};
+
+ struct dict_avp_data data = {
+ 459, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* User-Equipment-Info-Value */
+ {
+ /*
+ OctetString.
+ */
+ struct dict_avp_data data = {
+ 460, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-Value", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Value-Digits */
+ {
+ /*
+ Integer64.
+ */
+ struct dict_avp_data data = {
+ 447, /* Code */
+ 0, /* Vendor */
+ "Value-Digits", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Validity-Time */
+ {
+ /*
+ Unsigned32.
+ */
+ struct dict_avp_data data = {
+ 448, /* Code */
+ 0, /* Vendor */
+ "Validity-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+
+ /* Grouped AVPs below since they have dependencies on types above */
+
+ /* Redirect-Server */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 434, /* Code */
+ 0, /* Vendor */
+ "Redirect-Server", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Redirect-Address-Type", RULE_REQUIRED, -1, 1 },
+ { "Redirect-Server-Address", RULE_REQUIRED, -1, 1 }
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* Service-Parameter-Info */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 440, /* Code */
+ 0, /* Vendor */
+ "Service-Parameter-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Service-Parameter-Type", RULE_REQUIRED, -1, 1 },
+ { "Service-Parameter-Value", RULE_REQUIRED, -1, 1 }
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* Subscription-Id */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 443, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Subscription-Id-Type", RULE_REQUIRED, -1, 1 },
+ { "Subscription-Id-Data", RULE_REQUIRED, -1, 1 }
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* Unit-Value */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 445, /* Code */
+ 0, /* Vendor */
+ "Unit-Value", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Value-Digits", RULE_REQUIRED, -1, 1 },
+ { "Exponent", RULE_OPTIONAL, -1, 1 }
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* User-Equipment-Info */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 458, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "User-Equipment-Info-Type", RULE_REQUIRED, -1, 1 },
+ { "User-Equipment-Info-Value", RULE_REQUIRED, -1, 1 }
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* grouped AVPs using grouped AVPs */
+
+ /* CC-Money */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 413, /* Code */
+ 0, /* Vendor */
+ "CC-Money", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Unit-Value", RULE_REQUIRED, -1, 1 },
+ { "Currency-Code", RULE_OPTIONAL, -1, 1 }
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* Cost-Information */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 423, /* Code */
+ 0, /* Vendor */
+ "Cost-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Unit-Value", RULE_REQUIRED, -1, 1 },
+ { "Currency-Code", RULE_REQUIRED, -1, 1 },
+ { "Cost-Unit", RULE_OPTIONAL, -1, 1 }
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* Final-Unit-Indication */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 430, /* Code */
+ 0, /* Vendor */
+ "Final-Unit-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Final-Unit-Action", RULE_REQUIRED, -1, 1 },
+ { "Restriction-Filter-Rule", RULE_OPTIONAL, -1, -1 },
+ { "Filter-Id", RULE_OPTIONAL, -1, -1 },
+ { "Redirect-Server", RULE_OPTIONAL, -1, 1 },
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* Granted-Service-Unit */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 431, /* Code */
+ 0, /* Vendor */
+ "Granted-Service-Unit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Tariff-Time-Change", RULE_OPTIONAL, -1, 1 },
+ { "CC-Time", RULE_OPTIONAL, -1, 1 },
+ { "CC-Money", RULE_OPTIONAL, -1, 1 },
+ { "CC-Total-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Input-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Output-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Service-Specific-Units", RULE_OPTIONAL, -1, 1 }
+ /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* G-S-U-Pool-Reference */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 457, /* Code */
+ 0, /* Vendor */
+ "G-S-U-Pool-Reference", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "G-S-U-Pool-Identifier", RULE_REQUIRED, -1, 1 },
+ { "CC-Unit-Type", RULE_REQUIRED, -1, 1 },
+ { "Unit-Value", RULE_REQUIRED, -1, 1 }
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* Requested-Service-Unit */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 437, /* Code */
+ 0, /* Vendor */
+ "Requested-Service-Unit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "CC-Time", RULE_OPTIONAL, -1, 1 },
+ { "CC-Money", RULE_OPTIONAL, -1, 1 },
+ { "CC-Total-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Input-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Output-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Service-Specific-Units", RULE_OPTIONAL, -1, 1 }
+ /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* Used-Service-Unit */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 446, /* Code */
+ 0, /* Vendor */
+ "Used-Service-Unit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Tariff-Change-Usage", RULE_OPTIONAL, -1, 1 },
+ { "CC-Time", RULE_OPTIONAL, -1, 1 },
+ { "CC-Money", RULE_OPTIONAL, -1, 1 },
+ { "CC-Total-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Input-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Output-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Service-Specific-Units", RULE_OPTIONAL, -1, 1 }
+ /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* at least three levels of grouping */
+ /* Multiple-Services-Credit-Control */
+ {
+ /*
+ Grouped
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 456, /* Code */
+ 0, /* Vendor */
+ "Multiple-Services-Credit-Control", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] = {
+ { "Granted-Service-Unit", RULE_OPTIONAL, -1, 1 },
+ { "Requested-Service-Unit", RULE_OPTIONAL, -1, 1 },
+ { "Used-Service-Unit", RULE_OPTIONAL, -1, -1 },
+ { "Tariff-Change-Usage", RULE_OPTIONAL, -1, 1 },
+ { "Service-Identifier", RULE_OPTIONAL, -1, -1 },
+ { "Rating-Group", RULE_OPTIONAL, -1, 1 },
+ { "G-S-U-Pool-Reference", RULE_OPTIONAL, -1, -1 },
+ { "Validity-Time", RULE_OPTIONAL, -1, 1 },
+ { "Result-Code", RULE_OPTIONAL, -1, 1 },
+ { "Final-Unit-Indication", RULE_OPTIONAL, -1, 1 }
+ /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+
+ }
+
+
+ /* Commands section */
+ {
+ /* Credit-Control-Request (CCR) Command */
+ {
+ /*
+ From RFC 4006:
+
+ 3.1. Credit-Control-Request (CCR) Command
+
+ The Credit-Control-Request message (CCR) is indicated by the
+ command-code field being set to 272 and the 'R' bit being set in the
+ Command Flags field. It is used between the Diameter credit-control
+ client and the credit-control server to request credit authorization
+ for a given service.
+
+ The Auth-Application-Id MUST be set to the value 4, indicating the
+ Diameter credit-control application.
+
+ Message Format
+
+ <Credit-Control-Request> ::= < Diameter Header: 272, REQ, PXY >
+ < Session-Id >
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { Auth-Application-Id }
+ { Service-Context-Id }
+ { CC-Request-Type }
+ { CC-Request-Number }
+ [ Destination-Host ]
+ [ User-Name ]
+ [ CC-Sub-Session-Id ]
+ [ Acct-Multi-Session-Id ]
+ [ Origin-State-Id ]
+ [ Event-Timestamp ]
+ *[ Subscription-Id ]
+ [ Service-Identifier ]
+ [ Termination-Cause ]
+ [ Requested-Service-Unit ]
+ [ Requested-Action ]
+ *[ Used-Service-Unit ]
+ [ Multiple-Services-Indicator ]
+ *[ Multiple-Services-Credit-Control ]
+ *[ Service-Parameter-Info ]
+ [ CC-Correlation-Id ]
+ [ User-Equipment-Info ]
+ *[ Proxy-Info ]
+ *[ Route-Record ]
+ *[ AVP ]
+
+ 10.1. Credit-Control AVP Table
+
+ The table in this section is used to represent which credit-control
+ applications specific AVPs defined in this document are to be present
+ in the credit-control messages.
+
+ +-----------+
+ | Command |
+ | Code |
+ |-----+-----+
+ Attribute Name | CCR | CCA |
+ ------------------------------|-----+-----+
+ Acct-Multi-Session-Id | 0-1 | 0-1 |
+ Auth-Application-Id | 1 | 1 |
+ CC-Correlation-Id | 0-1 | 0 |
+ CC-Session-Failover | 0 | 0-1 |
+ CC-Request-Number | 1 | 1 |
+ CC-Request-Type | 1 | 1 |
+ CC-Sub-Session-Id | 0-1 | 0-1 |
+ Check-Balance-Result | 0 | 0-1 |
+ Cost-Information | 0 | 0-1 |
+ Credit-Control-Failure- | 0 | 0-1 |
+ Handling | | |
+ Destination-Host | 0-1 | 0 |
+ Destination-Realm | 1 | 0 |
+ Direct-Debiting-Failure- | 0 | 0-1 |
+ Handling | | |
+ Event-Timestamp | 0-1 | 0-1 |
+ Failed-AVP | 0 | 0+ |
+ Final-Unit-Indication | 0 | 0-1 |
+ Granted-Service-Unit | 0 | 0-1 |
+ Multiple-Services-Credit- | 0+ | 0+ |
+ Control | | |
+ Multiple-Services-Indicator | 0-1 | 0 |
+ Origin-Host | 1 | 1 |
+ Origin-Realm | 1 | 1 |
+ Origin-State-Id | 0-1 | 0-1 |
+ Proxy-Info | 0+ | 0+ |
+ Redirect-Host | 0 | 0+ |
+ Redirect-Host-Usage | 0 | 0-1 |
+ Redirect-Max-Cache-Time | 0 | 0-1 |
+ Requested-Action | 0-1 | 0 |
+ Requested-Service-Unit | 0-1 | 0 |
+ Route-Record | 0+ | 0+ |
+ Result-Code | 0 | 1 |
+ Service-Context-Id | 1 | 0 |
+ Service-Identifier | 0-1 | 0 |
+ Service-Parameter-Info | 0+ | 0 |
+ Session-Id | 1 | 1 |
+ Subscription-Id | 0+ | 0 |
+ Termination-Cause | 0-1 | 0 |
+ User-Equipment-Info | 0-1 | 0 |
+ Used-Service-Unit | 0+ | 0 |
+ User-Name | 0-1 | 0-1 |
+ Validity-Time | 0 | 0-1 |
+ ------------------------------|-----+-----+
+
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 272, /* Code */
+ "Credit-Control-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ {
+ { "Session-Id", RULE_FIXED_HEAD, -1, 1 },
+ { "Origin-Host", RULE_REQUIRED, -1, 1 },
+ { "Origin-Realm", RULE_REQUIRED, -1, 1 },
+ { "Destination-Realm", RULE_REQUIRED, -1, 1 },
+ { "Auth-Application-Id", RULE_REQUIRED, -1, 1 },
+ { "Service-Context-Id", RULE_REQUIRED, -1, 1 },
+ { "CC-Request-Type", RULE_REQUIRED, -1, 1 },
+ { "CC-Request-Number", RULE_REQUIRED, -1, 1 },
+ { "Destination-Host", RULE_OPTIONAL, -1, 1 },
+ { "User-Name", RULE_OPTIONAL, -1, 1 },
+ { "CC-Sub-Session-Id", RULE_OPTIONAL, -1, 1 },
+ { "Acct-Multi-Session-Id", RULE_OPTIONAL, -1, 1 },
+ { "Origin-State-Id", RULE_OPTIONAL, -1, 1 },
+ { "Event-Timestamp", RULE_OPTIONAL, -1, 1 },
+ { "Subscription-Id", RULE_OPTIONAL, -1, -1 },
+ { "Service-Identifier", RULE_OPTIONAL, -1, 1 },
+ { "Termination-Cause", RULE_OPTIONAL, -1, 1 },
+ { "Requested-Service-Unit", RULE_OPTIONAL, -1, 1 },
+ { "Requested-Action", RULE_OPTIONAL, -1, 1 },
+ { "Used-Service-Unit", RULE_OPTIONAL, -1, -1 },
+ { "Multiple-Services-Indicator", RULE_OPTIONAL, -1, 1 },
+ { "Multiple-Services-Credit-Control", RULE_OPTIONAL, -1, -1 },
+ { "Service-Parameter-Info", RULE_OPTIONAL, -1, -1 },
+ { "CC-Correlation-Id", RULE_OPTIONAL, -1, 1 },
+ { "User-Equipment-Info", RULE_OPTIONAL, -1, 1 },
+ { "Proxy-Info", RULE_OPTIONAL, -1, -1 },
+ { "Route-Record", RULE_OPTIONAL, -1, -1 }
+ /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data, dcca, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Credit-Control-Answer (CCA) Command */
+ {
+ /*
+ From RFC 4006:
+ 3.2. Credit-Control-Answer (CCA) Command
+
+ The Credit-Control-Answer message (CCA) is indicated by the command-
+ code field being set to 272 and the 'R' bit being cleared in the
+ Command Flags field. It is used between the credit-control server
+ and the Diameter credit-control client to acknowledge a Credit-
+ Control-Request command.
+
+ Message Format
+
+ <Credit-Control-Answer> ::= < Diameter Header: 272, PXY >
+ < Session-Id >
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ { Auth-Application-Id }
+ { CC-Request-Type }
+ { CC-Request-Number }
+ [ User-Name ]
+ [ CC-Session-Failover ]
+ [ CC-Sub-Session-Id ]
+ [ Acct-Multi-Session-Id ]
+ [ Origin-State-Id ]
+ [ Event-Timestamp ]
+ [ Granted-Service-Unit ]
+ *[ Multiple-Services-Credit-Control ]
+ [ Cost-Information]
+ [ Final-Unit-Indication ]
+ [ Check-Balance-Result ]
+ [ Credit-Control-Failure-Handling ]
+ [ Direct-Debiting-Failure-Handling ]
+ [ Validity-Time]
+ *[ Redirect-Host]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ *[ Proxy-Info ]
+ *[ Route-Record ]
+ *[ Failed-AVP ]
+ *[ AVP ]
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 272, /* Code */
+ "Credit-Control-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ {
+ { "Session-Id", RULE_FIXED_HEAD, -1, 1 },
+ { "Result-Code", RULE_REQUIRED, -1, 1 },
+ { "Origin-Host", RULE_REQUIRED, -1, 1 },
+ { "Origin-Realm", RULE_REQUIRED, -1, 1 },
+ { "Auth-Application-Id", RULE_REQUIRED, -1, 1 },
+ { "CC-Request-Type", RULE_REQUIRED, -1, 1 },
+ { "CC-Request-Number", RULE_REQUIRED, -1, 1 },
+ { "User-Name", RULE_OPTIONAL, -1, 1 },
+ { "CC-Session-Failover", RULE_OPTIONAL, -1, 1 },
+ { "CC-Sub-Session-Id", RULE_OPTIONAL, -1, 1 },
+ { "Acct-Multi-Session-Id", RULE_OPTIONAL, -1, 1 },
+ { "Origin-State-Id", RULE_OPTIONAL, -1, 1 },
+ { "Event-Timestamp", RULE_OPTIONAL, -1, 1 },
+ { "Granted-Service-Unit", RULE_OPTIONAL, -1, 1 },
+ { "Multiple-Services-Credit-Control", RULE_OPTIONAL, -1, -1 },
+ { "Cost-Information", RULE_OPTIONAL, -1, 1 },
+ { "Final-Unit-Indication", RULE_OPTIONAL, -1, 1 },
+ { "Check-Balance-Result", RULE_OPTIONAL, -1, 1 },
+ { "Credit-Control-Failure-Handling", RULE_OPTIONAL, -1, 1 },
+ { "Direct-Debiting-Failure-Handling", RULE_OPTIONAL, -1, 1 },
+ { "Validity-Time", RULE_OPTIONAL, -1, 1 },
+ { "Redirect-Host", RULE_OPTIONAL, -1, -1 },
+ { "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 },
+ { "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 },
+ { "Proxy-Info", RULE_OPTIONAL, -1, -1 },
+ { "Route-Record", RULE_OPTIONAL, -1, -1 },
+ { "Failed-AVP", RULE_OPTIONAL, -1, -1 }
+ /* plus any additional AVPs { "AVP", RULE_OPTIONAL, -1, -1 } */
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data, dcca, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ }
+ LOG_D( "Extension 'Dictionary definitions for DCCA (rfc4006)' initialized");
+ return 0;
+}
+
+/* needs dict_nasreq for Filter-Id */
+EXTENSION_ENTRY("dict_dcca", dict_dcca_entry, "dict_nasreq");
diff --git a/extensions/dict_dcca_3gpp/CMakeLists.txt b/extensions/dict_dcca_3gpp/CMakeLists.txt
new file mode 100644
index 0000000..7105c15
--- /dev/null
+++ b/extensions/dict_dcca_3gpp/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The dict_dcca_3gpp extension
+PROJECT("Diameter DCCA (Diameter Credit Control Application) 3GPP dictionary definitions" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_dcca_3gpp dict_dcca_3gpp.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_dcca_3gpp
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-rfc4006-extension-3gpp)
diff --git a/extensions/dict_dcca_3gpp/dict_dcca_3gpp.c b/extensions/dict_dcca_3gpp/dict_dcca_3gpp.c
new file mode 100644
index 0000000..dd79be4
--- /dev/null
+++ b/extensions/dict_dcca_3gpp/dict_dcca_3gpp.c
@@ -0,0 +1,10929 @@
+/*********************************************************************************************************
+ * Software License Agreement (BSD License) *
+ * Author: Thomas Klausner <tk@giga.or.at> *
+ * *
+ * Copyright (c) 2013, Thomas Klausner *
+ * All rights reserved. *
+ * *
+ * Written under contract by nfotex IT GmbH, http://nfotex.com/ *
+ * *
+ * Redistribution and use of this software in source and binary forms, with or without modification, are *
+ * permitted provided that the following conditions are met: *
+ * *
+ * * Redistributions of source code must retain the above *
+ * copyright notice, this list of conditions and the *
+ * following disclaimer. *
+ * *
+ * * Redistributions in binary form must reproduce the above *
+ * copyright notice, this list of conditions and the *
+ * following disclaimer in the documentation and/or other *
+ * materials provided with the distribution. *
+ * *
+ * 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. *
+ *********************************************************************************************************/
+
+/*
+ * Dictionary definitions for objects specified for DCCA by 3GPP.
+ *
+ * This extensions contains a lot of AVPs from various 3GPP standards
+ * documents, and some rules for the grouped AVPs described therein.
+ *
+ * This extension does not contain ALL AVPs described by 3GPP, but
+ * quite a big number of them.
+ *
+ * When extending the AVPs, please edit dict_dcca_3gpp.org instead and
+ * create pastable code with contrib/tools/org_to_fd.pl.
+ *
+ * Some points of consideration:
+ * 1. This dictionary could be split up per document.
+ *
+ * + pro: you can only load the AVPs/Rules you're interested in ->
+ * smaller memory size
+ *
+ * - con: the documents use AVPs from each other A LOT, so setting the
+ * dependencies correctly will be annoying
+ *
+ * - con: you need to load all of them as extensions
+ *
+ * 2. This dictionary contains ONE AVP in the "3GPP2" vendor space,
+ * since I found it wasteful to write a separate dictionary just for
+ * one AVP. Also, it is defined in a 3GPP document.
+ *
+ * 3. While there are quite a number of rules here already, many more
+ * are missing. I've only added rules for those grouped AVPs or
+ * commands in which I was concretely interested so far; many more
+ * will need to be added to make this complete.
+ *
+ * That being said, I hope this will be useful for you.
+ *
+ */
+
+
+/*
+ * Some comments on the 3GPP Standards documents themselves:
+ *
+ * 1. It would be good if 29.061 was reviewed to check for each AVP if
+ * it is Mandatory or not. The data currently in the document does not
+ * match what was in the previous version of the freeDiameter
+ * extension (the one that existedbefore I rewrote it) or what I saw
+ * so far. IIRC, even the table and the document contradict each
+ * other. The AVP table is also missing an entry for
+ * "External-Identifier", 28.
+ *
+ * 2. 29.140 has conflicting AVP names with other documents:
+ * - Sequence-Number is also in 32.329
+ * - Recipient-Address is also in 32.299
+ * - Status is also in 32.299
+ *
+ * 3. 29.229 has name conflict with 29.329 about User-Data (different
+ * AVP code 702, instead of 606) -- the weird thing is, the latter
+ * uses some AVPs from the former, but not this one.
+*/
+#include <freeDiameter/extension.h>
+
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+ CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
+ { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } ); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_dcca_3gpp_entry(char * conffile)
+{
+ /* Applications section */
+ {
+ /* Create the vendors */
+ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, NULL));
+ }
+ {
+ struct dict_vendor_data vendor_data = { 5535, "3GPP2" };
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, NULL));
+ }
+
+ }
+
+
+ struct dict_object * Address_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * IPFilterRule_type;
+ struct dict_object * Time_type;
+ struct dict_object * UTF8String_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+
+
+ /* The following is created automatically. Do not modify. */
+ /* Changes will be lost during the next update. Modify the source org file instead. */
+
+ /* 3GPP 29.061-c00 (12.0.0 2012.12.20) */
+ /* 3GPP 29.061 is not very clear and self-inconsistent about M */
+ /* for this reason, other sources are assumed more trustworthy */
+ /* M inconsistently specified */
+ /* 3GPP-IMSI */
+ {
+ struct dict_avp_data data = {
+ 1, /* Code */
+ 10415, /* Vendor */
+ "3GPP-IMSI", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* 29.061 says OctetString; dumps say UInt32; manually changed */
+ /* 29.061 says MUST NOT M; dumps say MUST */
+ /* 3GPP-Charging-Id */
+ {
+ struct dict_avp_data data = {
+ 2, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Charging-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; dumps say MUST */
+ /* 3GPP-PDP-Type */
+ {
+ struct dict_avp_data data = {
+ 3, /* Code */
+ 10415, /* Vendor */
+ "3GPP-PDP-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(3GPP-PDP-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* 3GPP-CG-Address */
+ {
+ struct dict_avp_data data = {
+ 4, /* Code */
+ 10415, /* Vendor */
+ "3GPP-CG-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-GPRS-Negotiated-QoS-Profile */
+ {
+ struct dict_avp_data data = {
+ 5, /* Code */
+ 10415, /* Vendor */
+ "3GPP-GPRS-Negotiated-QoS-Profile", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* M inconsistently specified; old contrib/3gg says MUST NOT */
+ /* 3GPP-SGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 6, /* Code */
+ 10415, /* Vendor */
+ "3GPP-SGSN-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 3GPP-GGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 7, /* Code */
+ 10415, /* Vendor */
+ "3GPP-GGSN-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; dumps say MUST */
+ /* 3GPP-IMSI-MCC-MNC */
+ {
+ struct dict_avp_data data = {
+ 8, /* Code */
+ 10415, /* Vendor */
+ "3GPP-IMSI-MCC-MNC", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-GGSN-MCC-MNC */
+ {
+ struct dict_avp_data data = {
+ 9, /* Code */
+ 10415, /* Vendor */
+ "3GPP-GGSN-MCC-MNC", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-NSAPI */
+ {
+ struct dict_avp_data data = {
+ 10, /* Code */
+ 10415, /* Vendor */
+ "3GPP-NSAPI", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* added manually, missing in AVP table */
+ /* 3GPP-Session-Stop-Indicator */
+ {
+ struct dict_avp_data data = {
+ 11, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Session-Stop-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-Selection-Mode */
+ {
+ struct dict_avp_data data = {
+ 12, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Selection-Mode", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-Charging-Characteristics */
+ {
+ struct dict_avp_data data = {
+ 13, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Charging-Characteristics", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-CG-IPv6-Address */
+ {
+ struct dict_avp_data data = {
+ 14, /* Code */
+ 10415, /* Vendor */
+ "3GPP-CG-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* M inconsistently specified */
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-SGSN-IPv6-Address */
+ {
+ struct dict_avp_data data = {
+ 15, /* Code */
+ 10415, /* Vendor */
+ "3GPP-SGSN-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-GGSN-IPv6-Address */
+ {
+ struct dict_avp_data data = {
+ 16, /* Code */
+ 10415, /* Vendor */
+ "3GPP-GGSN-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-IPv6-DNS-Servers */
+ {
+ struct dict_avp_data data = {
+ 17, /* Code */
+ 10415, /* Vendor */
+ "3GPP-IPv6-DNS-Servers", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 29.061 says MUST NOT M; old contrib/3gpp says MUST */
+ /* 3GPP-SGSN-MCC-MNC */
+ {
+ struct dict_avp_data data = {
+ 18, /* Code */
+ 10415, /* Vendor */
+ "3GPP-SGSN-MCC-MNC", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* M inconsistently specified */
+ /* 3GPP-IMEISV */
+ {
+ struct dict_avp_data data = {
+ 20, /* Code */
+ 10415, /* Vendor */
+ "3GPP-IMEISV", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* M inconsistently specified */
+ /* 3GPP-RAT-Type */
+ {
+ struct dict_avp_data data = {
+ 21, /* Code */
+ 10415, /* Vendor */
+ "3GPP-RAT-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* M inconsistently specified */
+ /* 3GPP-User-Location-Info */
+ {
+ struct dict_avp_data data = {
+ 22, /* Code */
+ 10415, /* Vendor */
+ "3GPP-User-Location-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* M inconsistently specified */
+ /* 3GPP-MS-TimeZone */
+ {
+ struct dict_avp_data data = {
+ 23, /* Code */
+ 10415, /* Vendor */
+ "3GPP-MS-TimeZone", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 3GPP-CAMEL-Charging-Info */
+ {
+ struct dict_avp_data data = {
+ 24, /* Code */
+ 10415, /* Vendor */
+ "3GPP-CAMEL-Charging-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 3GPP-Packet-Filter */
+ {
+ struct dict_avp_data data = {
+ 25, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Packet-Filter", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 3GPP-Negotiated-DSCP */
+ {
+ struct dict_avp_data data = {
+ 26, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Negotiated-DSCP", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 3GPP-Allocate-IP-Type */
+ {
+ struct dict_avp_data data = {
+ 27, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Allocate-IP-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* added manually, missing in AVP table */
+ /* External-Identifier */
+ {
+ struct dict_avp_data data = {
+ 28, /* Code */
+ 10415, /* Vendor */
+ "External-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* TMGI */
+ {
+ struct dict_avp_data data = {
+ 900, /* Code */
+ 10415, /* Vendor */
+ "TMGI", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Required-MBMS-Bearer-Capabilities */
+ {
+ struct dict_avp_data data = {
+ 901, /* Code */
+ 10415, /* Vendor */
+ "Required-MBMS-Bearer-Capabilities", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* MBMS-StartStop-Indication */
+ {
+ struct dict_avp_data data = {
+ 902, /* Code */
+ 10415, /* Vendor */
+ "MBMS-StartStop-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-StartStop-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MBMS-Service-Area */
+ {
+ struct dict_avp_data data = {
+ 903, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Service-Area", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MBMS-Session-Duration */
+ {
+ struct dict_avp_data data = {
+ 904, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Session-Duration", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Alternative-APN */
+ {
+ struct dict_avp_data data = {
+ 905, /* Code */
+ 10415, /* Vendor */
+ "Alternative-APN", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* MBMS-Service-Type */
+ {
+ struct dict_avp_data data = {
+ 906, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Service-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-Service-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MBMS-2G-3G-Indicator */
+ {
+ struct dict_avp_data data = {
+ 907, /* Code */
+ 10415, /* Vendor */
+ "MBMS-2G-3G-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-2G-3G-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MBMS-Session-Identity */
+ {
+ struct dict_avp_data data = {
+ 908, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Session-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* RAI */
+ {
+ struct dict_avp_data data = {
+ 909, /* Code */
+ 10415, /* Vendor */
+ "RAI", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Additional-MBMS-Trace-Info */
+ {
+ struct dict_avp_data data = {
+ 910, /* Code */
+ 10415, /* Vendor */
+ "Additional-MBMS-Trace-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MBMS-Time-To-Data-Transfer */
+ {
+ struct dict_avp_data data = {
+ 911, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Time-To-Data-Transfer", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MBMS-Session-Repetition-Number */
+ {
+ struct dict_avp_data data = {
+ 912, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Session-Repetition-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MBMS-Required-QoS */
+ {
+ struct dict_avp_data data = {
+ 913, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Required-QoS", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* MBMS-Counting-Information */
+ {
+ struct dict_avp_data data = {
+ 914, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Counting-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-Counting-Information)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MBMS-User-Data-Mode-Indication */
+ {
+ struct dict_avp_data data = {
+ 915, /* Code */
+ 10415, /* Vendor */
+ "MBMS-User-Data-Mode-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-User-Data-Mode-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MBMS-GGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 916, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GGSN-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MBMS-GGSN-IPv6-Address */
+ {
+ struct dict_avp_data data = {
+ 917, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GGSN-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MBMS-BMSC-SSM-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 918, /* Code */
+ 10415, /* Vendor */
+ "MBMS-BMSC-SSM-IP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MBMS-BMSC-SSM-IPv6-Address */
+ {
+ struct dict_avp_data data = {
+ 919, /* Code */
+ 10415, /* Vendor */
+ "MBMS-BMSC-SSM-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MBMS-Flow-Identifier */
+ {
+ struct dict_avp_data data = {
+ 920, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Flow-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* CN-IP-Multicast-Distribution */
+ {
+ struct dict_avp_data data = {
+ 921, /* Code */
+ 10415, /* Vendor */
+ "CN-IP-Multicast-Distribution", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CN-IP-Multicast-Distribution)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MBMS-HC-Indicator */
+ {
+ struct dict_avp_data data = {
+ 922, /* Code */
+ 10415, /* Vendor */
+ "MBMS-HC-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-HC-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* 3GPP 29.140-700 (7.0.0 2007.07.05) */
+ /* Served-User-Identity */
+ {
+ struct dict_avp_data data = {
+ 1100, /* Code */
+ 10415, /* Vendor */
+ "Served-User-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* reuses: MSISDN */
+ /* VASP-ID */
+ {
+ struct dict_avp_data data = {
+ 1101, /* Code */
+ 10415, /* Vendor */
+ "VASP-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* VAS-ID */
+ {
+ struct dict_avp_data data = {
+ 1102, /* Code */
+ 10415, /* Vendor */
+ "VAS-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Trigger-Event */
+ {
+ struct dict_avp_data data = {
+ 1103, /* Code */
+ 10415, /* Vendor */
+ "Trigger-Event", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Trigger-Event)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* reuses: 3GPP-IMSI */
+ /* Sender-Address */
+ {
+ struct dict_avp_data data = {
+ 1104, /* Code */
+ 10415, /* Vendor */
+ "Sender-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Initial-Recipient-Address */
+ {
+ struct dict_avp_data data = {
+ 1105, /* Code */
+ 10415, /* Vendor */
+ "Initial-Recipient-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Result-Recipient-Address */
+ {
+ struct dict_avp_data data = {
+ 1106, /* Code */
+ 10415, /* Vendor */
+ "Result-Recipient-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* conflicts with one in (more common) 32.329 */
+ /* Sequence-Number-29.140 */
+ {
+ struct dict_avp_data data = {
+ 1107, /* Code */
+ 10415, /* Vendor */
+ "Sequence-Number-29.140", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* conflicts with one in (more common) 32.299 */
+ /* Recipient-Address-29.140 */
+ {
+ struct dict_avp_data data = {
+ 1108, /* Code */
+ 10415, /* Vendor */
+ "Recipient-Address-29.140", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Routeing-Address */
+ {
+ struct dict_avp_data data = {
+ 1109, /* Code */
+ 10415, /* Vendor */
+ "Routeing-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Originating-Interface */
+ {
+ struct dict_avp_data data = {
+ 1110, /* Code */
+ 10415, /* Vendor */
+ "Originating-Interface", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Originating-Interface)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Delivery-Report */
+ {
+ struct dict_avp_data data = {
+ 1111, /* Code */
+ 10415, /* Vendor */
+ "Delivery-Report", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Delivery-Report)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Read-Reply */
+ {
+ struct dict_avp_data data = {
+ 1112, /* Code */
+ 10415, /* Vendor */
+ "Read-Reply", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Read-Reply)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Sender-Visibility */
+ {
+ struct dict_avp_data data = {
+ 1113, /* Code */
+ 10415, /* Vendor */
+ "Sender-Visibility", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Sender-Visibility)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Service-Key */
+ {
+ struct dict_avp_data data = {
+ 1114, /* Code */
+ 10415, /* Vendor */
+ "Service-Key", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Billing-Information */
+ {
+ struct dict_avp_data data = {
+ 1115, /* Code */
+ 10415, /* Vendor */
+ "Billing-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* conflicts with one in (more common) 32.299 */
+ /* Status-29.140 */
+ {
+ struct dict_avp_data data = {
+ 1116, /* Code */
+ 10415, /* Vendor */
+ "Status-29.140", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Status-Code */
+ {
+ struct dict_avp_data data = {
+ 1117, /* Code */
+ 10415, /* Vendor */
+ "Status-Code", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Status-Text */
+ {
+ struct dict_avp_data data = {
+ 1118, /* Code */
+ 10415, /* Vendor */
+ "Status-Text", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Routeing-Address-Resolution */
+ {
+ struct dict_avp_data data = {
+ 1119, /* Code */
+ 10415, /* Vendor */
+ "Routeing-Address-Resolution", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Routeing-Address-Resolution)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* 3GPP 29.173-c00 (12.0.0 2013.03.13) */
+ /* LMSI */
+ {
+ struct dict_avp_data data = {
+ 2400, /* Code */
+ 10415, /* Vendor */
+ "LMSI", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Serving-Node */
+ {
+ struct dict_avp_data data = {
+ 2401, /* Code */
+ 10415, /* Vendor */
+ "Serving-Node", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MME-Name */
+ {
+ struct dict_avp_data data = {
+ 2402, /* Code */
+ 10415, /* Vendor */
+ "MME-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+
+ /* MSC-Number */
+ {
+ struct dict_avp_data data = {
+ 2403, /* Code */
+ 10415, /* Vendor */
+ "MSC-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* LCS-Capabilities-Sets */
+ {
+ struct dict_avp_data data = {
+ 2404, /* Code */
+ 10415, /* Vendor */
+ "LCS-Capabilities-Sets", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* GMLC-Address */
+ {
+ struct dict_avp_data data = {
+ 2405, /* Code */
+ 10415, /* Vendor */
+ "GMLC-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Additional-Serving-Node */
+ {
+ struct dict_avp_data data = {
+ 2406, /* Code */
+ 10415, /* Vendor */
+ "Additional-Serving-Node", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PPR-Address */
+ {
+ struct dict_avp_data data = {
+ 2407, /* Code */
+ 10415, /* Vendor */
+ "PPR-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* MME-Realm */
+ {
+ struct dict_avp_data data = {
+ 2408, /* Code */
+ 10415, /* Vendor */
+ "MME-Realm", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+
+ /* SGSN-Name */
+ {
+ struct dict_avp_data data = {
+ 2409, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+
+ /* SGSN-Realm */
+ {
+ struct dict_avp_data data = {
+ 2410, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Realm", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+
+ /* 3GPP 29.210-670 (6.7.0 2006-12-18) */
+ /* PDP-Session-Operation */
+ {
+ struct dict_avp_data data = {
+ 1015, /* Code */
+ 10415, /* Vendor */
+ "PDP-Session-Operation", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PDP-Session-Operation)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* 3GPP 29.212-c00 (12.0.0 2013.03.15) */
+ /* Gx-specific */
+ /* ADC-Revalidation-Time */
+ {
+ struct dict_avp_data data = {
+ 2801, /* Code */
+ 10415, /* Vendor */
+ "ADC-Revalidation-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* ADC-Rule-Install */
+ {
+ struct dict_avp_data data = {
+ 1092, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Install", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* ADC-Rule-Remove */
+ {
+ struct dict_avp_data data = {
+ 1093, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Remove", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* ADC-Rule-Definition */
+ {
+ struct dict_avp_data data = {
+ 1094, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Definition", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* ADC-Rule-Base-Name */
+ {
+ struct dict_avp_data data = {
+ 1095, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Base-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* ADC-Rule-Name */
+ {
+ struct dict_avp_data data = {
+ 1096, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* ADC-Rule-Report */
+ {
+ struct dict_avp_data data = {
+ 1097, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Report", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Application-Detection-Information */
+ {
+ struct dict_avp_data data = {
+ 1098, /* Code */
+ 10415, /* Vendor */
+ "Application-Detection-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Access-Network-Charging-Identifier-Gx */
+ {
+ struct dict_avp_data data = {
+ 1022, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Charging-Identifier-Gx", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Allocation-Retention-Priority */
+ {
+ struct dict_avp_data data = {
+ 1034, /* Code */
+ 10415, /* Vendor */
+ "Allocation-Retention-Priority", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* AN-GW-Address */
+ {
+ struct dict_avp_data data = {
+ 1050, /* Code */
+ 10415, /* Vendor */
+ "AN-GW-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* APN-Aggregate-Max-Bitrate-DL */
+ {
+ struct dict_avp_data data = {
+ 1040, /* Code */
+ 10415, /* Vendor */
+ "APN-Aggregate-Max-Bitrate-DL", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* APN-Aggregate-Max-Bitrate-UL */
+ {
+ struct dict_avp_data data = {
+ 1041, /* Code */
+ 10415, /* Vendor */
+ "APN-Aggregate-Max-Bitrate-UL", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Bearer-Control-Mode */
+ {
+ struct dict_avp_data data = {
+ 1023, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Control-Mode", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Bearer-Control-Mode)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Bearer-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1020, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Bearer-Operation */
+ {
+ struct dict_avp_data data = {
+ 1021, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Operation", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Bearer-Operation)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Bearer-Usage */
+ {
+ struct dict_avp_data data = {
+ 1000, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Usage", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Bearer-Usage)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Charging-Rule-Install */
+ {
+ struct dict_avp_data data = {
+ 1001, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Install", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Charging-Rule-Remove */
+ {
+ struct dict_avp_data data = {
+ 1002, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Remove", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Charging-Rule-Definition */
+ {
+ struct dict_avp_data data = {
+ 1003, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Definition", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Charging-Rule-Base-Name */
+ {
+ struct dict_avp_data data = {
+ 1004, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Base-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Charging-Rule-Name */
+ {
+ struct dict_avp_data data = {
+ 1005, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Charging-Rule-Report */
+ {
+ struct dict_avp_data data = {
+ 1018, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Report", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Charging-Correlation-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1073, /* Code */
+ 10415, /* Vendor */
+ "Charging-Correlation-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Charging-Correlation-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* CoA-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 1035, /* Code */
+ 10415, /* Vendor */
+ "CoA-IP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* CoA-Information */
+ {
+ struct dict_avp_data data = {
+ 1039, /* Code */
+ 10415, /* Vendor */
+ "CoA-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* CSG-Information-Reporting */
+ {
+ struct dict_avp_data data = {
+ 1071, /* Code */
+ 10415, /* Vendor */
+ "CSG-Information-Reporting", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CSG-Information-Reporting)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Default-EPS-Bearer-QoS */
+ {
+ struct dict_avp_data data = {
+ 1049, /* Code */
+ 10415, /* Vendor */
+ "Default-EPS-Bearer-QoS", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Event-Report-Indication */
+ {
+ struct dict_avp_data data = {
+ 1033, /* Code */
+ 10415, /* Vendor */
+ "Event-Report-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Event-Trigger */
+ {
+ struct dict_avp_data data = {
+ 1006, /* Code */
+ 10415, /* Vendor */
+ "Event-Trigger", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Event-Trigger)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Flow-Direction */
+ {
+ struct dict_avp_data data = {
+ 1080, /* Code */
+ 10415, /* Vendor */
+ "Flow-Direction", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Flow-Direction)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Flow-Information */
+ {
+ struct dict_avp_data data = {
+ 1058, /* Code */
+ 10415, /* Vendor */
+ "Flow-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Flow-Label */
+ {
+ struct dict_avp_data data = {
+ 1057, /* Code */
+ 10415, /* Vendor */
+ "Flow-Label", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* IP-CAN-Type */
+ {
+ struct dict_avp_data data = {
+ 1027, /* Code */
+ 10415, /* Vendor */
+ "IP-CAN-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IP-CAN-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Guaranteed-Bitrate-DL */
+ {
+ struct dict_avp_data data = {
+ 1025, /* Code */
+ 10415, /* Vendor */
+ "Guaranteed-Bitrate-DL", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Guaranteed-Bitrate-UL */
+ {
+ struct dict_avp_data data = {
+ 1026, /* Code */
+ 10415, /* Vendor */
+ "Guaranteed-Bitrate-UL", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* HeNB-Local-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 2804, /* Code */
+ 10415, /* Vendor */
+ "HeNB-Local-IP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Metering-Method */
+ {
+ struct dict_avp_data data = {
+ 1007, /* Code */
+ 10415, /* Vendor */
+ "Metering-Method", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Metering-Method)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Monitoring-Key */
+ {
+ struct dict_avp_data data = {
+ 1066, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Key", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Mute-Notification */
+ {
+ struct dict_avp_data data = {
+ 2809, /* Code */
+ 10415, /* Vendor */
+ "Mute-Notification", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Mute-Notification)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Monitoring-Time */
+ {
+ struct dict_avp_data data = {
+ 2810, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Network-Request-Support */
+ {
+ struct dict_avp_data data = {
+ 1024, /* Code */
+ 10415, /* Vendor */
+ "Network-Request-Support", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Network-Request-Support)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Offline */
+ {
+ struct dict_avp_data data = {
+ 1008, /* Code */
+ 10415, /* Vendor */
+ "Offline", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Offline)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Online */
+ {
+ struct dict_avp_data data = {
+ 1009, /* Code */
+ 10415, /* Vendor */
+ "Online", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Online)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Packet-Filter-Content */
+ {
+ struct dict_avp_data data = {
+ 1059, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Content", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+
+ /* Packet-Filter-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1060, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Packet-Filter-Information */
+ {
+ struct dict_avp_data data = {
+ 1061, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Packet-Filter-Operation */
+ {
+ struct dict_avp_data data = {
+ 1062, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Operation", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Packet-Filter-Operation)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Packet-Filter-Usage */
+ {
+ struct dict_avp_data data = {
+ 1072, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Usage", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Packet-Filter-Usage)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PDN-Connection-ID */
+ {
+ struct dict_avp_data data = {
+ 1065, /* Code */
+ 10415, /* Vendor */
+ "PDN-Connection-ID", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Precedence */
+ {
+ struct dict_avp_data data = {
+ 1010, /* Code */
+ 10415, /* Vendor */
+ "Precedence", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Pre-emption-Capability */
+ {
+ struct dict_avp_data data = {
+ 1047, /* Code */
+ 10415, /* Vendor */
+ "Pre-emption-Capability", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Pre-emption-Capability)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Pre-emption-Vulnerability */
+ {
+ struct dict_avp_data data = {
+ 1048, /* Code */
+ 10415, /* Vendor */
+ "Pre-emption-Vulnerability", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Pre-emption-Vulnerability)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Priority-Level */
+ {
+ struct dict_avp_data data = {
+ 1046, /* Code */
+ 10415, /* Vendor */
+ "Priority-Level", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Redirect-Information */
+ {
+ struct dict_avp_data data = {
+ 1085, /* Code */
+ 10415, /* Vendor */
+ "Redirect-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Redirect-Support */
+ {
+ struct dict_avp_data data = {
+ 1086, /* Code */
+ 10415, /* Vendor */
+ "Redirect-Support", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Redirect-Support)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Reporting-Level */
+ {
+ struct dict_avp_data data = {
+ 1011, /* Code */
+ 10415, /* Vendor */
+ "Reporting-Level", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Reporting-Level)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Routing-Filter */
+ {
+ struct dict_avp_data data = {
+ 1078, /* Code */
+ 10415, /* Vendor */
+ "Routing-Filter", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Routing-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 1079, /* Code */
+ 10415, /* Vendor */
+ "Routing-IP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Routing-Rule-Definition */
+ {
+ struct dict_avp_data data = {
+ 1076, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Definition", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Routing-Rule-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1077, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Routing-Rule-Install */
+ {
+ struct dict_avp_data data = {
+ 1081, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Install", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Routing-Rule-Remove */
+ {
+ struct dict_avp_data data = {
+ 1075, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Remove", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PCC-Rule-Status */
+ {
+ struct dict_avp_data data = {
+ 1019, /* Code */
+ 10415, /* Vendor */
+ "PCC-Rule-Status", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PCC-Rule-Status)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Session-Release-Cause */
+ {
+ struct dict_avp_data data = {
+ 1045, /* Code */
+ 10415, /* Vendor */
+ "Session-Release-Cause", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Release-Cause)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* TDF-Information */
+ {
+ struct dict_avp_data data = {
+ 1087, /* Code */
+ 10415, /* Vendor */
+ "TDF-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* TDF-Application-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1088, /* Code */
+ 10415, /* Vendor */
+ "TDF-Application-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* TDF-Application-Instance-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2802, /* Code */
+ 10415, /* Vendor */
+ "TDF-Application-Instance-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* TDF-Destination-Host */
+ {
+ struct dict_avp_data data = {
+ 1089, /* Code */
+ 10415, /* Vendor */
+ "TDF-Destination-Host", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+
+ /* TDF-Destination-Realm */
+ {
+ struct dict_avp_data data = {
+ 1090, /* Code */
+ 10415, /* Vendor */
+ "TDF-Destination-Realm", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+
+ /* TDF-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 1091, /* Code */
+ 10415, /* Vendor */
+ "TDF-IP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* QoS-Class-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1028, /* Code */
+ 10415, /* Vendor */
+ "QoS-Class-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(QoS-Class-Identifier)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* QoS-Information */
+ {
+ struct dict_avp_data data = {
+ 1016, /* Code */
+ 10415, /* Vendor */
+ "QoS-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* QoS-Negotiation */
+ {
+ struct dict_avp_data data = {
+ 1029, /* Code */
+ 10415, /* Vendor */
+ "QoS-Negotiation", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(QoS-Negotiation)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* QoS-Upgrade */
+ {
+ struct dict_avp_data data = {
+ 1030, /* Code */
+ 10415, /* Vendor */
+ "QoS-Upgrade", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(QoS-Upgrade)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PS-to-CS-Session-Continuity */
+ {
+ struct dict_avp_data data = {
+ 1099, /* Code */
+ 10415, /* Vendor */
+ "PS-to-CS-Session-Continuity", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PS-to-CS-Session-Continuity)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Resource-Allocation-Notification */
+ {
+ struct dict_avp_data data = {
+ 1063, /* Code */
+ 10415, /* Vendor */
+ "Resource-Allocation-Notification", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Resource-Allocation-Notification)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Rule-Failure-Code */
+ {
+ struct dict_avp_data data = {
+ 1031, /* Code */
+ 10415, /* Vendor */
+ "Rule-Failure-Code", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Rule-Failure-Code)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Security-Parameter-Index */
+ {
+ struct dict_avp_data data = {
+ 1056, /* Code */
+ 10415, /* Vendor */
+ "Security-Parameter-Index", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* TFT-Filter */
+ {
+ struct dict_avp_data data = {
+ 1012, /* Code */
+ 10415, /* Vendor */
+ "TFT-Filter", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+
+ /* TFT-Packet-Filter-Information */
+ {
+ struct dict_avp_data data = {
+ 1013, /* Code */
+ 10415, /* Vendor */
+ "TFT-Packet-Filter-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* ToS-Traffic-Class */
+ {
+ struct dict_avp_data data = {
+ 1014, /* Code */
+ 10415, /* Vendor */
+ "ToS-Traffic-Class", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Tunnel-Header-Filter */
+ {
+ struct dict_avp_data data = {
+ 1036, /* Code */
+ 10415, /* Vendor */
+ "Tunnel-Header-Filter", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+
+ /* Tunnel-Header-Length */
+ {
+ struct dict_avp_data data = {
+ 1037, /* Code */
+ 10415, /* Vendor */
+ "Tunnel-Header-Length", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Tunnel-Information */
+ {
+ struct dict_avp_data data = {
+ 1038, /* Code */
+ 10415, /* Vendor */
+ "Tunnel-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* RAT-Type */
+ {
+ struct dict_avp_data data = {
+ 1032, /* Code */
+ 10415, /* Vendor */
+ "RAT-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(RAT-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Revalidation-Time */
+ {
+ struct dict_avp_data data = {
+ 1042, /* Code */
+ 10415, /* Vendor */
+ "Revalidation-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Rule-Activation-Time */
+ {
+ struct dict_avp_data data = {
+ 1043, /* Code */
+ 10415, /* Vendor */
+ "Rule-Activation-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* UDP-Source-Port */
+ {
+ struct dict_avp_data data = {
+ 2806, /* Code */
+ 10415, /* Vendor */
+ "UDP-Source-Port", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* UE-Local-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 2805, /* Code */
+ 10415, /* Vendor */
+ "UE-Local-IP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Usage-Monitoring-Information */
+ {
+ struct dict_avp_data data = {
+ 1067, /* Code */
+ 10415, /* Vendor */
+ "Usage-Monitoring-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Rule-Deactivation-Time */
+ {
+ struct dict_avp_data data = {
+ 1044, /* Code */
+ 10415, /* Vendor */
+ "Rule-Deactivation-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Usage-Monitoring-Level */
+ {
+ struct dict_avp_data data = {
+ 1068, /* Code */
+ 10415, /* Vendor */
+ "Usage-Monitoring-Level", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Usage-Monitoring-Level)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Usage-Monitoring-Report */
+ {
+ struct dict_avp_data data = {
+ 1069, /* Code */
+ 10415, /* Vendor */
+ "Usage-Monitoring-Report", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Usage-Monitoring-Report)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Usage-Monitoring-Support */
+ {
+ struct dict_avp_data data = {
+ 1070, /* Code */
+ 10415, /* Vendor */
+ "Usage-Monitoring-Support", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Usage-Monitoring-Support)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Gxx-specific */
+ /* QoS-Rule-Install */
+ {
+ struct dict_avp_data data = {
+ 1051, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Install", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* QoS-Rule-Remove */
+ {
+ struct dict_avp_data data = {
+ 1052, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Remove", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* QoS-Rule-Definition */
+ {
+ struct dict_avp_data data = {
+ 1053, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Definition", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* QoS-Rule-Name */
+ {
+ struct dict_avp_data data = {
+ 1054, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* QoS-Rule-Base-Name */
+ {
+ struct dict_avp_data data = {
+ 1074, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Base-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* QoS-Rule-Report */
+ {
+ struct dict_avp_data data = {
+ 1055, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Report", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Session-Linking-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1064, /* Code */
+ 10415, /* Vendor */
+ "Session-Linking-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Linking-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* S15-specific */
+ /* CS-Service-Qos-Request-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2807, /* Code */
+ 10415, /* Vendor */
+ "CS-Service-Qos-Request-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* CS-Service-QoS-Request-Operation */
+ {
+ struct dict_avp_data data = {
+ 2808, /* Code */
+ 10415, /* Vendor */
+ "CS-Service-QoS-Request-Operation", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CS-Service-QoS-Request-Operation)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* 3GPP 29.214-b80 (11.8.0 2013.03.15) */
+ /* Abort-Cause */
+ {
+ struct dict_avp_data data = {
+ 500, /* Code */
+ 10415, /* Vendor */
+ "Abort-Cause", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Abort-Cause)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Access-Network-Charging-Address */
+ {
+ struct dict_avp_data data = {
+ 501, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Charging-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Access-Network-Charging-Identifier */
+ {
+ struct dict_avp_data data = {
+ 502, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Charging-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Access-Network-Charging-Identifier-Value */
+ {
+ struct dict_avp_data data = {
+ 503, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Charging-Identifier-Value", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Acceptable-Service-Info */
+ {
+ struct dict_avp_data data = {
+ 526, /* Code */
+ 10415, /* Vendor */
+ "Acceptable-Service-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* AF-Application-Identifier */
+ {
+ struct dict_avp_data data = {
+ 504, /* Code */
+ 10415, /* Vendor */
+ "AF-Application-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* AF-Charging-Identifier */
+ {
+ struct dict_avp_data data = {
+ 505, /* Code */
+ 10415, /* Vendor */
+ "AF-Charging-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Application-Service-Provider-Identity */
+ {
+ struct dict_avp_data data = {
+ 532, /* Code */
+ 10415, /* Vendor */
+ "Application-Service-Provider-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Codec-Data */
+ {
+ struct dict_avp_data data = {
+ 524, /* Code */
+ 10415, /* Vendor */
+ "Codec-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Flow-Description */
+ {
+ struct dict_avp_data data = {
+ 507, /* Code */
+ 10415, /* Vendor */
+ "Flow-Description", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+
+ /* Flow-Number */
+ {
+ struct dict_avp_data data = {
+ 509, /* Code */
+ 10415, /* Vendor */
+ "Flow-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Flows */
+ {
+ struct dict_avp_data data = {
+ 510, /* Code */
+ 10415, /* Vendor */
+ "Flows", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Flow-Status */
+ {
+ struct dict_avp_data data = {
+ 511, /* Code */
+ 10415, /* Vendor */
+ "Flow-Status", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Flow-Status)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Flow-Usage */
+ {
+ struct dict_avp_data data = {
+ 512, /* Code */
+ 10415, /* Vendor */
+ "Flow-Usage", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Flow-Usage)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Service-URN */
+ {
+ struct dict_avp_data data = {
+ 525, /* Code */
+ 10415, /* Vendor */
+ "Service-URN", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Specific-Action */
+ {
+ struct dict_avp_data data = {
+ 513, /* Code */
+ 10415, /* Vendor */
+ "Specific-Action", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Specific-Action)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Max-Requested-Bandwidth-DL */
+ {
+ struct dict_avp_data data = {
+ 515, /* Code */
+ 10415, /* Vendor */
+ "Max-Requested-Bandwidth-DL", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Max-Requested-Bandwidth-UL */
+ {
+ struct dict_avp_data data = {
+ 516, /* Code */
+ 10415, /* Vendor */
+ "Max-Requested-Bandwidth-UL", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Media-Component-Description */
+ {
+ struct dict_avp_data data = {
+ 517, /* Code */
+ 10415, /* Vendor */
+ "Media-Component-Description", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Media-Component-Number */
+ {
+ struct dict_avp_data data = {
+ 518, /* Code */
+ 10415, /* Vendor */
+ "Media-Component-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Media-Sub-Component */
+ {
+ struct dict_avp_data data = {
+ 519, /* Code */
+ 10415, /* Vendor */
+ "Media-Sub-Component", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Media-Type */
+ {
+ struct dict_avp_data data = {
+ 520, /* Code */
+ 10415, /* Vendor */
+ "Media-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Media-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MPS-Identifier */
+ {
+ struct dict_avp_data data = {
+ 528, /* Code */
+ 10415, /* Vendor */
+ "MPS-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Min-Requested-Bandwidth-DL */
+ {
+ struct dict_avp_data data = {
+ 534, /* Code */
+ 10415, /* Vendor */
+ "Min-Requested-Bandwidth-DL", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Min-Requested-Bandwidth-UL */
+ {
+ struct dict_avp_data data = {
+ 535, /* Code */
+ 10415, /* Vendor */
+ "Min-Requested-Bandwidth-UL", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* RR-Bandwidth */
+ {
+ struct dict_avp_data data = {
+ 521, /* Code */
+ 10415, /* Vendor */
+ "RR-Bandwidth", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* RS-Bandwidth */
+ {
+ struct dict_avp_data data = {
+ 522, /* Code */
+ 10415, /* Vendor */
+ "RS-Bandwidth", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Service-Info-Status */
+ {
+ struct dict_avp_data data = {
+ 527, /* Code */
+ 10415, /* Vendor */
+ "Service-Info-Status", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Service-Info-Status)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SIP-Forking-Indication */
+ {
+ struct dict_avp_data data = {
+ 523, /* Code */
+ 10415, /* Vendor */
+ "SIP-Forking-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SIP-Forking-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Sponsor-Identity */
+ {
+ struct dict_avp_data data = {
+ 531, /* Code */
+ 10415, /* Vendor */
+ "Sponsor-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Sponsored-Connectivity-Data */
+ {
+ struct dict_avp_data data = {
+ 530, /* Code */
+ 10415, /* Vendor */
+ "Sponsored-Connectivity-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* AF-Signalling-Protocol */
+ {
+ struct dict_avp_data data = {
+ 529, /* Code */
+ 10415, /* Vendor */
+ "AF-Signalling-Protocol", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AF-Signalling-Protocol)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Required-Access-Info */
+ {
+ struct dict_avp_data data = {
+ 536, /* Code */
+ 10415, /* Vendor */
+ "Required-Access-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Required-Access-Info)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Rx-Request-Type */
+ {
+ struct dict_avp_data data = {
+ 533, /* Code */
+ 10415, /* Vendor */
+ "Rx-Request-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Rx-Request-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* IP-Domain-Id */
+ {
+ struct dict_avp_data data = {
+ 537, /* Code */
+ 10415, /* Vendor */
+ "IP-Domain-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 3GPP 29.229-b20 (11.2.0 2012.12.21) */
+ /* Associated-Identities */
+ {
+ struct dict_avp_data data = {
+ 632, /* Code */
+ 10415, /* Vendor */
+ "Associated-Identities", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Associated-Registered-Identities */
+ {
+ struct dict_avp_data data = {
+ 647, /* Code */
+ 10415, /* Vendor */
+ "Associated-Registered-Identities", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Call-ID-SIP-Header */
+ {
+ struct dict_avp_data data = {
+ 643, /* Code */
+ 10415, /* Vendor */
+ "Call-ID-SIP-Header", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Charging-Information */
+ {
+ struct dict_avp_data data = {
+ 618, /* Code */
+ 10415, /* Vendor */
+ "Charging-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Confidentiality-Key */
+ {
+ struct dict_avp_data data = {
+ 625, /* Code */
+ 10415, /* Vendor */
+ "Confidentiality-Key", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Contact */
+ {
+ struct dict_avp_data data = {
+ 641, /* Code */
+ 10415, /* Vendor */
+ "Contact", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Deregistration-Reason */
+ {
+ struct dict_avp_data data = {
+ 615, /* Code */
+ 10415, /* Vendor */
+ "Deregistration-Reason", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Digest-Algorithm */
+ {
+ struct dict_avp_data data = {
+ 111, /* Code */
+ 10415, /* Vendor */
+ "Digest-Algorithm", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Digest-HA1 */
+ {
+ struct dict_avp_data data = {
+ 121, /* Code */
+ 10415, /* Vendor */
+ "Digest-HA1", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Digest-QoP */
+ {
+ struct dict_avp_data data = {
+ 110, /* Code */
+ 10415, /* Vendor */
+ "Digest-QoP", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Digest-Realm */
+ {
+ struct dict_avp_data data = {
+ 104, /* Code */
+ 10415, /* Vendor */
+ "Digest-Realm", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Feature-List */
+ {
+ struct dict_avp_data data = {
+ 630, /* Code */
+ 10415, /* Vendor */
+ "Feature-List", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Feature-List-ID */
+ {
+ struct dict_avp_data data = {
+ 629, /* Code */
+ 10415, /* Vendor */
+ "Feature-List-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* From-SIP-Header */
+ {
+ struct dict_avp_data data = {
+ 644, /* Code */
+ 10415, /* Vendor */
+ "From-SIP-Header", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Identity-with-Emergency-Registration */
+ {
+ struct dict_avp_data data = {
+ 651, /* Code */
+ 10415, /* Vendor */
+ "Identity-with-Emergency-Registration", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Integrity-Key */
+ {
+ struct dict_avp_data data = {
+ 626, /* Code */
+ 10415, /* Vendor */
+ "Integrity-Key", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* LIA-Flags */
+ {
+ struct dict_avp_data data = {
+ 653, /* Code */
+ 10415, /* Vendor */
+ "LIA-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Loose-Route-Indication */
+ {
+ struct dict_avp_data data = {
+ 638, /* Code */
+ 10415, /* Vendor */
+ "Loose-Route-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Loose-Route-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Mandatory-Capability */
+ {
+ struct dict_avp_data data = {
+ 604, /* Code */
+ 10415, /* Vendor */
+ "Mandatory-Capability", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Multiple-Registration-Indication */
+ {
+ struct dict_avp_data data = {
+ 648, /* Code */
+ 10415, /* Vendor */
+ "Multiple-Registration-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Multiple-Registration-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Optional-Capability */
+ {
+ struct dict_avp_data data = {
+ 605, /* Code */
+ 10415, /* Vendor */
+ "Optional-Capability", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Originating-Request */
+ {
+ struct dict_avp_data data = {
+ 633, /* Code */
+ 10415, /* Vendor */
+ "Originating-Request", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Originating-Request)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Path */
+ {
+ struct dict_avp_data data = {
+ 640, /* Code */
+ 10415, /* Vendor */
+ "Path", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Primary-Charging-Collection-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 621, /* Code */
+ 10415, /* Vendor */
+ "Primary-Charging-Collection-Function-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterURI_type, NULL);
+ };
+
+ /* Primary-Event-Charging-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 619, /* Code */
+ 10415, /* Vendor */
+ "Primary-Event-Charging-Function-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterURI_type, NULL);
+ };
+
+ /* Priviledged-Sender-Indication */
+ {
+ struct dict_avp_data data = {
+ 652, /* Code */
+ 10415, /* Vendor */
+ "Priviledged-Sender-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Priviledged-Sender-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Public-Identity */
+ {
+ struct dict_avp_data data = {
+ 601, /* Code */
+ 10415, /* Vendor */
+ "Public-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Reason-Code */
+ {
+ struct dict_avp_data data = {
+ 616, /* Code */
+ 10415, /* Vendor */
+ "Reason-Code", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Reason-Code)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Reason-Info */
+ {
+ struct dict_avp_data data = {
+ 617, /* Code */
+ 10415, /* Vendor */
+ "Reason-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Record-Route */
+ {
+ struct dict_avp_data data = {
+ 646, /* Code */
+ 10415, /* Vendor */
+ "Record-Route", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Restoration-Info */
+ {
+ struct dict_avp_data data = {
+ 649, /* Code */
+ 10415, /* Vendor */
+ "Restoration-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SCSCF-Restoration-Info */
+ {
+ struct dict_avp_data data = {
+ 639, /* Code */
+ 10415, /* Vendor */
+ "SCSCF-Restoration-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SIP-Auth-Data-Item */
+ {
+ struct dict_avp_data data = {
+ 612, /* Code */
+ 10415, /* Vendor */
+ "SIP-Auth-Data-Item", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SIP-Authenticate */
+ {
+ struct dict_avp_data data = {
+ 609, /* Code */
+ 10415, /* Vendor */
+ "SIP-Authenticate", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SIP-Authentication-Context */
+ {
+ struct dict_avp_data data = {
+ 611, /* Code */
+ 10415, /* Vendor */
+ "SIP-Authentication-Context", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SIP-Authentication-Scheme */
+ {
+ struct dict_avp_data data = {
+ 608, /* Code */
+ 10415, /* Vendor */
+ "SIP-Authentication-Scheme", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SIP-Authorization */
+ {
+ struct dict_avp_data data = {
+ 610, /* Code */
+ 10415, /* Vendor */
+ "SIP-Authorization", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SIP-Digest-Authenticate */
+ {
+ struct dict_avp_data data = {
+ 635, /* Code */
+ 10415, /* Vendor */
+ "SIP-Digest-Authenticate", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SIP-Item-Number */
+ {
+ struct dict_avp_data data = {
+ 613, /* Code */
+ 10415, /* Vendor */
+ "SIP-Item-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SIP-Number-Auth-Items */
+ {
+ struct dict_avp_data data = {
+ 607, /* Code */
+ 10415, /* Vendor */
+ "SIP-Number-Auth-Items", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Secondary-Charging-Collection-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 622, /* Code */
+ 10415, /* Vendor */
+ "Secondary-Charging-Collection-Function-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterURI_type, NULL);
+ };
+
+ /* Secondary-Event-Charging-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 620, /* Code */
+ 10415, /* Vendor */
+ "Secondary-Event-Charging-Function-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, DiameterURI_type, NULL);
+ };
+
+ /* Server-Assignment-Type */
+ {
+ struct dict_avp_data data = {
+ 614, /* Code */
+ 10415, /* Vendor */
+ "Server-Assignment-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Server-Assignment-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Server-Capabilities */
+ {
+ struct dict_avp_data data = {
+ 603, /* Code */
+ 10415, /* Vendor */
+ "Server-Capabilities", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Server-Name */
+ {
+ struct dict_avp_data data = {
+ 602, /* Code */
+ 10415, /* Vendor */
+ "Server-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Session-Priority */
+ {
+ struct dict_avp_data data = {
+ 650, /* Code */
+ 10415, /* Vendor */
+ "Session-Priority", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Priority)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Subscription-Info */
+ {
+ struct dict_avp_data data = {
+ 642, /* Code */
+ 10415, /* Vendor */
+ "Subscription-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Supported-Applications */
+ {
+ struct dict_avp_data data = {
+ 631, /* Code */
+ 10415, /* Vendor */
+ "Supported-Applications", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Supported-Features */
+ {
+ struct dict_avp_data data = {
+ 628, /* Code */
+ 10415, /* Vendor */
+ "Supported-Features", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* To-SIP-Header */
+ {
+ struct dict_avp_data data = {
+ 645, /* Code */
+ 10415, /* Vendor */
+ "To-SIP-Header", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* UAR-Flags */
+ {
+ struct dict_avp_data data = {
+ 637, /* Code */
+ 10415, /* Vendor */
+ "UAR-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* User-Authorization-Type */
+ {
+ struct dict_avp_data data = {
+ 623, /* Code */
+ 10415, /* Vendor */
+ "User-Authorization-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(User-Authorization-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* User-Data */
+ {
+ struct dict_avp_data data = {
+ 606, /* Code */
+ 10415, /* Vendor */
+ "User-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* User-Data-Already-Available */
+ {
+ struct dict_avp_data data = {
+ 624, /* Code */
+ 10415, /* Vendor */
+ "User-Data-Already-Available", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(User-Data-Already-Available)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Visited-Network-Identifier */
+ {
+ struct dict_avp_data data = {
+ 600, /* Code */
+ 10415, /* Vendor */
+ "Visited-Network-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Wildcarded-Public-Identity */
+ {
+ struct dict_avp_data data = {
+ 634, /* Code */
+ 10415, /* Vendor */
+ "Wildcarded-Public-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* 3GPP 32.299-b60 (11.6.0 2012.12.21) */
+ /* AF-Correlation-Information */
+ {
+ struct dict_avp_data data = {
+ 1276, /* Code */
+ 10415, /* Vendor */
+ "AF-Correlation-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Access-Network-Information */
+ {
+ struct dict_avp_data data = {
+ 1263, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Access-Transfer-Information */
+ {
+ struct dict_avp_data data = {
+ 2709, /* Code */
+ 10415, /* Vendor */
+ "Access-Transfer-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Access-Transfer-Type */
+ {
+ struct dict_avp_data data = {
+ 2710, /* Code */
+ 10415, /* Vendor */
+ "Access-Transfer-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Access-Transfer-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Account-Expiration */
+ {
+ struct dict_avp_data data = {
+ 2309, /* Code */
+ 10415, /* Vendor */
+ "Account-Expiration", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Accumulated-Cost */
+ {
+ struct dict_avp_data data = {
+ 2052, /* Code */
+ 10415, /* Vendor */
+ "Accumulated-Cost", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Adaptations */
+ {
+ struct dict_avp_data data = {
+ 1217, /* Code */
+ 10415, /* Vendor */
+ "Adaptations", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Adaptations)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Additional-Content-Information */
+ {
+ struct dict_avp_data data = {
+ 1207, /* Code */
+ 10415, /* Vendor */
+ "Additional-Content-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Additional-Type-Information */
+ {
+ struct dict_avp_data data = {
+ 1205, /* Code */
+ 10415, /* Vendor */
+ "Additional-Type-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Address-Data */
+ {
+ struct dict_avp_data data = {
+ 897, /* Code */
+ 10415, /* Vendor */
+ "Address-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Address-Domain */
+ {
+ struct dict_avp_data data = {
+ 898, /* Code */
+ 10415, /* Vendor */
+ "Address-Domain", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Address-Type */
+ {
+ struct dict_avp_data data = {
+ 899, /* Code */
+ 10415, /* Vendor */
+ "Address-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Address-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Addressee-Type */
+ {
+ struct dict_avp_data data = {
+ 1208, /* Code */
+ 10415, /* Vendor */
+ "Addressee-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Addressee-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Alternate-Charged-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 1280, /* Code */
+ 10415, /* Vendor */
+ "Alternate-Charged-Party-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* AoC-Cost-Information */
+ {
+ struct dict_avp_data data = {
+ 2053, /* Code */
+ 10415, /* Vendor */
+ "AoC-Cost-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* AoC-Format */
+ {
+ struct dict_avp_data data = {
+ 2310, /* Code */
+ 10415, /* Vendor */
+ "AoC-Format", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AoC-Format)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* AoC-Information */
+ {
+ struct dict_avp_data data = {
+ 2054, /* Code */
+ 10415, /* Vendor */
+ "AoC-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* AoC-Request-Type */
+ {
+ struct dict_avp_data data = {
+ 2055, /* Code */
+ 10415, /* Vendor */
+ "AoC-Request-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AoC-Request-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* AoC-Service */
+ {
+ struct dict_avp_data data = {
+ 2311, /* Code */
+ 10415, /* Vendor */
+ "AoC-Service", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* AoC-Service-Obligatory-Type */
+ {
+ struct dict_avp_data data = {
+ 2312, /* Code */
+ 10415, /* Vendor */
+ "AoC-Service-Obligatory-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AoC-Service-Obligatory-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* AoC-Service-Type */
+ {
+ struct dict_avp_data data = {
+ 2313, /* Code */
+ 10415, /* Vendor */
+ "AoC-Service-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AoC-Service-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* AoC-Subscription-Information */
+ {
+ struct dict_avp_data data = {
+ 2314, /* Code */
+ 10415, /* Vendor */
+ "AoC-Subscription-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Applic-ID */
+ {
+ struct dict_avp_data data = {
+ 1218, /* Code */
+ 10415, /* Vendor */
+ "Applic-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Application-Server */
+ {
+ struct dict_avp_data data = {
+ 836, /* Code */
+ 10415, /* Vendor */
+ "Application-Server", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Application-Server-Information */
+ {
+ struct dict_avp_data data = {
+ 850, /* Code */
+ 10415, /* Vendor */
+ "Application-Server-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Application-Provided-Called-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 837, /* Code */
+ 10415, /* Vendor */
+ "Application-Provided-Called-Party-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Associated-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 2035, /* Code */
+ 10415, /* Vendor */
+ "Associated-Party-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Associated-URI */
+ {
+ struct dict_avp_data data = {
+ 856, /* Code */
+ 10415, /* Vendor */
+ "Associated-URI", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Aux-Applic-Info */
+ {
+ struct dict_avp_data data = {
+ 1219, /* Code */
+ 10415, /* Vendor */
+ "Aux-Applic-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Base-Time-Interval */
+ {
+ struct dict_avp_data data = {
+ 1265, /* Code */
+ 10415, /* Vendor */
+ "Base-Time-Interval", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Bearer-Service */
+ {
+ struct dict_avp_data data = {
+ 854, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Service", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* CG-Address */
+ {
+ struct dict_avp_data data = {
+ 846, /* Code */
+ 10415, /* Vendor */
+ "CG-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* CSG-Access-Mode */
+ {
+ struct dict_avp_data data = {
+ 2317, /* Code */
+ 10415, /* Vendor */
+ "CSG-Access-Mode", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CSG-Access-Mode)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* CSG-Membership-Indication */
+ {
+ struct dict_avp_data data = {
+ 2318, /* Code */
+ 10415, /* Vendor */
+ "CSG-Membership-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CSG-Membership-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* CUG-Information */
+ {
+ struct dict_avp_data data = {
+ 2304, /* Code */
+ 10415, /* Vendor */
+ "CUG-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Called-Asserted-Identity */
+ {
+ struct dict_avp_data data = {
+ 1250, /* Code */
+ 10415, /* Vendor */
+ "Called-Asserted-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Called-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 832, /* Code */
+ 10415, /* Vendor */
+ "Called-Party-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Calling-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 831, /* Code */
+ 10415, /* Vendor */
+ "Calling-Party-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Carrier-Select-Routing-Information */
+ {
+ struct dict_avp_data data = {
+ 2023, /* Code */
+ 10415, /* Vendor */
+ "Carrier-Select-Routing-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Cause-Code */
+ {
+ struct dict_avp_data data = {
+ 861, /* Code */
+ 10415, /* Vendor */
+ "Cause-Code", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Change-Condition */
+ {
+ struct dict_avp_data data = {
+ 2037, /* Code */
+ 10415, /* Vendor */
+ "Change-Condition", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Change-Time */
+ {
+ struct dict_avp_data data = {
+ 2038, /* Code */
+ 10415, /* Vendor */
+ "Change-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Charge-Reason-Code */
+ {
+ struct dict_avp_data data = {
+ 2118, /* Code */
+ 10415, /* Vendor */
+ "Charge-Reason-Code", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Charge-Reason-Code)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Charged-Party */
+ {
+ struct dict_avp_data data = {
+ 857, /* Code */
+ 10415, /* Vendor */
+ "Charged-Party", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Charging-Characteristics-Selection-Mode */
+ {
+ struct dict_avp_data data = {
+ 2066, /* Code */
+ 10415, /* Vendor */
+ "Charging-Characteristics-Selection-Mode", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Charging-Characteristics-Selection-Mode)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Class-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1214, /* Code */
+ 10415, /* Vendor */
+ "Class-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Class-Identifier)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Client-Address */
+ {
+ struct dict_avp_data data = {
+ 2018, /* Code */
+ 10415, /* Vendor */
+ "Client-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Content-Class */
+ {
+ struct dict_avp_data data = {
+ 1220, /* Code */
+ 10415, /* Vendor */
+ "Content-Class", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Content-Class)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Content-Disposition */
+ {
+ struct dict_avp_data data = {
+ 828, /* Code */
+ 10415, /* Vendor */
+ "Content-Disposition", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Content-Length */
+ {
+ struct dict_avp_data data = {
+ 827, /* Code */
+ 10415, /* Vendor */
+ "Content-Length", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Content-Size */
+ {
+ struct dict_avp_data data = {
+ 1206, /* Code */
+ 10415, /* Vendor */
+ "Content-Size", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Content-Type */
+ {
+ struct dict_avp_data data = {
+ 826, /* Code */
+ 10415, /* Vendor */
+ "Content-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Current-Tariff */
+ {
+ struct dict_avp_data data = {
+ 2056, /* Code */
+ 10415, /* Vendor */
+ "Current-Tariff", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* DRM-Content */
+ {
+ struct dict_avp_data data = {
+ 1221, /* Code */
+ 10415, /* Vendor */
+ "DRM-Content", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(DRM-Content)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Data-Coding-Scheme */
+ {
+ struct dict_avp_data data = {
+ 2001, /* Code */
+ 10415, /* Vendor */
+ "Data-Coding-Scheme", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Deferred-Location-Event-Type */
+ {
+ struct dict_avp_data data = {
+ 1230, /* Code */
+ 10415, /* Vendor */
+ "Deferred-Location-Event-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Delivery-Report-Requested */
+ {
+ struct dict_avp_data data = {
+ 1216, /* Code */
+ 10415, /* Vendor */
+ "Delivery-Report-Requested", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Delivery-Report-Requested)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Destination-Interface */
+ {
+ struct dict_avp_data data = {
+ 2002, /* Code */
+ 10415, /* Vendor */
+ "Destination-Interface", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Diagnostics */
+ {
+ struct dict_avp_data data = {
+ 2039, /* Code */
+ 10415, /* Vendor */
+ "Diagnostics", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Domain-Name */
+ {
+ struct dict_avp_data data = {
+ 1200, /* Code */
+ 10415, /* Vendor */
+ "Domain-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Dynamic-Address-Flag */
+ {
+ struct dict_avp_data data = {
+ 2051, /* Code */
+ 10415, /* Vendor */
+ "Dynamic-Address-Flag", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Dynamic-Address-Flag)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Dynamic-Address-Flag-Extension */
+ {
+ struct dict_avp_data data = {
+ 2068, /* Code */
+ 10415, /* Vendor */
+ "Dynamic-Address-Flag-Extension", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Dynamic-Address-Flag-Extension)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Early-Media-Description */
+ {
+ struct dict_avp_data data = {
+ 1272, /* Code */
+ 10415, /* Vendor */
+ "Early-Media-Description", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Envelope */
+ {
+ struct dict_avp_data data = {
+ 1266, /* Code */
+ 10415, /* Vendor */
+ "Envelope", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Envelope-End-Time */
+ {
+ struct dict_avp_data data = {
+ 1267, /* Code */
+ 10415, /* Vendor */
+ "Envelope-End-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Envelope-Reporting */
+ {
+ struct dict_avp_data data = {
+ 1268, /* Code */
+ 10415, /* Vendor */
+ "Envelope-Reporting", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Envelope-Reporting)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Envelope-Start-Time */
+ {
+ struct dict_avp_data data = {
+ 1269, /* Code */
+ 10415, /* Vendor */
+ "Envelope-Start-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Event */
+ {
+ struct dict_avp_data data = {
+ 825, /* Code */
+ 10415, /* Vendor */
+ "Event", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Event-Charging-TimeStamp */
+ {
+ struct dict_avp_data data = {
+ 1258, /* Code */
+ 10415, /* Vendor */
+ "Event-Charging-TimeStamp", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Event-Type */
+ {
+ struct dict_avp_data data = {
+ 823, /* Code */
+ 10415, /* Vendor */
+ "Event-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Expires */
+ {
+ struct dict_avp_data data = {
+ 888, /* Code */
+ 10415, /* Vendor */
+ "Expires", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* File-Repair-Supported */
+ {
+ struct dict_avp_data data = {
+ 1224, /* Code */
+ 10415, /* Vendor */
+ "File-Repair-Supported", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(File-Repair-Supported)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* From-Address */
+ {
+ struct dict_avp_data data = {
+ 2708, /* Code */
+ 10415, /* Vendor */
+ "From-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* GGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 847, /* Code */
+ 10415, /* Vendor */
+ "GGSN-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* IMS-Application-Reference-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2601, /* Code */
+ 10415, /* Vendor */
+ "IMS-Application-Reference-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* IMS-Charging-Identifier */
+ {
+ struct dict_avp_data data = {
+ 841, /* Code */
+ 10415, /* Vendor */
+ "IMS-Charging-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* IMS-Communication-Service-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1281, /* Code */
+ 10415, /* Vendor */
+ "IMS-Communication-Service-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* IMS-Emergency-Indicator */
+ {
+ struct dict_avp_data data = {
+ 2322, /* Code */
+ 10415, /* Vendor */
+ "IMS-Emergency-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IMS-Emergency-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* IMS-Information */
+ {
+ struct dict_avp_data data = {
+ 876, /* Code */
+ 10415, /* Vendor */
+ "IMS-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* IMSI-Unauthenticated-Flag */
+ {
+ struct dict_avp_data data = {
+ 2308, /* Code */
+ 10415, /* Vendor */
+ "IMSI-Unauthenticated-Flag", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IMSI-Unauthenticated-Flag)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* IP-Realm-Default-Indication */
+ {
+ struct dict_avp_data data = {
+ 2603, /* Code */
+ 10415, /* Vendor */
+ "IP-Realm-Default-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IP-Realm-Default-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Incoming-Trunk-Group-Id */
+ {
+ struct dict_avp_data data = {
+ 852, /* Code */
+ 10415, /* Vendor */
+ "Incoming-Trunk-Group-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Incremental-Cost */
+ {
+ struct dict_avp_data data = {
+ 2062, /* Code */
+ 10415, /* Vendor */
+ "Incremental-Cost", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Initial-IMS-Charging-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2321, /* Code */
+ 10415, /* Vendor */
+ "Initial-IMS-Charging-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Inter-Operator-Identifier */
+ {
+ struct dict_avp_data data = {
+ 838, /* Code */
+ 10415, /* Vendor */
+ "Inter-Operator-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Interface-Id */
+ {
+ struct dict_avp_data data = {
+ 2003, /* Code */
+ 10415, /* Vendor */
+ "Interface-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Interface-Port */
+ {
+ struct dict_avp_data data = {
+ 2004, /* Code */
+ 10415, /* Vendor */
+ "Interface-Port", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Interface-Text */
+ {
+ struct dict_avp_data data = {
+ 2005, /* Code */
+ 10415, /* Vendor */
+ "Interface-Text", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Interface-Type */
+ {
+ struct dict_avp_data data = {
+ 2006, /* Code */
+ 10415, /* Vendor */
+ "Interface-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Interface-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* LCS-APN */
+ {
+ struct dict_avp_data data = {
+ 1231, /* Code */
+ 10415, /* Vendor */
+ "LCS-APN", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* LCS-Client-Dialed-By-MS */
+ {
+ struct dict_avp_data data = {
+ 1233, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-Dialed-By-MS", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* LCS-Client-External-ID */
+ {
+ struct dict_avp_data data = {
+ 1234, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-External-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* LCS-Client-Id */
+ {
+ struct dict_avp_data data = {
+ 1232, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* LCS-Client-Name */
+ {
+ struct dict_avp_data data = {
+ 1235, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* LCS-Client-Type */
+ {
+ struct dict_avp_data data = {
+ 1241, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(LCS-Client-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* LCS-Data-Coding-Scheme */
+ {
+ struct dict_avp_data data = {
+ 1236, /* Code */
+ 10415, /* Vendor */
+ "LCS-Data-Coding-Scheme", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* LCS-Format-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1237, /* Code */
+ 10415, /* Vendor */
+ "LCS-Format-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(LCS-Format-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* LCS-Information */
+ {
+ struct dict_avp_data data = {
+ 878, /* Code */
+ 10415, /* Vendor */
+ "LCS-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* LCS-Name-String */
+ {
+ struct dict_avp_data data = {
+ 1238, /* Code */
+ 10415, /* Vendor */
+ "LCS-Name-String", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* LCS-Requestor-Id */
+ {
+ struct dict_avp_data data = {
+ 1239, /* Code */
+ 10415, /* Vendor */
+ "LCS-Requestor-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* LCS-Requestor-Id-String */
+ {
+ struct dict_avp_data data = {
+ 1240, /* Code */
+ 10415, /* Vendor */
+ "LCS-Requestor-Id-String", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Local-GW-Inserted-Indication */
+ {
+ struct dict_avp_data data = {
+ 2604, /* Code */
+ 10415, /* Vendor */
+ "Local-GW-Inserted-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Local-GW-Inserted-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Local-Sequence-Number */
+ {
+ struct dict_avp_data data = {
+ 2063, /* Code */
+ 10415, /* Vendor */
+ "Local-Sequence-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Location-Estimate */
+ {
+ struct dict_avp_data data = {
+ 1242, /* Code */
+ 10415, /* Vendor */
+ "Location-Estimate", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Location-Estimate-Type */
+ {
+ struct dict_avp_data data = {
+ 1243, /* Code */
+ 10415, /* Vendor */
+ "Location-Estimate-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Location-Estimate-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Location-Type */
+ {
+ struct dict_avp_data data = {
+ 1244, /* Code */
+ 10415, /* Vendor */
+ "Location-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Low-Balance-Indication */
+ {
+ struct dict_avp_data data = {
+ 2020, /* Code */
+ 10415, /* Vendor */
+ "Low-Balance-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Low-Balance-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Low-Priority-Indicator */
+ {
+ struct dict_avp_data data = {
+ 2602, /* Code */
+ 10415, /* Vendor */
+ "Low-Priority-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Low-Priority-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MBMSGW-Address */
+ {
+ struct dict_avp_data data = {
+ 2307, /* Code */
+ 10415, /* Vendor */
+ "MBMSGW-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* MBMS-Information */
+ {
+ struct dict_avp_data data = {
+ 880, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MBMS-User-Service-Type */
+ {
+ struct dict_avp_data data = {
+ 1225, /* Code */
+ 10415, /* Vendor */
+ "MBMS-User-Service-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-User-Service-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MM-Content-Type */
+ {
+ struct dict_avp_data data = {
+ 1203, /* Code */
+ 10415, /* Vendor */
+ "MM-Content-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MMBox-Storage-Requested */
+ {
+ struct dict_avp_data data = {
+ 1248, /* Code */
+ 10415, /* Vendor */
+ "MMBox-Storage-Requested", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MMBox-Storage-Requested)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MMS-Information */
+ {
+ struct dict_avp_data data = {
+ 877, /* Code */
+ 10415, /* Vendor */
+ "MMS-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MMTel-Information */
+ {
+ struct dict_avp_data data = {
+ 2030, /* Code */
+ 10415, /* Vendor */
+ "MMTel-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MMTel-SService-Type */
+ {
+ struct dict_avp_data data = {
+ 2031, /* Code */
+ 10415, /* Vendor */
+ "MMTel-SService-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Media-Initiator-Flag */
+ {
+ struct dict_avp_data data = {
+ 882, /* Code */
+ 10415, /* Vendor */
+ "Media-Initiator-Flag", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Media-Initiator-Flag)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Media-Initiator-Party */
+ {
+ struct dict_avp_data data = {
+ 1288, /* Code */
+ 10415, /* Vendor */
+ "Media-Initiator-Party", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Message-Body */
+ {
+ struct dict_avp_data data = {
+ 889, /* Code */
+ 10415, /* Vendor */
+ "Message-Body", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Message-Class */
+ {
+ struct dict_avp_data data = {
+ 1213, /* Code */
+ 10415, /* Vendor */
+ "Message-Class", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Message-ID */
+ {
+ struct dict_avp_data data = {
+ 1210, /* Code */
+ 10415, /* Vendor */
+ "Message-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Message-Size */
+ {
+ struct dict_avp_data data = {
+ 1212, /* Code */
+ 10415, /* Vendor */
+ "Message-Size", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Message-Type */
+ {
+ struct dict_avp_data data = {
+ 1211, /* Code */
+ 10415, /* Vendor */
+ "Message-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Message-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* NNI-Information */
+ {
+ struct dict_avp_data data = {
+ 2703, /* Code */
+ 10415, /* Vendor */
+ "NNI-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* NNI-Type */
+ {
+ struct dict_avp_data data = {
+ 2704, /* Code */
+ 10415, /* Vendor */
+ "NNI-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(NNI-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Neighbour-Node-Address */
+ {
+ struct dict_avp_data data = {
+ 2705, /* Code */
+ 10415, /* Vendor */
+ "Neighbour-Node-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Next-Tariff */
+ {
+ struct dict_avp_data data = {
+ 2057, /* Code */
+ 10415, /* Vendor */
+ "Next-Tariff", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Node-Functionality */
+ {
+ struct dict_avp_data data = {
+ 862, /* Code */
+ 10415, /* Vendor */
+ "Node-Functionality", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Node-Functionality)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Node-Id */
+ {
+ struct dict_avp_data data = {
+ 2064, /* Code */
+ 10415, /* Vendor */
+ "Node-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Number-Of-Diversions */
+ {
+ struct dict_avp_data data = {
+ 2034, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Diversions", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Number-Of-Messages-Sent */
+ {
+ struct dict_avp_data data = {
+ 2019, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Messages-Sent", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Number-Of-Participants */
+ {
+ struct dict_avp_data data = {
+ 885, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Participants", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Number-Of-Received-Talk-Bursts */
+ {
+ struct dict_avp_data data = {
+ 1282, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Received-Talk-Bursts", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Number-Of-Talk-Bursts */
+ {
+ struct dict_avp_data data = {
+ 1283, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Talk-Bursts", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Number-Portability-Routing-Information */
+ {
+ struct dict_avp_data data = {
+ 2024, /* Code */
+ 10415, /* Vendor */
+ "Number-Portability-Routing-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Offline-Charging */
+ {
+ struct dict_avp_data data = {
+ 1278, /* Code */
+ 10415, /* Vendor */
+ "Offline-Charging", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Online-Charging-Flag */
+ {
+ struct dict_avp_data data = {
+ 2303, /* Code */
+ 10415, /* Vendor */
+ "Online-Charging-Flag", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Online-Charging-Flag)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Originating-IOI */
+ {
+ struct dict_avp_data data = {
+ 839, /* Code */
+ 10415, /* Vendor */
+ "Originating-IOI", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Originator */
+ {
+ struct dict_avp_data data = {
+ 864, /* Code */
+ 10415, /* Vendor */
+ "Originator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Originator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Originator-Address */
+ {
+ struct dict_avp_data data = {
+ 886, /* Code */
+ 10415, /* Vendor */
+ "Originator-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Originator-Interface */
+ {
+ struct dict_avp_data data = {
+ 2009, /* Code */
+ 10415, /* Vendor */
+ "Originator-Interface", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Originator-Received-Address */
+ {
+ struct dict_avp_data data = {
+ 2027, /* Code */
+ 10415, /* Vendor */
+ "Originator-Received-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Originator-SCCP-Address */
+ {
+ struct dict_avp_data data = {
+ 2008, /* Code */
+ 10415, /* Vendor */
+ "Originator-SCCP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Outgoing-Session-Id */
+ {
+ struct dict_avp_data data = {
+ 2320, /* Code */
+ 10415, /* Vendor */
+ "Outgoing-Session-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Outgoing-Trunk-Group-Id */
+ {
+ struct dict_avp_data data = {
+ 853, /* Code */
+ 10415, /* Vendor */
+ "Outgoing-Trunk-Group-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* PDG-Address */
+ {
+ struct dict_avp_data data = {
+ 895, /* Code */
+ 10415, /* Vendor */
+ "PDG-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* PDG-Charging-Id */
+ {
+ struct dict_avp_data data = {
+ 896, /* Code */
+ 10415, /* Vendor */
+ "PDG-Charging-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PDN-Connection-Charging-ID */
+ {
+ struct dict_avp_data data = {
+ 2050, /* Code */
+ 10415, /* Vendor */
+ "PDN-Connection-Charging-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PDP-Address */
+ {
+ struct dict_avp_data data = {
+ 1227, /* Code */
+ 10415, /* Vendor */
+ "PDP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* PDP-Address-Prefix-Length */
+ {
+ struct dict_avp_data data = {
+ 2606, /* Code */
+ 10415, /* Vendor */
+ "PDP-Address-Prefix-Length", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PDP-Context-Type */
+ {
+ struct dict_avp_data data = {
+ 1247, /* Code */
+ 10415, /* Vendor */
+ "PDP-Context-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PDP-Context-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PS-Append-Free-Format-Data */
+ {
+ struct dict_avp_data data = {
+ 867, /* Code */
+ 10415, /* Vendor */
+ "PS-Append-Free-Format-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PS-Append-Free-Format-Data)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PS-Free-Format-Data */
+ {
+ struct dict_avp_data data = {
+ 866, /* Code */
+ 10415, /* Vendor */
+ "PS-Free-Format-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PS-Furnish-Charging-Information */
+ {
+ struct dict_avp_data data = {
+ 865, /* Code */
+ 10415, /* Vendor */
+ "PS-Furnish-Charging-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PS-Information */
+ {
+ struct dict_avp_data data = {
+ 874, /* Code */
+ 10415, /* Vendor */
+ "PS-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Participant-Access-Priority */
+ {
+ struct dict_avp_data data = {
+ 1259, /* Code */
+ 10415, /* Vendor */
+ "Participant-Access-Priority", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Participant-Access-Priority)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Participant-Action-Type */
+ {
+ struct dict_avp_data data = {
+ 2049, /* Code */
+ 10415, /* Vendor */
+ "Participant-Action-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Participant-Action-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Participant-Group */
+ {
+ struct dict_avp_data data = {
+ 1260, /* Code */
+ 10415, /* Vendor */
+ "Participant-Group", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Participants-Involved */
+ {
+ struct dict_avp_data data = {
+ 887, /* Code */
+ 10415, /* Vendor */
+ "Participants-Involved", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* PoC-Change-Condition */
+ {
+ struct dict_avp_data data = {
+ 1261, /* Code */
+ 10415, /* Vendor */
+ "PoC-Change-Condition", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Change-Condition)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PoC-Change-Time */
+ {
+ struct dict_avp_data data = {
+ 1262, /* Code */
+ 10415, /* Vendor */
+ "PoC-Change-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* PoC-Controlling-Address */
+ {
+ struct dict_avp_data data = {
+ 858, /* Code */
+ 10415, /* Vendor */
+ "PoC-Controlling-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* PoC-Event-Type */
+ {
+ struct dict_avp_data data = {
+ 2025, /* Code */
+ 10415, /* Vendor */
+ "PoC-Event-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Event-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PoC-Group-Name */
+ {
+ struct dict_avp_data data = {
+ 859, /* Code */
+ 10415, /* Vendor */
+ "PoC-Group-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* PoC-Information */
+ {
+ struct dict_avp_data data = {
+ 879, /* Code */
+ 10415, /* Vendor */
+ "PoC-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PoC-Server-Role */
+ {
+ struct dict_avp_data data = {
+ 883, /* Code */
+ 10415, /* Vendor */
+ "PoC-Server-Role", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Server-Role)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PoC-Session-Id */
+ {
+ struct dict_avp_data data = {
+ 1229, /* Code */
+ 10415, /* Vendor */
+ "PoC-Session-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* PoC-Session-Initiation-type */
+ {
+ struct dict_avp_data data = {
+ 1277, /* Code */
+ 10415, /* Vendor */
+ "PoC-Session-Initiation-type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Session-Initiation-type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PoC-Session-Type */
+ {
+ struct dict_avp_data data = {
+ 884, /* Code */
+ 10415, /* Vendor */
+ "PoC-Session-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Session-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PoC-User-Role */
+ {
+ struct dict_avp_data data = {
+ 1252, /* Code */
+ 10415, /* Vendor */
+ "PoC-User-Role", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PoC-User-Role-IDs */
+ {
+ struct dict_avp_data data = {
+ 1253, /* Code */
+ 10415, /* Vendor */
+ "PoC-User-Role-IDs", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* PoC-User-Role-info-Units */
+ {
+ struct dict_avp_data data = {
+ 1254, /* Code */
+ 10415, /* Vendor */
+ "PoC-User-Role-info-Units", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-User-Role-info-Units)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Positioning-Data */
+ {
+ struct dict_avp_data data = {
+ 1245, /* Code */
+ 10415, /* Vendor */
+ "Positioning-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Preferred-AoC-Currency */
+ {
+ struct dict_avp_data data = {
+ 2315, /* Code */
+ 10415, /* Vendor */
+ "Preferred-AoC-Currency", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Priority */
+ {
+ struct dict_avp_data data = {
+ 1209, /* Code */
+ 10415, /* Vendor */
+ "Priority", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Priority)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Quota-Consumption-Time */
+ {
+ struct dict_avp_data data = {
+ 881, /* Code */
+ 10415, /* Vendor */
+ "Quota-Consumption-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Quota-Holding-Time */
+ {
+ struct dict_avp_data data = {
+ 871, /* Code */
+ 10415, /* Vendor */
+ "Quota-Holding-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Rate-Element */
+ {
+ struct dict_avp_data data = {
+ 2058, /* Code */
+ 10415, /* Vendor */
+ "Rate-Element", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Read-Reply-Report-Requested */
+ {
+ struct dict_avp_data data = {
+ 1222, /* Code */
+ 10415, /* Vendor */
+ "Read-Reply-Report-Requested", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Read-Reply-Report-Requested)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Real-Time-Tariff-Information */
+ {
+ struct dict_avp_data data = {
+ 2305, /* Code */
+ 10415, /* Vendor */
+ "Real-Time-Tariff-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Received-Talk-Burst-Time */
+ {
+ struct dict_avp_data data = {
+ 1284, /* Code */
+ 10415, /* Vendor */
+ "Received-Talk-Burst-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Received-Talk-Burst-Volume */
+ {
+ struct dict_avp_data data = {
+ 1285, /* Code */
+ 10415, /* Vendor */
+ "Received-Talk-Burst-Volume", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Recipient-Address */
+ {
+ struct dict_avp_data data = {
+ 1201, /* Code */
+ 10415, /* Vendor */
+ "Recipient-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Recipient-Info */
+ {
+ struct dict_avp_data data = {
+ 2026, /* Code */
+ 10415, /* Vendor */
+ "Recipient-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Recipient-Received-Address */
+ {
+ struct dict_avp_data data = {
+ 2028, /* Code */
+ 10415, /* Vendor */
+ "Recipient-Received-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Recipient-SCCP-Address */
+ {
+ struct dict_avp_data data = {
+ 2010, /* Code */
+ 10415, /* Vendor */
+ "Recipient-SCCP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Refund-Information */
+ {
+ struct dict_avp_data data = {
+ 2022, /* Code */
+ 10415, /* Vendor */
+ "Refund-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Relationship-Mode */
+ {
+ struct dict_avp_data data = {
+ 2706, /* Code */
+ 10415, /* Vendor */
+ "Relationship-Mode", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Relationship-Mode)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Remaining-Balance */
+ {
+ struct dict_avp_data data = {
+ 2021, /* Code */
+ 10415, /* Vendor */
+ "Remaining-Balance", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Reply-Applic-ID */
+ {
+ struct dict_avp_data data = {
+ 1223, /* Code */
+ 10415, /* Vendor */
+ "Reply-Applic-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Reply-Path-Requested */
+ {
+ struct dict_avp_data data = {
+ 2011, /* Code */
+ 10415, /* Vendor */
+ "Reply-Path-Requested", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Reply-Path-Requested)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Reporting-Reason */
+ {
+ struct dict_avp_data data = {
+ 872, /* Code */
+ 10415, /* Vendor */
+ "Reporting-Reason", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Reporting-Reason)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Requested-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 1251, /* Code */
+ 10415, /* Vendor */
+ "Requested-Party-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Role-Of-Node */
+ {
+ struct dict_avp_data data = {
+ 829, /* Code */
+ 10415, /* Vendor */
+ "Role-Of-Node", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Role-Of-Node)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SDP-Answer-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 1275, /* Code */
+ 10415, /* Vendor */
+ "SDP-Answer-Timestamp", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* SDP-Media-Component */
+ {
+ struct dict_avp_data data = {
+ 843, /* Code */
+ 10415, /* Vendor */
+ "SDP-Media-Component", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SDP-Media-Description */
+ {
+ struct dict_avp_data data = {
+ 845, /* Code */
+ 10415, /* Vendor */
+ "SDP-Media-Description", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SDP-Media-Name */
+ {
+ struct dict_avp_data data = {
+ 844, /* Code */
+ 10415, /* Vendor */
+ "SDP-Media-Name", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SDP-Offer-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 1274, /* Code */
+ 10415, /* Vendor */
+ "SDP-Offer-Timestamp", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* SDP-Session-Description */
+ {
+ struct dict_avp_data data = {
+ 842, /* Code */
+ 10415, /* Vendor */
+ "SDP-Session-Description", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SDP-TimeStamps */
+ {
+ struct dict_avp_data data = {
+ 1273, /* Code */
+ 10415, /* Vendor */
+ "SDP-TimeStamps", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SDP-Type */
+ {
+ struct dict_avp_data data = {
+ 2036, /* Code */
+ 10415, /* Vendor */
+ "SDP-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SDP-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 1228, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* SGW-Address */
+ {
+ struct dict_avp_data data = {
+ 2067, /* Code */
+ 10415, /* Vendor */
+ "SGW-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* SGW-Change */
+ {
+ struct dict_avp_data data = {
+ 2065, /* Code */
+ 10415, /* Vendor */
+ "SGW-Change", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SGW-Change)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SIP-Method */
+ {
+ struct dict_avp_data data = {
+ 824, /* Code */
+ 10415, /* Vendor */
+ "SIP-Method", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SIP-Request-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 834, /* Code */
+ 10415, /* Vendor */
+ "SIP-Request-Timestamp", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* SIP-Request-Timestamp-Fraction */
+ {
+ struct dict_avp_data data = {
+ 2301, /* Code */
+ 10415, /* Vendor */
+ "SIP-Request-Timestamp-Fraction", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SIP-Response-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 835, /* Code */
+ 10415, /* Vendor */
+ "SIP-Response-Timestamp", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* SIP-Response-Timestamp-Fraction */
+ {
+ struct dict_avp_data data = {
+ 2302, /* Code */
+ 10415, /* Vendor */
+ "SIP-Response-Timestamp-Fraction", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SM-Discharge-Time */
+ {
+ struct dict_avp_data data = {
+ 2012, /* Code */
+ 10415, /* Vendor */
+ "SM-Discharge-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* SM-Message-Type */
+ {
+ struct dict_avp_data data = {
+ 2007, /* Code */
+ 10415, /* Vendor */
+ "SM-Message-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-Message-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SM-Protocol-ID */
+ {
+ struct dict_avp_data data = {
+ 2013, /* Code */
+ 10415, /* Vendor */
+ "SM-Protocol-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SM-Service-Type */
+ {
+ struct dict_avp_data data = {
+ 2029, /* Code */
+ 10415, /* Vendor */
+ "SM-Service-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-Service-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SM-Status */
+ {
+ struct dict_avp_data data = {
+ 2014, /* Code */
+ 10415, /* Vendor */
+ "SM-Status", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SM-User-Data-Header */
+ {
+ struct dict_avp_data data = {
+ 2015, /* Code */
+ 10415, /* Vendor */
+ "SM-User-Data-Header", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SMS-Information */
+ {
+ struct dict_avp_data data = {
+ 2000, /* Code */
+ 10415, /* Vendor */
+ "SMS-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SMS-Node */
+ {
+ struct dict_avp_data data = {
+ 2016, /* Code */
+ 10415, /* Vendor */
+ "SMS-Node", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SMS-Node)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SMSC-Address */
+ {
+ struct dict_avp_data data = {
+ 2017, /* Code */
+ 10415, /* Vendor */
+ "SMSC-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Scale-Factor */
+ {
+ struct dict_avp_data data = {
+ 2059, /* Code */
+ 10415, /* Vendor */
+ "Scale-Factor", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Served-Party-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 848, /* Code */
+ 10415, /* Vendor */
+ "Served-Party-IP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Service-Data-Container */
+ {
+ struct dict_avp_data data = {
+ 2040, /* Code */
+ 10415, /* Vendor */
+ "Service-Data-Container", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Service-Id */
+ {
+ struct dict_avp_data data = {
+ 855, /* Code */
+ 10415, /* Vendor */
+ "Service-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Service-Information */
+ {
+ struct dict_avp_data data = {
+ 873, /* Code */
+ 10415, /* Vendor */
+ "Service-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Service-Mode */
+ {
+ struct dict_avp_data data = {
+ 2032, /* Code */
+ 10415, /* Vendor */
+ "Service-Mode", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Service-Specific-Data */
+ {
+ struct dict_avp_data data = {
+ 863, /* Code */
+ 10415, /* Vendor */
+ "Service-Specific-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Service-Specific-Info */
+ {
+ struct dict_avp_data data = {
+ 1249, /* Code */
+ 10415, /* Vendor */
+ "Service-Specific-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Service-Specific-Type */
+ {
+ struct dict_avp_data data = {
+ 1257, /* Code */
+ 10415, /* Vendor */
+ "Service-Specific-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Serving-Node-Type */
+ {
+ struct dict_avp_data data = {
+ 2047, /* Code */
+ 10415, /* Vendor */
+ "Serving-Node-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Serving-Node-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Session-Direction */
+ {
+ struct dict_avp_data data = {
+ 2707, /* Code */
+ 10415, /* Vendor */
+ "Session-Direction", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Direction)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Start-Time */
+ {
+ struct dict_avp_data data = {
+ 2041, /* Code */
+ 10415, /* Vendor */
+ "Start-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Status */
+ {
+ struct dict_avp_data data = {
+ 2702, /* Code */
+ 10415, /* Vendor */
+ "Status", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Status)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Stop-Time */
+ {
+ struct dict_avp_data data = {
+ 2042, /* Code */
+ 10415, /* Vendor */
+ "Stop-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Submission-Time */
+ {
+ struct dict_avp_data data = {
+ 1202, /* Code */
+ 10415, /* Vendor */
+ "Submission-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Subscriber-Role */
+ {
+ struct dict_avp_data data = {
+ 2033, /* Code */
+ 10415, /* Vendor */
+ "Subscriber-Role", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Subscriber-Role)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Supplementary-Service */
+ {
+ struct dict_avp_data data = {
+ 2048, /* Code */
+ 10415, /* Vendor */
+ "Supplementary-Service", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Talk-Burst-Exchange */
+ {
+ struct dict_avp_data data = {
+ 1255, /* Code */
+ 10415, /* Vendor */
+ "Talk-Burst-Exchange", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Talk-Burst-Time */
+ {
+ struct dict_avp_data data = {
+ 1286, /* Code */
+ 10415, /* Vendor */
+ "Talk-Burst-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Talk-Burst-Volume */
+ {
+ struct dict_avp_data data = {
+ 1287, /* Code */
+ 10415, /* Vendor */
+ "Talk-Burst-Volume", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Tariff-Information */
+ {
+ struct dict_avp_data data = {
+ 2060, /* Code */
+ 10415, /* Vendor */
+ "Tariff-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Tariff-XML */
+ {
+ struct dict_avp_data data = {
+ 2306, /* Code */
+ 10415, /* Vendor */
+ "Tariff-XML", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Terminating-IOI */
+ {
+ struct dict_avp_data data = {
+ 840, /* Code */
+ 10415, /* Vendor */
+ "Terminating-IOI", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Time-First-Usage */
+ {
+ struct dict_avp_data data = {
+ 2043, /* Code */
+ 10415, /* Vendor */
+ "Time-First-Usage", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Time-Last-Usage */
+ {
+ struct dict_avp_data data = {
+ 2044, /* Code */
+ 10415, /* Vendor */
+ "Time-Last-Usage", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Time-Quota-Mechanism */
+ {
+ struct dict_avp_data data = {
+ 1270, /* Code */
+ 10415, /* Vendor */
+ "Time-Quota-Mechanism", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Time-Quota-Threshold */
+ {
+ struct dict_avp_data data = {
+ 868, /* Code */
+ 10415, /* Vendor */
+ "Time-Quota-Threshold", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Time-Quota-Type */
+ {
+ struct dict_avp_data data = {
+ 1271, /* Code */
+ 10415, /* Vendor */
+ "Time-Quota-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Time-Quota-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Time-Stamps */
+ {
+ struct dict_avp_data data = {
+ 833, /* Code */
+ 10415, /* Vendor */
+ "Time-Stamps", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Time-Usage */
+ {
+ struct dict_avp_data data = {
+ 2045, /* Code */
+ 10415, /* Vendor */
+ "Time-Usage", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Token-Text */
+ {
+ struct dict_avp_data data = {
+ 1215, /* Code */
+ 10415, /* Vendor */
+ "Token-Text", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Traffic-Data-Volumes */
+ {
+ struct dict_avp_data data = {
+ 2046, /* Code */
+ 10415, /* Vendor */
+ "Traffic-Data-Volumes", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Transcoder-Inserted-Indication */
+ {
+ struct dict_avp_data data = {
+ 2605, /* Code */
+ 10415, /* Vendor */
+ "Transcoder-Inserted-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Transcoder-Inserted-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Transit-IOI-List */
+ {
+ struct dict_avp_data data = {
+ 2701, /* Code */
+ 10415, /* Vendor */
+ "Transit-IOI-List", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Trigger */
+ {
+ struct dict_avp_data data = {
+ 1264, /* Code */
+ 10415, /* Vendor */
+ "Trigger", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Trigger-Type */
+ {
+ struct dict_avp_data data = {
+ 870, /* Code */
+ 10415, /* Vendor */
+ "Trigger-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Trigger-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Trunk-Group-Id */
+ {
+ struct dict_avp_data data = {
+ 851, /* Code */
+ 10415, /* Vendor */
+ "Trunk-Group-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Type-Number */
+ {
+ struct dict_avp_data data = {
+ 1204, /* Code */
+ 10415, /* Vendor */
+ "Type-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Type-Number)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Unit-Cost */
+ {
+ struct dict_avp_data data = {
+ 2061, /* Code */
+ 10415, /* Vendor */
+ "Unit-Cost", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Unit-Quota-Threshold */
+ {
+ struct dict_avp_data data = {
+ 1226, /* Code */
+ 10415, /* Vendor */
+ "Unit-Quota-Threshold", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* User-CSG-Information */
+ {
+ struct dict_avp_data data = {
+ 2319, /* Code */
+ 10415, /* Vendor */
+ "User-CSG-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* User-Participating-Type */
+ {
+ struct dict_avp_data data = {
+ 1279, /* Code */
+ 10415, /* Vendor */
+ "User-Participating-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(User-Participating-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* User-Session-Id */
+ {
+ struct dict_avp_data data = {
+ 830, /* Code */
+ 10415, /* Vendor */
+ "User-Session-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Volume-Quota-Threshold */
+ {
+ struct dict_avp_data data = {
+ 869, /* Code */
+ 10415, /* Vendor */
+ "Volume-Quota-Threshold", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* WAG-Address */
+ {
+ struct dict_avp_data data = {
+ 890, /* Code */
+ 10415, /* Vendor */
+ "WAG-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* WAG-PLMN-Id */
+ {
+ struct dict_avp_data data = {
+ 891, /* Code */
+ 10415, /* Vendor */
+ "WAG-PLMN-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* WLAN-Information */
+ {
+ struct dict_avp_data data = {
+ 875, /* Code */
+ 10415, /* Vendor */
+ "WLAN-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* WLAN-Radio-Container */
+ {
+ struct dict_avp_data data = {
+ 892, /* Code */
+ 10415, /* Vendor */
+ "WLAN-Radio-Container", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* WLAN-Session-Id */
+ {
+ struct dict_avp_data data = {
+ 1246, /* Code */
+ 10415, /* Vendor */
+ "WLAN-Session-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* WLAN-Technology */
+ {
+ struct dict_avp_data data = {
+ 893, /* Code */
+ 10415, /* Vendor */
+ "WLAN-Technology", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* WLAN-UE-Local-IPAddress */
+ {
+ struct dict_avp_data data = {
+ 894, /* Code */
+ 10415, /* Vendor */
+ "WLAN-UE-Local-IPAddress", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* 3GPP 29.272-c00 (12.0.0 2013.03.13) */
+ /* Subscription-Data */
+ {
+ struct dict_avp_data data = {
+ 1400, /* Code */
+ 10415, /* Vendor */
+ "Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Terminal-Information */
+ {
+ struct dict_avp_data data = {
+ 1401, /* Code */
+ 10415, /* Vendor */
+ "Terminal-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* IMEI */
+ {
+ struct dict_avp_data data = {
+ 1402, /* Code */
+ 10415, /* Vendor */
+ "IMEI", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Software-Version */
+ {
+ struct dict_avp_data data = {
+ 1403, /* Code */
+ 10415, /* Vendor */
+ "Software-Version", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* QoS-Subscribed */
+ {
+ struct dict_avp_data data = {
+ 1404, /* Code */
+ 10415, /* Vendor */
+ "QoS-Subscribed", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* ULR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1405, /* Code */
+ 10415, /* Vendor */
+ "ULR-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* ULA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1406, /* Code */
+ 10415, /* Vendor */
+ "ULA-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Visited-PLMN-Id */
+ {
+ struct dict_avp_data data = {
+ 1407, /* Code */
+ 10415, /* Vendor */
+ "Visited-PLMN-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Requested-EUTRAN-Authentication-Info */
+ {
+ struct dict_avp_data data = {
+ 1408, /* Code */
+ 10415, /* Vendor */
+ "Requested-EUTRAN-Authentication-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Requested-UTRAN-GERAN-Authentication-Info */
+ {
+ struct dict_avp_data data = {
+ 1409, /* Code */
+ 10415, /* Vendor */
+ "Requested-UTRAN-GERAN-Authentication-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Number-Of-Requested-Vectors */
+ {
+ struct dict_avp_data data = {
+ 1410, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Requested-Vectors", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Re-Synchronization-Info */
+ {
+ struct dict_avp_data data = {
+ 1411, /* Code */
+ 10415, /* Vendor */
+ "Re-Synchronization-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Immediate-Response-Preferred */
+ {
+ struct dict_avp_data data = {
+ 1412, /* Code */
+ 10415, /* Vendor */
+ "Immediate-Response-Preferred", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Authentication-Info */
+ {
+ struct dict_avp_data data = {
+ 1413, /* Code */
+ 10415, /* Vendor */
+ "Authentication-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* E-UTRAN-Vector */
+ {
+ struct dict_avp_data data = {
+ 1414, /* Code */
+ 10415, /* Vendor */
+ "E-UTRAN-Vector", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* UTRAN-Vector */
+ {
+ struct dict_avp_data data = {
+ 1415, /* Code */
+ 10415, /* Vendor */
+ "UTRAN-Vector", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* GERAN-Vector */
+ {
+ struct dict_avp_data data = {
+ 1416, /* Code */
+ 10415, /* Vendor */
+ "GERAN-Vector", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Network-Access-Mode */
+ {
+ struct dict_avp_data data = {
+ 1417, /* Code */
+ 10415, /* Vendor */
+ "Network-Access-Mode", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Network-Access-Mode)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* HPLMN-ODB */
+ {
+ struct dict_avp_data data = {
+ 1418, /* Code */
+ 10415, /* Vendor */
+ "HPLMN-ODB", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Item-Number */
+ {
+ struct dict_avp_data data = {
+ 1419, /* Code */
+ 10415, /* Vendor */
+ "Item-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Cancellation-Type */
+ {
+ struct dict_avp_data data = {
+ 1420, /* Code */
+ 10415, /* Vendor */
+ "Cancellation-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Cancellation-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* DSR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1421, /* Code */
+ 10415, /* Vendor */
+ "DSR-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* DSA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1422, /* Code */
+ 10415, /* Vendor */
+ "DSA-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Context-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1423, /* Code */
+ 10415, /* Vendor */
+ "Context-Identifier", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Subscriber-Status */
+ {
+ struct dict_avp_data data = {
+ 1424, /* Code */
+ 10415, /* Vendor */
+ "Subscriber-Status", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Subscriber-Status)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Operator-Determined-Barring */
+ {
+ struct dict_avp_data data = {
+ 1425, /* Code */
+ 10415, /* Vendor */
+ "Operator-Determined-Barring", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Access-Restriction-Data */
+ {
+ struct dict_avp_data data = {
+ 1426, /* Code */
+ 10415, /* Vendor */
+ "Access-Restriction-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* APN-OI-Replacement */
+ {
+ struct dict_avp_data data = {
+ 1427, /* Code */
+ 10415, /* Vendor */
+ "APN-OI-Replacement", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* All-APN-Configurations-Included-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1428, /* Code */
+ 10415, /* Vendor */
+ "All-APN-Configurations-Included-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(All-APN-Configurations-Included-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* APN-Configuration-Profile */
+ {
+ struct dict_avp_data data = {
+ 1429, /* Code */
+ 10415, /* Vendor */
+ "APN-Configuration-Profile", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* APN-Configuration */
+ {
+ struct dict_avp_data data = {
+ 1430, /* Code */
+ 10415, /* Vendor */
+ "APN-Configuration", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* EPS-Subscribed-QoS-Profile */
+ {
+ struct dict_avp_data data = {
+ 1431, /* Code */
+ 10415, /* Vendor */
+ "EPS-Subscribed-QoS-Profile", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* VPLMN-Dynamic-Address-Allowed */
+ {
+ struct dict_avp_data data = {
+ 1432, /* Code */
+ 10415, /* Vendor */
+ "VPLMN-Dynamic-Address-Allowed", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(VPLMN-Dynamic-Address-Allowed)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* STN-SR */
+ {
+ struct dict_avp_data data = {
+ 1433, /* Code */
+ 10415, /* Vendor */
+ "STN-SR", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Alert-Reason */
+ {
+ struct dict_avp_data data = {
+ 1434, /* Code */
+ 10415, /* Vendor */
+ "Alert-Reason", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Alert-Reason)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* AMBR */
+ {
+ struct dict_avp_data data = {
+ 1435, /* Code */
+ 10415, /* Vendor */
+ "AMBR", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* CSG-Subscription-Data */
+ {
+ struct dict_avp_data data = {
+ 1436, /* Code */
+ 10415, /* Vendor */
+ "CSG-Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* CSG-Id */
+ {
+ struct dict_avp_data data = {
+ 1437, /* Code */
+ 10415, /* Vendor */
+ "CSG-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PDN-GW-Allocation-Type */
+ {
+ struct dict_avp_data data = {
+ 1438, /* Code */
+ 10415, /* Vendor */
+ "PDN-GW-Allocation-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PDN-GW-Allocation-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Expiration-Date */
+ {
+ struct dict_avp_data data = {
+ 1439, /* Code */
+ 10415, /* Vendor */
+ "Expiration-Date", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* RAT-Frequency-Selection-Priority-ID */
+ {
+ struct dict_avp_data data = {
+ 1440, /* Code */
+ 10415, /* Vendor */
+ "RAT-Frequency-Selection-Priority-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* IDA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1441, /* Code */
+ 10415, /* Vendor */
+ "IDA-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PUA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1442, /* Code */
+ 10415, /* Vendor */
+ "PUA-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* NOR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1443, /* Code */
+ 10415, /* Vendor */
+ "NOR-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* User-Id */
+ {
+ struct dict_avp_data data = {
+ 1444, /* Code */
+ 10415, /* Vendor */
+ "User-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Equipment-Status */
+ {
+ struct dict_avp_data data = {
+ 1445, /* Code */
+ 10415, /* Vendor */
+ "Equipment-Status", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Equipment-Status)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Regional-Subscription-Zone-Code */
+ {
+ struct dict_avp_data data = {
+ 1446, /* Code */
+ 10415, /* Vendor */
+ "Regional-Subscription-Zone-Code", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* RAND */
+ {
+ struct dict_avp_data data = {
+ 1447, /* Code */
+ 10415, /* Vendor */
+ "RAND", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* XRES */
+ {
+ struct dict_avp_data data = {
+ 1448, /* Code */
+ 10415, /* Vendor */
+ "XRES", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* AUTN */
+ {
+ struct dict_avp_data data = {
+ 1449, /* Code */
+ 10415, /* Vendor */
+ "AUTN", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* KASME */
+ {
+ struct dict_avp_data data = {
+ 1450, /* Code */
+ 10415, /* Vendor */
+ "KASME", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Trace-Collection-Entity */
+ {
+ struct dict_avp_data data = {
+ 1452, /* Code */
+ 10415, /* Vendor */
+ "Trace-Collection-Entity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* Kc */
+ {
+ struct dict_avp_data data = {
+ 1453, /* Code */
+ 10415, /* Vendor */
+ "Kc", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SRES */
+ {
+ struct dict_avp_data data = {
+ 1454, /* Code */
+ 10415, /* Vendor */
+ "SRES", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PDN-Type */
+ {
+ struct dict_avp_data data = {
+ 1456, /* Code */
+ 10415, /* Vendor */
+ "PDN-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PDN-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Roaming-Restricted-Due-To-Unsupported-Feature */
+ {
+ struct dict_avp_data data = {
+ 1457, /* Code */
+ 10415, /* Vendor */
+ "Roaming-Restricted-Due-To-Unsupported-Feature", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Roaming-Restricted-Due-To-Unsupported-Feature)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Trace-Data */
+ {
+ struct dict_avp_data data = {
+ 1458, /* Code */
+ 10415, /* Vendor */
+ "Trace-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Trace-Reference */
+ {
+ struct dict_avp_data data = {
+ 1459, /* Code */
+ 10415, /* Vendor */
+ "Trace-Reference", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Trace-Depth */
+ {
+ struct dict_avp_data data = {
+ 1462, /* Code */
+ 10415, /* Vendor */
+ "Trace-Depth", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Trace-Depth)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Trace-NE-Type-List */
+ {
+ struct dict_avp_data data = {
+ 1463, /* Code */
+ 10415, /* Vendor */
+ "Trace-NE-Type-List", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Trace-Interface-List */
+ {
+ struct dict_avp_data data = {
+ 1464, /* Code */
+ 10415, /* Vendor */
+ "Trace-Interface-List", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Trace-Event-List */
+ {
+ struct dict_avp_data data = {
+ 1465, /* Code */
+ 10415, /* Vendor */
+ "Trace-Event-List", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* OMC-Id */
+ {
+ struct dict_avp_data data = {
+ 1466, /* Code */
+ 10415, /* Vendor */
+ "OMC-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* GPRS-Subscription-Data */
+ {
+ struct dict_avp_data data = {
+ 1467, /* Code */
+ 10415, /* Vendor */
+ "GPRS-Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Complete-Data-List-Included-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1468, /* Code */
+ 10415, /* Vendor */
+ "Complete-Data-List-Included-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Complete-Data-List-Included-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PDP-Context */
+ {
+ struct dict_avp_data data = {
+ 1469, /* Code */
+ 10415, /* Vendor */
+ "PDP-Context", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* PDP-Type */
+ {
+ struct dict_avp_data data = {
+ 1470, /* Code */
+ 10415, /* Vendor */
+ "PDP-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 3GPP2-MEID */
+ {
+ struct dict_avp_data data = {
+ 1471, /* Code */
+ 10415, /* Vendor */
+ "3GPP2-MEID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Specific-APN-Info */
+ {
+ struct dict_avp_data data = {
+ 1472, /* Code */
+ 10415, /* Vendor */
+ "Specific-APN-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* LCS-Info */
+ {
+ struct dict_avp_data data = {
+ 1473, /* Code */
+ 10415, /* Vendor */
+ "LCS-Info", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* GMLC-Number */
+ {
+ struct dict_avp_data data = {
+ 1474, /* Code */
+ 10415, /* Vendor */
+ "GMLC-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* LCS-PrivacyException */
+ {
+ struct dict_avp_data data = {
+ 1475, /* Code */
+ 10415, /* Vendor */
+ "LCS-PrivacyException", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SS-Code */
+ {
+ struct dict_avp_data data = {
+ 1476, /* Code */
+ 10415, /* Vendor */
+ "SS-Code", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SS-Status */
+ {
+ struct dict_avp_data data = {
+ 1477, /* Code */
+ 10415, /* Vendor */
+ "SS-Status", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Notification-To-UE-User */
+ {
+ struct dict_avp_data data = {
+ 1478, /* Code */
+ 10415, /* Vendor */
+ "Notification-To-UE-User", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Notification-To-UE-User)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* External-Client */
+ {
+ struct dict_avp_data data = {
+ 1479, /* Code */
+ 10415, /* Vendor */
+ "External-Client", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Client-Identity */
+ {
+ struct dict_avp_data data = {
+ 1480, /* Code */
+ 10415, /* Vendor */
+ "Client-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* GMLC-Restriction */
+ {
+ struct dict_avp_data data = {
+ 1481, /* Code */
+ 10415, /* Vendor */
+ "GMLC-Restriction", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(GMLC-Restriction)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PLMN-Client */
+ {
+ struct dict_avp_data data = {
+ 1482, /* Code */
+ 10415, /* Vendor */
+ "PLMN-Client", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PLMN-Client)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Service-Type */
+ {
+ struct dict_avp_data data = {
+ 1483, /* Code */
+ 10415, /* Vendor */
+ "Service-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* ServiceTypeIdentity */
+ {
+ struct dict_avp_data data = {
+ 1484, /* Code */
+ 10415, /* Vendor */
+ "ServiceTypeIdentity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MO-LR */
+ {
+ struct dict_avp_data data = {
+ 1485, /* Code */
+ 10415, /* Vendor */
+ "MO-LR", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Teleservice-List */
+ {
+ struct dict_avp_data data = {
+ 1486, /* Code */
+ 10415, /* Vendor */
+ "Teleservice-List", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* TS-Code */
+ {
+ struct dict_avp_data data = {
+ 1487, /* Code */
+ 10415, /* Vendor */
+ "TS-Code", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Call-Barring-Infor-List */
+ {
+ struct dict_avp_data data = {
+ 1488, /* Code */
+ 10415, /* Vendor */
+ "Call-Barring-Infor-List", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SGSN-Number */
+ {
+ struct dict_avp_data data = {
+ 1489, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* IDR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1490, /* Code */
+ 10415, /* Vendor */
+ "IDR-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* ICS-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1491, /* Code */
+ 10415, /* Vendor */
+ "ICS-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(ICS-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* IMS-Voice-Over-PS-Sessions-Supported */
+ {
+ struct dict_avp_data data = {
+ 1492, /* Code */
+ 10415, /* Vendor */
+ "IMS-Voice-Over-PS-Sessions-Supported", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IMS-Voice-Over-PS-Sessions-Supported)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions */
+ {
+ struct dict_avp_data data = {
+ 1493, /* Code */
+ 10415, /* Vendor */
+ "Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Last-UE-Activity-Time */
+ {
+ struct dict_avp_data data = {
+ 1494, /* Code */
+ 10415, /* Vendor */
+ "Last-UE-Activity-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* EPS-User-State */
+ {
+ struct dict_avp_data data = {
+ 1495, /* Code */
+ 10415, /* Vendor */
+ "EPS-User-State", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* EPS-Location-Information */
+ {
+ struct dict_avp_data data = {
+ 1496, /* Code */
+ 10415, /* Vendor */
+ "EPS-Location-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MME-User-State */
+ {
+ struct dict_avp_data data = {
+ 1497, /* Code */
+ 10415, /* Vendor */
+ "MME-User-State", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SGSN-User-State */
+ {
+ struct dict_avp_data data = {
+ 1498, /* Code */
+ 10415, /* Vendor */
+ "SGSN-User-State", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* User-State */
+ {
+ struct dict_avp_data data = {
+ 1499, /* Code */
+ 10415, /* Vendor */
+ "User-State", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(User-State)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MME-LocationInformation */
+ {
+ struct dict_avp_data data = {
+ 1600, /* Code */
+ 10415, /* Vendor */
+ "MME-LocationInformation", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SGSN-Location-Information */
+ {
+ struct dict_avp_data data = {
+ 1601, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Location-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* E-UTRAN-Cell-Global-Identity */
+ {
+ struct dict_avp_data data = {
+ 1602, /* Code */
+ 10415, /* Vendor */
+ "E-UTRAN-Cell-Global-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Tracking-Area-Identity */
+ {
+ struct dict_avp_data data = {
+ 1603, /* Code */
+ 10415, /* Vendor */
+ "Tracking-Area-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Cell-Global-Identity */
+ {
+ struct dict_avp_data data = {
+ 1604, /* Code */
+ 10415, /* Vendor */
+ "Cell-Global-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Routing-Area-Identity */
+ {
+ struct dict_avp_data data = {
+ 1605, /* Code */
+ 10415, /* Vendor */
+ "Routing-Area-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Location-Area-Identity */
+ {
+ struct dict_avp_data data = {
+ 1606, /* Code */
+ 10415, /* Vendor */
+ "Location-Area-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Service-Area-Identity */
+ {
+ struct dict_avp_data data = {
+ 1607, /* Code */
+ 10415, /* Vendor */
+ "Service-Area-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Geographical-Information */
+ {
+ struct dict_avp_data data = {
+ 1608, /* Code */
+ 10415, /* Vendor */
+ "Geographical-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Geodetic-Information */
+ {
+ struct dict_avp_data data = {
+ 1609, /* Code */
+ 10415, /* Vendor */
+ "Geodetic-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Current-Location-Retrieved */
+ {
+ struct dict_avp_data data = {
+ 1610, /* Code */
+ 10415, /* Vendor */
+ "Current-Location-Retrieved", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Current-Location-Retrieved)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Age-Of-Location-Information */
+ {
+ struct dict_avp_data data = {
+ 1611, /* Code */
+ 10415, /* Vendor */
+ "Age-Of-Location-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Active-APN */
+ {
+ struct dict_avp_data data = {
+ 1612, /* Code */
+ 10415, /* Vendor */
+ "Active-APN", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Error-Diagnostic */
+ {
+ struct dict_avp_data data = {
+ 1614, /* Code */
+ 10415, /* Vendor */
+ "Error-Diagnostic", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Error-Diagnostic)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Ext-PDP-Address */
+ {
+ struct dict_avp_data data = {
+ 1621, /* Code */
+ 10415, /* Vendor */
+ "Ext-PDP-Address", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Address_type, NULL);
+ };
+
+ /* UE-SRVCC-Capability */
+ {
+ struct dict_avp_data data = {
+ 1615, /* Code */
+ 10415, /* Vendor */
+ "UE-SRVCC-Capability", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(UE-SRVCC-Capability)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MPS-Priority */
+ {
+ struct dict_avp_data data = {
+ 1616, /* Code */
+ 10415, /* Vendor */
+ "MPS-Priority", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* VPLMN-LIPA-Allowed */
+ {
+ struct dict_avp_data data = {
+ 1617, /* Code */
+ 10415, /* Vendor */
+ "VPLMN-LIPA-Allowed", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(VPLMN-LIPA-Allowed)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* LIPA-Permission */
+ {
+ struct dict_avp_data data = {
+ 1618, /* Code */
+ 10415, /* Vendor */
+ "LIPA-Permission", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(LIPA-Permission)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Subscribed-Periodic-RAU-TAU-Timer */
+ {
+ struct dict_avp_data data = {
+ 1619, /* Code */
+ 10415, /* Vendor */
+ "Subscribed-Periodic-RAU-TAU-Timer", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Ext-PDP-Type */
+ {
+ struct dict_avp_data data = {
+ 1620, /* Code */
+ 10415, /* Vendor */
+ "Ext-PDP-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SIPTO-Permission */
+ {
+ struct dict_avp_data data = {
+ 1613, /* Code */
+ 10415, /* Vendor */
+ "SIPTO-Permission", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SIPTO-Permission)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MDT-Configuration */
+ {
+ struct dict_avp_data data = {
+ 1622, /* Code */
+ 10415, /* Vendor */
+ "MDT-Configuration", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Job-Type */
+ {
+ struct dict_avp_data data = {
+ 1623, /* Code */
+ 10415, /* Vendor */
+ "Job-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Job-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Area-Scope */
+ {
+ struct dict_avp_data data = {
+ 1624, /* Code */
+ 10415, /* Vendor */
+ "Area-Scope", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* List-Of-Measurements */
+ {
+ struct dict_avp_data data = {
+ 1625, /* Code */
+ 10415, /* Vendor */
+ "List-Of-Measurements", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Reporting-Trigger */
+ {
+ struct dict_avp_data data = {
+ 1626, /* Code */
+ 10415, /* Vendor */
+ "Reporting-Trigger", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Report-Interval */
+ {
+ struct dict_avp_data data = {
+ 1627, /* Code */
+ 10415, /* Vendor */
+ "Report-Interval", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Report-Interval)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Report-Amount */
+ {
+ struct dict_avp_data data = {
+ 1628, /* Code */
+ 10415, /* Vendor */
+ "Report-Amount", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Report-Amount)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Event-Threshold-RSRP */
+ {
+ struct dict_avp_data data = {
+ 1629, /* Code */
+ 10415, /* Vendor */
+ "Event-Threshold-RSRP", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Event-Threshold-RSRQ */
+ {
+ struct dict_avp_data data = {
+ 1630, /* Code */
+ 10415, /* Vendor */
+ "Event-Threshold-RSRQ", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Logging-Interval */
+ {
+ struct dict_avp_data data = {
+ 1631, /* Code */
+ 10415, /* Vendor */
+ "Logging-Interval", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Logging-Interval)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Logging-Duration */
+ {
+ struct dict_avp_data data = {
+ 1632, /* Code */
+ 10415, /* Vendor */
+ "Logging-Duration", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Logging-Duration)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Relay-Node-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1633, /* Code */
+ 10415, /* Vendor */
+ "Relay-Node-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Relay-Node-Indicator)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* MDT-User-Consent */
+ {
+ struct dict_avp_data data = {
+ 1634, /* Code */
+ 10415, /* Vendor */
+ "MDT-User-Consent", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MDT-User-Consent)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* PUR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1635, /* Code */
+ 10415, /* Vendor */
+ "PUR-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Subscribed-VSRVCC */
+ {
+ struct dict_avp_data data = {
+ 1636, /* Code */
+ 10415, /* Vendor */
+ "Subscribed-VSRVCC", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Subscribed-VSRVCC)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Equivalent-PLMN-List */
+ {
+ struct dict_avp_data data = {
+ 1637, /* Code */
+ 10415, /* Vendor */
+ "Equivalent-PLMN-List", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* CLR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1638, /* Code */
+ 10415, /* Vendor */
+ "CLR-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* UVR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1639, /* Code */
+ 10415, /* Vendor */
+ "UVR-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* UVA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1640, /* Code */
+ 10415, /* Vendor */
+ "UVA-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* VPLMN-CSG-Subscription-Data */
+ {
+ struct dict_avp_data data = {
+ 1641, /* Code */
+ 10415, /* Vendor */
+ "VPLMN-CSG-Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Time-Zone */
+ {
+ struct dict_avp_data data = {
+ 1642, /* Code */
+ 10415, /* Vendor */
+ "Time-Zone", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* A-MSISDN */
+ {
+ struct dict_avp_data data = {
+ 1643, /* Code */
+ 10415, /* Vendor */
+ "A-MSISDN", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MME-Number-for-MT-SMS */
+ {
+ struct dict_avp_data data = {
+ 1645, /* Code */
+ 10415, /* Vendor */
+ "MME-Number-for-MT-SMS", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SMS-Register-Request */
+ {
+ struct dict_avp_data data = {
+ 1648, /* Code */
+ 10415, /* Vendor */
+ "SMS-Register-Request", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SMS-Register-Request)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Local-Time-Zone */
+ {
+ struct dict_avp_data data = {
+ 1649, /* Code */
+ 10415, /* Vendor */
+ "Local-Time-Zone", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Daylight-Saving-Time */
+ {
+ struct dict_avp_data data = {
+ 1650, /* Code */
+ 10415, /* Vendor */
+ "Daylight-Saving-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Daylight-Saving-Time)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Subscription-Data-Flags */
+ {
+ struct dict_avp_data data = {
+ 1654, /* Code */
+ 10415, /* Vendor */
+ "Subscription-Data-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Measurement-Period-UMTS */
+ {
+ struct dict_avp_data data = {
+ 1655, /* Code */
+ 10415, /* Vendor */
+ "Measurement-Period-UMTS", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Measurement-Period-UMTS)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Measurement-Period-LTE */
+ {
+ struct dict_avp_data data = {
+ 1656, /* Code */
+ 10415, /* Vendor */
+ "Measurement-Period-LTE", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Measurement-Period-LTE)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Collection-Period-RRM-LTE */
+ {
+ struct dict_avp_data data = {
+ 1657, /* Code */
+ 10415, /* Vendor */
+ "Collection-Period-RRM-LTE", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Collection-Period-RRM-LTE)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Collection-Period-RRM-UMTS */
+ {
+ struct dict_avp_data data = {
+ 1658, /* Code */
+ 10415, /* Vendor */
+ "Collection-Period-RRM-UMTS", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Collection-Period-RRM-UMTS)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Positioning-Method */
+ {
+ struct dict_avp_data data = {
+ 1659, /* Code */
+ 10415, /* Vendor */
+ "Positioning-Method", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Measurement-Quantity */
+ {
+ struct dict_avp_data data = {
+ 1660, /* Code */
+ 10415, /* Vendor */
+ "Measurement-Quantity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Event-Threshold-Event-1F */
+ {
+ struct dict_avp_data data = {
+ 1661, /* Code */
+ 10415, /* Vendor */
+ "Event-Threshold-Event-1F", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Event-Threshold-Event-1I */
+ {
+ struct dict_avp_data data = {
+ 1662, /* Code */
+ 10415, /* Vendor */
+ "Event-Threshold-Event-1I", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 3GPP 29.329-b50 (11.5.0 2012.12.21) */
+ /* User-Identity */
+ {
+ struct dict_avp_data data = {
+ 700, /* Code */
+ 10415, /* Vendor */
+ "User-Identity", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* MSISDN */
+ {
+ struct dict_avp_data data = {
+ 701, /* Code */
+ 10415, /* Vendor */
+ "MSISDN", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Name conflict with 29.229 User-Data (606), renamed */
+ /* User-Data-29.329 */
+ {
+ struct dict_avp_data data = {
+ 702, /* Code */
+ 10415, /* Vendor */
+ "User-Data-29.329", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Data-Reference */
+ {
+ struct dict_avp_data data = {
+ 703, /* Code */
+ 10415, /* Vendor */
+ "Data-Reference", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Data-Reference)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Service-Indication */
+ {
+ struct dict_avp_data data = {
+ 704, /* Code */
+ 10415, /* Vendor */
+ "Service-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Subs-Req-Type */
+ {
+ struct dict_avp_data data = {
+ 705, /* Code */
+ 10415, /* Vendor */
+ "Subs-Req-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Subs-Req-Type)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Requested-Domain */
+ {
+ struct dict_avp_data data = {
+ 706, /* Code */
+ 10415, /* Vendor */
+ "Requested-Domain", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Requested-Domain)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Current-Location */
+ {
+ struct dict_avp_data data = {
+ 707, /* Code */
+ 10415, /* Vendor */
+ "Current-Location", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Current-Location)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Identity-Set */
+ {
+ struct dict_avp_data data = {
+ 708, /* Code */
+ 10415, /* Vendor */
+ "Identity-Set", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Identity-Set)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Expiry-Time */
+ {
+ struct dict_avp_data data = {
+ 709, /* Code */
+ 10415, /* Vendor */
+ "Expiry-Time", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* Send-Data-Indication */
+ {
+ struct dict_avp_data data = {
+ 710, /* Code */
+ 10415, /* Vendor */
+ "Send-Data-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Send-Data-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* in 29.229 */
+ /* Server-Name */
+ /* Supported-Features */
+ /* Feature-List-ID */
+ /* Feature-List */
+ /* Supported-Applications */
+ /* Public-Identity */
+ /* DSAI-Tag */
+ {
+ struct dict_avp_data data = {
+ 711, /* Code */
+ 10415, /* Vendor */
+ "DSAI-Tag", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* in 29.229 */
+ /* Wildcarded-Public-Identity */
+ /* Wildcarded-IMPU */
+ {
+ struct dict_avp_data data = {
+ 636, /* Code */
+ 10415, /* Vendor */
+ "Wildcarded-IMPU", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* in 29.229 */
+ /* Session-Priority */
+ /* One-Time-Notification */
+ {
+ struct dict_avp_data data = {
+ 712, /* Code */
+ 10415, /* Vendor */
+ "One-Time-Notification", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(One-Time-Notification)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Requested-Nodes */
+ {
+ struct dict_avp_data data = {
+ 713, /* Code */
+ 10415, /* Vendor */
+ "Requested-Nodes", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Serving-Node-Indication */
+ {
+ struct dict_avp_data data = {
+ 714, /* Code */
+ 10415, /* Vendor */
+ "Serving-Node-Indication", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Serving-Node-Indication)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* Repository-Data-ID */
+ {
+ struct dict_avp_data data = {
+ 715, /* Code */
+ 10415, /* Vendor */
+ "Repository-Data-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Sequence-Number */
+ {
+ struct dict_avp_data data = {
+ 716, /* Code */
+ 10415, /* Vendor */
+ "Sequence-Number", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* UDR-Flags */
+ {
+ struct dict_avp_data data = {
+ 719, /* Code */
+ 10415, /* Vendor */
+ "UDR-Flags", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* OMA DDS Charging_Data V1.0 20110201-A */
+ /* Application-Server-Id */
+ {
+ struct dict_avp_data data = {
+ 2101, /* Code */
+ 10415, /* Vendor */
+ "Application-Server-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Application-Service-Type */
+ {
+ struct dict_avp_data data = {
+ 2102, /* Code */
+ 10415, /* Vendor */
+ "Application-Service-Type", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Application-Session-Id */
+ {
+ struct dict_avp_data data = {
+ 2103, /* Code */
+ 10415, /* Vendor */
+ "Application-Session-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Content-ID */
+ {
+ struct dict_avp_data data = {
+ 2116, /* Code */
+ 10415, /* Vendor */
+ "Content-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* Content-provider-ID */
+ {
+ struct dict_avp_data data = {
+ 2117, /* Code */
+ 10415, /* Vendor */
+ "Content-provider-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* DCD-Information */
+ {
+ struct dict_avp_data data = {
+ 2115, /* Code */
+ 10415, /* Vendor */
+ "DCD-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Delivery-Status */
+ {
+ struct dict_avp_data data = {
+ 2104, /* Code */
+ 10415, /* Vendor */
+ "Delivery-Status", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* IM-Information */
+ {
+ struct dict_avp_data data = {
+ 2110, /* Code */
+ 10415, /* Vendor */
+ "IM-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Number-Of-Messages-Successfully-Exploded */
+ {
+ struct dict_avp_data data = {
+ 2111, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Messages-Successfully-Exploded", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Number-Of-Messages-Successfully-Sent */
+ {
+ struct dict_avp_data data = {
+ 2112, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Messages-Successfully-Sent", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Service-Generic-Information */
+ {
+ struct dict_avp_data data = {
+ 1256, /* Code */
+ 10415, /* Vendor */
+ "Service-Generic-Information", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Total-Number-Of-Messages-Exploded */
+ {
+ struct dict_avp_data data = {
+ 2113, /* Code */
+ 10415, /* Vendor */
+ "Total-Number-Of-Messages-Exploded", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* Total-Number-Of-Messages-Sent */
+ {
+ struct dict_avp_data data = {
+ 2114, /* Code */
+ 10415, /* Vendor */
+ "Total-Number-Of-Messages-Sent", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+
+
+
+ /*****************************************************/
+ /* end of generated data, rules below added manually */
+ /*****************************************************/
+
+
+
+ /* 3GPP2-BSID */
+ {
+ struct dict_avp_data data = {
+ 9010, /* Code */
+ 5535, /* Vendor */
+ "3GPP2-BSID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */ /* XXX: guessed */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* 29.212 */
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Allocation-Retention-Priority";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Priority-Level" }, RULE_REQUIRED, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Pre-emption-Capability" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Pre-emption-Vulnerability" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "QoS-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Class-Identifier" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-UL" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-DL" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Guaranteed-Bitrate-UL" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Guaranteed-Bitrate-DL" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Identifier" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Allocation-Retention-Priority" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Aggregate-Max-Bitrate-UL" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Aggregate-Max-Bitrate-DL" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ /* 32.299 */
+
+ {
+ /* additional allowed AVPs */
+ struct dict_object *ccr;
+ CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Request", &ccr);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "AoC-Request-Type"}, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Information"}, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, ccr);
+ }
+
+ {
+ /* additional allowed AVPs */
+ struct dict_object *ccr;
+ CHECK_dict_search(DICT_COMMAND, CMD_BY_NAME, "Credit-Control-Answer", &ccr);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Low-Balance-Indication"}, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Remaining-Balance"}, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Information"}, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, ccr);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Address-Domain";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Domain-Name" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-IMSI-MCC-MNC" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Application-Server-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Application-Server" }, RULE_REQUIRED, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Provided-Called-Party-Address" }, RULE_OPTIONAL, -1, -1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Destination-Interface";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Interface-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Text" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Port" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Type" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Envelope";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Envelope-Start-Time" }, RULE_REQUIRED, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Envelope-End-Time" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Total-Octets" }, RULE_REQUIRED, -1, 1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Input-Octets" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Output-Octets" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Service-Specific-Units" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Event-Type";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SIP-Method" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Event" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Expires" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "IMS-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Event-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Role-Of-Node" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Node-Functionality" }, RULE_REQUIRED, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Session-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Outgoing-Session-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Priority" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Calling-Party-Address" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Called-Party-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Called-Asserted-Identity" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Number-Portability-Routing-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Carrier-Select-Routing-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Alternate-Charged-Party-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Requested-Party-Address" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Associated-URI" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Stamps" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Server-Information" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Inter-Operator-Identifier" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Transit-IOI-List" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Charging-Identifier" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Session-Description" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Media-Component" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Served-Party-IP-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Capabilities" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Trunk-Group-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Service" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Specific-Info" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-Body" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Cause-Code" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Early-Media-Description" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Communication-Service-Identifier" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Application-Reference-Identifier" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Online-Charging-Flag" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Real-Time-Tariff-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Account-Expiration" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Initial-IMS-Charging-Identifier" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "NNI-Information" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "From-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Emergency-Indicator" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Transfer-Information" }, RULE_OPTIONAL, -1, -1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Message-Class";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Class-Identifier" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Token-Text" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "MMS-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Originator-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-Address" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Submission-Time" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "MM-Content-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Priority" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-ID" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-Size" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-Class" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Delivery-Report-Requested" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Read-Reply-Report-Requested" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "MMBox-Storage-Requested" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Applic-ID" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Reply-Applic-ID" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Aux-Applic-Info" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-Class" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "DRM-Content" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Adaptations" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "VASP-ID" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "VAS-ID" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ /* Multiple-Services-Credit-Control */
+ /* additional allowed AVPs */
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 0;
+ vpa.avp_name = "Multiple-Services-Credit-Control";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Time-Quota-Threshold" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Volume-Quota-Threshold" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Unit-Quota-Threshold" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Quota-Holding-Time" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Quota-Consumption-Time" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Reporting-Reason" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trigger" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-Furnish-Charging-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Refund-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "AF-Correlation-Information" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Envelope" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Envelope-Reporting" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Quota-Mechanism" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Specific-Info" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Offline-Charging";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Quota-Consumption-Time" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Quota-Mechanism" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Envelope-Reporting" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 0, .avp_name = "Multiple-Services-Credit-Control" }, RULE_OPTIONAL, -1, -1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Originator-Address";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Address-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Data" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Domain" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Originator-Interface";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Interface-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Text" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Port" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Type" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "PS-Furnish-Charging-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Id" }, RULE_REQUIRED, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-Free-Format-Data" }, RULE_REQUIRED, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-Append-Free-Format-Data" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "PS-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Connection-Charging-ID" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Node-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-PDP-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "PDP-Address" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDP-Address-Prefix-Length" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Dynamic-Address-Flag" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Dynamic-Address-Flag-Extension" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Address" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GGSN-Address" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGW-Address" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CG-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-Node-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SGW-Change" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-IMSI-MCC-MNC" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "IMSI-Unauthenticated-Flag" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-GGSN-MCC-MNC" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-NSAPI" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Session-Stop-Indicator" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Selection-Mode" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Characteristics-Selection-Mode" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Base-Name" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 5535, .avp_name = "3GPP2-BSID" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-RAT-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-Furnish-Charging-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "PDP-Context-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Offline-Charging" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Traffic-Data-Volumes" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Data-Container" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Terminal-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Start-Time" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Stop-Time" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Condition" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Diagnostics" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Low-Priority-Indicator" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Number-for-MT-SMS" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Name" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Realm" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Recipient-Address";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Address-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Data" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Domain" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Addressee-Type" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Recipient-Info";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Destination-Interface" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-Address" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-Received-Address" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-SCCP-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Protocol-ID" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Recipient-Received-Address";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Address-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Data" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Domain" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "SDP-Media-Component";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SDP-Media-Name" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Media-Description" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Local-GW-Inserted-Indication" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-Realm-Default-Indication" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Transcoder-Inserted-Indication" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Media-Initiator-Flag" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Media-Initiator-Party" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier-Value" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Type" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Service-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AoC-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "WLAN-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "MMS-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "PoC-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SMS-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "MMTel-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Generic-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "IM-Information" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "DCD-Information" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "SMS-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SMS-Node" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Client-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Originator-SCCP-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SMSC-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Data-Coding-Scheme" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Discharge-Time" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Message-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Originator-Interface" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Protocol-ID" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Reply-Path-Requested" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Status" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-User-Data-Header" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Number-Of-Messages-Sent" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-Info" }, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Originator-Received-Address" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Service-Type" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Time-Quota-Mechanism";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Time-Quota-Type" }, RULE_REQUIRED, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Base-Time-Interval" }, RULE_REQUIRED, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Time-Stamps";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SIP-Request-Timestamp" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Response-Timestamp" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Request-Timestamp-Fraction" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Response-Timestamp-Fraction" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ {
+ /* Used-Service-Unit */
+ /* additional allowed AVPs */
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 0;
+ vpa.avp_name = "Used-Service-Unit";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Reporting-Reason" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Charging-TimeStamp" }, RULE_OPTIONAL, -1, -1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ /* OMA */
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "DCD-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Content-ID" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-provider-ID" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "IM-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Total-Number-Of-Messages-Sent" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Total-Number-Of-Messages-Exploded" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Number-Of-Messages-Successfully-Sent" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Number-Of-Messages-Successfully-Exploded" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 10415;
+ vpa.avp_name = "Service-Generic-Information";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Application-Server-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Service-Type" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Session-Id" }, RULE_OPTIONAL, -1, 1 },
+ { { .avp_vendor = 10415, .avp_name = "Delivery-Status" }, RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules(rules, rule_avp);
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for DCCA 3GPP' initialized");
+ return 0;
+}
+
+EXTENSION_ENTRY("dict_dcca_3gpp", dict_dcca_3gpp_entry, "dict_dcca");
diff --git a/extensions/dict_dcca_3gpp/dict_dcca_3gpp.org b/extensions/dict_dcca_3gpp/dict_dcca_3gpp.org
new file mode 100644
index 0000000..e7eb34f
--- /dev/null
+++ b/extensions/dict_dcca_3gpp/dict_dcca_3gpp.org
@@ -0,0 +1,789 @@
+| Attribute Name | Code | Section defined | Value Type | MUST | MAY | SHLD NOT | MUST NOT | Encr |
+| # 3GPP 29.061-c00 (12.0.0 2012.12.20) | | | | | | | | |
+| # 3GPP 29.061 is not very clear and self-inconsistent about M | | | | | | | | |
+| # for this reason, other sources are assumed more trustworthy | | | | | | | | |
+| # M inconsistently specified | | | | | | | | |
+| 3GPP-IMSI | 1 | 16.4.7 | UTF8String | M,V | P | | | |
+| # 29.061 says OctetString; dumps say UInt32; manually changed | | | | | | | | |
+| # 29.061 says MUST NOT M; dumps say MUST | | | | | | | | |
+| 3GPP-Charging-Id | 2 | 16.4.7 | Unsigned32 | M,V | P | | | |
+| # 29.061 says MUST NOT M; dumps say MUST | | | | | | | | |
+| 3GPP-PDP-Type | 3 | 16.4.7 | Enumerated | M,V | P | | | |
+| 3GPP-CG-Address | 4 | 16.4.7 | OctetString | V | P | | M | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-GPRS-Negotiated-QoS-Profile | 5 | 16.4.7 | UTF8String | M,V | P | | | |
+| # M inconsistently specified; old contrib/3gg says MUST NOT | | | | | | | | |
+| 3GPP-SGSN-Address | 6 | 16.4.7 | OctetString | V | P | | M | |
+| 3GPP-GGSN-Address | 7 | 16.4.7 | OctetString | V | P | | M | |
+| # 29.061 says MUST NOT M; dumps say MUST | | | | | | | | |
+| 3GPP-IMSI-MCC-MNC | 8 | 16.4.7 | UTF8String | M,V | P | | | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-GGSN-MCC-MNC | 9 | 16.4.7 | UTF8String | M,V | P | | | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-NSAPI | 10 | 16.4.7 | OctetString | M,V | P | | | |
+| # added manually, missing in AVP table | | | | | | | | |
+| 3GPP-Session-Stop-Indicator | 11 | 16.4.7 | OctetString | V | P | | M | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-Selection-Mode | 12 | 16.4.7 | UTF8String | M,V | P | | | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-Charging-Characteristics | 13 | 16.4.7 | UTF8String | M,V | P | | | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-CG-IPv6-Address | 14 | 16.4.7 | OctetString | M,V | P | | | |
+| # M inconsistently specified | | | | | | | | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-SGSN-IPv6-Address | 15 | 16.4.7 | OctetString | M,V | P | | | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-GGSN-IPv6-Address | 16 | 16.4.7 | OctetString | M,V | P | | | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-IPv6-DNS-Servers | 17 | 16.4.7 | OctetString | M,V | P | | | |
+| # 29.061 says MUST NOT M; old contrib/3gpp says MUST | | | | | | | | |
+| 3GPP-SGSN-MCC-MNC | 18 | 16.4.7 | UTF8String | M,V | P | | | |
+| # M inconsistently specified | | | | | | | | |
+| 3GPP-IMEISV | 20 | 16.4.7 | OctetString | M,V | P | | | |
+| # M inconsistently specified | | | | | | | | |
+| 3GPP-RAT-Type | 21 | 16.4.7 | OctetString | M,V | P | | | |
+| # M inconsistently specified | | | | | | | | |
+| 3GPP-User-Location-Info | 22 | 16.4.7 | OctetString | M,V | P | | | |
+| # M inconsistently specified | | | | | | | | |
+| 3GPP-MS-TimeZone | 23 | 16.4.7 | OctetString | M,V | P | | | |
+| 3GPP-CAMEL-Charging-Info | 24 | 16.4.7 | OctetString | V | P | | M | |
+| 3GPP-Packet-Filter | 25 | 16.4.7 | OctetString | V | P | | M | |
+| 3GPP-Negotiated-DSCP | 26 | 16.4.7 | OctetString | V | P | | M | |
+| 3GPP-Allocate-IP-Type | 27 | 16.4.7 | OctetString | V | P | | M | |
+| # added manually, missing in AVP table | | | | | | | | |
+| External-Identifier | 28 | 16.4.7 | OctetString | V | P | | M | |
+| TMGI | 900 | 17.07.02 | OctetString | M,V | P | | | |
+| Required-MBMS-Bearer-Capabilities | 901 | 17.07.03 | UTF8String | M,V | P | | | |
+| MBMS-StartStop-Indication | 902 | 17.07.05 | Enumerated | M,V | P | | | |
+| MBMS-Service-Area | 903 | 17.07.06 | OctetString | M,V | P | | | |
+| MBMS-Session-Duration | 904 | 17.07.07 | OctetString | M,V | P | | | |
+| Alternative-APN | 905 | 17.07.08 | UTF8String | M,V | P | | | |
+| MBMS-Service-Type | 906 | 17.07.09 | Enumerated | M,V | P | | | |
+| MBMS-2G-3G-Indicator | 907 | 17.07.10 | Enumerated | M,V | P | | | |
+| MBMS-Session-Identity | 908 | 17.07.11 | OctetString | M.V | P | | | |
+| RAI | 909 | 17.07.12 | UTF8String | M,V | P | | | |
+| Additional-MBMS-Trace-Info | 910 | 17.07.13 | OctetString | M,V | P | | | |
+| MBMS-Time-To-Data-Transfer | 911 | 17.07.14 | OctetString | M,V | P | | | |
+| MBMS-Session-Repetition-Number | 912 | 17.07.15 | OctetString | M.V | P | | | |
+| MBMS-Required-QoS | 913 | 17.07.16 | UTF8String | M.V | P | | | |
+| MBMS-Counting-Information | 914 | 17.07.17 | Enumerated | M.V | P | | | |
+| MBMS-User-Data-Mode-Indication | 915 | 17.07.18 | Enumerated | M.V | P | | | |
+| MBMS-GGSN-Address | 916 | 17.07.19 | OctetString | M.V | P | | | |
+| MBMS-GGSN-IPv6-Address | 917 | 17.07.20 | OctetString | M.V | P | | | |
+| MBMS-BMSC-SSM-IP-Address | 918 | 17.07.21 | OctetString | M.V | P | | | |
+| MBMS-BMSC-SSM-IPv6-Address | 919 | 17.07.22 | OctetString | M.V | P | | | |
+| MBMS-Flow-Identifier | 920 | 17.7.23 | OctetString | M,V | P | | | |
+| CN-IP-Multicast-Distribution | 921 | 17.7.24 | Enumerated | M,V | P | | | |
+| MBMS-HC-Indicator | 922 | 17.7.25 | Enumerated | M,V | P | | | |
+| # 3GPP 29.140-700 (7.0.0 2007.07.05) | | | | | | | | |
+| Served-User-Identity | 1100 | 6.3.1 | Grouped | M,V | | | | N |
+| # reuses: MSISDN | 701 | 6.3.2 | OctetString | M,V | | | | N |
+| VASP-ID | 1101 | 6.3.3 | UTF8String | M,V | | | | N |
+| VAS-ID | 1102 | 6.3.4 | UTF8String | M,V | | | | N |
+| Trigger-Event | 1103 | 6.3.5 | Enumerated | M,V | | | | N |
+| # reuses: 3GPP-IMSI | 1 | 6.3.6 | UTF8String | M,V | | | | N |
+| Sender-Address | 1104 | 6.3.7 | UTF8String | M,V | | | | N |
+| Initial-Recipient-Address | 1105 | 6.3.8 | Grouped | M,V | | | | N |
+| Result-Recipient-Address | 1106 | 6.3.9 | Grouped | M,V | | | | N |
+| # conflicts with one in (more common) 32.329 | | | | | | | | |
+| Sequence-Number-29.140 | 1107 | 6.3.10 | Unsigned32 | M,V | | | | N |
+| # conflicts with one in (more common) 32.299 | | | | | | | | |
+| Recipient-Address-29.140 | 1108 | 6.3.11 | UTF8String | M,V | | | | N |
+| Routeing-Address | 1109 | 6.3.12 | UTF8String | M,V | | | | N |
+| Originating-Interface | 1110 | 6.3.13 | Enumerated | M,V | | | | N |
+| Delivery-Report | 1111 | 6.3.14 | Enumerated | M,V | | | | N |
+| Read-Reply | 1112 | 6.3.15 | Enumerated | M,V | | | | N |
+| Sender-Visibility | 1113 | 6.3.16 | Enumerated | M,V | | | | N |
+| Service-Key | 1114 | 6.3.17 | UTF8String | M,V | | | | N |
+| Billing-Information | 1115 | 6.3.18 | UTF8String | M,V | | | | N |
+| # conflicts with one in (more common) 32.299 | | | | | | | | |
+| Status-29.140 | 1116 | 6.3.19 | Grouped | M,V | | | | N |
+| Status-Code | 1117 | 6.3.20 | UTF8String | M,V | | | | N |
+| Status-Text | 1118 | 6.3.21 | UTF8String | M,V | | | | N |
+| Routeing-Address-Resolution | 1119 | 6.3.22 | Enumerated | M,V | | | | N |
+| # 3GPP 29.173-c00 (12.0.0 2013.03.13) | | | | | | | | |
+| LMSI | 2400 | 6.4.2 | OctetString | M,V | | | | N |
+| Serving-Node | 2401 | 6.4.3 | Grouped | M,V | | | | N |
+| MME-Name | 2402 | 6.4.4 | DiameterIdentity | M,V | | | | N |
+| MSC-Number | 2403 | 6.4.5 | OctetString | M,V | | | | N |
+| LCS-Capabilities-Sets | 2404 | 6.4.6 | Unsigned32 | M,V | | | | N |
+| GMLC-Address | 2405 | 6.4.7 | Address | M,V | | | | N |
+| Additional-Serving-Node | 2406 | 6.4.8 | Grouped | M,V | | | | N |
+| PPR-Address | 2407 | 6.4.9 | Address | M,V | | | | N |
+| MME-Realm | 2408 | 6.4.12 | DiameterIdentity | V | | | M | N |
+| SGSN-Name | 2409 | 6.4.13 | DiameterIdentity | V | | | M | N |
+| SGSN-Realm | 2410 | 6.4.14 | DiameterIdentity | V | | | M | N |
+| # 3GPP 29.210-670 (6.7.0 2006-12-18) | | | | | | | | |
+| PDP-Session-Operation | 1015 | 5.2.21 | Enumerated | M,V | P | | | Y |
+| # 3GPP 29.212-c00 (12.0.0 2013.03.15) | | | | | | | | |
+| # Gx-specific | | | | | | | | |
+| ADC-Revalidation-Time | 2801 | 5.3.93 | Time | V | P | | M | Y |
+| ADC-Rule-Install | 1092 | 5.3.85 | Grouped | V | P | | M | Y |
+| ADC-Rule-Remove | 1093 | 5.3.86 | Grouped | V | P | | M | Y |
+| ADC-Rule-Definition | 1094 | 5.3.87 | Grouped | V | P | | M | Y |
+| ADC-Rule-Base-Name | 1095 | 5.3.88 | UTF8String | V | P | | M | Y |
+| ADC-Rule-Name | 1096 | 5.3.89 | OctetString | V | P | | M | Y |
+| ADC-Rule-Report | 1097 | 5.3.90 | Grouped | V | P | | M | Y |
+| Application-Detection-Information | 1098 | 5.3.91 | Grouped | V | P | | M | Y |
+| Access-Network-Charging-Identifier-Gx | 1022 | 5.3.22 | Grouped | M,V | P | | | Y |
+| Allocation-Retention-Priority | 1034 | 5.3.32 | Grouped | V | P | | M | Y |
+| AN-GW-Address | 1050 | 5.3.49 | Address | V | P | | M | Y |
+| APN-Aggregate-Max-Bitrate-DL | 1040 | 5.3.39 | Unsigned32 | V | P | | M | Y |
+| APN-Aggregate-Max-Bitrate-UL | 1041 | 5.3.40 | Unsigned32 | V | P | | M | Y |
+| Bearer-Control-Mode | 1023 | 5.3.23 | Enumerated | M,V | P | | | Y |
+| Bearer-Identifier | 1020 | 5.3.20 | OctetString | M,V | P | | | Y |
+| Bearer-Operation | 1021 | 5.3.21 | Enumerated | M,V | P | | | Y |
+| Bearer-Usage | 1000 | 5.3.1 | Enumerated | M,V | P | | | Y |
+| Charging-Rule-Install | 1001 | 5.3.2 | Grouped | M,V | P | | | Y |
+| Charging-Rule-Remove | 1002 | 5.3.3 | Grouped | M,V | P | | | Y |
+| Charging-Rule-Definition | 1003 | 5.3.4 | Grouped | M,V | P | | | Y |
+| Charging-Rule-Base-Name | 1004 | 5.3.5 | UTF8String | M,V | P | | | Y |
+| Charging-Rule-Name | 1005 | 5.3.6 | OctetString | M,V | P | | | Y |
+| Charging-Rule-Report | 1018 | 5.3.18 | Grouped | M,V | P | | | Y |
+| Charging-Correlation-Indicator | 1073 | 5.3.67 | Enumerated | V | P | | M | Y |
+| CoA-IP-Address | 1035 | 5.3.33 | Address | V | P | | M | Y |
+| CoA-Information | 1039 | 5.3.37 | Grouped | V | P | | M | Y |
+| CSG-Information-Reporting | 1071 | 5.3.64 | Enumerated | V | P | | M | Y |
+| Default-EPS-Bearer-QoS | 1049 | 5.3.48 | Grouped | V | P | | M | Y |
+| Event-Report-Indication | 1033 | 5.3.30 | Grouped | V | P | | M | Y |
+| Event-Trigger | 1006 | 5.3.7 | Enumerated | M,V | P | | | Y |
+| Flow-Direction | 1080 | 5.3.65 | Enumerated | V | P | | M | Y |
+| Flow-Information | 1058 | 5.3.53 | Grouped | V | P | | M | Y |
+| Flow-Label | 1057 | 5.3.52 | OctetString | V | P | | M | Y |
+| IP-CAN-Type | 1027 | 5.3.27 | Enumerated | M,V | P | | | Y |
+| Guaranteed-Bitrate-DL | 1025 | 5.3.25 | Unsigned32 | M,V | P | | | Y |
+| Guaranteed-Bitrate-UL | 1026 | 5.3.26 | Unsigned32 | M,V | P | | | Y |
+| HeNB-Local-IP-Address | 2804 | 5.3.95 | Address | V | P | | M | Y |
+| Metering-Method | 1007 | 5.3.8 | Enumerated | M,V | P | | | Y |
+| Monitoring-Key | 1066 | 5.3.59 | OctetString | V | P | | M | Y |
+| Mute-Notification | 2809 | 5.3.98 | Enumerated | V | P | | M | Y |
+| Monitoring-Time | 2810 | 5.3.99 | Time | V | P | | M | Y |
+| Network-Request-Support | 1024 | 5.3.24 | Enumerated | M,V | P | | | Y |
+| Offline | 1008 | 5.3.9 | Enumerated | M,V | P | | | Y |
+| Online | 1009 | 5.3.10 | Enumerated | M,V | P | | | Y |
+| Packet-Filter-Content | 1059 | 5.3.54 | IPFilterRule | V | P | | M | Y |
+| Packet-Filter-Identifier | 1060 | 5.3.55 | OctetString | V | P | | M | Y |
+| Packet-Filter-Information | 1061 | 5.3.56 | Grouped | V | P | | M | Y |
+| Packet-Filter-Operation | 1062 | 5.3.57 | Enumerated | V | P | | M | Y |
+| Packet-Filter-Usage | 1072 | 5.3.66 | Enumerated | V | P | | M | Y |
+| PDN-Connection-ID | 1065 | 5.3.58 | OctetString | V | P | | | Y |
+| Precedence | 1010 | 5.3.11 | Unsigned32 | M,V | P | | | Y |
+| Pre-emption-Capability | 1047 | 5.3.46 | Enumerated | V | P | | M | Y |
+| Pre-emption-Vulnerability | 1048 | 5.3.47 | Enumerated | V | P | | M | Y |
+| Priority-Level | 1046 | 5.3.45 | Unsigned32 | V | P | | M | Y |
+| Redirect-Information | 1085 | 5.3.82 | Grouped | V | P | | M | Y |
+| Redirect-Support | 1086 | 5.3.83 | Enumerated | V | P | | M | Y |
+| Reporting-Level | 1011 | 5.3.12 | Enumerated | M,V | P | | | Y |
+| Routing-Filter | 1078 | 5.3.72 | Grouped | V | P | | M | Y |
+| Routing-IP-Address | 1079 | 5.3.73 | Address | V | P | | M | Y |
+| Routing-Rule-Definition | 1076 | 5.3.70 | Grouped | V | P | | M | Y |
+| Routing-Rule-Identifier | 1077 | 5.3.71 | OctetString | V | P | | M | Y |
+| Routing-Rule-Install | 1081 | 5.3.68 | Grouped | V | P | | M | Y |
+| Routing-Rule-Remove | 1075 | 5.3.69 | Grouped | V | P | | M | Y |
+| PCC-Rule-Status | 1019 | 5.3.19 | Enumerated | M,V | P | | | Y |
+| Session-Release-Cause | 1045 | 5.3.44 | Enumerated | M,V | P | | | Y |
+| TDF-Information | 1087 | 5.3.78 | Grouped | V | P | | M | Y |
+| TDF-Application-Identifier | 1088 | 5.3.77 | OctetString | V | P | | M | Y |
+| TDF-Application-Instance-Identifier | 2802 | 5.3.92 | OctetString | V | P | | M | Y |
+| TDF-Destination-Host | 1089 | 5.3.80 | DiameterIdentity | V | P | | M | Y |
+| TDF-Destination-Realm | 1090 | 5.3.79 | DiameterIdentity | V | P | | M | Y |
+| TDF-IP-Address | 1091 | 5.3.81 | Address | V | P | | M | Y |
+| QoS-Class-Identifier | 1028 | 5.3.17 | Enumerated | M,V | P | | | Y |
+| QoS-Information | 1016 | 5.3.16 | Grouped | M.V | P | | | Y |
+| QoS-Negotiation | 1029 | 5.3.28 | Enumerated | M,V | P | | | Y |
+| QoS-Upgrade | 1030 | 5.3.29 | Enumerated | M.V | P | | | Y |
+| PS-to-CS-Session-Continuity | 1099 | 5.3.84 | Enumerated | V | P | | | Y |
+| Resource-Allocation-Notification | 1063 | 5.3.50 | Enumerated | V | P | | M | Y |
+| Rule-Failure-Code | 1031 | 5.3.38 | Enumerated | M.V | P | | | Y |
+| Security-Parameter-Index | 1056 | 5.3.51 | OctetString | V | P | | M | Y |
+| TFT-Filter | 1012 | 5.3.13 | IPFilterRule | M,V | P | | | Y |
+| TFT-Packet-Filter-Information | 1013 | 5.3.14 | Grouped | M,V | P | | | Y |
+| ToS-Traffic-Class | 1014 | 5.3.15 | OctetString | M,V | P | | | Y |
+| Tunnel-Header-Filter | 1036 | 5.3.34 | IPFilterRule | V | P | | M | Y |
+| Tunnel-Header-Length | 1037 | 5.3.35 | Unsigned32 | V | P | | M | Y |
+| Tunnel-Information | 1038 | 5.3.36 | Grouped | V | P | | M | Y |
+| RAT-Type | 1032 | 5.3.31 | Enumerated | V | P | | M | Y |
+| Revalidation-Time | 1042 | 5.3.41 | Time | M,V | P | | | Y |
+| Rule-Activation-Time | 1043 | 5.3.42 | Time | M,V | P | | | Y |
+| UDP-Source-Port | 2806 | 5.3.97 | Unsigned32 | V | P | | M | Y |
+| UE-Local-IP-Address | 2805 | 5.3.96 | Address | V | P | | M | Y |
+| Usage-Monitoring-Information | 1067 | 5.3.60 | Grouped | V | P | | M | Y |
+| Rule-Deactivation-Time | 1044 | 5.3.43 | Time | M,V | P | | | Y |
+| Usage-Monitoring-Level | 1068 | 5.3.61 | Enumerated | V | P | | M | Y |
+| Usage-Monitoring-Report | 1069 | 5.3.62 | Enumerated | V | P | | M | Y |
+| Usage-Monitoring-Support | 1070 | 5.3.63 | Enumerated | V | P | | M | Y |
+| # Gxx-specific | | | | | | | | |
+| QoS-Rule-Install | 1051 | 5a.3.1 | Grouped | M,V | P | | | Y |
+| QoS-Rule-Remove | 1052 | 5a.3.2 | Grouped | M,V | P | | | Y |
+| QoS-Rule-Definition | 1053 | 5a.3.3 | Grouped | M,V | P | | | Y |
+| QoS-Rule-Name | 1054 | 5a.3.4 | OctetString | M,V | P | | | Y |
+| QoS-Rule-Base-Name | 1074 | 5a.3.7 | UTF8String | V | P | | M | Y |
+| QoS-Rule-Report | 1055 | 5a.3.5 | Grouped | M,V | P | | | Y |
+| Session-Linking-Indicator | 1064 | 5a.3.6 | Enumerated | M,V | P | | | Y |
+| # S15-specific | | | | | | | | |
+| CS-Service-Qos-Request-Identifier | 2807 | E.6.3.2 | OctetString | M,V | P | | | Y |
+| CS-Service-QoS-Request-Operation | 2808 | E.6.3.3 | Enumerated | M.V | P | | | Y |
+| # 3GPP 29.214-b80 (11.8.0 2013.03.15) | | | | | | | | |
+| Abort-Cause | 500 | 5.3.1 | Enumerated | M,V | P | | | Y |
+| Access-Network-Charging-Address | 501 | 5.3.2 | Address | M,V | P | | | Y |
+| Access-Network-Charging-Identifier | 502 | 5.3.3 | Grouped | M,V | P | | | Y |
+| Access-Network-Charging-Identifier-Value | 503 | 5.3.4 | OctetString | M,V | P | | | Y |
+| Acceptable-Service-Info | 526 | 5.3.24 | Grouped | M,V | P | | | Y |
+| AF-Application-Identifier | 504 | 5.3.5 | OctetString | M,V | P | | | Y |
+| AF-Charging-Identifier | 505 | 5.3.6 | OctetString | M,V | P | | | Y |
+| Application-Service-Provider-Identity | 532 | 5.3.29 | UTF8String | V | P | | M | Y |
+| Codec-Data | 524 | 5.3.7 | OctetString | M,V | P | | | Y |
+| Flow-Description | 507 | 5.3.8 | IPFilterRule | M,V | P | | | Y |
+| Flow-Number | 509 | 5.3.9 | Unsigned32 | M,V | P | | | Y |
+| Flows | 510 | 5.3.10 | Grouped | M,V | P | | | Y |
+| Flow-Status | 511 | 5.3.11 | Enumerated | M,V | P | | | Y |
+| Flow-Usage | 512 | 5.3.12 | Enumerated | M,V | P | | | Y |
+| Service-URN | 525 | 5.3.23 | OctetString | M,V | P | | | Y |
+| Specific-Action | 513 | 5.3.13 | Enumerated | M,V | P | | | Y |
+| Max-Requested-Bandwidth-DL | 515 | 5.3.14 | Unsigned32 | M,V | P | | | Y |
+| Max-Requested-Bandwidth-UL | 516 | 5.3.15 | Unsigned32 | M,V | P | | | Y |
+| Media-Component-Description | 517 | 5.3.16 | Grouped | M,V | P | | | Y |
+| Media-Component-Number | 518 | 5.3.17 | Unsigned32 | M,V | P | | | Y |
+| Media-Sub-Component | 519 | 5.3.18 | Grouped | M,V | P | | | Y |
+| Media-Type | 520 | 5.3.19 | Enumerated | M,V | P | | | Y |
+| MPS-Identifier | 528 | 5.3.30 | OctetString | V | P | | M | Y |
+| Min-Requested-Bandwidth-DL | 534 | 5.3.32 | Unsigned32 | V | P | | M | Y |
+| Min-Requested-Bandwidth-UL | 535 | 5.3.33 | Unsigned32 | V | P | | M | Y |
+| RR-Bandwidth | 521 | 5.3.20 | Unsigned32 | M,V | P | | | Y |
+| RS-Bandwidth | 522 | 5.3.21 | Unsigned32 | M,V | P | | | Y |
+| Service-Info-Status | 527 | 5.3.25 | Enumerated | M,V | P | | | Y |
+| SIP-Forking-Indication | 523 | 5.3.22 | Enumerated | M,V | P | | | Y |
+| Sponsor-Identity | 531 | 5.3.28 | UTF8String | V | P | | M | Y |
+| Sponsored-Connectivity-Data | 530 | 5.3.27 | Grouped | V | P | | M | Y |
+| AF-Signalling-Protocol | 529 | 5.3.26 | Enumerated | V | P | | M | Y |
+| Required-Access-Info | 536 | 5.3.34 | Enumerated | V | P | | M | Y |
+| Rx-Request-Type | 533 | 5.3.31 | Enumerated | V | P | | M | Y |
+| IP-Domain-Id | 537 | 5.3.35 | OctetString | V | P | | M | Y |
+| # 3GPP 29.229-b20 (11.2.0 2012.12.21) | | | | | | | | |
+| Associated-Identities | 632 | 6.3.33 | Grouped | V | | | M | N |
+| Associated-Registered-Identities | 647 | 6.3.50 | Grouped | V | | | M | N |
+| Call-ID-SIP-Header | 643 | 6.3.49.1 | OctetString | V | | | M | N |
+| Charging-Information | 618 | 6.3.19 | Grouped | M,V | | | | N |
+| Confidentiality-Key | 625 | 6.3.27 | OctetString | M,V | | | | N |
+| Contact | 641 | 6.3.48 | OctetString | V | | | M | N |
+| Deregistration-Reason | 615 | 6.3.16 | Grouped | M,V | | | | N |
+| Digest-Algorithm | 111 | 6.3.39 | UTF8String | M | | | V | N |
+| Digest-HA1 | 121 | 6.3.41 | UTF8String | M | | | V | N |
+| Digest-QoP | 110 | 6.3.40 | UTF8String | M | | | V | N |
+| Digest-Realm | 104 | 6.3.37 | UTF8String | M | | | V | N |
+| Feature-List | 630 | 6.3.31 | Unsigned32 | V | | | M | N |
+| Feature-List-ID | 629 | 6.3.30 | Unsigned32 | V | | | M | N |
+| From-SIP-Header | 644 | 6.3.49.2 | OctetString | V | | | M | N |
+| Identity-with-Emergency-Registration | 651 | 6.3.57 | Grouped | V | | | M | N |
+| Integrity-Key | 626 | 6.3.28 | OctetString | M,V | | | | N |
+| LIA-Flags | 653 | 6.3.59 | Unsigned32 | V | | | M | N |
+| Loose-Route-Indication | 638 | 6.3.45 | Enumerated | V | | | M | N |
+| Mandatory-Capability | 604 | 6.3.5 | Unsigned32 | M,V | | | | N |
+| Multiple-Registration-Indication | 648 | 6.3.51 | Enumerated | V | | | M | N |
+| Optional-Capability | 605 | 6.3.6 | Unsigned32 | M,V | | | | N |
+| Originating-Request | 633 | 6.3.34 | Enumerated | M,V | | | | N |
+| Path | 640 | 6.3.47 | OctetString | V | | | M | N |
+| Primary-Charging-Collection-Function-Name | 621 | 6.3.22 | DiameterURI | M,V | | | | N |
+| Primary-Event-Charging-Function-Name | 619 | 6.3.20 | DiameterURI | M,V | | | | N |
+| Priviledged-Sender-Indication | 652 | 6.3.58 | Enumerated | V | | | M | N |
+| Public-Identity | 601 | 6.3.2 | UTF8String | M,V | | | | N |
+| Reason-Code | 616 | 6.3.17 | Enumerated | M,V | | | | N |
+| Reason-Info | 617 | 6.3.18 | UTF8String | M,V | | | | N |
+| Record-Route | 646 | 6.3.49.4 | OctetString | V | | | M | N |
+| Restoration-Info | 649 | 6.3.52 | Grouped | V | | | M | N |
+| SCSCF-Restoration-Info | 639 | 6.3.46 | Grouped | V | | | M | N |
+| SIP-Auth-Data-Item | 612 | 6.3.13 | Grouped | M,V | | | | N |
+| SIP-Authenticate | 609 | 6.3.10 | OctetString | M,V | | | | N |
+| SIP-Authentication-Context | 611 | 6.3.12 | OctetString | M,V | | | | N |
+| SIP-Authentication-Scheme | 608 | 6.3.9 | UTF8String | M,V | | | | N |
+| SIP-Authorization | 610 | 6.3.11 | OctetString | M,V | | | | N |
+| SIP-Digest-Authenticate | 635 | 6.3.36 | Grouped | V | | | M | N |
+| SIP-Item-Number | 613 | 6.3.14 | Unsigned32 | M,V | | | | N |
+| SIP-Number-Auth-Items | 607 | 6.3.8 | Unsigned32 | M,V | | | | N |
+| Secondary-Charging-Collection-Function-Name | 622 | 6.3.23 | DiameterURI | M,V | | | | N |
+| Secondary-Event-Charging-Function-Name | 620 | 6.3.21 | DiameterURI | M,V | | | | N |
+| Server-Assignment-Type | 614 | 6.3.15 | Enumerated | M,V | | | | N |
+| Server-Capabilities | 603 | 6.3.4 | Grouped | M,V | | | | N |
+| Server-Name | 602 | 6.3.3 | UTF8String | M,V | | | | N |
+| Session-Priority | 650 | 6.3.56 | Enumerated | V | | | M | N |
+| Subscription-Info | 642 | 6.3.49 | Grouped | V | | | M | N |
+| Supported-Applications | 631 | 6.3.32 | Grouped | V | | | M | N |
+| Supported-Features | 628 | 6.3.29 | Grouped | V | M | | | N |
+| To-SIP-Header | 645 | 6.3.49.3 | OctetString | V | | | M | N |
+| UAR-Flags | 637 | 6.3.44 | Unsigned32 | V | | | M | N |
+| User-Authorization-Type | 623 | 6.3.24 | Enumerated | M,V | | | | N |
+| User-Data | 606 | 6.3.7 | OctetString | M,V | | | | N |
+| User-Data-Already-Available | 624 | 6.3.26 | Enumerated | M,V | | | | N |
+| Visited-Network-Identifier | 600 | 6.3.1 | OctetString | M,V | | | | N |
+| Wildcarded-Public-Identity | 634 | 6.3.35 | UTF8String | V | | | M | N |
+| # 3GPP 32.299-b60 (11.6.0 2012.12.21) | | | | | | | | |
+| AF-Correlation-Information | 1276 | | Grouped | M,V | P | | | N |
+| Access-Network-Information | 1263 | | OctetString | M,V | P | | | N |
+| Access-Transfer-Information | 2709 | | Grouped | M,V | P | | | N |
+| Access-Transfer-Type | 2710 | | Enumerated | M,V | P | | | N |
+| Account-Expiration | 2309 | | Time | M,V | P | | | N |
+| Accumulated-Cost | 2052 | | Grouped | M,V | P | | | N |
+| Adaptations | 1217 | | Enumerated | M,V | P | | | N |
+| Additional-Content-Information | 1207 | | Grouped | M,V | P | | | N |
+| Additional-Type-Information | 1205 | | UTF8String | M,V | P | | | N |
+| Address-Data | 897 | | UTF8String | M,V | P | | | N |
+| Address-Domain | 898 | | Grouped | M,V | P | | | N |
+| Address-Type | 899 | | Enumerated | M,V | P | | | N |
+| Addressee-Type | 1208 | | Enumerated | M,V | P | | | N |
+| Alternate-Charged-Party-Address | 1280 | | UTF8String | V.M | P | | | N |
+| AoC-Cost-Information | 2053 | | Grouped | M,V | P | | | N |
+| AoC-Format | 2310 | | Enumerated | M,V | P | | | N |
+| AoC-Information | 2054 | | Grouped | V.M | P | | | N |
+| AoC-Request-Type | 2055 | | Enumerated | V.M | P | | | N |
+| AoC-Service | 2311 | | Grouped | M,V | P | | | N |
+| AoC-Service-Obligatory-Type | 2312 | | Enumerated | M,V | P | | | N |
+| AoC-Service-Type | 2313 | | Enumerated | M,V | P | | | N |
+| AoC-Subscription-Information | 2314 | | Grouped | M,V | P | | | N |
+| Applic-ID | 1218 | | UTF8String | M,V | P | | | N |
+| Application-Server | 836 | | UTF8String | M,V | P | | | N |
+| Application-Server-Information | 850 | | Grouped | M,V | P | | | N |
+| Application-Provided-Called-Party-Address | 837 | | UTF8String | M,V | P | | | N |
+| Associated-Party-Address | 2035 | | UTF8String | M,V | P | | | N |
+| Associated-URI | 856 | | UTF8String | M,V | P | | | N |
+| Aux-Applic-Info | 1219 | | UTF8String | M,V | P | | | N |
+| Base-Time-Interval | 1265 | | Unsigned32 | M,V | P | | | N |
+| Bearer-Service | 854 | | OctetString | M,V | P | | | N |
+| CG-Address | 846 | | Address | M,V | P | | | Y |
+| CSG-Access-Mode | 2317 | | Enumerated | M,V | P | | | N |
+| CSG-Membership-Indication | 2318 | | Enumerated | M,V | P | | | N |
+| CUG-Information | 2304 | | OctetString | M,V | P | | | N |
+| Called-Asserted-Identity | 1250 | | UTF8String | M,V | P | | | N |
+| Called-Party-Address | 832 | | UTF8String | M,V | P | | | N |
+| Calling-Party-Address | 831 | | UTF8String | M,V | P | | | N |
+| Carrier-Select-Routing-Information | 2023 | | UTF8String | M,V | P | | | N |
+| Cause-Code | 861 | | Integer32 | M,V | P | | | N |
+| Change-Condition | 2037 | | Integer32 | M,V | P | | | N |
+| Change-Time | 2038 | | Time | M,V | P | | | N |
+| Charge-Reason-Code | 2118 | | Enumerated | M,V | P | | | N |
+| Charged-Party | 857 | | UTF8String | M,V | P | | | N |
+| Charging-Characteristics-Selection-Mode | 2066 | | Enumerated | M,V | P | | | N |
+| Class-Identifier | 1214 | | Enumerated | M,V | P | | | N |
+| Client-Address | 2018 | | Address | M,V | P | | | N |
+| Content-Class | 1220 | | Enumerated | M,V | P | | | N |
+| Content-Disposition | 828 | | UTF8String | M,V | P | | | N |
+| Content-Length | 827 | | Unsigned32 | M,V | P | | | N |
+| Content-Size | 1206 | | Unsigned32 | M,V | P | | | N |
+| Content-Type | 826 | | UTF8String | M,V | P | | | N |
+| Current-Tariff | 2056 | | Grouped | M,V | P | | | N |
+| DRM-Content | 1221 | | Enumerated | M,V | P | | | N |
+| Data-Coding-Scheme | 2001 | | Integer32 | M,V | P | | | N |
+| Deferred-Location-Event-Type | 1230 | | UTF8String | M,V | P | | | N |
+| Delivery-Report-Requested | 1216 | | Enumerated | M,V | P | | | N |
+| Destination-Interface | 2002 | | Grouped | M,V | P | | | N |
+| Diagnostics | 2039 | | Integer32 | M,V | P | | | N |
+| Domain-Name | 1200 | | UTF8String | M,V | P | | | N |
+| Dynamic-Address-Flag | 2051 | | Enumerated | M,V | P | | | N |
+| Dynamic-Address-Flag-Extension | 2068 | | Enumerated | M,V | P | | | N |
+| Early-Media-Description | 1272 | | Grouped | M,V | P | | | N |
+| Envelope | 1266 | | Grouped | M,V | P | | | N |
+| Envelope-End-Time | 1267 | | Time | M,V | P | | | N |
+| Envelope-Reporting | 1268 | | Enumerated | M,V | P | | | N |
+| Envelope-Start-Time | 1269 | | Time | M,V | P | | | N |
+| Event | 825 | | UTF8String | M,V | P | | | N |
+| Event-Charging-TimeStamp | 1258 | | Time | M,V | P | | | N |
+| Event-Type | 823 | | Grouped | M,V | P | | | N |
+| Expires | 888 | | Unsigned32 | M,V | P | | | N |
+| File-Repair-Supported | 1224 | | Enumerated | M,V | P | | | Y |
+| From-Address | 2708 | | UTF8String | M,V | P | | | N |
+| GGSN-Address | 847 | | Address | M,V | P | | | N |
+| IMS-Application-Reference-Identifier | 2601 | | UTF8String | M,V | P | | | N |
+| IMS-Charging-Identifier | 841 | | UTF8String | M,V | P | | | N |
+| IMS-Communication-Service-Identifier | 1281 | | UTF8String | M,V | P | | | N |
+| IMS-Emergency-Indicator | 2322 | | Enumerated | M,V | P | | | N |
+| IMS-Information | 876 | | Grouped | M,V | P | | | N |
+| IMSI-Unauthenticated-Flag | 2308 | | Enumerated | M,V | P | | | N |
+| IP-Realm-Default-Indication | 2603 | | Enumerated | M,V | P | | | N |
+| Incoming-Trunk-Group-Id | 852 | | UTF8String | M,V | P | | | N |
+| Incremental-Cost | 2062 | | Grouped | M,V | P | | | N |
+| Initial-IMS-Charging-Identifier | 2321 | | UTF8String | M,V | P | | | N |
+| Inter-Operator-Identifier | 838 | | Grouped | M,V | P | | | N |
+| Interface-Id | 2003 | | UTF8String | M,V | P | | | N |
+| Interface-Port | 2004 | | UTF8String | M,V | P | | | N |
+| Interface-Text | 2005 | | UTF8String | M,V | P | | | N |
+| Interface-Type | 2006 | | Enumerated | M,V | P | | | N |
+| LCS-APN | 1231 | | UTF8String | M,V | P | | | N |
+| LCS-Client-Dialed-By-MS | 1233 | | UTF8String | M,V | P | | | N |
+| LCS-Client-External-ID | 1234 | | UTF8String | M,V | P | | | N |
+| LCS-Client-Id | 1232 | | Grouped | M,V | P | | | N |
+| LCS-Client-Name | 1235 | | Grouped | M,V | P | | | N |
+| LCS-Client-Type | 1241 | | Enumerated | M,V | P | | | N |
+| LCS-Data-Coding-Scheme | 1236 | | UTF8String | M,V | P | | | N |
+| LCS-Format-Indicator | 1237 | | Enumerated | M,V | P | | | N |
+| LCS-Information | 878 | | Grouped | M,V | P | | | N |
+| LCS-Name-String | 1238 | | UTF8String | M,V | P | | | N |
+| LCS-Requestor-Id | 1239 | | Grouped | M,V | P | | | N |
+| LCS-Requestor-Id-String | 1240 | | UTF8String | M,V | P | | | N |
+| Local-GW-Inserted-Indication | 2604 | | Enumerated | M,V | P | | | N |
+| Local-Sequence-Number | 2063 | | Unsigned32 | M,V | P | | | N |
+| Location-Estimate | 1242 | | OctetString | M,V | P | | | N |
+| Location-Estimate-Type | 1243 | | Enumerated | M,V | P | | | N |
+| Location-Type | 1244 | | Grouped | M,V | P | | | N |
+| Low-Balance-Indication | 2020 | | Enumerated | M,V | P | | | N |
+| Low-Priority-Indicator | 2602 | | Enumerated | M,V | P | | | N |
+| MBMS GW-Address | 2307 | | Address | M,V | P | | | N |
+| MBMS-Information | 880 | | Grouped | M,V | P | | | N |
+| MBMS-User-Service-Type | 1225 | | Enumerated | M,V | P | | | Y |
+| MM-Content-Type | 1203 | | Grouped | M,V | P | | | N |
+| MMBox-Storage-Requested | 1248 | | Enumerated | M,V | P | | | N |
+| MMS-Information | 877 | | Grouped | M,V | P | | | N |
+| MMTel-Information | 2030 | | Grouped | M,V | P | | | N |
+| MMTel-SService-Type | 2031 | | Unsigned32 | M,V | P | | | N |
+| Media-Initiator-Flag | 882 | | Enumerated | M,V | P | | | N |
+| Media-Initiator-Party | 1288 | | UTF8String | M,V | P | | | N |
+| Message-Body | 889 | | Grouped | M,V | P | | | N |
+| Message-Class | 1213 | | Grouped | M,V | P | | | N |
+| Message-ID | 1210 | | UTF8String | M,V | P | | | N |
+| Message-Size | 1212 | | Unsigned32 | M,V | P | | | N |
+| Message-Type | 1211 | | Enumerated | M,V | P | | | N |
+| NNI-Information | 2703 | | Grouped | M,V | P | | | N |
+| NNI-Type | 2704 | | Enumerated | M,V | P | | | N |
+| Neighbour-Node-Address | 2705 | | Address | M,V | P | | | N |
+| Next-Tariff | 2057 | | Grouped | V/M | P | | | N |
+| Node-Functionality | 862 | | Enumerated | M,V | P | | | N |
+| Node-Id | 2064 | | UTF8String | M,V | P | | | N |
+| Number-Of-Diversions | 2034 | | Unsigned32 | M,V | P | | | N |
+| Number-Of-Messages-Sent | 2019 | | Unsigned32 | M,V | P | | | N |
+| Number-Of-Participants | 885 | | Unsigned32 | M,V | P | | | N |
+| Number-Of-Received-Talk-Bursts | 1282 | | Unsigned32 | M,V | P | | | N |
+| Number-Of-Talk-Bursts | 1283 | | Unsigned32 | M,V | P | | | N |
+| Number-Portability-Routing-Information | 2024 | | UTF8String | M,V | P | | | N |
+| Offline-Charging | 1278 | | Grouped | M,V | P | | | N |
+| Online-Charging-Flag | 2303 | | Enumerated | M,V | P | | | N |
+| Originating-IOI | 839 | | UTF8String | M,V | P | | | N |
+| Originator | 864 | | Enumerated | M,V | P | | | N |
+| Originator-Address | 886 | | Grouped | M,V | P | | | N |
+| Originator-Interface | 2009 | | Grouped | M,V | P | | | N |
+| Originator-Received-Address | 2027 | | Grouped | M,V | P | | | N |
+| Originator-SCCP-Address | 2008 | | Address | M,V | P | | | N |
+| Outgoing-Session-Id | 2320 | | UTF8String | M,V | P | | | N |
+| Outgoing-Trunk-Group-Id | 853 | | UTF8String | M,V | P | | | N |
+| PDG-Address | 895 | | Address | M,V | P | | | N |
+| PDG-Charging-Id | 896 | | Unsigned32 | M,V | P | | | N |
+| PDN-Connection-Charging-ID | 2050 | | Unsigned32 | M,V | P | | | N |
+| PDP-Address | 1227 | | Address | M,V | P | | | Y |
+| PDP-Address-Prefix-Length | 2606 | | Unsigned32 | M,V | P | | | Y |
+| PDP-Context-Type | 1247 | | Enumerated | M,V | P | | | N |
+| PS-Append-Free-Format-Data | 867 | | Enumerated | M,V | P | | | N |
+| PS-Free-Format-Data | 866 | | OctetString | M,V | P | | | N |
+| PS-Furnish-Charging-Information | 865 | | Grouped | M,V | P | | | N |
+| PS-Information | 874 | | Grouped | M,V | P | | | N |
+| Participant-Access-Priority | 1259 | | Enumerated | M,V | P | | | N |
+| Participant-Action-Type | 2049 | | Enumerated | M,V | P | | | N |
+| Participant-Group | 1260 | | Grouped | M,V | P | | | N |
+| Participants-Involved | 887 | | UTF8String | M,V | P | | | N |
+| PoC-Change-Condition | 1261 | | Enumerated | M,V | P | | | N |
+| PoC-Change-Time | 1262 | | Time | M,V | P | | | N |
+| PoC-Controlling-Address | 858 | | UTF8String | M,V | P | | | N |
+| PoC-Event-Type | 2025 | | Enumerated | M,V | P | | | N |
+| PoC-Group-Name | 859 | | UTF8String | M,V | P | | | N |
+| PoC-Information | 879 | | Grouped | M,V | P | | | N |
+| PoC-Server-Role | 883 | | Enumerated | M,V | P | | | N |
+| PoC-Session-Id | 1229 | | UTF8String | M,V | P | | | N |
+| PoC-Session-Initiation-type | 1277 | | Enumerated | M,V | P | | | N |
+| PoC-Session-Type | 884 | | Enumerated | M,V | P | | | N |
+| PoC-User-Role | 1252 | | Grouped | M,V | P | | | N |
+| PoC-User-Role-IDs | 1253 | | UTF8String | M,V | P | | | N |
+| PoC-User-Role-info-Units | 1254 | | Enumerated | M,V | P | | | N |
+| Positioning-Data | 1245 | | UTF8String | M,V | P | | | N |
+| Preferred-AoC-Currency | 2315 | | Unsigned32 | M,V | P | | | N |
+| Priority | 1209 | | Enumerated | M,V | P | | | N |
+| Quota-Consumption-Time | 881 | | Unsigned32 | M,V | P | | | N |
+| Quota-Holding-Time | 871 | | Unsigned32 | M,V | P | | | N |
+| Rate-Element | 2058 | | Grouped | M,V | P | | | N |
+| Read-Reply-Report-Requested | 1222 | | Enumerated | M,V | P | | | N |
+| Real-Time-Tariff-Information | 2305 | | Grouped | M,V | P | | | N |
+| Received-Talk-Burst-Time | 1284 | | Unsigned32 | M,V | P | | | N |
+| Received-Talk-Burst-Volume | 1285 | | Unsigned32 | M,V | P | | | N |
+| Recipient-Address | 1201 | | Grouped | M,V | P | | | N |
+| Recipient-Info | 2026 | | Grouped | M,V | P | | | N |
+| Recipient-Received-Address | 2028 | | Grouped | M,V | P | | | N |
+| Recipient-SCCP-Address | 2010 | | Address | M,V | P | | | N |
+| Refund-Information | 2022 | | OctetString | M,V | P | | | N |
+| Relationship-Mode | 2706 | | Enumerated | M,V | P | | | N |
+| Remaining-Balance | 2021 | | Grouped | M,V | P | | | N |
+| Reply-Applic-ID | 1223 | | UTF8String | M,V | P | | | N |
+| Reply-Path-Requested | 2011 | | Enumerated | M,V | P | | | N |
+| Reporting-Reason | 872 | | Enumerated | M,V | P | | | N |
+| Requested-Party-Address | 1251 | | UTF8String | M,V | P | | | N |
+| Role-Of-Node | 829 | | Enumerated | M,V | P | | | N |
+| SDP-Answer-Timestamp | 1275 | | Time | M,V | P | | | N |
+| SDP-Media-Component | 843 | | Grouped | M,V | P | | | N |
+| SDP-Media-Description | 845 | | UTF8String | M,V | P | | | N |
+| SDP-Media-Name | 844 | | UTF8String | M,V | P | | | N |
+| SDP-Offer-Timestamp | 1274 | | Time | M,V | P | | | N |
+| SDP-Session-Description | 842 | | UTF8String | M,V | P | | | N |
+| SDP-TimeStamps | 1273 | | Grouped | M,V | P | | | N |
+| SDP-Type | 2036 | | Enumerated | M,V | P | | | N |
+| SGSN-Address | 1228 | | Address | M,V | P | | | N |
+| SGW-Address | 2067 | | Address | M,V | P | | | N |
+| SGW-Change | 2065 | | Enumerated | M,V | P | | | N |
+| SIP-Method | 824 | | UTF8String | M,V | P | | | N |
+| SIP-Request-Timestamp | 834 | | Time | M,V | P | | | N |
+| SIP-Request-Timestamp-Fraction | 2301 | | Unsigned32 | M,V | P | | | N |
+| SIP-Response-Timestamp | 835 | | Time | M,V | P | | | N |
+| SIP-Response-Timestamp-Fraction | 2302 | | Unsigned32 | M,V | P | | | N |
+| SM-Discharge-Time | 2012 | | Time | M,V | P | | | N |
+| SM-Message-Type | 2007 | | Enumerated | M,V | P | | | N |
+| SM-Protocol-ID | 2013 | | OctetString | M,V | P | | | N |
+| SM-Service-Type | 2029 | | Enumerated | M,V | P | | | N |
+| SM-Status | 2014 | | OctetString | M,V | P | | | N |
+| SM-User-Data-Header | 2015 | | OctetString | M,V | P | | | N |
+| SMS-Information | 2000 | | Grouped | M,V | P | | | N |
+| SMS-Node | 2016 | | Enumerated | M,V | P | | | N |
+| SMSC-Address | 2017 | | Address | M,V | P | | | N |
+| Scale-Factor | 2059 | | Grouped | M,V | P | | | N |
+| Served-Party-IP-Address | 848 | | Address | M,V | P | | | N |
+| Service-Data-Container | 2040 | | Grouped | M,V | P | | | N |
+| Service-Id | 855 | | UTF8String | M,V | P | | | N |
+| Service-Information | 873 | | Grouped | M,V | P | | | N |
+| Service-Mode | 2032 | | Unsigned32 | M,V | P | | | N |
+| Service-Specific-Data | 863 | | UTF8String | M,V | P | | | N |
+| Service-Specific-Info | 1249 | | Grouped | M,V | P | | | N |
+| Service-Specific-Type | 1257 | | Unsigned32 | M,V | P | | | N |
+| Serving-Node-Type | 2047 | | Enumerated | M,V | P | | | N |
+| Session-Direction | 2707 | | Enumerated | M,V | P | | | N |
+| Start-Time | 2041 | | Time | M,V | P | | | N |
+| Status | 2702 | | Enumerated | M,V | P | | | N |
+| Stop-Time | 2042 | | Time | M,V | P | | | N |
+| Submission-Time | 1202 | | Time | M,V | P | | | N |
+| Subscriber-Role | 2033 | | Enumerated | M,V | P | | | N |
+| Supplementary-Service | 2048 | | Grouped | M,V | P | | | N |
+| Talk-Burst-Exchange | 1255 | | Grouped | M,V | P | | | N |
+| Talk-Burst-Time | 1286 | | Unsigned32 | M,V | P | | | N |
+| Talk-Burst-Volume | 1287 | | Unsigned32 | M,V | P | | | N |
+| Tariff-Information | 2060 | | Grouped | M,V | P | | | N |
+| Tariff-XML | 2306 | | UTF8String | M,V | P | | | N |
+| Terminating-IOI | 840 | | UTF8String | M,V | P | | | N |
+| Time-First-Usage | 2043 | | Time | M,V | P | | | N |
+| Time-Last-Usage | 2044 | | Time | M,V | P | | | N |
+| Time-Quota-Mechanism | 1270 | | Grouped | M,V | P | | | N |
+| Time-Quota-Threshold | 868 | | Unsigned32 | M,V | P | | | N |
+| Time-Quota-Type | 1271 | | Enumerated | M,V | P | | | N |
+| Time-Stamps | 833 | | Grouped | M,V | P | | | N |
+| Time-Usage | 2045 | | Unsigned32 | M,V | P | | | N |
+| Token-Text | 1215 | | UTF8String | M,V | P | | | N |
+| Traffic-Data-Volumes | 2046 | | Grouped | M,V | P | | | N |
+| Transcoder-Inserted-Indication | 2605 | | Enumerated | M,V | P | | | N |
+| Transit-IOI-List | 2701 | | UTF8String | M,V | P | | | N |
+| Trigger | 1264 | | Grouped | M,V | P | | | N |
+| Trigger-Type | 870 | | Enumerated | M,V | P | | | N |
+| Trunk-Group-Id | 851 | | Grouped | M,V | P | | | N |
+| Type-Number | 1204 | | Enumerated | M,V | P | | | N |
+| Unit-Cost | 2061 | | Grouped | M,V | P | | | N |
+| Unit-Quota-Threshold | 1226 | | Unsigned32 | M,V | P | | | N |
+| User-CSG-Information | 2319 | | Grouped | M,V | P | | | N |
+| User-Participating-Type | 1279 | | Enumerated | M,V | P | | | N |
+| User-Session-Id | 830 | | UTF8String | M,V | P | | | N |
+| Volume-Quota-Threshold | 869 | | Unsigned32 | M,V | P | | | N |
+| WAG-Address | 890 | | Address | M,V | P | | | N |
+| WAG-PLMN-Id | 891 | | OctetString | M,V | P | | | N |
+| WLAN-Information | 875 | | Grouped | M,V | P | | | N |
+| WLAN-Radio-Container | 892 | | Grouped | M,V | P | | | N |
+| WLAN-Session-Id | 1246 | | UTF8String | M,V | P | | | N |
+| WLAN-Technology | 893 | | Unsigned32 | M,V | P | | | N |
+| WLAN-UE-Local-IPAddress | 894 | | Address | M,V | P | | | N |
+| # 3GPP 29.272-c00 (12.0.0 2013.03.13) | | | | | | | | |
+| Subscription-Data | 1400 | 7.3.2 | Grouped | M,V | | | | N |
+| Terminal-Information | 1401 | 7.3.3 | Grouped | M,V | | | | N |
+| IMEI | 1402 | 7.3.4 | UTF8String | M,V | | | | N |
+| Software-Version | 1403 | 7.3.5 | UTF8String | M,V | | | | N |
+| QoS-Subscribed | 1404 | 7.3.77 | OctetString | M,V | | | | N |
+| ULR-Flags | 1405 | 7.3.7 | Unsigned32 | M,V | | | | N |
+| ULA-Flags | 1406 | 7.3.8 | Unsigned32 | M,V | | | | N |
+| Visited-PLMN-Id | 1407 | 7.3.9 | OctetString | M,V | | | | N |
+| Requested-EUTRAN-Authentication-Info | 1408 | 7.3.11 | Grouped | M,V | | | | N |
+| Requested-UTRAN- GERAN-Authentication-Info | 1409 | 7.3.12 | Grouped | M,V | | | | N |
+| Number-Of-Requested-Vectors | 1410 | 7.3.14 | Unsigned32 | M,V | | | | N |
+| Re-Synchronization-Info | 1411 | 7.3.15 | OctetString | M,V | | | | N |
+| Immediate-Response-Preferred | 1412 | 7.3.16 | Unsigned32 | M,V | | | | N |
+| Authentication-Info | 1413 | 7.3.17 | Grouped | M,V | | | | N |
+| E-UTRAN-Vector | 1414 | 7.3.18 | Grouped | M,V | | | | N |
+| UTRAN-Vector | 1415 | 7.3.19 | Grouped | M,V | | | | N |
+| GERAN-Vector | 1416 | 7.3.20 | Grouped | M,V | | | | N |
+| Network-Access-Mode | 1417 | 7.3.21 | Enumerated | M,V | | | | N |
+| HPLMN-ODB | 1418 | 7.3.22 | Unsigned32 | M,V | | | | N |
+| Item-Number | 1419 | 7.3.23 | Unsigned32 | M,V | | | | N |
+| Cancellation-Type | 1420 | 7.3.24 | Enumerated | M,V | | | | N |
+| DSR-Flags | 1421 | 7.3.25 | Unsigned32 | M,V | | | | N |
+| DSA-Flags | 1422 | 7.3.26 | Unsigned32 | M,V | | | | N |
+| Context-Identifier | 1423 | 7.3.27 | Unsigned32 | M,V | | | | N |
+| Subscriber-Status | 1424 | 7.3.29 | Enumerated | M,V | | | | N |
+| Operator-Determined-Barring | 1425 | 7.3.30 | Unsigned32 | M,V | | | | N |
+| Access-Restriction-Data | 1426 | 7.3.31 | Unsigned32 | M,V | | | | N |
+| APN-OI-Replacement | 1427 | 7.3.32 | UTF8String | M,V | | | | N |
+| All-APN-Configurations-Included-Indicator | 1428 | 7.3.33 | Enumerated | M,V | | | | N |
+| APN-Configuration-Profile | 1429 | 7.3.34 | Grouped | M,V | | | | N |
+| APN-Configuration | 1430 | 7.3.35 | Grouped | M,V | | | | N |
+| EPS-Subscribed-QoS-Profile | 1431 | 7.3.37 | Grouped | M,V | | | | N |
+| VPLMN-Dynamic-Address-Allowed | 1432 | 7.3.38 | Enumerated | M,V | | | | N |
+| STN-SR | 1433 | 7.3.39 | OctetString | M,V | | | | N |
+| Alert-Reason | 1434 | 7.3.83 | Enumerated | M,V | | | | N |
+| AMBR | 1435 | 7.3.41 | Grouped | M,V | | | | N |
+| CSG-Subscription-Data | 1436 | 7.3.78 | Grouped | M. V | | | | N |
+| CSG-Id | 1437 | 7.3.79 | Unsigned32 | M,V | | | | N |
+| PDN-GW-Allocation-Type | 1438 | 7.3.44 | Enumerated | M,V | | | | N |
+| Expiration-Date | 1439 | 7.3.80 | Time | M,V | | | | N |
+| RAT-Frequency-Selection-Priority-ID | 1440 | 7.3.46 | Unsigned32 | M,V | | | | N |
+| IDA-Flags | 1441 | 7.3.47 | Unsigned32 | M,V | | | | N |
+| PUA-Flags | 1442 | 7.3.48 | Unsigned32 | M,V | | | | N |
+| NOR-Flags | 1443 | 7.3.49 | Unsigned32 | M,V | | | | N |
+| User-Id | 1444 | 7.3.50 | UTF8String | V | | | M | N |
+| Equipment-Status | 1445 | 7.3.51 | Enumerated | M,V | | | | N |
+| Regional-Subscription-Zone-Code | 1446 | 7.3.52 | OctetString | M,V | | | | N |
+| RAND | 1447 | 7.3.53 | OctetString | M,V | | | | N |
+| XRES | 1448 | 7.3.54 | OctetString | M,V | | | | N |
+| AUTN | 1449 | 7.3.55 | OctetString | M,V | | | | N |
+| KASME | 1450 | 7.3.56 | OctetString | M,V | | | | N |
+| Trace-Collection-Entity | 1452 | 7.3.98 | Address | M,V | | | | N |
+| Kc | 1453 | 7.3.59 | OctetString | M,V | | | | N |
+| SRES | 1454 | 7.3.60 | OctetString | M,V | | | | N |
+| PDN-Type | 1456 | 7.3.62 | Enumerated | M,V | | | | N |
+| Roaming-Restricted-Due-To-Unsupported-Feature | 1457 | 7.3.81 | Enumerated | M,V | | | | N |
+| Trace-Data | 1458 | 7.3.63 | Grouped | M,V | | | | N |
+| Trace-Reference | 1459 | 7.3.64 | OctetString | M,V | | | | N |
+| Trace-Depth | 1462 | 7.3.67 | Enumerated | M,V | | | | N |
+| Trace-NE-Type-List | 1463 | 7.3.68 | OctetString | M,V | | | | N |
+| Trace-Interface-List | 1464 | 7.3.69 | OctetString | M,V | | | | N |
+| Trace-Event-List | 1465 | 7.3.70 | OctetString | M,V | | | | N |
+| OMC-Id | 1466 | 7.3.71 | OctetString | M,V | | | | N |
+| GPRS-Subscription-Data | 1467 | 7.3.72 | Grouped | M,V | | | | N |
+| Complete-Data-List-Included-Indicator | 1468 | 7.3.73 | Enumerated | M,V | | | | N |
+| PDP-Context | 1469 | 7.3.74 | Grouped | M,V | | | | N |
+| PDP-Type | 1470 | 7.3.75 | OctetString | M,V | | | | N |
+| 3GPP2-MEID | 1471 | 7.3.6 | OctetString | M,V | | | | N |
+| Specific-APN-Info | 1472 | 7.3.82 | Grouped | M,V | | | | N |
+| LCS-Info | 1473 | 7.3.84 | Grouped | M,V | | | | N |
+| GMLC-Number | 1474 | 7.3.85 | OctetString | M,V | | | | N |
+| LCS-PrivacyException | 1475 | 7.3.86 | Grouped | M,V | | | | N |
+| SS-Code | 1476 | 7.3.87 | OctetString | M,V | | | | N |
+| SS-Status | 1477 | 7.3.88 | Grouped | M,V | | | | N |
+| Notification-To-UE-User | 1478 | 7.3.89 | Enumerated | M,V | | | | N |
+| External-Client | 1479 | 7.3.90 | Grouped | M,V | | | | N |
+| Client-Identity | 1480 | 7.3.91 | OctetString | M,V | | | | N |
+| GMLC-Restriction | 1481 | 7.3.92 | Enumerated | M,V | | | | N |
+| PLMN-Client | 1482 | 7.3.93 | Enumerated | M,V | | | | N |
+| Service-Type | 1483 | 7.3.94 | Grouped | M,V | | | | N |
+| ServiceTypeIdentity | 1484 | 7.3.95 | Unsigned32 | M,V | | | | N |
+| MO-LR | 1485 | 7.3.96 | Grouped | M,V | | | | N |
+| Teleservice-List | 1486 | 7.3.99 | Grouped | M,V | | | | N |
+| TS-Code | 1487 | 7.3.100 | OctetString | M,V | | | | N |
+| Call-Barring-Infor-List | 1488 | 7.3.101 | Grouped | M,V | | | | N |
+| SGSN-Number | 1489 | 7.3.102 | OctetString | M,V | | | | N |
+| IDR-Flags | 1490 | 7.3.103 | Unsigned32 | M,V | | | | N |
+| ICS-Indicator | 1491 | 7.3.104 | Enumerated | V | | | M | N |
+| IMS-Voice-Over-PS-Sessions-Supported | 1492 | 7.3.106 | Enumerated | V | | | M | N |
+| Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions | 1493 | 7.3.107 | Enumerated | V | | | M | N |
+| Last-UE-Activity-Time | 1494 | 7.3.108 | Time | V | | | M | N |
+| EPS-User-State | 1495 | 7.3.110 | Grouped | V | | | M | N |
+| EPS-Location-Information | 1496 | 7.3.111 | Grouped | V | | | M | N |
+| MME-User-State | 1497 | 7.3.112 | Grouped | V | | | M | N |
+| SGSN-User-State | 1498 | 7.3.113 | Grouped | V | | | M | N |
+| User-State | 1499 | 7.3.114 | Enumerated | V | | | M | N |
+| MME-Location Information | 1600 | 7.3.115 | Grouped | V | | | M | N |
+| SGSN-Location-Information | 1601 | 7.3.116 | Grouped | V | | | M | N |
+| E-UTRAN-Cell-Global-Identity | 1602 | 7.3.117 | OctetString | V | | | M | N |
+| Tracking-Area-Identity | 1603 | 7.3.118 | OctetString | V | | | M | N |
+| Cell-Global-Identity | 1604 | 7.3.119 | OctetString | V | | | M | N |
+| Routing-Area-Identity | 1605 | 7.3.120 | OctetString | V | | | M | N |
+| Location-Area-Identity | 1606 | 7.3.121 | OctetString | V | | | M | N |
+| Service-Area-Identity | 1607 | 7.3.122 | OctetString | V | | | M | N |
+| Geographical-Information | 1608 | 7.3.123 | OctetString | V | | | M | N |
+| Geodetic-Information | 1609 | 7.3.124 | OctetString | V | | | M | N |
+| Current-Location-Retrieved | 1610 | 7.3.125 | Enumerated | V | | | M | N |
+| Age-Of-Location-Information | 1611 | 7.3.126 | Unsigned32 | V | | | M | N |
+| Active-APN | 1612 | 7.3.127 | Grouped | V | | | M | N |
+| Error-Diagnostic | 1614 | 7.3.128 | Enumerated | V | | | M | N |
+| Ext-PDP-Address | 1621 | 7.3.129 | Address | V | | | M | N |
+| UE-SRVCC-Capability | 1615 | 7.3.130 | Enumerated | V | | | M | N |
+| MPS-Priority | 1616 | 7.3.131 | Unsigned32 | V | | | M | N |
+| VPLMN-LIPA-Allowed | 1617 | 7.3.132 | Enumerated | V | | | M | N |
+| LIPA-Permission | 1618 | 7.3.133 | Enumerated | V | | | M | N |
+| Subscribed-Periodic-RAU-TAU-Timer | 1619 | 7.3.134 | Unsigned32 | V | | | M | N |
+| Ext-PDP-Type | 1620 | 7.3.75A | OctetString | V | | | M | N |
+| SIPTO-Permission | 1613 | 7.3.135 | Enumerated | V | | | M | N |
+| MDT-Configuration | 1622 | 7.3.136 | Grouped | V | | | M | N |
+| Job-Type | 1623 | 7.3.137 | Enumerated | V | | | M | N |
+| Area-Scope | 1624 | 7.3.138 | Grouped | V | | | M | N |
+| List-Of-Measurements | 1625 | 7.3.139 | Unsigned32 | V | | | M | N |
+| Reporting-Trigger | 1626 | 7.3.140 | Unsigned32 | V | | | M | N |
+| Report-Interval | 1627 | 7.3.141 | Enumerated | V | | | M | N |
+| Report-Amount | 1628 | 7.3.142 | Enumerated | V | | | M | N |
+| Event-Threshold-RSRP | 1629 | 7.3.143 | Unsigned32 | V | | | M | N |
+| Event-Threshold-RSRQ | 1630 | 7.3.144 | Unsigned32 | V | | | M | N |
+| Logging-Interval | 1631 | 7.3.145 | Enumerated | V | | | M | N |
+| Logging-Duration | 1632 | 7.3.146 | Enumerated | V | | | M | N |
+| Relay-Node-Indicator | 1633 | 7.3.147 | Enumerated | V | | | M | N |
+| MDT-User-Consent | 1634 | 7.3.148 | Enumerated | V | | | M | N |
+| PUR-Flags | 1635 | 7.3.149 | Unsigned32 | V | | | M | N |
+| Subscribed-VSRVCC | 1636 | 7.3.150 | Enumerated | V | | | M | N |
+| Equivalent-PLMN-List | 1637 | 7.3.151 | Grouped | V | | | M | N |
+| CLR-Flags | 1638 | 7.3.152 | Unsigned32 | V | | | M | N |
+| UVR-Flags | 1639 | 7.3.153 | Unsigned32 | M,V | | | | N |
+| UVA-Flags | 1640 | 7.3.154 | Unsigned32 | M,V | | | | N |
+| VPLMN-CSG-Subscription-Data | 1641 | 7.3.155 | Grouped | M,V | | | | N |
+| Time-Zone | 1642 | 7.3.163 | UTF8String | V | | | M | N |
+| A-MSISDN | 1643 | 7.3.157 | OctetString | V | | | M | N |
+| MME-Number-for-MT-SMS | 1645 | 7.3.159 | OctetString | V | | | M | N |
+| SMS-Register-Request | 1648 | 7.3.162 | Enumerated | V | | | M | N |
+| Local-Time-Zone | 1649 | 7.3.156 | Grouped | V | | | M | N |
+| Daylight-Saving-Time | 1650 | 7.3.164 | Enumerated | V | | | M | N |
+| Subscription-Data-Flags | 1654 | 7.3.165 | Unsigned32 | V | | | M | N |
+| Measurement-Period-UMTS | 1655 | 7.3.166 | Enumerated | V | | | M | N |
+| Measurement-Period-LTE | 1656 | 7.3.167 | Enumerated | V | | | M | N |
+| Collection-Period-RRM-LTE | 1657 | 7.3.168 | Enumerated | V | | | M | N |
+| Collection-Period-RRM-UMTS | 1658 | 7.3.169 | Enumerated | V | | | M | N |
+| Positioning-Method | 1659 | 7.3.170 | OctetString | V | | | M | N |
+| Measurement-Quantity | 1660 | 7.3.171 | OctetString | V | | | M | N |
+| Event-Threshold-Event-1F | 1661 | 7.3.172 | Integer32 | V | | | M | N |
+| Event-Threshold-Event-1I | 1662 | 7.3.173 | Integer32 | V | | | M | N |
+| # 3GPP 29.329-b50 (11.5.0 2012.12.21) | | | | | | | | |
+| User-Identity | 700 | 6.3.1 | Grouped | M,V | | | | N |
+| MSISDN | 701 | 6.3.2 | OctetString | M,V | | | | N |
+| # Name conflict with 29.229 User-Data (606), renamed | | | | | | | | |
+| User-Data-29.329 | 702 | 6.3.3 | OctetString | M,V | | | | N |
+| Data-Reference | 703 | 6.3.4 | Enumerated | M,V | | | | N |
+| Service-Indication | 704 | 6.3.5 | OctetString | M,V | | | | N |
+| Subs-Req-Type | 705 | 6.3.6 | Enumerated | M,V | | | | N |
+| Requested-Domain | 706 | 6.3.7 | Enumerated | M,V | | | | N |
+| Current-Location | 707 | 6.3.8 | Enumerated | M,V | | | | N |
+| Identity-Set | 708 | 6.3.10 | Enumerated | V | | | M | N |
+| Expiry-Time | 709 | 6.3.16 | Time | V | | | M | N |
+| Send-Data-Indication | 710 | 6.3.17 | Enumerated | V | | | M | N |
+| # in 29.229 | | | | | | | | |
+| # Server-Name | 602 | 6.3.9 | UTF8String | M,V | | | | N |
+| # Supported-Features | 628 | 6.3.11 | Grouped | V | M | | | N |
+| # Feature-List-ID | 629 | 6.3.12 | Unsigned32 | V | | | M | N |
+| # Feature-List | 630 | 6.3.13 | Unsigned32 | V | | | M | N |
+| # Supported-Applications | 631 | 6.3.14 | Grouped | V | | | M | N |
+| # Public-Identity | 601 | 6.3.15 | UTF8String | M,V | | | | N |
+| DSAI-Tag | 711 | 6.3.18 | OctetString | M,V | | | | N |
+| # in 29.229 | | | | | | | | |
+| # Wildcarded-Public-Identity | 634 | 6.3.19 | UTF8String | V | | | M | N |
+| Wildcarded-IMPU | 636 | 6.3.20 | UTF8String | V | | | M | N |
+| # in 29.229 | | | | | | | | |
+| # Session-Priority | 650 | 6.3.21 | Enumerated | V | | | M | N |
+| One-Time-Notification | 712 | 6.3.22 | Enumerated | V | | | M | N |
+| Requested-Nodes | 713 | 6.3.7A | Unsigned32 | V | | | M | N |
+| Serving-Node-Indication | 714 | 6.3.23 | Enumerated | V | | | M | N |
+| Repository-Data-ID | 715 | 6.3.24 | Grouped | V | | | M | N |
+| Sequence-Number | 716 | 6.3.25 | Unsigned32 | V | | | M | N |
+| UDR-Flags | 719 | 6.3.28 | Unsigned32 | V | | | M | N |
+| # OMA DDS Charging_Data V1.0 20110201-A | | | | | | | | |
+| Application-Server-Id | 2101 | 8.4 | UTF8String | M,V | | | | Y |
+| Application-Service-Type | 2102 | 8.4 | UTF8String | M,V | | | | Y |
+| Application-Session-Id | 2103 | 8.4 | UTF8String | M,V | | | | Y |
+| Content-ID | 2116 | 8.4 | UTF8String | M,V | | | | Y |
+| Content-provider-ID | 2117 | 8.4 | UTF8String | M,V | | | | Y |
+| DCD-Information | 2115 | 8.5.5 | Grouped | M,V | | | | Y |
+| Delivery-Status | 2104 | 8.4 | UTF8String | M,V | | | | Y |
+| IM-Information | 2110 | 8.5.6 | Grouped | M,V | | | | Y |
+| Number-Of-Messages-Successfully-Exploded | 2111 | 8.4 | Unsigned32 | M,V | | | | Y |
+| Number-Of-Messages-Successfully-Sent | 2112 | 8.4 | Unsigned32 | M,V | | | | Y |
+| Service-Generic-Information | 1256 | 8.5.10 | Grouped | M,V | | | | Y |
+| Total-Number-Of-Messages-Exploded | 2113 | 8.4 | Unsigned32 | M,V | | | | Y |
+| Total-Number-Of-Messages-Sent | 2114 | 8.4 | Unsigned32 | M,V | | | | Y |
diff --git a/extensions/dict_dcca_starent/CMakeLists.txt b/extensions/dict_dcca_starent/CMakeLists.txt
new file mode 100644
index 0000000..8152a02
--- /dev/null
+++ b/extensions/dict_dcca_starent/CMakeLists.txt
@@ -0,0 +1,14 @@
+# The dict_dcca_starent extension
+PROJECT("Diameter DCCA (Diameter Credit Control Application) Starent dictionary definitions " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_dcca_starent dict_dcca_starent.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_dcca_starent
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-rfc4006-extension-starent)
+
diff --git a/extensions/dict_dcca_starent/dict_dcca_starent.c b/extensions/dict_dcca_starent/dict_dcca_starent.c
new file mode 100644
index 0000000..e791f1f
--- /dev/null
+++ b/extensions/dict_dcca_starent/dict_dcca_starent.c
@@ -0,0 +1,478 @@
+/*
+ * Dictionary definitions of objects specified in DCCA by Starent.
+ */
+#include <freeDiameter/extension.h>
+
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+ CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ char *avp_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_ALL_VENDORS, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_ALL_VENDORS, \
+ (_rulearray)[__ar].avp_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
+ return ENOENT; \
+ } \
+ CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
+ { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_name ); \
+ return EINVAL; \
+ } ); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_dcca_starent_entry(char * conffile)
+{
+ /* Applications section */
+ {
+ /* Create the vendors */
+ {
+ struct dict_vendor_data vendor_data = { 8164, "Starent" };
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &vendor_data, NULL, NULL));
+ }
+
+ }
+
+
+ struct dict_object * Address_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * IPFilterRule_type;
+ struct dict_object * Time_type;
+ struct dict_object * UTF8String_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+
+ /* The following is created automatically. Do not modify. */
+ /* Changes will be lost during the next update. Modify the source org file instead. */
+
+ /* Cisco ASR 5000 Series AAA Interface */
+ /* Administration and Reference */
+ /* Release 8.x and 9.0 */
+ /* Last Updated June 30, 2010 */
+ /* updated using v15 docs from Jan 2014 */
+ /* www.cisco.com/c/dam/en/us/td/docs/wireless/asr_5000/15-0/15-0-AAA-Reference.pdf */
+ /* SN-Volume-Quota-Threshold */
+ {
+ struct dict_avp_data data = {
+ 501, /* Code */
+ 8164, /* Vendor */
+ "SN-Volume-Quota-Threshold", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Unit-Quota-Threshold */
+ {
+ struct dict_avp_data data = {
+ 502, /* Code */
+ 8164, /* Vendor */
+ "SN-Unit-Quota-Threshold", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Time-Quota-Threshold */
+ {
+ struct dict_avp_data data = {
+ 503, /* Code */
+ 8164, /* Vendor */
+ "SN-Time-Quota-Threshold", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Total-Used-Service-Unit */
+ {
+ struct dict_avp_data data = {
+ 504, /* Code */
+ 8164, /* Vendor */
+ "SN-Total-Used-Service-Unit", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Absolute-Validity-Time */
+ {
+ struct dict_avp_data data = {
+ 505, /* Code */
+ 8164, /* Vendor */
+ "SN-Absolute-Validity-Time", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* SN-Bandwidth-Control */
+ {
+ struct dict_avp_data data = {
+ 512, /* Code */
+ 8164, /* Vendor */
+ "SN-Bandwidth-Control", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Starent/Enumerated(SN-Bandwidth-Control)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SN-Transparent-Data */
+ {
+ struct dict_avp_data data = {
+ 513, /* Code */
+ 8164, /* Vendor */
+ "SN-Transparent-Data", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Traffic-Policy */
+ {
+ struct dict_avp_data data = {
+ 514, /* Code */
+ 8164, /* Vendor */
+ "SN-Traffic-Policy", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SN-Firewall-Policy */
+ {
+ struct dict_avp_data data = {
+ 515, /* Code */
+ 8164, /* Vendor */
+ "SN-Firewall-Policy", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SN-Usage-Monitoring-Control */
+ {
+ struct dict_avp_data data = {
+ 517, /* Code */
+ 8164, /* Vendor */
+ "SN-Usage-Monitoring-Control", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Monitoring-Key */
+ {
+ struct dict_avp_data data = {
+ 518, /* Code */
+ 8164, /* Vendor */
+ "SN-Monitoring-Key", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Usage-Volume */
+ {
+ struct dict_avp_data data = {
+ 519, /* Code */
+ 8164, /* Vendor */
+ "SN-Usage-Volume", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Service-Flow-Detection */
+ {
+ struct dict_avp_data data = {
+ 520, /* Code */
+ 8164, /* Vendor */
+ "SN-Service-Flow-Detection", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Starent/Enumerated(SN-Service-Flow-Detection)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SN-Usage-Monitoring */
+ {
+ struct dict_avp_data data = {
+ 521, /* Code */
+ 8164, /* Vendor */
+ "SN-Usage-Monitoring", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Starent/Enumerated(SN-Usage-Monitoring)", NULL, NULL, NULL };
+ CHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new(DICT_AVP, &data, type, NULL);
+ };
+
+ /* SN-Session-Start-Indicator */
+ {
+ struct dict_avp_data data = {
+ 522, /* Code */
+ 8164, /* Vendor */
+ "SN-Session-Start-Indicator", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Phase0-PSAPName */
+ {
+ struct dict_avp_data data = {
+ 523, /* Code */
+ 8164, /* Vendor */
+ "SN-Phase0-PSAPName", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SN-Charging-Id */
+ {
+ struct dict_avp_data data = {
+ 525, /* Code */
+ 8164, /* Vendor */
+ "SN-Charging-Id", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Remaining-Service-Unit */
+ {
+ struct dict_avp_data data = {
+ 526, /* Code */
+ 8164, /* Vendor */
+ "SN-Remaining-Service-Unit", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Service-Start-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 527, /* Code */
+ 8164, /* Vendor */
+ "SN-Service-Start-Timestamp", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, Time_type, NULL);
+ };
+
+ /* SN-Rulebase-Id */
+ {
+ struct dict_avp_data data = {
+ 528, /* Code */
+ 8164, /* Vendor */
+ "SN-Rulebase-Id", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SN-CF-Policy-ID */
+ {
+ struct dict_avp_data data = {
+ 529, /* Code */
+ 8164, /* Vendor */
+ "SN-CF-Policy-ID", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Charging-Collection-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 530, /* Code */
+ 8164, /* Vendor */
+ "SN-Charging-Collection-Function-Name", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, UTF8String_type, NULL);
+ };
+
+ /* SN-Fast-Reauth-Username */
+ {
+ struct dict_avp_data data = {
+ 11010, /* Code */
+ 8164, /* Vendor */
+ "SN-Fast-Reauth-Username", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+ /* SN-Pseudonym-Username */
+ {
+ struct dict_avp_data data = {
+ 11011, /* Code */
+ 8164, /* Vendor */
+ "SN-Pseudonym-Username", /* Name */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR |AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new(DICT_AVP, &data, NULL, NULL);
+ };
+
+
+
+ /* Rules section */
+
+ /* SN-Remaining-Service-Unit */
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 8164;
+ vpa.avp_name = "SN-Remaining-Service-Unit";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] = {
+ { "Tariff-Change-Usage", RULE_OPTIONAL, -1, 1 },
+ { "CC-Time", RULE_OPTIONAL, -1, 1 },
+ { "CC-Total-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Input-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Output-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Service-Specific-Units", RULE_OPTIONAL, -1, 1 },
+ { "Reporting-Reason", RULE_OPTIONAL, -1, 1 }
+ };
+ PARSE_loc_rules( rules, rule_avp );
+ }
+
+ /* SN-Total-Used-Service-Unit */
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 8164;
+ vpa.avp_name = "SN-Total-Used-Service-Unit";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] = {
+ { "Tariff-Change-Usage", RULE_OPTIONAL, -1, 1 },
+ { "CC-Time", RULE_OPTIONAL, -1, 1 },
+ { "CC-Total-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Input-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Output-Octets", RULE_OPTIONAL, -1, 1 },
+ { "CC-Service-Specific-Units", RULE_OPTIONAL, -1, 1 },
+ { "Reporting-Reason", RULE_OPTIONAL, -1, 1 }
+ };
+ PARSE_loc_rules( rules, rule_avp );
+ }
+
+ /* SN-Usage-Monitoring-Control */
+ {
+ struct dict_object *rule_avp;
+ struct dict_avp_request vpa;
+ vpa.avp_vendor = 8164;
+ vpa.avp_name = "SN-Usage-Monitoring-Control";
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
+ struct local_rules_definition rules[] = {
+ { "SN-Monitoring-Key", RULE_OPTIONAL, -1, 1 },
+ { "SN-Usage-Monitoring", RULE_OPTIONAL, -1, 1 },
+ { "SN-Usage-Volume", RULE_OPTIONAL, -1, 1 },
+ };
+ PARSE_loc_rules( rules, rule_avp );
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for DCCA Starent' initialized");
+ return 0;
+}
+
+EXTENSION_ENTRY("dict_dcca_starent", dict_dcca_starent_entry, "dict_dcca_3gpp");
diff --git a/extensions/dict_dcca_starent/dict_dcca_starent.org b/extensions/dict_dcca_starent/dict_dcca_starent.org
new file mode 100644
index 0000000..7514d9f
--- /dev/null
+++ b/extensions/dict_dcca_starent/dict_dcca_starent.org
@@ -0,0 +1,31 @@
+| Attribute Name | Code | Section defined | Value Type | MUST | MAY | SHLD NOT | MUST NOT | Encr |
+| # Cisco ASR 5000 Series AAA Interface | | | | | | | | |
+| # Administration and Reference | | | | | | | | |
+| # Release 8.x and 9.0 | | | | | | | | |
+| # Last Updated June 30, 2010 | | | | | | | | |
+| # updated using v15 docs from Jan 2014 | | | | | | | | |
+| # www.cisco.com/c/dam/en/us/td/docs/wireless/asr_5000/15-0/15-0-AAA-Reference.pdf | | | | | | | | |
+| SN-Volume-Quota-Threshold | 501 | | Unsigned32 | M,V | | | | |
+| SN-Unit-Quota-Threshold | 502 | | Unsigned32 | M,V | | | | |
+| SN-Time-Quota-Threshold | 503 | | Unsigned32 | M,V | | | | |
+| SN-Total-Used-Service-Unit | 504 | | Grouped | V | | | | |
+| SN-Absolute-Validity-Time | 505 | | Time | V | | | | |
+| SN-Bandwidth-Control | 512 | | Enumerated | M,V | | | | |
+| SN-Transparent-Data | 513 | | OctetString | V | | | | |
+| SN-Traffic-Policy | 514 | | UTF8String | V | | | | |
+| SN-Firewall-Policy | 515 | | UTF8String | V | | | | |
+| SN-Usage-Monitoring-Control | 517 | | Grouped | V | | | | |
+| SN-Monitoring-Key | 518 | | Unsigned32 | V | | | | |
+| SN-Usage-Volume | 519 | | Unsigned64 | V | | | | |
+| SN-Service-Flow-Detection | 520 | | Enumerated | V | | | | |
+| SN-Usage-Monitoring | 521 | | Enumerated | V | | | | |
+| SN-Session-Start-Indicator | 522 | | OctetString | M,V | | | | |
+| SN-Phase0-PSAPName | 523 | | UTF8String | V | | | | |
+| SN-Charging-Id | 525 | | OctetString | V | | | | |
+| SN-Remaining-Service-Unit | 526 | | Grouped | V | | | | |
+| SN-Service-Start-Timestamp | 527 | | Time | V | | | | |
+| SN-Rulebase-Id | 528 | | UTF8String | M,V | | | | |
+| SN-CF-Policy-ID | 529 | | Unsigned32 | M,V | | | | |
+| SN-Charging-Collection-Function-Name | 530 | | UTF8String | V | | | | |
+| SN-Fast-Reauth-Username | 11010 | | OctetString | M,V | | | | |
+| SN-Pseudonym-Username | 11011 | | OctetString | M,V | | | | |
diff --git a/extensions/dict_draftload_avps/CMakeLists.txt b/extensions/dict_draftload_avps/CMakeLists.txt
new file mode 100644
index 0000000..a0c8244
--- /dev/null
+++ b/extensions/dict_draftload_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_draftload_avps extension
+PROJECT("dict_draftload_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_draftload_avps dict_draftload_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_draftload_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-DRAFTLOAD_AVPS)
+
+
+
diff --git a/extensions/dict_draftload_avps/dict_draftload_avps.c b/extensions/dict_draftload_avps/dict_draftload_avps.c
new file mode 100644
index 0000000..aa8c760
--- /dev/null
+++ b/extensions/dict_draftload_avps/dict_draftload_avps.c
@@ -0,0 +1,236 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in draftload_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.4
+
+const char *draftload_avps_proto_ver = PROTO_VER;
+const double draftload_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_draftload_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Load-Type */
+ {
+ struct dict_avp_data data = {
+ 651, /* Code */
+ 0, /* Vendor */
+ "Load-Type", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Load-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "HOST", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PEER", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Load-Value */
+ {
+ struct dict_avp_data data = {
+ 652, /* Code */
+ 0, /* Vendor */
+ "Load-Value", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SourceID */
+ {
+ struct dict_avp_data data = {
+ 649, /* Code */
+ 0, /* Vendor */
+ "SourceID", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* Load */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 650, /* Code */
+ 0, /* Vendor */
+ "Load", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_draftload_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Load */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Load"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Load-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Load-Value"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "SourceID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for draftload_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_draftload_avps_load_defs(conffile);
+ return dict_draftload_avps_load_rules(conffile);
+}
+
+const char* dict_draftload_avps_proto_ver(char * conffile) {
+ return draftload_avps_proto_ver;
+}
+
+const double dict_draftload_avps_gen_ts(char * conffile) {
+ return draftload_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_draftload_avps", dict_draftload_avps_load_defs, dict_draftload_avps_load_rules);
+
+
+
diff --git a/extensions/dict_draftload_avps/draftload_avps.did b/extensions/dict_draftload_avps/draftload_avps.did
new file mode 100644
index 0000000..930430e
--- /dev/null
+++ b/extensions/dict_draftload_avps/draftload_avps.did
@@ -0,0 +1 @@
+dict_draftload_avps
diff --git a/extensions/dict_eap/CMakeLists.txt b/extensions/dict_eap/CMakeLists.txt
new file mode 100644
index 0000000..c10b557
--- /dev/null
+++ b/extensions/dict_eap/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The dict_eap extension
+PROJECT("Diameter EAP (RFC4072) dictionary definitions" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_eap dict_eap.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_eap
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-RFC4072)
diff --git a/extensions/dict_eap/dict_eap.c b/extensions/dict_eap/dict_eap.c
new file mode 100644
index 0000000..0de5731
--- /dev/null
+++ b/extensions/dict_eap/dict_eap.c
@@ -0,0 +1,519 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * Dictionary definitions of objects specified in Diameter EAP application (RFC4072).
+ */
+#include <freeDiameter/extension.h>
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+ CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ char *avp_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME, \
+ (_rulearray)[__ar].avp_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
+ return ENOENT; \
+ } \
+ CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
+ { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_name ); \
+ return EINVAL; \
+ } ); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int deap_entry(char * conffile)
+{
+ struct dict_object * eap;
+ TRACE_ENTRY("%p", conffile);
+
+ /* Applications section */
+ {
+ /* EAP (RFC 4072) */
+ {
+ struct dict_application_data data = { 5, "Diameter Extensible Authentication Protocol (EAP) Application" };
+ CHECK_dict_new( DICT_APPLICATION, &data , NULL, &eap);
+ }
+ }
+
+ /* AVP section */
+ {
+ /* EAP-Payload */
+ {
+ /*
+ The EAP-Payload AVP (AVP Code 462) is of type OctetString and is used
+ to encapsulate the actual EAP packet that is being exchanged between
+ the EAP client and the home Diameter server.
+ */
+ struct dict_avp_data data = {
+ 462, /* Code */
+ 0, /* Vendor */
+ "EAP-Payload", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* EAP-Reissued-Payload */
+ {
+ /*
+ The EAP-Reissued-Payload AVP (AVP Code 463) is of type OctetString.
+ */
+ struct dict_avp_data data = {
+ 463, /* Code */
+ 0, /* Vendor */
+ "EAP-Reissued-Payload", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* EAP-Master-Session-Key */
+ {
+ /*
+ The EAP-Master-Session-Key AVP (AVP Code 464) is of type OctetString.
+ It contains keying material for protecting the communications between
+ the user and the NAS. Exactly how this keying material is used
+ depends on the link layer in question, and is beyond the scope of
+ this document.
+ */
+ struct dict_avp_data data = {
+ 464, /* Code */
+ 0, /* Vendor */
+ "EAP-Master-Session-Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* EAP-Key-Name */
+ {
+ /*
+ The EAP-Key-Name AVP (Radius Attribute Type 102) is of type
+ OctetString. It contains an opaque key identifier (name) generated
+ by the EAP method. Exactly how this name is used depends on the link
+ layer in question, and is beyond the scope of this document (see
+ [EAPKey] for more discussion).
+
+ Note that not all link layers use this name, and currently most EAP
+ methods do not generate it. Since the NAS operates in pass-through
+ mode, it cannot know the Key-Name before receiving it from the AAA
+ server. As a result, a Key-Name AVP sent in a Diameter-EAP-Request
+ MUST NOT contain any data. A home Diameter server receiving a
+ Diameter-EAP-Request with a Key-Name AVP with non-empty data MUST
+ silently discard the AVP. In addition, the home Diameter server
+ SHOULD include this AVP in Diameter-EAP-Response only if an empty
+ EAP-Key-Name AVP was present in Diameter-EAP-Request.
+ */
+ struct dict_avp_data data = {
+ 102, /* Code */
+ 0, /* Vendor */
+ "EAP-Key-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-EAP-Auth-Method */
+ {
+ /*
+ The Accounting-EAP-Auth-Method AVP (AVP Code 465) is of type
+ Unsigned64. In case of expanded types [EAP, Section 5.7], this AVP
+ contains the value ((Vendor-Id * 2^32) + Vendor-Type).
+ */
+ struct dict_avp_data data = {
+ 465, /* Code */
+ 0, /* Vendor */
+ "Accounting-EAP-Auth-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ }
+
+/********************/
+/* Commands section */
+/********************/
+ {
+ /* To avoid defining global variables for all the AVP that we use here, we do search the dictionary in each sub-block.
+ * This is far from optimal, but the code is clearer like this, and the time it requires at execution is not noticeable.
+ */
+ /* Diameter-EAP-Request (DER) Command */
+ {
+ /*
+ The Diameter-EAP-Request (DER) command, indicated by the Command-Code
+ field set to 268 and the 'R' bit set in the Command Flags field, is
+ sent by a Diameter client to a Diameter server, and conveys an
+ EAP-Response from the EAP client. The Diameter-EAP-Request MUST
+ contain one EAP-Payload AVP containing the actual EAP payload. An
+ EAP-Payload AVP with no data MAY be sent to the Diameter server to
+ initiate an EAP authentication session.
+
+ The DER message MAY be the result of a multi-round authentication
+ exchange that occurs when the DEA is received with the Result-Code
+ AVP set to DIAMETER_MULTI_ROUND_AUTH [BASE]. A subsequent DER
+ message MUST include any State AVPs [NASREQ] that were present in the
+ DEA. For re-authentication, it is recommended that the Identity
+ request be skipped in order to reduce the number of authentication
+ round trips. This is only possible when the user's identity is
+ already known by the home Diameter server.
+
+ Message format
+
+ <Diameter-EAP-Request> ::= < Diameter Header: 268, REQ, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { Auth-Request-Type }
+ [ Destination-Host ]
+ [ NAS-Identifier ]
+ [ NAS-IP-Address ]
+ [ NAS-IPv6-Address ]
+ [ NAS-Port ]
+ [ NAS-Port-Id ]
+ [ NAS-Port-Type ]
+ [ Origin-State-Id ]
+ [ Port-Limit ]
+ [ User-Name ]
+ { EAP-Payload }
+ [ EAP-Key-Name ]
+ [ Service-Type ]
+ [ State ]
+ [ Authorization-Lifetime ]
+ [ Auth-Grace-Period ]
+ [ Auth-Session-State ]
+ [ Callback-Number ]
+ [ Called-Station-Id ]
+ [ Calling-Station-Id ]
+ [ Originating-Line-Info ]
+ [ Connect-Info ]
+ * [ Framed-Compression ]
+ [ Framed-Interface-Id ]
+ [ Framed-IP-Address ]
+ * [ Framed-IPv6-Prefix ]
+ [ Framed-IP-Netmask ]
+ [ Framed-MTU ]
+ [ Framed-Protocol ]
+ * [ Tunneling ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 268, /* Code */
+ "Diameter-EAP-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Request-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Identifier", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IPv6-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Port-Limit", RULE_OPTIONAL, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "EAP-Payload", RULE_REQUIRED, -1, 1 }
+ ,{ "EAP-Key-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Session-State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Callback-Number", RULE_OPTIONAL, -1, 1 }
+ ,{ "Called-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Calling-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Originating-Line-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "Connect-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Compression", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-Interface-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Prefix", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-IP-Netmask", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-MTU", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunneling", RULE_OPTIONAL, -1,-1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1,-1 }
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , eap, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Diameter-EAP-Answer (DEA) Command */
+ {
+ /*
+ The Diameter-EAP-Answer (DEA) message, indicated by the Command-Code
+ field set to 268 and the 'R' bit cleared in the Command Flags field,
+ is sent by the Diameter server to the client for one of the following
+ reasons:
+
+ 1. The message is part of a multi-round authentication exchange, and
+ the server is expecting a subsequent Diameter-EAP-Request. This
+ is indicated by setting the Result-Code to
+ DIAMETER_MULTI_ROUND_AUTH, and MAY include zero or more State
+ AVPs.
+
+ 2. The EAP client has been successfully authenticated and
+ authorized, in which case the message MUST include the
+ Result-Code AVP indicating success, and SHOULD include an
+ EAP-Payload of type EAP-Success. This event MUST cause the
+ access device to provide service to the EAP client.
+
+ 3. The EAP client has not been successfully authenticated and/or
+ authorized, and the Result-Code AVP is set to indicate failure.
+ This message SHOULD include an EAP-Payload, but this AVP is not
+ used to determine whether service is to be provided.
+
+ If the message from the Diameter client included a request for
+ authorization, a successful response MUST include the authorization
+ AVPs that are relevant to the service being provided.
+
+ Message format
+
+ <Diameter-EAP-Answer> ::= < Diameter Header: 268, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Auth-Request-Type }
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ [ User-Name ]
+ [ EAP-Payload ]
+ [ EAP-Reissued-Payload ]
+ [ EAP-Master-Session-Key ]
+ [ EAP-Key-Name ]
+ [ Multi-Round-Time-Out ]
+ [ Accounting-EAP-Auth-Method ]
+ [ Service-Type ]
+ * [ Class ]
+ * [ Configuration-Token ]
+ [ Acct-Interim-Interval ]
+ [ Error-Message ]
+ [ Error-Reporting-Host ]
+ * [ Failed-AVP ]
+ [ Idle-Timeout ]
+ [ Authorization-Lifetime ]
+ [ Auth-Grace-Period ]
+ [ Auth-Session-State ]
+ [ Re-Auth-Request-Type ]
+ [ Session-Timeout ]
+ [ State ]
+ * [ Reply-Message ]
+ [ Origin-State-Id ]
+ * [ Filter-Id ]
+ [ Port-Limit ]
+ [ Callback-Id ]
+ [ Callback-Number ]
+ [ Framed-Appletalk-Link ]
+ * [ Framed-Appletalk-Network ]
+ [ Framed-Appletalk-Zone ]
+ * [ Framed-Compression ]
+ [ Framed-Interface-Id ]
+ [ Framed-IP-Address ]
+ * [ Framed-IPv6-Prefix ]
+ [ Framed-IPv6-Pool ]
+ * [ Framed-IPv6-Route ]
+ [ Framed-IP-Netmask ]
+ * [ Framed-Route ]
+ [ Framed-Pool ]
+ [ Framed-IPX-Network ]
+ [ Framed-MTU ]
+ [ Framed-Protocol ]
+ [ Framed-Routing ]
+ * [ NAS-Filter-Rule ]
+ * [ QoS-Filter-Rule ]
+ * [ Tunneling ]
+ * [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 268, /* Code */
+ "Diameter-EAP-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Request-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "EAP-Payload", RULE_OPTIONAL, -1, 1 }
+ ,{ "EAP-Reissued-Payload", RULE_OPTIONAL, -1, 1 }
+ ,{ "EAP-Master-Session-Key", RULE_OPTIONAL, -1, 1 }
+ ,{ "EAP-Key-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "Multi-Round-Time-Out", RULE_OPTIONAL, -1, 1 }
+ ,{ "Accounting-EAP-Auth-Method", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Class", RULE_OPTIONAL, -1,-1 }
+ ,{ "Configuration-Token", RULE_OPTIONAL, -1,-1 }
+ ,{ "Acct-Interim-Interval", RULE_OPTIONAL, -1, 1 }
+ ,{ "Error-Message", RULE_OPTIONAL, -1, 1 }
+ ,{ "Error-Reporting-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Failed-AVP", RULE_OPTIONAL, -1,-1 }
+ ,{ "Idle-Timeout", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Session-State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Re-Auth-Request-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Session-Timeout", RULE_OPTIONAL, -1, 1 }
+ ,{ "State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Reply-Message", RULE_OPTIONAL, -1,-1 }
+ ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Filter-Id", RULE_OPTIONAL, -1,-1 }
+ ,{ "Port-Limit", RULE_OPTIONAL, -1, 1 }
+ ,{ "Callback-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Callback-Number", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-AppleTalk-Link", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-AppleTalk-Network", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-AppleTalk-Zone", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Compression", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-Interface-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Prefix", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-IPv6-Pool", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Route", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-IP-Netmask", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Route", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-Pool", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPX-Network", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-MTU", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Routing", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Filter-Rule", RULE_OPTIONAL, -1,-1 }
+ ,{ "QoS-Filter-Rule", RULE_OPTIONAL, -1,-1 }
+ ,{ "Tunneling", RULE_OPTIONAL, -1,-1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1,-1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 }
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , eap, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Accounting-Request */
+ {
+ /*
+ Add additional rules of the ABNF (compared to Base definition):
+
+ Attribute Name | ACR | ACA |
+ ---------------------------------------|-----+-----+
+ Accounting-EAP-Auth-Method | 0+ | 0 |
+ */
+ struct dict_object * cmd;
+ struct local_rules_definition rules[] =
+ { { "Accounting-EAP-Auth-Method", RULE_OPTIONAL, -1,-1 }
+ };
+
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Accounting-Request", &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for EAP' initialized");
+ return 0;
+}
+
+EXTENSION_ENTRY("dict_eap", deap_entry, "dict_nasreq");
diff --git a/extensions/dict_etsi283034_avps/CMakeLists.txt b/extensions/dict_etsi283034_avps/CMakeLists.txt
new file mode 100644
index 0000000..9f4aa25
--- /dev/null
+++ b/extensions/dict_etsi283034_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_etsi283034_avps extension
+PROJECT("dict_etsi283034_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_etsi283034_avps dict_etsi283034_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_etsi283034_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-ETSI283034_AVPS)
+
+
+
diff --git a/extensions/dict_etsi283034_avps/dict_etsi283034_avps.c b/extensions/dict_etsi283034_avps/dict_etsi283034_avps.c
new file mode 100644
index 0000000..37d1221
--- /dev/null
+++ b/extensions/dict_etsi283034_avps/dict_etsi283034_avps.c
@@ -0,0 +1,250 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in etsi283034_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697184.91
+
+const char *etsi283034_avps_proto_ver = PROTO_VER;
+const double etsi283034_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_etsi283034_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 13019, "ETSI" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Address-Realm */
+ {
+ struct dict_avp_data data = {
+ 301, /* Code */
+ 13019, /* Vendor */
+ "Address-Realm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Logical-Access-Id */
+ {
+ struct dict_avp_data data = {
+ 302, /* Code */
+ 13019, /* Vendor */
+ "Logical-Access-Id", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Physical-Access-Id */
+ {
+ struct dict_avp_data data = {
+ 303, /* Code */
+ 13019, /* Vendor */
+ "Physical-Access-Id", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Line-Identifier */
+ {
+ struct dict_avp_data data = {
+ 500, /* Code */
+ 13019, /* Vendor */
+ "Line-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Reservation-Priority */
+ {
+ struct dict_avp_data data = {
+ 458, /* Code */
+ 13019, /* Vendor */
+ "Reservation-Priority", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "ETSI/Enumerated(Reservation-Priority)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PRIORITY_ONE", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "PRIORITY_TWO", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "PRIORITY_THREE", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "PRIORITY_FOUR", { .i32=4 }};
+ struct dict_enumval_data t_5 = { "PRIORITY_FIVE", { .i32=5 }};
+ struct dict_enumval_data t_6 = { "PRIORITY_SIX", { .i32=6 }};
+ struct dict_enumval_data t_7 = { "PRIORITY_SEVEN", { .i32=7 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_etsi283034_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for etsi283034_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_etsi283034_avps_load_defs(conffile);
+ return dict_etsi283034_avps_load_rules(conffile);
+}
+
+const char* dict_etsi283034_avps_proto_ver(char * conffile) {
+ return etsi283034_avps_proto_ver;
+}
+
+const double dict_etsi283034_avps_gen_ts(char * conffile) {
+ return etsi283034_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_etsi283034_avps", dict_etsi283034_avps_load_defs, dict_etsi283034_avps_load_rules);
+
+
+
diff --git a/extensions/dict_etsi283034_avps/etsi283034_avps.did b/extensions/dict_etsi283034_avps/etsi283034_avps.did
new file mode 100644
index 0000000..f2e2c1f
--- /dev/null
+++ b/extensions/dict_etsi283034_avps/etsi283034_avps.did
@@ -0,0 +1 @@
+dict_etsi283034_avps
diff --git a/extensions/dict_legacy_xml/CMakeLists.txt b/extensions/dict_legacy_xml/CMakeLists.txt
new file mode 100644
index 0000000..561fbc5
--- /dev/null
+++ b/extensions/dict_legacy_xml/CMakeLists.txt
@@ -0,0 +1,35 @@
+# The dict_legacy_xml extension
+PROJECT("Legacy XML dictionary files support" C)
+
+# Parser files
+BISON_FILE(dict_lxml.y)
+FLEX_FILE(dict_lxml.l)
+SET_SOURCE_FILES_PROPERTIES(lex.dict_lxml.c dict_lxml.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# We use LibXml2 (from GNOME) to parse XML files
+FIND_PACKAGE(LibXml2 REQUIRED)
+
+# List of source files
+SET( DICT_LXML_SRC
+ dict_lxml.c
+ dict_lxml_xml.c
+ dict_lxml.h
+ lex.dict_lxml.c
+ dict_lxml.tab.c
+ dict_lxml.tab.h
+)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(dict_legacy_xml ${DICT_LXML_SRC})
+
+TARGET_LINK_LIBRARIES(dict_legacy_xml ${LIBXML2_LIBRARIES} )
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_legacy_xml
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-legacy)
diff --git a/extensions/dict_legacy_xml/dict_lxml.c b/extensions/dict_legacy_xml/dict_lxml.c
new file mode 100644
index 0000000..e4b8d8f
--- /dev/null
+++ b/extensions/dict_legacy_xml/dict_lxml.c
@@ -0,0 +1,54 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * Legacy XML dictionary files support for freeDiameter.
+ */
+
+#include "dict_lxml.h"
+
+/* entry point */
+static int dict_lxml_entry(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* Parse the configuration file -- everything happens there */
+ CHECK_FCT( dict_lxml_handle(conffile) );
+
+ /* We're done */
+ return 0;
+}
+
+EXTENSION_ENTRY("dict_legacy_xml", dict_lxml_entry);
diff --git a/extensions/dict_legacy_xml/dict_lxml.h b/extensions/dict_legacy_xml/dict_lxml.h
new file mode 100644
index 0000000..e862d62
--- /dev/null
+++ b/extensions/dict_legacy_xml/dict_lxml.h
@@ -0,0 +1,48 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Header file for the dict_legacy_xml extension.
+ *
+ * See the dict_legacy_xml.conf.sample file for the format of the configuration file.
+ */
+
+/* FreeDiameter's common include file */
+#include <freeDiameter/extension.h>
+
+/* Parse the configuration file */
+int dict_lxml_handle(char * conffile);
+
+/* Parse an XML file and return the number of dictionary objects or -1 on error */
+int dict_lxml_parse(char * xmlfilename);
diff --git a/extensions/dict_legacy_xml/dict_lxml.l b/extensions/dict_legacy_xml/dict_lxml.l
new file mode 100644
index 0000000..fc612bb
--- /dev/null
+++ b/extensions/dict_legacy_xml/dict_lxml.l
@@ -0,0 +1,98 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Tokenizer
+ *
+ */
+
+%{
+#include "dict_lxml.h"
+/* Include yacc tokens definitions */
+#include "dict_lxml.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+qstring \"[^\"\n]*\"
+
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+ /* Recognize quoted strings */
+{qstring} {
+ /* Match a quoted string. */
+ CHECK_MALLOC_DO( yylval->string = strdup(yytext+1),
+ {
+ TRACE_DEBUG(INFO, "Unable to copy the string '%s': %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ } );
+ yylval->string[strlen(yytext) - 2] = '\0';
+ return QSTRING;
+ }
+
+ /* Valid single characters for yyparse */
+[;] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]\";\n]+ {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/dict_legacy_xml/dict_lxml.y b/extensions/dict_legacy_xml/dict_lxml.y
new file mode 100644
index 0000000..4cafb4f
--- /dev/null
+++ b/extensions/dict_legacy_xml/dict_lxml.y
@@ -0,0 +1,141 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ * See doc/dict_legacy_xml.conf.sample for configuration file format
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "dict_lxml.h"
+#include "dict_lxml.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+static int nb_files = 0;
+static int nb_dict = 0;
+
+/* Parse the configuration file */
+int dict_lxml_handle(char * conffile)
+{
+ extern FILE * dict_lxmlin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ dict_lxmlin = fopen(conffile, "r");
+ if (dict_lxmlin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(dict_lxmlin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ } else {
+ TRACE_DEBUG(FULL, "%d XML dictionary files parsed successfully, %d dictionary objects added.", nb_files, nb_dict);
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int dict_lxmllex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ char *string; /* The string is allocated by strdup in lex.*/
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */
+%token <string> QSTRING
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK */
+ | conffile xmlfile
+ ;
+
+ /* a RULE entry */
+xmlfile: QSTRING ';'
+ {
+ int ret = dict_lxml_parse($1);
+ if (ret < 0) {
+ yyerror (&yylloc, conffile, "An error occurred while parsing a file, aborting...");
+ YYERROR;
+ }
+ nb_files++;
+ nb_dict += ret;
+ }
+ ;
diff --git a/extensions/dict_legacy_xml/dict_lxml_xml.c b/extensions/dict_legacy_xml/dict_lxml_xml.c
new file mode 100644
index 0000000..748c43f
--- /dev/null
+++ b/extensions/dict_legacy_xml/dict_lxml_xml.c
@@ -0,0 +1,1816 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "dict_lxml.h"
+
+/*
+The internal freeDiameter dictionary has strong dependency relations between
+the different objects, as follow:
+
+ vendor
+ / \
+ application \
+ / \ |
+ command \ |
+ | type |
+ | / \ |
+ \ enumval \ |
+ \ avp
+ \ _____/
+ \ /
+ rule
+
+It means an AVP cannot be defined unless the parent TYPE has already been defined,
+in turn depending on parent APPLICATION, etc. (top-to-bottom dependencies on the graph)
+
+On the other hand, the hierarchy of the XML format described in draft-frascone-xml-dictionary-00
+does not enforce most of these dependencies, the structure is as follows:
+
+ vendor application
+ / | \
+ command | avp
+ / type \
+ rule enumval
+
+(in addition if DTD validation was performed, command and avp refer to vendor, avp refers to type,
+but we do not do it for larger compatibility -- we just report when errors are found)
+
+As a consequence of this difference, it is impossible to parse the XML tree and create the dictionary objects in freeDiameter
+in only 1 pass. To avoid parsing the tree several times, we use a temporary structure in memory to contain all the data
+from the XML file, and when the parsing is complete we store all the objects in the dictionary.
+*/
+
+/* We use the SAX interface of libxml2 (from GNOME) to parse the XML file. */
+#include <libxml/parser.h>
+
+/*******************************************/
+ /* Helper functions */
+static int xmltoint(xmlChar * xmlinteger, uint32_t * conv) {
+ TRACE_ENTRY("%p %p", xmlinteger, conv);
+
+ /* Attempt at converting the string to an integer */
+ if (sscanf((char *)xmlinteger, "%u", conv) != 1) {
+ TRACE_DEBUG(INFO, "Unable to convert '%s' to integer.", (char *)xmlinteger)
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+
+/*******************************************
+ The temporary structure that is being built when the XML file is parsed
+ *******************************************/
+
+/* VENDOR */
+struct t_vend {
+ struct fd_list chain; /* link in the t_dictionary->vendors */
+ uint32_t id;
+ uint8_t * name;
+};
+
+static int new_vendor(struct fd_list * parent, xmlChar * xmlid, xmlChar * xmlname) {
+ struct t_vend * new;
+ uint32_t id = 0;
+
+ TRACE_ENTRY("%p %p %p", parent, xmlid, xmlname);
+ CHECK_PARAMS( parent && xmlid && xmlname );
+
+ CHECK_FCT( xmltoint(xmlid, &id) );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct t_vend)) );
+ memset(new, 0, sizeof(struct t_vend));
+ fd_list_init(&new->chain, NULL);
+ new->id = id;
+ CHECK_MALLOC( new->name = (uint8_t *)strdup((char *)xmlname) );
+
+ fd_list_insert_before(parent, &new->chain);
+
+ return 0;
+}
+
+static void dump_vendor(struct t_vend * v) {
+ fd_log_debug(" Vendor %d:'%s'", v->id, (char *)v->name);
+}
+
+static void del_vendor_contents(struct t_vend * v) {
+ TRACE_ENTRY("%p", v);
+ free(v->name);
+}
+
+
+/* RULE */
+struct t_rule {
+ struct fd_list chain; /* link in either t_cmd or t_avp */
+ uint8_t * avpname;
+ int max;
+ int min;
+};
+
+static int new_rule(struct fd_list * parent, xmlChar * xmlname, /* position is never used */ xmlChar * xmlmaximum, xmlChar * xmlminimum) {
+ struct t_rule * new;
+ uint32_t min, max;
+
+ TRACE_ENTRY("%p %p %p %p", parent, xmlname, xmlmaximum, xmlminimum);
+ CHECK_PARAMS( parent && xmlname );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct t_rule)) );
+ memset(new, 0, sizeof(struct t_rule));
+ fd_list_init(&new->chain, NULL);
+ if (xmlminimum) {
+ CHECK_FCT( xmltoint(xmlminimum, &min) );
+ new->min = (int) min;
+ } else {
+ new->min = -1;
+ }
+ if (xmlmaximum) {
+ CHECK_FCT( xmltoint(xmlmaximum, &max) );
+ new->max = (int) max;
+ } else {
+ new->max = -1;
+ }
+ CHECK_MALLOC( new->avpname = (uint8_t *)strdup((char *)xmlname) );
+
+ fd_list_insert_before(parent, &new->chain);
+
+ return 0;
+}
+
+static void dump_rule(struct t_rule * r, char * prefix) {
+ fd_log_debug("%s ", prefix);
+ if (r->min != -1)
+ fd_log_debug("m:%d ", r->min);
+ if (r->max != -1)
+ fd_log_debug("M:%d ", r->max);
+ fd_log_debug("%s", (char *)r->avpname);
+}
+
+static void del_rule_contents(struct t_rule * r) {
+ TRACE_ENTRY("%p",r);
+ free(r->avpname);
+}
+
+
+/* COMMAND */
+struct t_cmd {
+ struct fd_list chain; /* link in t_appl->commands */
+ uint32_t code;
+ uint8_t * name;
+ uint8_t flags;
+ uint8_t fmask;
+ struct fd_list reqrules_fixed; /* list of t_rule */
+ struct fd_list reqrules_required; /* list of t_rule */
+ struct fd_list reqrules_optional; /* list of t_rule */
+ struct fd_list ansrules_fixed; /* list of t_rule */
+ struct fd_list ansrules_required; /* list of t_rule */
+ struct fd_list ansrules_optional; /* list of t_rule */
+};
+
+static int new_cmd(struct fd_list * parent, xmlChar * xmlcode, xmlChar * xmlname /*, ignore the vendor id because we don't use it */, xmlChar * xmlpbit, struct t_cmd **ret) {
+ struct t_cmd * new;
+ uint32_t code;
+ uint32_t flag = 0;
+ uint32_t fmask = 0;
+
+ TRACE_ENTRY("%p %p %p %p", parent, xmlcode, xmlname, xmlpbit);
+ CHECK_PARAMS( parent && xmlcode && xmlname );
+
+ CHECK_FCT( xmltoint(xmlcode, &code) );
+
+ if (xmlpbit) {
+ uint32_t val;
+ CHECK_FCT( xmltoint(xmlpbit, &val) );
+ fmask |= CMD_FLAG_PROXIABLE;
+ if (val)
+ flag |= CMD_FLAG_PROXIABLE;
+ }
+
+ CHECK_MALLOC( new = malloc(sizeof(struct t_cmd)) );
+ memset(new, 0, sizeof(struct t_cmd));
+ fd_list_init(&new->chain, NULL);
+ new->code = code;
+ CHECK_MALLOC( new->name = (uint8_t *)strdup((char *)xmlname) );
+ new->flags = flag;
+ new->fmask = fmask;
+ fd_list_init(&new->reqrules_fixed, NULL);
+ fd_list_init(&new->reqrules_required, NULL);
+ fd_list_init(&new->reqrules_optional, NULL);
+ fd_list_init(&new->ansrules_fixed, NULL);
+ fd_list_init(&new->ansrules_required, NULL);
+ fd_list_init(&new->ansrules_optional, NULL);
+
+ fd_list_insert_before(parent, &new->chain);
+
+ *ret = new;
+
+ return 0;
+}
+
+static void dump_cmd(struct t_cmd * c) {
+ struct fd_list * li;
+ fd_log_debug(" Command %d %s: %s", c->code,
+ c->fmask ? ( c->flags ? "[P=1]" : "[P=0]") : "", c->name);
+ for (li = c->reqrules_fixed.next; li != &c->reqrules_fixed; li = li->next)
+ dump_rule((struct t_rule *)li, " Request fixed AVP:");
+ for (li = c->reqrules_required.next; li != &c->reqrules_required; li = li->next)
+ dump_rule((struct t_rule *)li, " Request required AVP:");
+ for (li = c->reqrules_optional.next; li != &c->reqrules_optional; li = li->next)
+ dump_rule((struct t_rule *)li, " Request optional AVP:");
+ for (li = c->ansrules_fixed.next; li != &c->ansrules_fixed; li = li->next)
+ dump_rule((struct t_rule *)li, " Answer fixed AVP:");
+ for (li = c->ansrules_required.next; li != &c->ansrules_required; li = li->next)
+ dump_rule((struct t_rule *)li, " Answer required AVP:");
+ for (li = c->ansrules_optional.next; li != &c->ansrules_optional; li = li->next)
+ dump_rule((struct t_rule *)li, " Answer optional AVP:");
+}
+
+static void del_cmd_contents(struct t_cmd * c) {
+ TRACE_ENTRY("%p", c);
+ free(c->name);
+ while (!FD_IS_LIST_EMPTY(&c->reqrules_fixed)) {
+ struct fd_list * li = c->reqrules_fixed.next;
+ fd_list_unlink(li);
+ del_rule_contents((struct t_rule *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&c->reqrules_required)) {
+ struct fd_list * li = c->reqrules_required.next;
+ fd_list_unlink(li);
+ del_rule_contents((struct t_rule *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&c->reqrules_optional)) {
+ struct fd_list * li = c->reqrules_optional.next;
+ fd_list_unlink(li);
+ del_rule_contents((struct t_rule *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&c->ansrules_fixed)) {
+ struct fd_list * li = c->ansrules_fixed.next;
+ fd_list_unlink(li);
+ del_rule_contents((struct t_rule *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&c->ansrules_required)) {
+ struct fd_list * li = c->ansrules_required.next;
+ fd_list_unlink(li);
+ del_rule_contents((struct t_rule *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&c->ansrules_optional)) {
+ struct fd_list * li = c->ansrules_optional.next;
+ fd_list_unlink(li);
+ del_rule_contents((struct t_rule *)li);
+ free(li);
+ }
+}
+
+/* TYPE */
+struct t_typedefn {
+ struct fd_list chain; /* link in t_appl->types */
+ uint8_t * name;
+ uint8_t * parent_name;
+};
+
+static int new_type(struct fd_list * parent, xmlChar * xmlname, xmlChar * xmlparent /*, xmlChar * xmldescription -- ignore */) {
+ struct t_typedefn * new;
+
+ TRACE_ENTRY("%p %p %p", parent, xmlname, xmlparent);
+ CHECK_PARAMS( parent && xmlname );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct t_typedefn)) );
+ memset(new, 0, sizeof(struct t_typedefn));
+ fd_list_init(&new->chain, NULL);
+ CHECK_MALLOC( new->name = (uint8_t *)strdup((char *)xmlname) );
+ if (xmlparent) {
+ CHECK_MALLOC( new->parent_name = (uint8_t *)strdup((char *)xmlparent) );
+ }
+
+ fd_list_insert_before(parent, &new->chain);
+
+ return 0;
+}
+
+static void dump_type(struct t_typedefn * t) {
+ fd_log_debug(" Type %s%s%s%s", (char *)t->name,
+ t->parent_name ? "(parent: " : "",
+ t->parent_name ? (char *)t->parent_name : "",
+ t->parent_name ? ")" : "");
+}
+
+static void del_type_contents(struct t_typedefn * t) {
+ TRACE_ENTRY("%p", t);
+ free(t->name);
+ free(t->parent_name);
+}
+
+
+/* TYPE INSIDE AVP */
+struct t_avptype {
+ struct fd_list chain; /* link in t_avp->type */
+ uint8_t * type_name;
+};
+
+static int new_avptype(struct fd_list * parent, xmlChar * xmlname) {
+ struct t_avptype * new;
+
+ TRACE_ENTRY("%p %p", parent, xmlname);
+ CHECK_PARAMS( parent && xmlname );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct t_avptype)) );
+ memset(new, 0, sizeof(struct t_avptype));
+ fd_list_init(&new->chain, NULL);
+ CHECK_MALLOC( new->type_name = (uint8_t *)strdup((char *)xmlname) );
+
+ fd_list_insert_before(parent, &new->chain);
+
+ return 0;
+}
+
+static void dump_avptype(struct t_avptype * t) {
+ fd_log_debug(" data type: %s", t->type_name);
+}
+
+static void del_avptype_contents(struct t_avptype * t) {
+ TRACE_ENTRY("%p", t);
+ free(t->type_name);
+}
+
+
+/* ENUM */
+struct t_enum {
+ struct fd_list chain; /* link in t_avp->enums */
+ uint32_t code;
+ uint8_t * name;
+};
+
+static int new_enum(struct fd_list * parent, xmlChar * xmlcode, xmlChar * xmlname) {
+ struct t_enum * new;
+ uint32_t code = 0;
+
+ TRACE_ENTRY("%p %p %p", parent, xmlcode, xmlname);
+ CHECK_PARAMS( parent && xmlcode && xmlname );
+
+ CHECK_FCT( xmltoint(xmlcode, &code) );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct t_enum)) );
+ memset(new, 0, sizeof(struct t_enum));
+ fd_list_init(&new->chain, NULL);
+ new->code = code;
+ CHECK_MALLOC( new->name = (uint8_t *)strdup((char *)xmlname) );
+
+ fd_list_insert_before(parent, &new->chain);
+
+ return 0;
+}
+
+static void dump_enum(struct t_enum * e) {
+ fd_log_debug(" Value: %d == %s", e->code, e->name);
+}
+
+static void del_enum_contents(struct t_enum * e) {
+ TRACE_ENTRY("%p", e);
+ free(e->name);
+}
+
+/* AVP */
+struct t_avp {
+ struct fd_list chain; /* link in t_appl->avps */
+ uint32_t code;
+ uint8_t * name;
+ uint8_t flags;
+ uint8_t fmask;
+ uint32_t vendor;
+ struct fd_list type; /* list of t_avptype -- there must be at max 1 item in the list */
+ struct fd_list enums; /* list of t_enum */
+ struct fd_list grouped_fixed; /* list of t_rule */
+ struct fd_list grouped_required; /* list of t_rule */
+ struct fd_list grouped_optional; /* list of t_rule */
+};
+
+static int new_avp(struct fd_list * parent, xmlChar * xmlcode, xmlChar * xmlname, xmlChar * xmlmandatory, xmlChar * xmlvendor, struct t_avp **ret) {
+ /* we ignore description, may-encrypt, protected, ... */
+ struct t_avp * new;
+ uint32_t code;
+ uint32_t vendor = 0;
+ uint32_t flag = 0;
+ uint32_t fmask = 0;
+
+ TRACE_ENTRY("%p %p %p %p %p", parent, xmlcode, xmlname, xmlmandatory, xmlvendor);
+ CHECK_PARAMS( parent && xmlcode && xmlname );
+
+ CHECK_FCT( xmltoint(xmlcode, &code) );
+
+ if (xmlmandatory && !strcasecmp((char *)xmlmandatory, "must")) {
+ flag |= AVP_FLAG_MANDATORY;
+ fmask |= AVP_FLAG_MANDATORY;
+ }
+
+ if (xmlvendor) {
+ CHECK_FCT( xmltoint(xmlvendor, &vendor) );
+ if (vendor)
+ flag |= AVP_FLAG_VENDOR;
+ fmask |= AVP_FLAG_VENDOR;
+ }
+
+ CHECK_MALLOC( new = malloc(sizeof(struct t_avp)) );
+ memset(new, 0, sizeof(struct t_avp));
+ fd_list_init(&new->chain, NULL);
+ new->code = code;
+ CHECK_MALLOC( new->name = (uint8_t *)strdup((char *)xmlname) );
+ new->flags = flag;
+ new->fmask = fmask;
+ new->vendor= vendor;
+ fd_list_init(&new->type, NULL);
+ fd_list_init(&new->enums, NULL);
+ fd_list_init(&new->grouped_fixed, NULL);
+ fd_list_init(&new->grouped_required, NULL);
+ fd_list_init(&new->grouped_optional, NULL);
+
+ fd_list_insert_before(parent, &new->chain);
+
+ *ret = new;
+
+ return 0;
+}
+
+static void dump_avp(struct t_avp * a) {
+ struct fd_list * li;
+ fd_log_debug(" AVP %d %s%s: %s", a->code,
+ a->fmask & AVP_FLAG_MANDATORY ? ( a->flags & AVP_FLAG_MANDATORY ? "[M=1]" : "[M=0]") : "",
+ a->fmask & AVP_FLAG_VENDOR ? ( a->flags & AVP_FLAG_VENDOR ? "[V=1]" : "[V=0]") : "",
+ a->name);
+ if (a->fmask & AVP_FLAG_VENDOR)
+ fd_log_debug(" vendor: %d", a->vendor);
+ for (li = a->type.next; li != &a->type; li = li->next)
+ dump_avptype((struct t_avptype *)li);
+ for (li = a->enums.next; li != &a->enums; li = li->next)
+ dump_enum((struct t_enum *)li);
+ for (li = a->grouped_fixed.next; li != &a->grouped_fixed; li = li->next)
+ dump_rule((struct t_rule *)li, " Grouped, fixed AVP:");
+ for (li = a->grouped_required.next; li != &a->grouped_required; li = li->next)
+ dump_rule((struct t_rule *)li, " Grouped, required AVP:");
+ for (li = a->grouped_optional.next; li != &a->grouped_optional; li = li->next)
+ dump_rule((struct t_rule *)li, " Grouped, optional AVP:");
+}
+
+static void del_avp_contents(struct t_avp * a) {
+ TRACE_ENTRY("%p", a);
+ free(a->name);
+ while (!FD_IS_LIST_EMPTY(&a->type)) {
+ struct fd_list * li = a->type.next;
+ fd_list_unlink(li);
+ del_avptype_contents((struct t_avptype *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&a->enums)) {
+ struct fd_list * li = a->enums.next;
+ fd_list_unlink(li);
+ del_enum_contents((struct t_enum *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&a->grouped_fixed)) {
+ struct fd_list * li = a->grouped_fixed.next;
+ fd_list_unlink(li);
+ del_rule_contents((struct t_rule *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&a->grouped_required)) {
+ struct fd_list * li = a->grouped_required.next;
+ fd_list_unlink(li);
+ del_rule_contents((struct t_rule *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&a->grouped_optional)) {
+ struct fd_list * li = a->grouped_optional.next;
+ fd_list_unlink(li);
+ del_rule_contents((struct t_rule *)li);
+ free(li);
+ }
+}
+
+
+/* APPLICATION */
+struct t_appl {
+ struct fd_list chain; /* link in the t_dictionary->base_and_applications, the sentinel corresponds to "base" */
+ uint32_t id;
+ uint8_t * name;
+ struct fd_list commands; /* list of t_cmd */
+ struct fd_list types; /* list of t_typedefn */
+ struct fd_list avps; /* list of t_avp */
+};
+
+static int new_appl(struct fd_list * parent, xmlChar * xmlid, xmlChar * xmlname /* We ignore the URI */, struct t_appl **ret) {
+ struct t_appl * new;
+ uint32_t id = 0;
+
+ TRACE_ENTRY("%p %p %p", parent, xmlid, xmlname);
+ CHECK_PARAMS( parent && xmlid && xmlname );
+
+ CHECK_FCT( xmltoint(xmlid, &id) );
+
+ CHECK_MALLOC( new = malloc(sizeof(struct t_appl)) );
+ memset(new, 0, sizeof(struct t_appl));
+ fd_list_init(&new->chain, NULL);
+ new->id = id;
+ CHECK_MALLOC( new->name = (uint8_t *)strdup((char *)xmlname) );
+
+ fd_list_init(&new->commands, NULL);
+ fd_list_init(&new->types, NULL);
+ fd_list_init(&new->avps, NULL);
+
+ fd_list_insert_before(parent, &new->chain);
+
+ *ret = new;
+
+ return 0;
+}
+
+static void dump_appl(struct t_appl * a) {
+ struct fd_list * li;
+ fd_log_debug(" Application %d: %s", a->id, a->name);
+ for (li = a->commands.next; li != &a->commands; li = li->next)
+ dump_cmd((struct t_cmd *)li);
+ for (li = a->types.next; li != &a->types; li = li->next)
+ dump_type((struct t_typedefn *)li);
+ for (li = a->avps.next; li != &a->avps; li = li->next)
+ dump_avp((struct t_avp *)li);
+}
+
+static void del_appl_contents(struct t_appl * a) {
+ TRACE_ENTRY("%p", a);
+ free(a->name);
+ while (!FD_IS_LIST_EMPTY(&a->commands)) {
+ struct fd_list * li = a->commands.next;
+ fd_list_unlink(li);
+ del_cmd_contents((struct t_cmd *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&a->types)) {
+ struct fd_list * li = a->types.next;
+ fd_list_unlink(li);
+ del_type_contents((struct t_typedefn *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&a->avps)) {
+ struct fd_list * li = a->avps.next;
+ fd_list_unlink(li);
+ del_avp_contents((struct t_avp *)li);
+ free(li);
+ }
+}
+
+/* DICTIONARY */
+struct t_dictionary {
+ struct fd_list vendors;
+ struct t_appl base_and_applications;
+};
+
+static void dump_dict(struct t_dictionary * d) {
+ struct fd_list * li;
+ for (li = d->vendors.next; li != &d->vendors; li = li->next)
+ dump_vendor((struct t_vend *)li);
+ dump_appl(&d->base_and_applications);
+ for (li = d->base_and_applications.chain.next; li != &d->base_and_applications.chain; li = li->next)
+ dump_appl((struct t_appl *)li);
+}
+
+static void del_dict_contents(struct t_dictionary * d) {
+ TRACE_ENTRY("%p", d);
+ while (!FD_IS_LIST_EMPTY(&d->vendors)) {
+ struct fd_list * li = d->vendors.next;
+ fd_list_unlink(li);
+ del_vendor_contents((struct t_vend *)li);
+ free(li);
+ }
+ while (!FD_IS_LIST_EMPTY(&d->base_and_applications.chain)) {
+ struct fd_list * li = d->base_and_applications.chain.next;
+ fd_list_unlink(li);
+ del_appl_contents((struct t_appl *)li);
+ free(li);
+ }
+ d->base_and_applications.name = NULL;
+ del_appl_contents(&d->base_and_applications);
+}
+
+/*********************************************/
+
+/* The states for the SAX parser, corresponding roughly to the expected structure of the XML file.
+We use the states mostly to validate the XML file. */
+enum state {
+ INIT = 0,
+ START, /* In "dictionary" */
+ IN_VENDOR,
+ IN_APPLICATION, /* note that "base" is equivalent to "application" for our state machine */
+ IN_COMMAND,
+ IN_REQRULES,
+ IN_REQRULES_FIXED,
+ IN_REQRULES_REQUIRED,
+ IN_REQRULES_OPTIONAL,
+ IN_ANSRULES,
+ IN_ANSRULES_FIXED,
+ IN_ANSRULES_REQUIRED,
+ IN_ANSRULES_OPTIONAL,
+ IN_TYPEDEFN,
+ IN_AVP,
+ IN_AVP_TYPE,
+ IN_AVP_ENUM,
+ IN_AVP_GROUPED,
+ IN_AVP_GROUPED_FIXED,
+ IN_AVP_GROUPED_REQUIRED,
+ IN_AVP_GROUPED_OPTIONAL
+};
+
+
+/* The context passed to the SAX parser */
+struct parser_ctx {
+ enum state state; /* the current state */
+ int error_depth; /* if non 0, we are in an unexpected element, wait until the count goes back to 0 to resume normal parsing. */
+ struct t_dictionary dict; /* The dictionary being built */
+ struct t_appl * cur_app;
+ struct t_cmd * cur_cmd;
+ struct t_avp * cur_avp;
+ char * xmlfilename; /* Name of the file, for error messages */
+};
+
+/* Find an attribute with given name in the list */
+static void get_attr(const xmlChar ** atts_array, const char * attr_name, xmlChar ** attr_val) {
+ int i;
+ *attr_val = NULL;
+ if (atts_array == NULL)
+ return;
+ for (i=0; atts_array[i] != NULL; i+=2) {
+ if (!strcasecmp((char *)atts_array[i], attr_name)) {
+ /* found */
+ *attr_val = (xmlChar *)atts_array[i+1];
+ return;
+ }
+ }
+ /* not found */
+ return;
+}
+
+/* The following macro avoids duplicating a lot of code in the state machine */
+#define ADD_RULE( _parent_list ) { \
+ xmlChar *xname, *xmin, *xmax; \
+ /* We are expecting an <avprule> tag at this point */ \
+ if (strcasecmp((char *)name, "avprule")) \
+ goto xml_tree_error; \
+ /* Search the expected attributes */ \
+ get_attr(atts, "name", &xname); \
+ get_attr(atts, "maximum", &xmax); \
+ get_attr(atts, "minimum", &xmin); \
+ /* Check the mandatory name is here */ \
+ CHECK_PARAMS_DO(xname, \
+ { TRACE_DEBUG(INFO, "Invalid 'avprule' tag found without 'name' attribute."); goto xml_tree_error; } ); \
+ /* Create the rule and add into the parent list */ \
+ CHECK_FCT_DO( new_rule((_parent_list), xname, xmax, xmin),\
+ { TRACE_DEBUG(INFO, "An error occurred while parsing an avprule tag. Entry ignored."); goto xml_tree_error; } ); \
+ /* Done. we don't change the state */ \
+}
+
+
+/* The function called on each XML element start tag (startElementSAXFunc) */
+static void SAXstartelem (void * ctx, const xmlChar * name, const xmlChar ** atts)
+{
+ struct parser_ctx * data = ctx;
+ TRACE_ENTRY("%p %p %p", ctx, name, atts);
+ CHECK_PARAMS_DO( ctx && name, { return; } );
+
+ TRACE_DEBUG(CALL, "Tag: <%s>", (char *)name);
+
+ if (data->error_depth) /* we are in an unknown element, just skip until it is closed */
+ goto xml_tree_error;
+
+ switch (data->state) {
+ case INIT: /* we are just starting. We only expect a <dictionary> tag, reject anything else. */
+ if (strcasecmp((char *)name, "dictionary"))
+ goto xml_tree_error;
+
+ data->state = START;
+ break;
+
+ case START:
+ /* We are in <dictionary>
+ Valid tags are: <vendor>, <base>, <application> */
+ if (!strcasecmp((char *)name, "vendor")) {
+ xmlChar *xid, *xname;
+
+ get_attr(atts, "id", &xid);
+ get_attr(atts, "name", &xname);
+
+ /* id and name are required */
+ CHECK_PARAMS_DO(xid && xname,
+ { TRACE_DEBUG(INFO, "Invalid 'vendor' tag found without 'id' or 'name' attribute."); goto xml_tree_error; } );
+
+
+ CHECK_FCT_DO( new_vendor(&data->dict.vendors, xid, xname),
+ { TRACE_DEBUG(INFO, "An error occurred while parsing a vendor tag. Entry ignored."); goto xml_tree_error; } )
+
+ data->state = IN_VENDOR;
+ break;
+ }
+
+ if (!strcasecmp((char *)name, "base")) {
+ /* we don't care for the 'uri' attribute */
+ data->cur_app = &data->dict.base_and_applications;
+ data->state = IN_APPLICATION;
+ break;
+ }
+
+ if (!strcasecmp((char *)name, "application")) {
+ /* we don't care for the 'uri' attribute */
+ xmlChar *xid, *xname;
+ char buf[50];
+
+ get_attr(atts, "id", &xid);
+ get_attr(atts, "name", &xname);
+
+ CHECK_PARAMS_DO(xid,
+ { TRACE_DEBUG(INFO, "Invalid 'application' tag found without 'id' attribute."); goto xml_tree_error; } );
+
+ /* Name is optional, if not provided we create a name */
+ if (!xname) {
+ snprintf(buf, sizeof(buf), "Application %s", xid);
+ xname = (xmlChar *)buf;
+ }
+
+ CHECK_FCT_DO( new_appl(&data->dict.base_and_applications.chain, xid, xname, &data->cur_app),
+ { TRACE_DEBUG(INFO, "An error occurred while parsing an application tag. Entry ignored."); goto xml_tree_error; } )
+
+ data->state = IN_APPLICATION;
+ break;
+ }
+
+ /* Other tags are errors */
+ goto xml_tree_error;
+
+
+ case IN_VENDOR: /* nothing is allowed inside <vendor> */
+ goto xml_tree_error;
+
+ case IN_APPLICATION:
+ /* We are in <base> or <application>
+ Valid tags are: <command>, <typedefn>, <avp> */
+ if (!strcasecmp((char *)name, "command")) {
+ /* we don't care for the 'vendor-id' attribute. */
+ xmlChar *xcode, *xname, *xpbit;
+
+ get_attr(atts, "code", &xcode);
+ get_attr(atts, "name", &xname);
+ get_attr(atts, "pbit", &xpbit);
+
+ /* code and name are required */
+ CHECK_PARAMS_DO(xcode && xname,
+ { TRACE_DEBUG(INFO, "Invalid 'command' tag found without 'code' or 'name' attribute."); goto xml_tree_error; } );
+
+ CHECK_FCT_DO( new_cmd( &data->cur_app->commands, xcode, xname, xpbit, &data->cur_cmd),
+ { TRACE_DEBUG(INFO, "An error occurred while parsing a command tag. Entry ignored."); goto xml_tree_error; } )
+
+ data->state = IN_COMMAND;
+ break;
+ }
+
+ if (!strcasecmp((char *)name, "typedefn")) {
+ /* we don't care for the 'description' attribute. */
+ xmlChar *xname, *xparent;
+
+ get_attr(atts, "type-name", &xname);
+ get_attr(atts, "type-parent", &xparent);
+
+ /* name is required */
+ CHECK_PARAMS_DO(xname,
+ { TRACE_DEBUG(INFO, "Invalid 'typedefn' tag found without 'name' attribute."); goto xml_tree_error; } );
+
+ CHECK_FCT_DO( new_type( &data->cur_app->types, xname, xparent),
+ { TRACE_DEBUG(INFO, "An error occurred while parsing a typedefn tag. Entry ignored."); goto xml_tree_error; } )
+
+ data->state = IN_TYPEDEFN;
+ break;
+ }
+
+ if (!strcasecmp((char *)name, "avp")) {
+ /* we don't care for the description, may-encrypt, and protected attributes */
+ xmlChar *xname, *xcode, *xmandatory, *xvendor;
+
+ get_attr(atts, "name", &xname);
+ get_attr(atts, "code", &xcode);
+ get_attr(atts, "mandatory", &xmandatory);
+ get_attr(atts, "vendor-id", &xvendor);
+
+ /* code and name are required */
+ CHECK_PARAMS_DO(xcode && xname,
+ { TRACE_DEBUG(INFO, "Invalid 'avp' tag found without 'code' or 'name' attribute."); goto xml_tree_error; } );
+
+ CHECK_FCT_DO( new_avp(&data->cur_app->avps, xcode, xname, xmandatory, xvendor, &data->cur_avp),
+ { TRACE_DEBUG(INFO, "An error occurred while parsing an avp tag. Entry ignored."); goto xml_tree_error; } )
+
+ data->state = IN_AVP;
+ break;
+ }
+ /* Other tags are errors */
+ goto xml_tree_error;
+
+
+ case IN_COMMAND:
+ /* We are in <command>
+ Valid tags are: <requestrules>, <answerrules> */
+ if (!strcasecmp((char *)name, "requestrules")) {
+ data->state = IN_REQRULES;
+ break;
+ }
+ if (!strcasecmp((char *)name, "answerrules")) {
+ data->state = IN_ANSRULES;
+ break;
+ }
+ /* Other tags are errors */
+ goto xml_tree_error;
+
+ case IN_REQRULES:
+ /* We are in <requestrules>
+ Valid tags are: <fixed>, <required>, <optional> */
+ if (!strcasecmp((char *)name, "fixed")) {
+ data->state = IN_REQRULES_FIXED;
+ break;
+ }
+ if (!strcasecmp((char *)name, "required")) {
+ data->state = IN_REQRULES_REQUIRED;
+ break;
+ }
+ if (!strcasecmp((char *)name, "optional")) {
+ data->state = IN_REQRULES_OPTIONAL;
+ break;
+ }
+ /* Other tags are errors */
+ goto xml_tree_error;
+
+ case IN_ANSRULES:
+ /* We are in <answerrules>
+ Valid tags are: <fixed>, <required>, <optional> */
+ if (!strcasecmp((char *)name, "fixed")) {
+ data->state = IN_ANSRULES_FIXED;
+ break;
+ }
+ if (!strcasecmp((char *)name, "required")) {
+ data->state = IN_ANSRULES_REQUIRED;
+ break;
+ }
+ if (!strcasecmp((char *)name, "optional")) {
+ data->state = IN_ANSRULES_OPTIONAL;
+ break;
+ }
+ /* Other tags are errors */
+ goto xml_tree_error;
+
+ case IN_REQRULES_FIXED:
+ /* We are in <command><answerrules><fixed>
+ Valid tags are: <avprule> */
+ ADD_RULE( &data->cur_cmd->reqrules_fixed );
+ break;
+ case IN_REQRULES_REQUIRED:
+ ADD_RULE( &data->cur_cmd->reqrules_required );
+ break;
+ case IN_REQRULES_OPTIONAL:
+ ADD_RULE( &data->cur_cmd->reqrules_optional );
+ break;
+ case IN_ANSRULES_FIXED:
+ ADD_RULE( &data->cur_cmd->ansrules_fixed );
+ break;
+ case IN_ANSRULES_REQUIRED:
+ ADD_RULE( &data->cur_cmd->ansrules_required );
+ break;
+ case IN_ANSRULES_OPTIONAL:
+ ADD_RULE( &data->cur_cmd->ansrules_optional );
+ break;
+
+
+ case IN_TYPEDEFN: /* nothing is allowed inside <typedefn> */
+ goto xml_tree_error;
+
+
+ case IN_AVP:
+ /* We are in <avp>
+ Valid tags are: <type>, <enum>, <grouped> */
+ if (!strcasecmp((char *)name, "type")) {
+ xmlChar *xname;
+
+ get_attr(atts, "type-name", &xname);
+
+ /* name is required */
+ CHECK_PARAMS_DO(xname,
+ { TRACE_DEBUG(INFO, "Invalid 'type' tag found without 'name' attribute."); goto xml_tree_error; } );
+
+ /* Check there is only 1 type */
+ if (!FD_IS_LIST_EMPTY(&data->cur_avp->type)) {
+ TRACE_DEBUG(INFO, "Multiple 'type' tags found for AVP.");
+ goto xml_tree_error;
+ }
+
+ /* Add the new type */
+ CHECK_FCT_DO( new_avptype(&data->cur_avp->type, xname),
+ { TRACE_DEBUG(INFO, "An error occurred while parsing a type tag. Entry ignored."); goto xml_tree_error; } )
+
+ data->state = IN_AVP_TYPE;
+ break;
+ }
+ if (!strcasecmp((char *)name, "enum")) {
+ xmlChar *xcode, *xname;
+
+ get_attr(atts, "code", &xcode);
+ get_attr(atts, "name", &xname);
+
+ /* code and name are required */
+ CHECK_PARAMS_DO(xcode && xname,
+ { TRACE_DEBUG(INFO, "Invalid 'enum' tag found without 'code' or 'name' attribute."); goto xml_tree_error; } );
+
+ CHECK_FCT_DO( new_enum(&data->cur_avp->enums, xcode, xname),
+ { TRACE_DEBUG(INFO, "An error occurred while parsing a command tag. Entry ignored."); goto xml_tree_error; } )
+
+ data->state = IN_AVP_ENUM;
+ break;
+ }
+ if (!strcasecmp((char *)name, "grouped")) {
+ /* no attribute for this one */
+ data->state = IN_AVP_GROUPED;
+ break;
+ }
+ /* Other tags are errors */
+ goto xml_tree_error;
+
+ case IN_AVP_TYPE: /* nothing is allowed inside <type> */
+ goto xml_tree_error;
+
+ case IN_AVP_ENUM: /* nothing is allowed inside <enum> */
+ goto xml_tree_error;
+
+ case IN_AVP_GROUPED:
+ /* We are in <avp><grouped>
+ Valid tags are: <fixed>, <required>, <optional> */
+ if (!strcasecmp((char *)name, "fixed")) {
+ data->state = IN_AVP_GROUPED_FIXED;
+ break;
+ }
+ if (!strcasecmp((char *)name, "required")) {
+ data->state = IN_AVP_GROUPED_REQUIRED;
+ break;
+ }
+ if (!strcasecmp((char *)name, "optional")) {
+ data->state = IN_AVP_GROUPED_OPTIONAL;
+ break;
+ }
+ /* Other tags are errors */
+ goto xml_tree_error;
+
+ case IN_AVP_GROUPED_FIXED:
+ /* We are in <avp><grouped><fixed>
+ Valid tags are: <avprule> */
+ ADD_RULE( &data->cur_avp->grouped_fixed );
+ break;
+ case IN_AVP_GROUPED_REQUIRED:
+ ADD_RULE( &data->cur_avp->grouped_required );
+ break;
+ case IN_AVP_GROUPED_OPTIONAL:
+ ADD_RULE( &data->cur_avp->grouped_optional );
+ break;
+
+
+ default:
+ TRACE_DEBUG(INFO, "Internal parsing error, unexpected state %d.", data->state);
+ }
+
+ return;
+
+xml_tree_error:
+ if (!data->error_depth) {
+ TRACE_DEBUG(INFO, "Unexpected XML element found: '%s'. Ignoring...", name);
+ }
+ data->error_depth += 1;
+ if (data->cur_app || data->cur_cmd || data->cur_avp) {
+ TRACE_DEBUG(INFO, "Error encountered while parsing tag of:");
+ if (data->cur_app)
+ fd_log_debug(" Application: '%s'", data->cur_app->name);
+ if (data->cur_cmd)
+ fd_log_debug(" Command : '%s'", data->cur_cmd->name);
+ if (data->cur_avp)
+ fd_log_debug(" AVP : '%s'", data->cur_avp->name);
+ }
+ return;
+}
+
+/* The function called on each XML element end tag (endElementSAXFunc) */
+static void SAXendelem (void * ctx, const xmlChar * name)
+{
+ struct parser_ctx * data = ctx;
+ TRACE_ENTRY("%p %p", ctx, name);
+ CHECK_PARAMS_DO( ctx && name, { return; } );
+
+ TRACE_DEBUG(CALL, "Tag: </%s>", (char *)name);
+
+ if (data->error_depth) {
+ /* we are recovering from an erroneous element */
+ data->error_depth -= 1;
+ return;
+ }
+
+ switch (data->state) {
+ case INIT:
+ goto state_machine_error;
+
+ case START:
+ if (strcasecmp((char *)name, "dictionary"))
+ goto state_machine_error;
+
+ data->state = 0;
+ break;
+
+ case IN_VENDOR:
+ if (strcasecmp((char *)name, "vendor"))
+ goto state_machine_error;
+
+ data->state = START;
+ break;
+
+ case IN_APPLICATION:
+ if (strcasecmp((char *)name, "base") && strcasecmp((char *)name, "application"))
+ goto state_machine_error;
+
+ data->cur_app = NULL;
+ data->state = START;
+ break;
+
+ case IN_COMMAND:
+ if (strcasecmp((char *)name, "command"))
+ goto state_machine_error;
+
+ data->cur_cmd = NULL;
+ data->state = IN_APPLICATION;
+ break;
+
+ case IN_REQRULES:
+ if (strcasecmp((char *)name, "requestrules"))
+ goto state_machine_error;
+
+ data->state = IN_COMMAND;
+ break;
+
+ case IN_REQRULES_FIXED:
+ if (!strcasecmp((char *)name, "avprule"))
+ /* we don't have a special state for these, just ignore */
+ return;
+ if (strcasecmp((char *)name, "fixed"))
+ goto state_machine_error;
+ data->state = IN_REQRULES;
+ break;
+ case IN_REQRULES_REQUIRED:
+ if (!strcasecmp((char *)name, "avprule"))
+ /* we don't have a special state for these, just ignore */
+ return;
+ if (strcasecmp((char *)name, "required"))
+ goto state_machine_error;
+ data->state = IN_REQRULES;
+ break;
+ case IN_REQRULES_OPTIONAL:
+ if (!strcasecmp((char *)name, "avprule"))
+ /* we don't have a special state for these, just ignore */
+ return;
+ if (strcasecmp((char *)name, "optional"))
+ goto state_machine_error;
+ data->state = IN_REQRULES;
+ break;
+
+ case IN_ANSRULES:
+ if (strcasecmp((char *)name, "answerrules"))
+ goto state_machine_error;
+
+ data->state = IN_COMMAND;
+ break;
+ case IN_ANSRULES_FIXED:
+ if (!strcasecmp((char *)name, "avprule"))
+ /* we don't have a special state for these, just ignore */
+ return;
+ if (strcasecmp((char *)name, "fixed"))
+ goto state_machine_error;
+ data->state = IN_ANSRULES;
+ break;
+ case IN_ANSRULES_REQUIRED:
+ if (!strcasecmp((char *)name, "avprule"))
+ /* we don't have a special state for these, just ignore */
+ return;
+ if (strcasecmp((char *)name, "required"))
+ goto state_machine_error;
+ data->state = IN_ANSRULES;
+ break;
+ case IN_ANSRULES_OPTIONAL:
+ if (!strcasecmp((char *)name, "avprule"))
+ /* we don't have a special state for these, just ignore */
+ return;
+ if (strcasecmp((char *)name, "optional"))
+ goto state_machine_error;
+ data->state = IN_ANSRULES;
+ break;
+
+
+ case IN_TYPEDEFN:
+ if (strcasecmp((char *)name, "typedefn"))
+ goto state_machine_error;
+
+ data->state = IN_APPLICATION;
+ break;
+
+ case IN_AVP:
+ if (strcasecmp((char *)name, "avp"))
+ goto state_machine_error;
+
+ data->cur_avp = NULL;
+ data->state = IN_APPLICATION;
+ break;
+
+ case IN_AVP_TYPE:
+ if (strcasecmp((char *)name, "type"))
+ goto state_machine_error;
+
+ data->state = IN_AVP;
+ break;
+
+ case IN_AVP_ENUM:
+ if (strcasecmp((char *)name, "enum"))
+ goto state_machine_error;
+
+ data->state = IN_AVP;
+ break;
+
+ case IN_AVP_GROUPED:
+ if (strcasecmp((char *)name, "grouped"))
+ goto state_machine_error;
+
+ data->state = IN_AVP;
+ break;
+
+ case IN_AVP_GROUPED_FIXED:
+ if (!strcasecmp((char *)name, "avprule"))
+ /* we don't have a special state for these, just ignore */
+ return;
+ if (strcasecmp((char *)name, "fixed"))
+ goto state_machine_error;
+ data->state = IN_AVP_GROUPED;
+ break;
+ case IN_AVP_GROUPED_REQUIRED:
+ if (!strcasecmp((char *)name, "avprule"))
+ return;
+ if (strcasecmp((char *)name, "required"))
+ goto state_machine_error;
+ data->state = IN_AVP_GROUPED;
+ break;
+ case IN_AVP_GROUPED_OPTIONAL:
+ if (!strcasecmp((char *)name, "avprule"))
+ return;
+ if (strcasecmp((char *)name, "optional"))
+ goto state_machine_error;
+ data->state = IN_AVP_GROUPED;
+ break;
+
+ default:
+ TRACE_DEBUG(INFO, "Internal parsing error, unexpected state %d.", data->state);
+ }
+
+ return;
+
+state_machine_error:
+ TRACE_DEBUG(INFO, "Internal parsing error, ignored [state %d, closing tag '%s'].", data->state, name);
+ return;
+}
+
+/* The SAX parser sends a warning, error, fatalerror -- do we need these ?
+static void SAXwarning (void * ctx, const char * msg, ...)
+{
+
+}
+static void SAXerror (void * ctx, const char * msg, ...)
+{
+
+}
+static void SAXfatal (void * ctx, const char * msg, ...)
+{
+
+}
+*/
+
+
+
+
+/*********************************************/
+ /* 2nd pass: from memory to fD dictionary */
+/*********************************************/
+
+/* Find or create a vendor */
+static int vend_to_fD(struct t_vend * v, struct dictionary * fD_dict, struct dict_object ** fd_v, int * nb_added)
+{
+ int ret;
+ struct dict_object * prev = NULL;
+ struct dict_vendor_data vd;
+
+ TRACE_ENTRY("%p %p %p %p", v, fD_dict, fd_v, nb_added);
+
+ CHECK_PARAMS(v && fD_dict);
+
+ /* Prepare the data in fD's format */
+ memset(&vd, 0, sizeof(vd));
+ vd.vendor_id = v->id;
+ vd.vendor_name = (char *)v->name;
+
+ /* Create or search in the dictionary */
+ ret = fd_dict_new ( fD_dict, DICT_VENDOR, &vd, NULL, &prev );
+ if (fd_v)
+ *fd_v = prev;
+ if (ret == EEXIST) {
+ /* Conflict with existing entry */
+ CHECK_FCT( fd_dict_getval(prev, &vd) );
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Warning: Conflicting entry.");
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] New entry (ignored): %u - '%s'", v->id, (char *)v->name);
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Old entry : %u - '%s'", vd.vendor_id, vd.vendor_name);
+ return 0;
+ } else {
+ /* other errors are stoppers */
+ CHECK_FCT(ret);
+ }
+
+ /* Update count */
+ if (nb_added)
+ *nb_added += 1;
+
+ /* Done */
+ return 0;
+}
+
+/* Find the base fD type from a type name */
+static int resolve_base_type(struct dictionary * fD_dict, uint8_t * type_name, enum dict_avp_basetype * basetype, struct dict_object **type)
+{
+ int ret;
+ struct dict_type_data td;
+ struct dict_object *t;
+
+ TRACE_ENTRY("%p, %p %p", fD_dict, type_name, basetype);
+ CHECK_PARAMS( fD_dict && type_name && basetype );
+
+ /* First, check if the type is already in the dictionary */
+ ret = fd_dict_search ( fD_dict, DICT_TYPE, TYPE_BY_NAME, type_name, &t, ENOENT);
+ switch (ret) {
+ case 0: /* the type is already in the dictionary */
+ CHECK_FCT( fd_dict_getval(t, &td) );
+ *basetype = td.type_base;
+ if (type)
+ *type = t;
+ return 0;
+
+ case ENOENT: /* We did not find it, it is maybe normal */
+ break;
+
+ default:
+ /* An unexpected error occurred */
+ CHECK_FCT(ret);
+ }
+
+ /* at this point we did not find the type in the dictionary */
+#define PREDEF_TYPES( _typename_, _basetype_ ) \
+ if (!strcasecmp((char *)type_name, (_typename_))) { \
+ *basetype = (_basetype_); \
+ return 0; \
+ }
+
+ PREDEF_TYPES( "OctetString", AVP_TYPE_OCTETSTRING );
+ PREDEF_TYPES( "Integer32", AVP_TYPE_INTEGER32 );
+ PREDEF_TYPES( "Integer64", AVP_TYPE_INTEGER64 );
+ PREDEF_TYPES( "Unsigned32", AVP_TYPE_UNSIGNED32 );
+ PREDEF_TYPES( "Enumerated", AVP_TYPE_INTEGER32 );
+ PREDEF_TYPES( "Unsigned64", AVP_TYPE_UNSIGNED64 );
+ PREDEF_TYPES( "Float32", AVP_TYPE_FLOAT32 );
+ PREDEF_TYPES( "Float64", AVP_TYPE_FLOAT64 );
+
+ /* When we reach this point, we have not yet found this type anywhere. */
+ TODO("Type not found. Maybe search in whole xmldictionary if it is defined later?");
+ TRACE_DEBUG(INFO, "The type '%s' could not be resolved. Please check it is defined before use.", type_name);
+ return ENOENT;
+}
+
+/* Find or create a type. */
+static int typdefn_to_fD(struct t_typedefn * t, struct dictionary * fD_dict, struct dict_object * fd_appl, struct dict_object ** fd_t, int * nb_added)
+{
+ int ret;
+ struct dict_object * prev = NULL;
+ struct dict_type_data td;
+
+ TRACE_ENTRY("%p %p %p %p %p", t, fD_dict, fd_appl, fd_t, nb_added);
+
+ CHECK_PARAMS(t && fD_dict);
+
+ /* Prepare the data in fD's format */
+ memset(&td, 0, sizeof(td));
+ td.type_name = (char *)t->name;
+
+ /* infer td.type_base from t->parent_name */
+ CHECK_FCT( resolve_base_type(fD_dict, t->parent_name, &td.type_base, NULL) );
+
+ /* Create or search in the dictionary */
+ ret = fd_dict_new ( fD_dict, DICT_TYPE, &td, fd_appl, &prev );
+ if (fd_t)
+ *fd_t = prev;
+ if (ret == EEXIST) {
+ /* Conflict with existing entry */
+ enum dict_avp_basetype xmlbt = td.type_base;
+ extern const char * type_base_name[]; /* in libfreeDiameter/dictionary.c */
+ CHECK_FCT( fd_dict_getval(prev, &td) );
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Warning: Conflicting entry.");
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] New entry (ignored): '%s' (%d - %s)", t->name, xmlbt, type_base_name[xmlbt] );
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Old entry : '%s' (%d - %s)", td.type_name, td.type_base, type_base_name[td.type_base]);
+ return 0;
+ } else {
+ /* other errors are stoppers */
+ CHECK_FCT(ret);
+ }
+
+ /* Update count */
+ if (nb_added)
+ *nb_added += 1;
+
+ /* Done */
+ return 0;
+}
+
+/* Process one list of rules */
+static int rules_to_fD_onelist(struct dictionary * fD_dict, struct dict_object * parent, enum rule_position position, struct fd_list * list, int * nb_added)
+{
+ struct dict_rule_data rd;
+ struct fd_list * li;
+ int order = 0;
+ int ret;
+
+ TRACE_ENTRY("%p %p %d %p %p", fD_dict, parent, position, list, nb_added);
+
+ CHECK_PARAMS(fD_dict && parent && position && list);
+
+ for (li = list->next; li != list; li = li->next) {
+ struct t_rule * r = (struct t_rule *)li;
+
+ /* The [AVP] rule in all ABNF definitions is implicit in freeDiameter, skip it */
+ if (!strcmp((char *)r->avpname, "AVP"))
+ continue;
+
+ /* Prepare rule data */
+ memset(&rd, 0, sizeof(rd));
+ rd.rule_position = position;
+ rd.rule_order = ++order; /* actually only used for fixed rules, but no harm for others */
+ rd.rule_min = r->min;
+ rd.rule_max = r->max;
+
+ /* Resolve the AVP */
+ ret = fd_dict_search(fD_dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS, r->avpname, &rd.rule_avp, ENOENT);
+ if (ret == ENOENT) {
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Error: AVP '%s' used in a rule before being defined.", r->avpname);
+ }
+ CHECK_FCT(ret);
+
+ /* Now create the new rule */
+ CHECK_FCT_DO( ret = fd_dict_new ( fD_dict, DICT_RULE, &rd, parent, NULL ),
+ { TRACE_DEBUG(INFO, "Error creating rule for sub-AVP '%s'", r->avpname); return ret; } );
+ if (nb_added)
+ *nb_added += 1;
+ }
+
+ return 0;
+}
+
+/* Process lists of rules */
+static int rules_to_fD(struct dictionary * fD_dict, struct dict_object * parent, struct fd_list * fixed, struct fd_list * required, struct fd_list * optional, int * nb_added)
+{
+ int ret;
+
+ TRACE_ENTRY("%p %p %p %p %p %p", fD_dict, parent, fixed, required, optional, nb_added);
+
+ /* Process the rules */
+ CHECK_FCT_DO( ret = rules_to_fD_onelist(fD_dict, parent, RULE_FIXED_HEAD, fixed, nb_added),
+ { TRACE_DEBUG(INFO, "Error processing FIXED rules"); return ret; } );
+ CHECK_FCT_DO( ret = rules_to_fD_onelist(fD_dict, parent, RULE_REQUIRED, required, nb_added),
+ { TRACE_DEBUG(INFO, "Error processing REQUIRED rules"); return ret; } );
+ CHECK_FCT_DO( ret = rules_to_fD_onelist(fD_dict, parent, RULE_OPTIONAL, optional, nb_added),
+ { TRACE_DEBUG(INFO, "Error processing OPTIONAL rules"); return ret; } );
+
+ return 0;
+}
+
+/* Find or create an AVP (and dependent objects) */
+static int avp_to_fD(struct t_avp * a, struct dictionary * fD_dict, struct dict_object * fd_appl, struct dict_object ** fd_a, int * nb_added)
+{
+ int ret;
+ struct dict_object * prev = NULL, *type = NULL;
+ struct dict_avp_data ad;
+ struct fd_list * li;
+
+ TRACE_ENTRY("%p %p %p %p %p", a, fD_dict, fd_appl, fd_a, nb_added);
+
+ CHECK_PARAMS(a && fD_dict);
+
+ /* Prepare the data in fD's format */
+ memset(&ad, 0, sizeof(ad));
+ ad.avp_code = a->code;
+ ad.avp_vendor = a->vendor;
+ ad.avp_name = (char *)a->name;
+ ad.avp_flag_mask = a->fmask | AVP_FLAG_VENDOR;
+ ad.avp_flag_val = a->flags;
+
+ if (!FD_IS_LIST_EMPTY(&a->type)) {
+ /* special exception: we use per-AVP enumerated types in fD */
+ if (!strcasecmp("Enumerated", (char *)((struct t_avptype *)a->type.next)->type_name))
+ goto enumerated;
+ /* Let's allow "Integer32" instead of "Enumerated" also... */
+ if ((!FD_IS_LIST_EMPTY(&a->enums)) && (!strcasecmp("Integer32", (char *)((struct t_avptype *)a->type.next)->type_name)))
+ goto enumerated;
+
+ /* The type was explicitly specified, resolve it */
+ CHECK_FCT( resolve_base_type(fD_dict, ((struct t_avptype *)a->type.next)->type_name, &ad.avp_basetype, &type) );
+ } else {
+ /* The type was not specified, try to infer it from provided data */
+ if ( !FD_IS_LIST_EMPTY(&a->grouped_optional)
+ || !FD_IS_LIST_EMPTY(&a->grouped_required)
+ || !FD_IS_LIST_EMPTY(&a->grouped_fixed) ) {
+ /* The AVP has rules, it is a grouped AVP */
+ CHECK_PARAMS_DO( FD_IS_LIST_EMPTY(&a->enums),
+ { TRACE_DEBUG(INFO, "Conflict: The AVP '%s' has both enum values and rules.", ad.avp_name); return EINVAL; } );
+ ad.avp_basetype = AVP_TYPE_GROUPED;
+ } else {
+ /* It should be an enumerated AVP... */
+ if (FD_IS_LIST_EMPTY(&a->enums)) {
+ TRACE_DEBUG(INFO, "Error: Missing type information for AVP '%s'", ad.avp_name);
+ return EINVAL;
+ } else {
+ /* We create a new type to hold the enumerated values -- fD specifics */
+ char typename[256];
+ struct dict_type_data tdata;
+
+enumerated:
+ snprintf(typename, sizeof(typename), "Enumerated(%s)", ad.avp_name);
+ memset(&tdata, 0, sizeof(tdata));
+ tdata.type_base = AVP_TYPE_INTEGER32;
+ tdata.type_name = &typename[0];
+ CHECK_FCT( fd_dict_new ( fD_dict, DICT_TYPE, &tdata, fd_appl, &type ) );
+ if (nb_added)
+ *nb_added += 1;
+
+ ad.avp_basetype = AVP_TYPE_INTEGER32;
+ }
+ }
+ }
+
+ /* At this point, ad.avp_basetype is defined and type might also be */
+
+ /* Create or search in the dictionary */
+ ret = fd_dict_new ( fD_dict, DICT_AVP, &ad, type, &prev );
+ if (fd_a)
+ *fd_a = prev;
+ if (ret == EEXIST) {
+ /* Conflict with existing entry */
+ CHECK_FCT( fd_dict_getval(prev, &ad) );
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Warning: Conflicting entry.");
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] New entry (ignored): %u - '%s'", a->code, (char *)a->name);
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Old entry : %u - '%s'", ad.avp_code, ad.avp_name);
+ goto inside;
+ } else {
+ /* other errors are stoppers */
+ CHECK_FCT(ret);
+ }
+
+ /* Update count */
+ if (nb_added)
+ *nb_added += 1;
+
+inside:
+ /* Now, the inner elements, if any */
+
+ if ( (!FD_IS_LIST_EMPTY(&a->enums)) && (ad.avp_basetype != AVP_TYPE_UNSIGNED32)) {
+ TRACE_DEBUG(INFO, "AVP '%s' type is not an Unsigned32 but it has enum values (invalid in this extension).", ad.avp_name);
+ return EINVAL;
+ }
+
+ /* In case of enumeration, define the enum values */
+ for (li = a->enums.next; li != &a->enums; li = li->next) {
+ struct t_enum * e = (struct t_enum *)li;
+ struct dict_enumval_data ed;
+
+ memset(&ed, 0, sizeof(ed));
+ ed.enum_name = (char *)e->name;
+ ed.enum_value.u32 = e->code;
+
+ CHECK_FCT_DO( ret = fd_dict_new ( fD_dict, DICT_ENUMVAL, &ed, type, NULL ),
+ {
+ TRACE_DEBUG(INFO, "Error defining constant value '%s' for AVP '%s': %s", ed.enum_name, ad.avp_name, strerror(ret));
+ return ret;
+ } );
+ if (nb_added)
+ *nb_added += 1;
+ }
+
+ /* In case of grouped AVP, check the type is really grouped */
+ if ( !FD_IS_LIST_EMPTY(&a->grouped_optional)
+ || !FD_IS_LIST_EMPTY(&a->grouped_required)
+ || !FD_IS_LIST_EMPTY(&a->grouped_fixed) ) {
+ CHECK_PARAMS_DO( ad.avp_basetype == AVP_TYPE_GROUPED,
+ { TRACE_DEBUG(INFO, "Got rules for non-grouped AVP '%s'", ad.avp_name); return EINVAL;} );
+ CHECK_FCT_DO( ret = rules_to_fD(fD_dict, prev, &a->grouped_fixed, &a->grouped_required, &a->grouped_optional, nb_added),
+ { TRACE_DEBUG(INFO, "Error processing rules for AVP '%s': %s", ad.avp_name, strerror(ret)); return ret; } );
+ }
+
+ /* done! */
+ return 0;
+}
+
+/* Find or create a command. */
+static int cmd_to_fD(struct t_cmd * c, struct dictionary * fD_dict, struct dict_object * fd_appl, struct dict_object ** fd_req, int * nb_added)
+{
+ int ret;
+ struct dict_object * req = NULL, *ans = NULL;
+ struct dict_cmd_data cd;
+ char cmdname[512];
+
+ TRACE_ENTRY("%p %p %p %p %p", c, fD_dict, fd_appl, fd_req, nb_added);
+
+ CHECK_PARAMS(c && fD_dict);
+
+ /* Prepare the request data in fD's format */
+ memset(&cd, 0, sizeof(cd));
+ cd.cmd_code = c->code;
+ snprintf(cmdname, sizeof(cmdname), "%s-Request", (char *)c->name);
+ cd.cmd_name = &cmdname[0];
+ cd.cmd_flag_mask = c->fmask | CMD_FLAG_REQUEST | CMD_FLAG_ERROR;
+ cd.cmd_flag_val = c->flags | CMD_FLAG_REQUEST;
+
+ /* Create or search in the dictionary */
+ ret = fd_dict_new ( fD_dict, DICT_COMMAND, &cd, fd_appl, &req );
+ if (fd_req)
+ *fd_req = req;
+ if (ret == EEXIST) {
+ struct dict_cmd_data prevcd;
+ /* Conflict with existing entry */
+ CHECK_FCT( fd_dict_getval(req, &prevcd) );
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Warning: Conflicting entry.");
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] New entry (ignored): %u - '%s'", cd.cmd_code, cd.cmd_name);
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Old entry : %u - '%s'", prevcd.cmd_code, prevcd.cmd_name);
+ goto answer;
+ } else {
+ /* other errors are stoppers */
+ CHECK_FCT(ret);
+ }
+
+ /* Update count */
+ if (nb_added)
+ *nb_added += 1;
+
+answer:
+ /* update data for the answer */
+ snprintf(cmdname, sizeof(cmdname), "%s-Answer", (char *)c->name);
+ cd.cmd_flag_val &= ~CMD_FLAG_REQUEST;
+ cd.cmd_flag_mask &= ~CMD_FLAG_ERROR;
+
+ ret = fd_dict_new ( fD_dict, DICT_COMMAND, &cd, fd_appl, &ans );
+ if (ret == EEXIST) {
+ struct dict_cmd_data prevcd;
+ /* Conflict with existing entry */
+ CHECK_FCT( fd_dict_getval(ans, &prevcd) );
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Warning: Conflicting entry.");
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] New entry (ignored): %u - '%s'", cd.cmd_code, cd.cmd_name);
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Old entry : %u - '%s'", prevcd.cmd_code, prevcd.cmd_name);
+ goto rules;
+ } else {
+ /* other errors are stoppers */
+ CHECK_FCT(ret);
+ }
+
+ /* Update count */
+ if (nb_added)
+ *nb_added += 1;
+
+rules:
+ /* Now process the rules inside the command */
+ CHECK_FCT_DO( ret = rules_to_fD(fD_dict, req, &c->reqrules_fixed, &c->reqrules_required, &c->reqrules_optional, nb_added),
+ {
+ TRACE_DEBUG(INFO, "Error converting data from request rules: %s", strerror(ret));
+ return ret;
+ } );
+ CHECK_FCT_DO( ret = rules_to_fD(fD_dict, ans, &c->ansrules_fixed, &c->ansrules_required, &c->ansrules_optional, nb_added),
+ {
+ TRACE_DEBUG(INFO, "Error converting data from answer rules: %s", strerror(ret));
+ return ret;
+ } );
+
+ /* Done */
+ return 0;
+}
+
+/* Find or create an application (and dependent objects) */
+static int appl_to_fD(struct t_appl * a, struct dictionary * fD_dict, struct dict_object ** fd_a, int * nb_added)
+{
+ int ret;
+ struct dict_object * prev = NULL;
+ struct dict_application_data ad;
+ struct fd_list * li;
+
+ TRACE_ENTRY("%p %p %p %p", a, fD_dict, fd_a, nb_added);
+
+ CHECK_PARAMS(a && fD_dict);
+
+ if (a->id) { /* skip app 0 */
+
+ /* Prepare the data in fD's format */
+ memset(&ad, 0, sizeof(ad));
+ ad.application_id = a->id;
+ ad.application_name = (char *)a->name;
+
+ /* Create or search in the dictionary */
+ ret = fd_dict_new ( fD_dict,
+ DICT_APPLICATION,
+ &ad,
+ NULL /* we don't have a parent vendor in XML files, so currently everything links to no vendor */,
+ &prev );
+ if (fd_a)
+ *fd_a = prev;
+ if (ret == EEXIST) {
+ /* Conflict with existing entry */
+ CHECK_FCT( fd_dict_getval(prev, &ad) );
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Warning: Conflicting entry.");
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] New entry (ignored): %u - '%s'", a->id, (char *)a->name);
+ TRACE_DEBUG(INFO, "[dict_legacy_xml] Old entry : %u - '%s'", ad.application_id, ad.application_name);
+ goto inside;
+ } else {
+ /* other errors are stoppers */
+ CHECK_FCT(ret);
+ }
+
+ /* Update count */
+ if (nb_added)
+ *nb_added += 1;
+ }
+
+inside:
+ /* Now, the inner elements */
+
+ /* First, define all the types */
+ for (li = a->types.next; li != &a->types; li = li->next) {
+ CHECK_FCT_DO( ret = typdefn_to_fD((struct t_typedefn *)li, fD_dict, prev, NULL, nb_added),
+ {
+ TRACE_DEBUG(INFO, "Error converting data from typedefn '%s': %s", ((struct t_typedefn *)li)->name, strerror(ret));
+ return ret;
+ } );
+ }
+
+ /* Then, AVPs, enums, and grouped AVP rules */
+ for (li = a->avps.next; li != &a->avps; li = li->next) {
+ CHECK_FCT_DO( ret = avp_to_fD((struct t_avp *)li, fD_dict, prev, NULL, nb_added),
+ {
+ TRACE_DEBUG(INFO, "Error converting data from AVP '%s': %s", ((struct t_avp *)li)->name, strerror(ret));
+ return ret;
+ } );
+ }
+
+ /* Finally, the commands and rules */
+ for (li = a->commands.next; li != &a->commands; li = li->next) {
+ CHECK_FCT_DO( ret = cmd_to_fD((struct t_cmd *)li, fD_dict, prev, NULL, nb_added),
+ {
+ TRACE_DEBUG(INFO, "Error converting data from command '%s': %s", ((struct t_cmd *)li)->name, strerror(ret));
+ return ret;
+ } );
+ }
+
+ /* done! */
+ return 0;
+}
+
+
+static int dict_to_fD(struct dictionary * fD_dict, struct t_dictionary * xmldict, int * nb_added)
+{
+ struct fd_list * li;
+ int ret;
+
+ TRACE_ENTRY("%p %p %p", fD_dict, xmldict, nb_added);
+
+ CHECK_PARAMS(fD_dict && xmldict && nb_added);
+
+ *nb_added = 0;
+
+ /* Create all the vendors */
+ for (li = xmldict->vendors.next; li != &xmldict->vendors; li = li->next) {
+ CHECK_FCT_DO( ret = vend_to_fD((struct t_vend *)li, fD_dict, NULL, nb_added),
+ {
+ TRACE_DEBUG(INFO, "Error converting data from vendor '%s': %s", ((struct t_vend *)li)->name, strerror(ret));
+ return ret;
+ } );
+ }
+
+ /* Now, process each application */
+ CHECK_FCT_DO( ret = appl_to_fD(&xmldict->base_and_applications, fD_dict, NULL, nb_added),
+ {
+ TRACE_DEBUG(INFO, "Error converting data from Base application: %s", strerror(ret));
+ return ret;
+ } );
+ for (li = xmldict->base_and_applications.chain.next; li != &xmldict->base_and_applications.chain; li = li->next) {
+ CHECK_FCT_DO( ret = appl_to_fD((struct t_appl *) li, fD_dict, NULL, nb_added),
+ {
+ TRACE_DEBUG(INFO, "Error converting data from application '%s': %s", ((struct t_appl *)li)->name, strerror(ret));
+ return ret;
+ } );
+ }
+
+ /* Complete! */
+ return 0;
+}
+
+
+
+
+
+/*********************************************/
+
+int dict_lxml_parse(char * xmlfilename)
+{
+ xmlSAXHandler handler;
+ struct parser_ctx data;
+ int ret;
+
+ TRACE_ENTRY("%p", xmlfilename);
+
+ CHECK_PARAMS_DO(xmlfilename, { return -1; } );
+
+ TRACE_DEBUG(FULL, "Parsing next XML file: %s...", xmlfilename);
+
+ /* Initialize the parser */
+ memset(&handler, 0, sizeof(handler));
+ handler.startElement = SAXstartelem;
+ handler.endElement = SAXendelem;
+
+ /* Initialize the data */
+ memset(&data, 0, sizeof(data));
+ fd_list_init( &data.dict.vendors, NULL );
+ fd_list_init( &data.dict.base_and_applications.chain, NULL );
+ data.dict.base_and_applications.name = (uint8_t *)"[Diameter Base Protocol]";
+ fd_list_init( &data.dict.base_and_applications.commands, NULL );
+ fd_list_init( &data.dict.base_and_applications.types, NULL );
+ fd_list_init( &data.dict.base_and_applications.avps, NULL );
+ data.xmlfilename = xmlfilename;
+
+ /* Parse the file */
+ ret = xmlSAXUserParseFile(&handler, &data, xmlfilename);
+ if (ret < 0) {
+ TRACE_DEBUG(INFO, "An error occurred while parsing %s, aborting.", xmlfilename);
+ del_dict_contents(&data.dict);
+ return -1;
+ }
+
+ TRACE_DEBUG(FULL, "XML file parsing, 1st pass completed.");
+ if (TRACE_BOOL(ANNOYING)) {
+ dump_dict(&data.dict);
+ }
+
+ /* Now, convert all the objects from the temporary tree into the freeDiameter dictionary */
+ CHECK_FCT_DO( dict_to_fD(fd_g_config->cnf_dict, &data.dict, &ret),
+ {
+ TRACE_DEBUG(INFO, "Error while converting data read from file '%s'", xmlfilename);
+ del_dict_contents(&data.dict);
+ return -1;
+ } );
+
+ TRACE_DEBUG(FULL, "Conversion from '%s' to freeDiameter internal format complete.", xmlfilename);
+
+ /* Done */
+ del_dict_contents(&data.dict);
+
+ return ret;
+}
diff --git a/extensions/dict_mip6a/CMakeLists.txt b/extensions/dict_mip6a/CMakeLists.txt
new file mode 100644
index 0000000..44a9c93
--- /dev/null
+++ b/extensions/dict_mip6a/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The dict_mip6a extension
+PROJECT("Diameter Mobile IPv6 Auth (MIP6A) Dictionary Definitions" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_mip6a dict_mip6a.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_mip6a
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-mip6)
diff --git a/extensions/dict_mip6a/dict_mip6a.c b/extensions/dict_mip6a/dict_mip6a.c
new file mode 100644
index 0000000..a31aeed
--- /dev/null
+++ b/extensions/dict_mip6a/dict_mip6a.c
@@ -0,0 +1,1094 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Francois Bard <francois@tera.ics.keio.ac.jp> *
+* *
+* Copyright (c) 2010, Teraoka Laboratory, Keio University *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+/*
+
+The following table complete the one in RFC 5778, page 18. The AVPs are implemented below following the order of this table.
+We try to keep the structure of the grouped AVP by declaring the contained AVPs just before the grouped AVP they depend on.
+The number of '+' indicates the depth of the contained AVP.
+
+DEPTH NAME AVP RFC TYPE NOTES
+
+ MIP6-Feature-Vector 124 5447 Unsigned64
+ User-Name 1 3588 UTF8String
+ Service-Selection 493 5778 UTF8String
+ MIP-MN-AAA-SPI 341 5778 Unsigned32
++ MIP-Home-Agent-Address 334 4004 Address
+++ Destination-Host 293 3588 DiameterIdentity
+++ Destination-Realm 283 3588 DiameterIdentity
++ MIP-Home-Agent-Host 348 4004 Grouped
++ MIP6-Home-Link-Prefix 125 5447 OctetString
+ MIP6-Agent-Info 486 5447 Grouped
++ MIP-Replay-Mode 346 4004 Enumerated
++ MIP-Algorithm-Type 345 4004 Enumerated
++ MIP-MN-HA-SPI 491 5778 Unsigned32
++ MIP-MSA-Lifetime 367 4004 Unsigned32
++ MIP-Session-Key 343 4004 OctetString
+ MIP-MN-HA-MSA 492 5778 Grouped different from MIP-MN-to-HA-MSA (331)
+ MIP-Mobile-Node-Address 333 4004 Address
+ MIP-Careof-Address 487 5778 Address
+ MIP-Authenticator 488 5778 OctetString
+ MIP-MAC-Mobility-Data 489 5778 OctetString
+ MIP-Timestamp 490 5778 OctetString
+ Chargeable-User-Identity 89 5778 OctetString
+ MIP6-Auth-Mode 494 5778 Enumerated
+
+QoS AVPs (RFC 5777 - implemented in the corresponding dictionary)
+
+ QoS-Capability 578 5777 Grouped
+ QoS-Resources 508 5777 Grouped
+
+ACCOUNTING AVPs (section 6.21)
+
+ Accounting-Input-Octets 363 4004, 4005 Unsigned64
+ Accounting-Output-Octets 364 4004, 4005 Unsigned64
+ Accounting-Input-Packets 365 4004, 4005 Unsigned64
+ Accounting-Output-Packets 366 4004, 4005 Unsigned64
+ Acct-Multi-Session-Id 50 3588 UTF8String
+ Acct-Session-Time 46 2866, 4004 Unsigned32
+ MIP6-Feature-Vector ----------------------------------
+ MIP-Mobile-Node-Address ----------------------------------
+ MIP6-Agent-Info ----------------------------------
+ Chargeable-User-Identity ----------------------------------
+ Service-Selection ----------------------------------
+ QoS-Resources ----------------------------------
+ QoS-Capability ----------------------------------
+ MIP-Careof-Address ----------------------------------
+
+RADIUS AVPs (contained in the MIR/MIA)
+
+ NAS-Identifier 32 2865 radius (see avp)
+ NAS-IP-Address 4 2865 radius (see avp)
+ NAS-IPv6-Address 95 3162 radius (see avp)
+ NAS-Port-Type 61 2865 radius (see avp)
+ Called-Station-Id 30 2865 radius (see avp)
+ Calling-Station-Id 31 2865 radius (see avp)
+
+
+*/
+
+/****************************************************************************************************************************************
+* *
+* This table is a copy of the registry named "MIP6 Authentication Mode Registry" and managed by IANA. *
+* source : http://www.iana.org/assignments/aaa-parameters/aaa-parameters.txt *
+* up to date on october 2010 *
+* *
+* Value Token Reference *
+* 0 Reserved [RFC5778] *
+* 1 MIP6_AUTH_MN_AAA [RFC5778] *
+* 2-4294967295 Unassigned *
+* *
+****************************************************************************************************************************************/
+
+
+/*
+
+NOTES
+
+check for omissions !
+
+*/
+
+#include <freeDiameter/extension.h>
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+ CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ char *avp_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME, \
+ (_rulearray)[__ar].avp_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
+ return ENOENT; \
+ } \
+ CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
+ { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_name ); \
+ return EINVAL; \
+ } ); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+
+/* Defines if there are any */
+
+//New Result-Code for MIP (RFC5778, Section 7.*)
+#define DIAMETER_SUCCESS_RELOCATE_HA 2009
+#define DIAMETER_ERROR_MIP6_AUTH_MODE 5041
+
+//Others
+#define MIP6_AUTH_MN_AAA 1
+
+/* Dictionary */
+
+int dict_mip6a_init(char * conffile)
+{
+ struct dict_object * mip6a;
+ {
+ struct dict_application_data data = { 8, "Diameter Mobile IPv6 Auth (MIP6A) Application" };
+ CHECK_dict_new( DICT_APPLICATION, &data , NULL, &mip6a);
+ }
+
+ /***************/
+ /* AVP section */
+ /***************/
+ {
+ /* Loading all the derived data formats */
+
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+
+ ///////////////////////////////////////////
+ /* AVPs for Mobile IPv6 Auth Application */
+ ///////////////////////////////////////////
+
+ /* MIP6-Feature-Vector - RFC 5447 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 124, /* Code */
+ 0, /* Vendor */
+ "MIP6-Feature-Vector", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* User-Name - RFC 3588 */
+
+ /*
+ Implemented in the base protocol
+ */
+
+ /* Service-Selection - RFC 5778 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 493, /* Code */
+ 0, /* Vendor */
+ "Service-Selection", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* MIP-MN-AAA-SPI - RFC 5778 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 341, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-AAA-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Destination-Host - Base Protocol */
+
+ /*
+ Implemented in the base protocol
+ */
+
+ /* Destination-Realm - Base Protocol */
+
+ /*
+ Implemented in the base protocol
+ */
+
+ /* MIP-Home-Agent-Address - RFC 4004 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 334, /* Code */
+ 0, /* Vendor */
+ "MIP-Home-Agent-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* MIP-Home-Agent-Host - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 348, /* Code */
+ 0, /* Vendor */
+ "MIP-Home-Agent-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+
+ struct local_rules_definition rules[] =
+ { { "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_REQUIRED, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* MIP6-Home-Link-Prefix - RFC 5447 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 125, /* Code */
+ 0, /* Vendor */
+ "MIP6-Home-Link-Prefix", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP6-Agent-Info - RFC 5447*/
+ {
+ /*
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 486, /* Code */
+ 0, /* Vendor */
+ "MIP6-Agent-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+
+ struct local_rules_definition rules[] =
+ { { "MIP-Home-Agent-Address", RULE_OPTIONAL, -1, 2 }
+ ,{ "MIP-Home-Agent-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Home-Link-Prefix", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* MIP-Replay-Mode - RFC 5778 & 4004 */
+ {
+ /*
+
+ */
+ struct dict_object * type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Replay-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_0 = { "None", { .i32 = 1 }};
+ struct dict_enumval_data t_1 = { "Timestamp", { .i32 = 2 }};
+ struct dict_avp_data data = {
+ 346, /* Code */
+ 0, /* Vendor */
+ "MIP-Replay-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* MIP-Algorithm-Type - RFC 5778 & 4004 */
+ {
+ /*
+
+ */
+ struct dict_object * type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Algorithm-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_2 = { "HMAC-SHA-1 [HMAC]", { .i32 = 2 }};
+ struct dict_avp_data data = {
+ 345, /* Code */
+ 0, /* Vendor */
+ "MIP-Algorithm-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* MIP-MN-HA-SPI - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 491, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-HA-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-MSA-Lifetime - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 367, /* Code */
+ 0, /* Vendor */
+ "MIP-MSA-Lifetime", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-Session-Key - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 343, /* Code */
+ 0, /* Vendor */
+ "MIP-Session-Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-MN-HA-MSA - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 492, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-HA-MSA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+
+ struct local_rules_definition rules[] =
+ { { "MIP-Session-Key", RULE_REQUIRED, -1, 1 }
+ ,{ "MIP-MSA-Lifetime", RULE_REQUIRED, -1, 1 }
+ ,{ "MIP-MN-HA-SPI", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Algorithm-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Replay-Mode", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* MIP-Mobile-Node-Address - RFC 4004 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 333, /* Code */
+ 0, /* Vendor */
+ "MIP-Mobile-Node-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* MIP-Careof-Address - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 487, /* Code */
+ 0, /* Vendor */
+ "MIP-Careof-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* MIP-Authenticator - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 488, /* Code */
+ 0, /* Vendor */
+ "MIP-Authenticator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-MAC-Mobility-Data - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 489, /* Code */
+ 0, /* Vendor */
+ "MIP-MAC-Mobility-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-Timestamp - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 490, /* Code */
+ 0, /* Vendor */
+ "MIP-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Chargeable-User-Identity - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 89, /* Code */
+ 0, /* Vendor */
+ "Chargeable-User-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP6-Auth-Mode - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_object * type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP6-Auth-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_0 = { "None", { .i32 = MIP6_AUTH_MN_AAA }};
+ struct dict_avp_data data = {
+ 494, /* Code */
+ 0, /* Vendor */
+ "MIP6-Auth-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ //////////////
+ /* QoS AVPs */
+ //////////////
+
+ /* QoS-Capability */
+
+ /*
+ Implemented in RFC 5777
+ */
+
+ /* QoS-Resources */
+
+ /*
+ Implemented in RFC 5777
+ */
+
+ /////////////////////
+ /* Accounting AVPs */
+ /////////////////////
+
+ /* Accounting-Input-Octets - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 363, /* Code */
+ 0, /* Vendor */
+ "Accounting-Input-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-Output-Octets - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 364, /* Code */
+ 0, /* Vendor */
+ "Accounting-Output-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-Input-Packets - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 365, /* Code */
+ 0, /* Vendor */
+ "Accounting-Input-Packets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-Output-Packets - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 366, /* Code */
+ 0, /* Vendor */
+ "Accounting-Output-Packets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Acct-Multi-Session-Id - RFC 3588 */
+
+ /*
+ Implemented in the base protocol
+ */
+
+ /* Acct-Session-Time - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 46, /* Code */
+ 0, /* Vendor */
+ "Acct-Session-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /////////////////////////////////////
+ /* Radius AVPs - used in MIR & MIA */
+ /////////////////////////////////////
+
+ /*
+ We used the following correspondences for determining the type of the Radius AVPs
+
+ Radius Diameter
+
+ text UTF8Sting
+ string OctetString
+ address Address
+ integer Unsigned32
+ time Time
+ */
+
+
+ /* NAS-Identifier 32 3575 */
+ {
+ /*
+ string -> OctetString
+ */
+
+ struct dict_avp_data data = {
+ 32, /* Code */
+ 0, /* Vendor */
+ "NAS-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* NAS-IP-Address 4 3575 */
+ {
+ /*
+ address -> Address
+ */
+
+ struct dict_avp_data data = {
+ 4, /* Code */
+ 0, /* Vendor */
+ "NAS-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* NAS-IPv6-Address 95 3162 */
+ {
+ /*
+ address -> Address
+ */
+
+ struct dict_avp_data data = {
+ 95, /* Code */
+ 0, /* Vendor */
+ "NAS-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* NAS-Port-Type 61 2865 */
+ {
+ /*
+ integer -> Unsigned32
+
+ Value
+
+ The Value field is four octets. "Virtual" refers to a connection
+ to the NAS via some transport protocol, instead of through a
+ physical port. For example, if a user telnetted into a NAS to
+ authenticate himself as an Outbound-User, the Access-Request might
+ include NAS-Port-Type = Virtual as a hint to the RADIUS server
+ that the user was not on a physical port.
+
+ 0 Async
+ 1 Sync
+ 2 ISDN Sync
+ 3 ISDN Async V.120
+ 4 ISDN Async V.110
+ 5 Virtual
+ 6 PIAFS
+ 7 HDLC Clear Channel
+ 8 X.25
+ 9 X.75
+ 10 G.3 Fax
+ 11 SDSL - Symmetric DSL
+ 12 ADSL-CAP - Asymmetric DSL, Carrierless Amplitude Phase
+ Modulation
+ 13 ADSL-DMT - Asymmetric DSL, Discrete Multi-Tone
+ 14 IDSL - ISDN Digital Subscriber Line
+ 15 Ethernet
+ 16 xDSL - Digital Subscriber Line of unknown type
+ 17 Cable
+ 18 Wireless - Other
+ 19 Wireless - IEEE 802.11
+
+ PIAFS is a form of wireless ISDN commonly used in Japan, and
+ stands for PHS (Personal Handyphone System) Internet Access Forum
+ Standard (PIAFS).
+ */
+
+ struct dict_avp_data data = {
+ 61, /* Code */
+ 0, /* Vendor */
+ "NAS-Port-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Called-Station-Id 30 2865 */
+ {
+ /*
+ string -> OctetString
+ */
+
+ struct dict_avp_data data = {
+ 30, /* Code */
+ 0, /* Vendor */
+ "Called-Station-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+ /* Calling-Station-Id 31 2865 */
+ {
+ /*
+ string -> OctetString
+ */
+
+ struct dict_avp_data data = {
+ 31, /* Code */
+ 0, /* Vendor */
+ "Calling-Station-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+ }
+
+/*******************/
+/* Command section */
+/*******************/
+
+ {
+ /* MIP6-Request (MIR) */
+ {
+ /*
+
+ The MIP6-Request (MIR), indicated by the Command-Code field set to
+ 325 and the 'R' bit set in the Command Flags field, is sent by the
+ HA, acting as a Diameter client, in order to request the
+ authentication and authorization of an MN.
+
+ Although the HA provides the Diameter server with replay protection-
+ related information, the HA is responsible for the replay protection.
+
+ The message format is shown below.
+
+ <MIP6-Request> ::= < Diameter Header: 325, REQ, PXY >
+ < Session-ID >
+ { Auth-Application-Id }
+ { User-Name }
+ { Destination-Realm }
+ { Origin-Host }
+ { Origin-Realm }
+ { Auth-Request-Type }
+ [ Destination-Host ]
+ [ Origin-State-Id ]
+ [ NAS-Identifier ]
+ [ NAS-IP-Address ]
+ [ NAS-IPv6-Address ]
+ [ NAS-Port-Type ]
+ [ Called-Station-Id ]
+ [ Calling-Station-Id ]
+ [ MIP6-Feature-Vector ]
+ { MIP6-Auth-Mode }
+ [ MIP-MN-AAA-SPI ]
+ [ MIP-MN-HA-SPI ]
+ 1*2{ MIP-Mobile-Node-Address }
+ { MIP6-Agent-Info }
+ { MIP-Careof-Address }
+ [ MIP-Authenticator ]
+ [ MIP-MAC-Mobility-Data ]
+ [ MIP-Timestamp ]
+ [ QoS-Capability ]
+ * [ QoS-Resources ]
+ [ Chargeable-User-Identity ]
+ [ Service-Selection ]
+ [ Authorization-Lifetime ]
+ [ Auth-Session-State ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+ If the MN is both authenticated and authorized for the mobility
+ service, then the Auth-Request-Type AVP is set to the value
+ AUTHORIZE_AUTHENTICATE. This is the case when the MIP6-Auth-Mode is
+ set to the value MIP6_AUTH_MN_AAA.
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 325, /* Code */
+ "MIP6-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "User-Name", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Request-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Identifier", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IPv6-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Called-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Calling-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Feature-Vector", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Auth-Mode", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-MN-AAA-SPI", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-MN-HA-SPI", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Mobile-Node-Address", RULE_OPTIONAL, 1, 2 }
+ ,{ "MIP6-Agent-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Careof-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Authenticator", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-MAC-Mobility-Data", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Timestamp", RULE_OPTIONAL, -1, 1 }
+ ,{ "QoS-Capability", RULE_OPTIONAL, -1, 1 }
+ ,{ "QoS-Resources", RULE_OPTIONAL, -1, -1 }
+ ,{ "Chargeable-User-Identity", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Selection", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Session-State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data, mip6a, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* MIP6-Answer (MIA) */
+ {
+ /*
+
+ The MIP6-Answer (MIA) message, indicated by the Command-Code field
+ set to 325 and the 'R' bit cleared in the Command Flags field, is
+ sent by the Diameter server in response to the MIP6-Request message.
+
+ The User-Name AVP MAY be included in the MIA if it is present in the
+ MIR. The Result-Code AVP MAY contain one of the values defined in
+ Section 7, in addition to the values defined in [RFC3588].
+
+ An MIA message with the Result-Code AVP set to DIAMETER_SUCCESS MUST
+ include the MIP-Mobile-Node-Address AVP.
+
+ The message format is shown below.
+
+ <MIP6-Answer> ::= < Diameter Header: 325, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ { Auth-Request-Type }
+ [ User-Name ]
+ [ Authorization-Lifetime ]
+ [ Auth-Session-State ]
+ [ Error-Message ]
+ [ Error-Reporting-Host ]
+ [ Re-Auth-Request-Type ]
+ [ MIP6-Feature-Vector ]
+ [ MIP6-Agent-Info ]
+ *2[ MIP-Mobile-Node-Address ]
+ [ MIP-MN-HA-MSA ]
+ * [ QoS-Resources ]
+ [ Chargeable-User-Identity ]
+ [ Service-Selection ]
+ [ Origin-State-Id ]
+ * [ Proxy-Info ]
+ * [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Failed-AVP ]
+ * [ AVP ]
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 325, /* Code */
+ "MIP6-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Request-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Session-State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Error-Message", RULE_OPTIONAL, -1, 1 }
+ ,{ "Error-Reporting-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Re-Auth-Request-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Feature-Vector", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Agent-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Mobile-Node-Address", RULE_OPTIONAL, -1, 2 }
+ ,{ "MIP-MN-HA-MSA", RULE_OPTIONAL, -1, 1 }
+ ,{ "QoS-Resources", RULE_OPTIONAL, -1, -1 }
+ ,{ "Chargeable-User-Identity", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Selection", RULE_OPTIONAL, -1, 1 }
+ ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1, -1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Failed-AVP", RULE_OPTIONAL, -1, -1 }
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data, mip6a, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ }
+ LOG_D( "Dictionary Extension 'Diameter Mobile IPv6 Auth (MIP6A)' initialized");
+ return 0;
+}
+EXTENSION_ENTRY("dict_mip6a", dict_mip6a_init, "dict_rfc5777");
diff --git a/extensions/dict_mip6i/CMakeLists.txt b/extensions/dict_mip6i/CMakeLists.txt
new file mode 100644
index 0000000..15d0c24
--- /dev/null
+++ b/extensions/dict_mip6i/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The dict_mip6i extension
+PROJECT("Diameter Mobile IPv6 IKE (MIP6I) Dictionary Definition" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_mip6i dict_mip6i.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_mip6i
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-mip6)
diff --git a/extensions/dict_mip6i/dict_mip6i.c b/extensions/dict_mip6i/dict_mip6i.c
new file mode 100644
index 0000000..7977ccc
--- /dev/null
+++ b/extensions/dict_mip6i/dict_mip6i.c
@@ -0,0 +1,1137 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Francois Bard <francois@tera.ics.keio.ac.jp> *
+* *
+* Copyright (c) 2010, Teraoka Laboratory, Keio University *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+/*
+
+The following table complete the one in RFC 5778, page 18. The AVPs are implemented below following the order of this table.
+We try to keep the structure of the grouped AVP by declaring the contained AVPs just before the grouped AVP they depend on.
+The number of '+' indicates the depth of the contained AVP.
+
+DEPTH NAME AVP RFC TYPE NOTES
+
+ MIP6-Feature-Vector 124 5447 Unsigned64
+ MIP-Mobile-Node-Address 333 4004 Address
++ MIP-Home-Agent-Address 334 4004 Address
+++ Destination-Host 293 3588 DiameterIdentity
+++ Destination-Realm 283 3588 DiameterIdentity
++ MIP-Home-Agent-Host 348 4004 Grouped
++ MIP6-Home-Link-Prefix 125 5447 OctetString
+ MIP6-Agent-Info 486 5447 Grouped
+ User-Name 1 3588 UTF8String
+ Service-Selection 493 5778 UTF8String
++ MIP-Replay-Mode 346 4004 Enumerated
++ MIP-Algorithm-Type 345 4004 Enumerated
++ MIP-MN-HA-SPI 491 5778 Unsigned32
++ MIP-MSA-Lifetime 367 4004 Unsigned32
++ MIP-Session-Key 343 4004 OctetString
+ MIP-MN-HA-MSA 492 5778 Grouped different from MIP-MN-to-HA-MSA (331)
+ Chargeable-User-Identity 89 5778 OctetString
+
+QoS AVPs (RFC 5777 - implemented in the corresponding dictionary)
+
+ QoS-Capability 578 5777 Grouped
+ QoS-Resources 508 5777 Grouped
+
+ACCOUNTING AVPs (section 6.21)
+
+ Accounting-Input-Octets 363 4004, 4005 Unsigned64
+ Accounting-Output-Octets 364 4004, 4005 Unsigned64
+ Accounting-Input-Packets 365 4004, 4005 Unsigned64
+ Accounting-Output-Packets 366 4004, 4005 Unsigned64
+ Acct-Multi-Session-Id 50 3588 UTF8String
+ Acct-Session-Time 46 2866, 4004 Unsigned32
+ MIP6-Feature-Vector ----------------------------------
+ MIP-Mobile-Node-Address ----------------------------------
+ MIP6-Agent-Info ----------------------------------
+ Chargeable-User-Identity ----------------------------------
+ Service-Selection ----------------------------------
+ QoS-Resources ----------------------------------
+ QoS-Capability ----------------------------------
+ MIP-Careof-Address 487 5778 Address needed (appears in MIR/MIA)
+
+REST OF THE AVPs IN THE MIR & MIA EXCLUDING *[AVP] (as written on page 19 of RFC 5778)
+
+MIP6-Request
+
+ Session-ID 263 3588
+ Auth-Application-Id 258 3588
+ User-Name 1 3588
+ Destination-Realm 283 3588
+ Origin-Host 264 3588
+ Origin-Realm 296 3588
+ Auth-Request-Type 274 3588
+ Origin-State-Id 278 3588
+ NAS-Identifier 32 2865 radius (see avp) needed (radius)
+ NAS-IP-Address 4 2865 radius (see avp) needed (radius)
+ NAS-IPv6-Address 95 3162 radius (see avp) needed (radius)
+ NAS-Port-Type 61 2865 radius (see avp) needed (radius)
+ Called-Station-Id 30 2865 radius (see avp) needed (radius)
+ Calling-Station-Id 31 2865 radius (see avp) needed (radius)
+ MIP6-Feature-Vector ------------
+ MIP6-Auth-Mode 494 5778 Enumerated needed (mip6a)
+ MIP-MN-AAA-SPI 341 5778 Unsigned32 needed (mip6a)
+ MIP-MN-HA-SPI ------------
+ MIP-Mobile-Node-Address ------------
+ MIP6-Agent-Info ------------
+ MIP-Careof-Address ------------
+ MIP-Authenticator 488 5778 OctetString needed (mip6a)
+ MIP-MAC-Mobility-Data 489 5778 OctetString needed (mip6a)
+ MIP-Timestamp 490 5778 OctetString needed (mip6a)
+ QoS-Capability ------------
+ QoS-Resources ------------
+ Chargeable-User-Identity ------------
+ Service-Selection ------------
+ Authorization-Lifetime 291 3588
+ Auth-Session-State 277 3588
+ Proxy-Info 284 3588
+ Route-Record 282 3588
+
+MIP6-Answer - All of them are already implemented as base protocol AVPs or implemented earlier.
+
+*/
+
+/****************************************************************************************************************************************
+* *
+* This table is a copy of the registry named "MIP6 Authentication Mode Registry" and managed by IANA. *
+* source : http://www.iana.org/assignments/aaa-parameters/aaa-parameters.txt *
+* up to date on october 2010 *
+* *
+* Value Token Reference *
+* 0 Reserved [RFC5778] *
+* 1 MIP6_AUTH_MN_AAA [RFC5778] *
+* 2-4294967295 Unassigned *
+* *
+****************************************************************************************************************************************/
+
+
+/*
+
+NOTES
+
+check for omissions !
+
+*/
+
+#include <freeDiameter/extension.h>
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+ CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ char *avp_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME, \
+ (_rulearray)[__ar].avp_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
+ return ENOENT; \
+ } \
+ CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
+ { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_name ); \
+ return EINVAL; \
+ } ); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+
+/* Defines if there are any */
+
+//New Result-Code for MIP (RFC5778, Section 7.*)
+#define DIAMETER_SUCCESS_RELOCATE_HA 2009
+#define DIAMETER_ERROR_MIP6_AUTH_MODE 5041
+
+//others
+#define MIP6_AUTH_MN_AAA 1
+
+/* Dictionary */
+
+int dict_mip6i_init(char * conffile)
+{
+ struct dict_object * mip6i;
+ {
+ struct dict_application_data data = { 7, "Diameter Mobile IPv6 IKE (MIP6I) Application" };
+ CHECK_dict_new( DICT_APPLICATION, &data , NULL, &mip6i);
+ }
+
+ /***************/
+ /* AVP section */
+ /***************/
+ {
+ /* Loading all the derived data formats */
+
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+
+ /* MIP6-Feature-Vector - RFC 5447 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 124, /* Code */
+ 0, /* Vendor */
+ "MIP6-Feature-Vector", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-Mobile-Node-Address - RFC 4004 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 333, /* Code */
+ 0, /* Vendor */
+ "MIP-Mobile-Node-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* MIP-Home-Agent-Address - RFC 4004 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 334, /* Code */
+ 0, /* Vendor */
+ "MIP-Home-Agent-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* Destination-Host - Base Protocol */
+
+ /*
+ Implemented in the base protocol
+ */
+
+ /* Destination-Realm - Base Protocol */
+
+ /*
+ Implemented in the base protocol
+ */
+
+ /* MIP-Home-Agent-Host - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 348, /* Code */
+ 0, /* Vendor */
+ "MIP-Home-Agent-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+
+ struct local_rules_definition rules[] =
+ { { "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_REQUIRED, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* MIP6-Home-Link-Prefix - RFC 5447 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 125, /* Code */
+ 0, /* Vendor */
+ "MIP6-Home-Link-Prefix", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP6-Agent-Info - RFC 5447 */
+ {
+ /*
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 486, /* Code */
+ 0, /* Vendor */
+ "MIP6-Agent-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+
+ struct local_rules_definition rules[] =
+ { { "MIP-Home-Agent-Address", RULE_OPTIONAL, -1, 2 }
+ ,{ "MIP-Home-Agent-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Home-Link-Prefix", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* User-Name - RFC 3588 */
+
+ /*
+ Implemented in the base protocol
+ */
+
+ /* Service-Selection - RFC 5778 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 493, /* Code */
+ 0, /* Vendor */
+ "Service-Selection", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* MIP-Replay-Mode - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_object * type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Replay-Mode)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "None", { .i32 = 1 }};
+ struct dict_enumval_data t_2 = { "Timestamp", { .i32 = 2 }};
+
+ struct dict_avp_data data = {
+ 346, /* Code */
+ 0, /* Vendor */
+ "MIP-Replay-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1 , type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* MIP-Algorithm-Type - RFC 5778 */
+ {
+ /*
+ The MIP-Algorithm-Type AVP (AVP Code 345) is of type Enumerated and
+ contains the Algorithm identifier for the associated Mobile IPv6
+ MN-HA Authentication Option. The Diameter server selects the
+ algorithm type. Existing algorithm types are defined in [RFC4004]
+ that also fulfill current RFC 4285 requirements. This AVP is reused
+ from [RFC4004].
+ */
+ struct dict_object * type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Algorithm-Type)" , NULL, NULL, NULL };
+ struct dict_enumval_data t_2 = { "HMAC-SHA-1 [HMAC]", { .i32 = 2 }};
+
+ struct dict_avp_data data = {
+ 345, /* Code */
+ 0, /* Vendor */
+ "MIP-Algorithm-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* MIP-MN-HA-SPI - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 491, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-HA-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-MSA-Lifetime - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 367, /* Code */
+ 0, /* Vendor */
+ "MIP-MSA-Lifetime", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-Session-Key - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 343, /* Code */
+ 0, /* Vendor */
+ "MIP-Session-Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-MN-HA-MSA - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 492, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-HA-MSA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+
+ struct local_rules_definition rules[] =
+ { { "MIP-Session-Key", RULE_REQUIRED, -1, 1 }
+ ,{ "MIP-MSA-Lifetime", RULE_REQUIRED, -1, 1 }
+ ,{ "MIP-MN-HA-SPI", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Algorithm-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Replay-Mode", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* Chargeable-User-Identity - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 89, /* Code */
+ 0, /* Vendor */
+ "Chargeable-User-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ //////////////
+ /* QoS AVPs */
+ //////////////
+
+ /* QoS-Capability */
+
+ /*
+ Implemented in RFC 5777
+ */
+
+ /* QoS-Resources */
+
+ /*
+ Implemented in RFC 5777
+ */
+
+ /////////////////////
+ /* Accounting AVPs */
+ /////////////////////
+
+ /* Accounting-Input-Octets - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 363, /* Code */
+ 0, /* Vendor */
+ "Accounting-Input-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-Output-Octets - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 364, /* Code */
+ 0, /* Vendor */
+ "Accounting-Output-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-Input-Packets - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 365, /* Code */
+ 0, /* Vendor */
+ "Accounting-Input-Packets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-Output-Packets - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 366, /* Code */
+ 0, /* Vendor */
+ "Accounting-Output-Packets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Acct-Multi-Session-Id - RFC 3588 */
+
+ /*
+ Implemented in the base protocol
+ */
+
+ /* Acct-Session-Time - RFC 4004 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 46, /* Code */
+ 0, /* Vendor */
+ "Acct-Session-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-Careof-Address - RFC 5778 */
+ {
+ /*
+ This AVP is needed in MIP6I at least for implementation reasons
+ (it appears in a command)
+ */
+
+ struct dict_avp_data data = {
+ 487, /* Code */
+ 0, /* Vendor */
+ "MIP-Careof-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /////////////////////////////////////
+ /* Radius AVPs used in MIR & MIA */
+ /////////////////////////////////////
+
+ /*
+ We used the following correspondences for determining the type of the Radius AVPs
+
+ Radius Diameter
+
+ text UTF8Sting
+ string OctetString
+ address Address
+ integer Unsigned32
+ time Time
+ */
+
+
+ /* NAS-Identifier 32 3575 */
+ {
+ /*
+ string -> OctetString
+ */
+
+ struct dict_avp_data data = {
+ 32, /* Code */
+ 0, /* Vendor */
+ "NAS-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* NAS-IP-Address 4 3575 */
+ {
+ /*
+ address -> Address
+ */
+
+ struct dict_avp_data data = {
+ 4, /* Code */
+ 0, /* Vendor */
+ "NAS-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* NAS-IPv6-Address 95 3162 */
+ {
+ /*
+ address -> Address
+ */
+
+ struct dict_avp_data data = {
+ 95, /* Code */
+ 0, /* Vendor */
+ "NAS-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* NAS-Port-Type 61 2865 */
+ {
+ /*
+ integer -> Unsigned32
+
+ Value
+
+ The Value field is four octets. "Virtual" refers to a connection
+ to the NAS via some transport protocol, instead of through a
+ physical port. For example, if a user telnetted into a NAS to
+ authenticate himself as an Outbound-User, the Access-Request might
+ include NAS-Port-Type = Virtual as a hint to the RADIUS server
+ that the user was not on a physical port.
+
+ 0 Async
+ 1 Sync
+ 2 ISDN Sync
+ 3 ISDN Async V.120
+ 4 ISDN Async V.110
+ 5 Virtual
+ 6 PIAFS
+ 7 HDLC Clear Channel
+ 8 X.25
+ 9 X.75
+ 10 G.3 Fax
+ 11 SDSL - Symmetric DSL
+ 12 ADSL-CAP - Asymmetric DSL, Carrierless Amplitude Phase
+ Modulation
+ 13 ADSL-DMT - Asymmetric DSL, Discrete Multi-Tone
+ 14 IDSL - ISDN Digital Subscriber Line
+ 15 Ethernet
+ 16 xDSL - Digital Subscriber Line of unknown type
+ 17 Cable
+ 18 Wireless - Other
+ 19 Wireless - IEEE 802.11
+
+ PIAFS is a form of wireless ISDN commonly used in Japan, and
+ stands for PHS (Personal Handyphone System) Internet Access Forum
+ Standard (PIAFS).
+ */
+
+ struct dict_avp_data data = {
+ 61, /* Code */
+ 0, /* Vendor */
+ "NAS-Port-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Called-Station-Id 30 2865 */
+ {
+ /*
+ string -> OctetString
+ */
+
+ struct dict_avp_data data = {
+ 30, /* Code */
+ 0, /* Vendor */
+ "Called-Station-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+ /* Calling-Station-Id 31 2865 */
+ {
+ /*
+ string -> OctetString
+ */
+
+ struct dict_avp_data data = {
+ 31, /* Code */
+ 0, /* Vendor */
+ "Calling-Station-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ ///////////////////////////////////////////////////////////
+ /* REST OF THE AVP IN THE MIR AND MIA EXCLUDING *[AVP] */
+ ///////////////////////////////////////////////////////////
+
+ /* MIP6-Auth-Mode - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_object * type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP6-Auth-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_0 = { "None", { .i32 = MIP6_AUTH_MN_AAA }};
+ struct dict_avp_data data = {
+ 494, /* Code */
+ 0, /* Vendor */
+ "MIP6-Auth-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_0 , type, NULL);
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* MIP-MN-AAA-SPI - RFC 5778 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 341, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-AAA-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-Authenticator - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 488, /* Code */
+ 0, /* Vendor */
+ "MIP-Authenticator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-MAC-Mobility-Data - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 489, /* Code */
+ 0, /* Vendor */
+ "MIP-MAC-Mobility-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-Timestamp - RFC 5778 */
+ {
+ /*
+
+ */
+ struct dict_avp_data data = {
+ 490, /* Code */
+ 0, /* Vendor */
+ "MIP-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+ }
+
+/*******************/
+/* Command section */
+/*******************/
+
+ {
+ /* Diameter-EAP-Request (DER) */
+
+ /*
+ Defined in dict_eap
+ */
+
+ /* Diameter-EAP-Answer (DEA) - COPIED FROM dict_eap.c, SEE IT FOR MORE REFERENCE */
+
+ /*
+ Defined in dict_eap
+ */
+
+ /* MIP6-Request (MIR) */
+ {
+ /*
+
+ The MIP6-Request (MIR), indicated by the Command-Code field set to
+ 325 and the 'R' bit set in the Command Flags field, is sent by the
+ HA, acting as a Diameter client, in order to request the
+ authentication and authorization of an MN.
+
+ Although the HA provides the Diameter server with replay protection-
+ related information, the HA is responsible for the replay protection.
+
+ The message format is shown below.
+
+ <MIP6-Request> ::= < Diameter Header: 325, REQ, PXY >
+ < Session-ID >
+ { Auth-Application-Id }
+ { User-Name }
+ { Destination-Realm }
+ { Origin-Host }
+ { Origin-Realm }
+ { Auth-Request-Type }
+ [ Destination-Host ]
+ [ Origin-State-Id ]
+ [ NAS-Identifier ]
+ [ NAS-IP-Address ]
+ [ NAS-IPv6-Address ]
+ [ NAS-Port-Type ]
+ [ Called-Station-Id ]
+ [ Calling-Station-Id ]
+ [ MIP6-Feature-Vector ]
+ { MIP6-Auth-Mode }
+ [ MIP-MN-AAA-SPI ]
+ [ MIP-MN-HA-SPI ]
+ 1*2{ MIP-Mobile-Node-Address }
+ { MIP6-Agent-Info }
+ { MIP-Careof-Address }
+ [ MIP-Authenticator ]
+ [ MIP-MAC-Mobility-Data ]
+ [ MIP-Timestamp ]
+ [ QoS-Capability ]
+ * [ QoS-Resources ]
+ [ Chargeable-User-Identity ]
+ [ Service-Selection ]
+ [ Authorization-Lifetime ]
+ [ Auth-Session-State ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+ If the MN is both authenticated and authorized for the mobility
+ service, then the Auth-Request-Type AVP is set to the value
+ AUTHORIZE_AUTHENTICATE. This is the case when the MIP6-Auth-Mode is
+ set to the value MIP6_AUTH_MN_AAA.
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 325, /* Code */
+ "MIP6-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "User-Name", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Request-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Identifier", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IPv6-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Called-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Calling-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Feature-Vector", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Auth-Mode", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-MN-AAA-SPI", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-MN-HA-SPI", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Mobile-Node-Address", RULE_OPTIONAL, 1, 2 }
+ ,{ "MIP6-Agent-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Careof-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Authenticator", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-MAC-Mobility-Data", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Timestamp", RULE_OPTIONAL, -1, 1 }
+ ,{ "QoS-Capability", RULE_OPTIONAL, -1, 1 }
+ ,{ "QoS-Resources", RULE_OPTIONAL, -1, -1 }
+ ,{ "Chargeable-User-Identity", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Selection", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Session-State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data, mip6i, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* MIP6-Answer (MIA) */
+ {
+ /*
+
+ The MIP6-Answer (MIA) message, indicated by the Command-Code field
+ set to 325 and the 'R' bit cleared in the Command Flags field, is
+ sent by the Diameter server in response to the MIP6-Request message.
+
+ The User-Name AVP MAY be included in the MIA if it is present in the
+ MIR. The Result-Code AVP MAY contain one of the values defined in
+ Section 7, in addition to the values defined in [RFC3588].
+
+ An MIA message with the Result-Code AVP set to DIAMETER_SUCCESS MUST
+ include the MIP-Mobile-Node-Address AVP.
+
+ The message format is shown below.
+
+ <MIP6-Answer> ::= < Diameter Header: 325, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ { Auth-Request-Type }
+ [ User-Name ]
+ [ Authorization-Lifetime ]
+ [ Auth-Session-State ]
+ [ Error-Message ]
+ [ Error-Reporting-Host ]
+ [ Re-Auth-Request-Type ]
+ [ MIP6-Feature-Vector ]
+ [ MIP6-Agent-Info ]
+ *2[ MIP-Mobile-Node-Address ]
+ [ MIP-MN-HA-MSA ]
+ * [ QoS-Resources ]
+ [ Chargeable-User-Identity ]
+ [ Service-Selection ]
+ [ Origin-State-Id ]
+ * [ Proxy-Info ]
+ * [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Failed-AVP ]
+ * [ AVP ]
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 325, /* Code */
+ "MIP6-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Request-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Session-State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Error-Message", RULE_OPTIONAL, -1, 1 }
+ ,{ "Error-Reporting-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Re-Auth-Request-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Feature-Vector", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Agent-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP-Mobile-Node-Address", RULE_OPTIONAL, -1, 2 }
+ ,{ "MIP-MN-HA-MSA", RULE_OPTIONAL, -1, 1 }
+ ,{ "QoS-Resources", RULE_OPTIONAL, -1, -1 }
+ ,{ "Chargeable-User-Identity", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Selection", RULE_OPTIONAL, -1, 1 }
+ ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1, -1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Failed-AVP", RULE_OPTIONAL, -1, -1 }
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data, mip6i, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ }
+
+ LOG_D( "Dictionary Extension 'Diameter Mobile IPv6 IKE (MIP6I)' initialized");
+ return 0;
+}
+EXTENSION_ENTRY("dict_mip6i", dict_mip6i_init, "dict_rfc5777");
diff --git a/extensions/dict_nas_mipv6/CMakeLists.txt b/extensions/dict_nas_mipv6/CMakeLists.txt
new file mode 100644
index 0000000..517e948
--- /dev/null
+++ b/extensions/dict_nas_mipv6/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The dict_nas_mipv6 extension
+PROJECT("MIPv6 NAS-to-HAAA Interaction Dictionary Definition" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_nas_mipv6 dict_nas_mipv6.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_nas_mipv6
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-mip6)
diff --git a/extensions/dict_nas_mipv6/dict_nas_mipv6.c b/extensions/dict_nas_mipv6/dict_nas_mipv6.c
new file mode 100644
index 0000000..438e596
--- /dev/null
+++ b/extensions/dict_nas_mipv6/dict_nas_mipv6.c
@@ -0,0 +1,258 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Francois Bard <francois@tera.ics.keio.ac.jp> *
+* *
+* Copyright (c) 2010, Teraoka Laboratory, Keio University *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+/*
+
+The following table lists the AVPs needed for the NAS to HAAA server interaction.
+We try to keep the structure of the grouped AVP by declaring the contained AVPs just before the grouped AVP they depend on.
+The number of '+' indicates the depth of the contained AVP.
+
+DEPTH NAME AVP CODE RFC TYPE IMPLEMENTED NOTES
+
+ MIP6-Feature-Vector 124 5447 Unsigned64 yes
++ MIP-Home-Agent-Address 334 4004 Address not yet
+++ Destination-Host 293 3588 DiameterIdentity no (Base)
+++ Destination-Realm 283 3588 DiameterIdentity no (Base)
++ MIP-Home-Agent-Host 348 4004 Grouped not yet
++ MIP6-Home-Link-Prefix 125 5447 OctetString yes
+ MIP6-Agent-Info 486 5447 Grouped yes
+
+*/
+
+
+
+#include <freeDiameter/extension.h>
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+ CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ char *avp_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME, \
+ (_rulearray)[__ar].avp_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
+ return ENOENT; \
+ } \
+ CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
+ { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_name ); \
+ return EINVAL; \
+ } ); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+
+
+
+
+/* Defines if there are any */
+
+/* Define Flags for MIP6-Feature-Vector*/
+
+#define MIP6_INTEGRATED 0x0000000000000001
+#define LOCAL_HOME_AGENT_ASSIGNMENT 0x0000000000000002
+
+/* Dictionary */
+
+int dict_nas_mipv6_init(char * conffile)
+{
+ struct dict_object * nas_mipv6;
+ {
+ struct dict_application_data data = { 5447, "MIPv6 NAS-to-HAAA Interaction" };
+ CHECK_dict_new( DICT_APPLICATION, &data , NULL, &nas_mipv6);
+ }
+
+ /* AVP section */
+ {
+ /* Loading the derived data formats */
+
+ struct dict_object * Address_type;
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+
+ /* MIP6-Feature-Vector */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 124, /* Code */
+ 0, /* Vendor */
+ "MIP6-Feature-Vector", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP-Home-Agent-Address - RFC 4004 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 334, /* Code */
+ 0, /* Vendor */
+ "MIP-Home-Agent-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
+ }
+
+ /* Destination-Host - Base Protocol */
+
+ /* Destination-Realm - Base Protocol */
+
+ /* MIP-Home-Agent-Host - RFC 4004 */
+ {
+ /*
+ The MIP-Home-Agent-Host AVP (AVP Code 348) is of type Grouped and
+ contains the identity of the assigned Home Agent. If the MIP-Home-
+ Agent-Host AVP is present in the AMR, the AAAH MUST copy it into the
+ HAR.
+
+ MIP-Home-Agent-Host ::= < AVP Header: 348 >
+ { Destination-Realm }
+ { Destination-Host }
+ * [ AVP ]
+ */
+
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 348, /* Code */
+ 0, /* Vendor */
+ "MIP-Home-Agent-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+
+ struct local_rules_definition rules[] =
+ { { "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_REQUIRED, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* MIP6-Home-Link-Prefix */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 125, /* Code */
+ 0, /* Vendor */
+ "MIP6-Home-Link-Prefix", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* MIP6-Agent-Info */
+ {
+ /*
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 486, /* Code */
+ 0, /* Vendor */
+ "MIP6-Agent-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+
+ struct local_rules_definition rules[] =
+ { { "MIP-Home-Agent-Address", RULE_OPTIONAL, -1, 2 }
+ ,{ "MIP-Home-Agent-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "MIP6-Home-Link-Prefix", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+ }
+
+ LOG_D( "Dictionary Extension 'MIPv6 NAS-to-HAAA Interaction' initialized");
+ return 0;
+}
+EXTENSION_ENTRY("dict_nas_mipv6", dict_nas_mipv6_init);
diff --git a/extensions/dict_nasreq/CMakeLists.txt b/extensions/dict_nasreq/CMakeLists.txt
new file mode 100644
index 0000000..438e3c1
--- /dev/null
+++ b/extensions/dict_nasreq/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The dict_nasreq extension
+PROJECT("Diameter NASREQ (RFC4005) dictionary definitions" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_nasreq dict_nasreq.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_nasreq
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-RFC4005)
diff --git a/extensions/dict_nasreq/dict_nasreq.c b/extensions/dict_nasreq/dict_nasreq.c
new file mode 100644
index 0000000..a87907b
--- /dev/null
+++ b/extensions/dict_nasreq/dict_nasreq.c
@@ -0,0 +1,3735 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * Dictionary definitions of objects specified in Diameter NASREQ (RFC4005).
+ */
+#include <freeDiameter/extension.h>
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+ CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ char *avp_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME, \
+ (_rulearray)[__ar].avp_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
+ return ENOENT; \
+ } \
+ CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
+ { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_name ); \
+ return EINVAL; \
+ } ); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dnr_entry(char * conffile)
+{
+ struct dict_object * nasreq;
+ TRACE_ENTRY("%p", conffile);
+
+ /* No Vendors definitions */
+
+ /* Applications section */
+ {
+ /* NASREQ (RFC 4005) */
+ {
+ struct dict_application_data data = { 1, "Diameter Network Access Server Application" };
+ CHECK_dict_new( DICT_APPLICATION, &data, NULL, &nasreq);
+ }
+ }
+
+ /* Derived AVP types section */
+ {
+ /* QoSFilterRule */
+ {
+ /*
+ The QosFilterRule format is derived from the OctetString AVP Base
+ Format. It uses the ASCII charset. Packets may be marked or
+ metered based on the following information:
+
+ Direction (in or out)
+ Source and destination IP address (possibly masked)
+ Protocol
+ Source and destination port (lists or ranges)
+ DSCP values (no mask or range)
+
+ Rules for the appropriate direction are evaluated in order; the
+ first matched rule terminates the evaluation. Each packet is
+ evaluated once. If no rule matches, the packet is treated as best
+ effort. An access device unable to interpret or apply a QoS rule
+ SHOULD NOT terminate the session.
+
+ QoSFilterRule filters MUST follow the following format:
+
+ action dir proto from src to dst [options]
+
+ tag - Mark packet with a specific DSCP
+ [DIFFSERV]. The DSCP option MUST be
+ included.
+ meter - Meter traffic. The metering options
+ MUST be included.
+
+ dir The format is as described under IPFilterRule.
+
+ proto The format is as described under IPFilterRule.
+
+ src and dst The format is as described under IPFilterRule.
+
+ options:
+
+ DSCP <color>
+ Color values as defined in [DIFFSERV]. Exact
+ matching of DSCP values is required (no masks or
+ ranges).
+
+ metering <rate> <color_under> <color_over>
+ The metering option provides Assured Forwarding,
+ as defined in [DIFFSERVAF], and MUST be present
+ if the action is set to meter. The rate option is
+ the throughput, in bits per second, used
+ by the access device to mark packets. Traffic
+ over the rate is marked with the color_over
+ codepoint, and traffic under the rate is marked
+ with the color_under codepoint. The color_under
+ and color_over options contain the drop
+ preferences and MUST conform to the recommended
+ codepoint keywords described in [DIFFSERVAF]
+ (e.g., AF13).
+
+ The metering option also supports the strict
+ limit on traffic required by Expedited
+ Forwarding, as defined in [DIFFSERVEF]. The
+ color_over option may contain the keyword "drop"
+ to prevent forwarding of traffic that exceeds the
+ rate parameter.
+
+ The rule syntax is a modified subset of ipfw(8) from FreeBSD,
+ and the ipfw.c code may provide a useful base for
+ implementations.
+ */
+ struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "QoSFilterRule" , NULL , NULL };
+ CHECK_dict_new( DICT_TYPE, &data , NULL, NULL);
+ }
+
+ }
+
+ /* AVP section */
+ {
+ struct dict_object * UTF8String_type;
+ struct dict_object * IPFilterRule_type;
+ struct dict_object * QoSFilterRule_type;
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "QoSFilterRule", &QoSFilterRule_type);
+
+/********************************
+ * NAS Session AVPs *
+ ********************************/
+ /* NAS-Port */
+ {
+ /*
+ The NAS-Port AVP (AVP Code 5) is of type Unsigned32 and contains the
+ physical or virtual port number of the NAS which is authenticating
+ the user. Note that "port" is meant in its sense as a service
+ connection on the NAS, not as an IP protocol identifier.
+
+ Either NAS-Port or NAS-Port-Id (AVP Code 87) SHOULD be present in
+ AA-Request (AAR) commands if the NAS differentiates among its ports.
+ */
+ struct dict_avp_data data = {
+ 5, /* Code */
+ 0, /* Vendor */
+ "NAS-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* NAS-Port-Id */
+ {
+ /*
+ The NAS-Port-Id AVP (AVP Code 87) is of type UTF8String and consists
+ of ASCII text identifying the port of the NAS authenticating the
+ user. Note that "port" is meant in its sense as a service connection
+ on the NAS, not as an IP protocol identifier.
+
+ Either NAS-Port or NAS-Port-Id SHOULD be present in AA-Request (AAR)
+ commands if the NAS differentiates among its ports. NAS-Port-Id is
+ intended for use by NASes that cannot conveniently number their
+ ports.
+ */
+ struct dict_avp_data data = {
+ 87, /* Code */
+ 0, /* Vendor */
+ "NAS-Port-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* NAS-Port-Type */
+ {
+ /*
+ The NAS-Port-Type AVP (AVP Code 61) is of type Enumerated and
+ contains the type of the port on which the NAS is authenticating the
+ user. This AVP SHOULD be present if the NAS uses the same NAS-Port
+ number ranges for different service types concurrently.
+
+ The supported values are defined in [RADIUSTypes]. The following
+ list is informational and subject to change by the IANA.
+
+ http://www.iana.org/assignments/radius-types
+ Sub-registry: Values for RADIUS Attribute 61, NAS-Port-Type
+ Reference: [RFC2865]
+
+ Extract on 2009.06.01:
+ 0 Async [RFC2865]
+ 1 Sync [RFC2865]
+ 2 ISDN Sync [RFC2865]
+ 3 ISDN Async V.120 [RFC2865]
+ 4 ISDN Async V.110 [RFC2865]
+ 5 Virtual [RFC2865]
+ 6 PIAFS [RFC2865]
+ 7 HDLC Clear Channel [RFC2865]
+ 8 X.25 [RFC2865]
+ 9 X.75 [RFC2865]
+ 10 G.3 Fax [RFC2865]
+ 11 SDSL - Symmetric DSL [RFC2865]
+ 12 ADSL-CAP - Asymmetric DSL, Carrierless Amplitude Phase Modulation [RFC2865]
+ 13 ADSL-DMT - Asymmetric DSL, Discrete Multi-Tone [RFC2865]
+ 14 IDSL - ISDN Digital Subscriber Line [RFC2865]
+ 15 Ethernet [RFC2865]
+ 16 xDSL - Digital Subscriber Line of unknown type [RFC2865]
+ 17 Cable [RFC2865]
+ 18 Wireless - Other [RFC2865]
+ 19 Wireless - IEEE 802.11 [RFC2865]
+ 20 Token-Ring [RFC3580]
+ 21 FDDI [RFC3580]
+ 22 Wireless - CDMA2000 [McCann]
+ 23 Wireless - UMTS [McCann]
+ 24 Wireless - 1X-EV [McCann]
+ 25 IAPP [IEEE 802.11F][Kerry]
+ 26 FTTP - Fiber to the Premises [Nyce]
+ 27 Wireless - IEEE 802.16 [IEEE 802.16] 12 December 2006
+ 28 Wireless - IEEE 802.20 [IEEE 802.20] 12 December 2006
+ 29 Wireless - IEEE 802.22 [IEEE 802.22] 12 December 2006
+ 30 PPPoA - PPP over ATM [RFC4603]
+ 31 PPPoEoA - PPP over Ethernet over ATM [RFC4603]
+ 32 PPPoEoE - PPP over Ethernet over Ethernet [RFC4603]
+ 33 PPPoEoVLAN - PPP over Ethernet over VLAN [RFC4603]
+ 34 PPPoEoQinQ - PPP over Ethernet over IEEE 802.1QinQ [RFC4603]
+ 35 xPON - Passive Optical Network [Hublet][Yan] 19 June 2007
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(NAS-Port-Type)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "Async [RFC2865]"),
+ enumval_def_u32( 1, "Sync [RFC2865]"),
+ enumval_def_u32( 2, "ISDN Sync [RFC2865]"),
+ enumval_def_u32( 3, "ISDN Async V.120 [RFC2865]"),
+ enumval_def_u32( 4, "ISDN Async V.110 [RFC2865]"),
+ enumval_def_u32( 5, "Virtual [RFC2865]"),
+ enumval_def_u32( 6, "PIAFS [RFC2865]"),
+ enumval_def_u32( 7, "HDLC Clear Channel [RFC2865]"),
+ enumval_def_u32( 8, "X.25 [RFC2865]"),
+ enumval_def_u32( 9, "X.75 [RFC2865]"),
+ enumval_def_u32(10, "G.3 Fax [RFC2865]"),
+ enumval_def_u32(11, "SDSL - Symmetric DSL [RFC2865]"),
+ enumval_def_u32(12, "ADSL-CAP - Asymmetric DSL, Carrierless Amplitude Phase Modulation [RFC2865]"),
+ enumval_def_u32(13, "ADSL-DMT - Asymmetric DSL, Discrete Multi-Tone [RFC2865]"),
+ enumval_def_u32(14, "IDSL - ISDN Digital Subscriber Line [RFC2865]"),
+ enumval_def_u32(15, "Ethernet [RFC2865]"),
+ enumval_def_u32(16, "xDSL - Digital Subscriber Line of unknown type [RFC2865]"),
+ enumval_def_u32(17, "Cable [RFC2865]"),
+ enumval_def_u32(18, "Wireless - Other [RFC2865]"),
+ enumval_def_u32(19, "Wireless - IEEE 802.11 [RFC2865]"),
+ enumval_def_u32(20, "Token-Ring [RFC3580]"),
+ enumval_def_u32(21, "FDDI [RFC3580]"),
+ enumval_def_u32(22, "Wireless - CDMA2000 [McCann]"),
+ enumval_def_u32(23, "Wireless - UMTS [McCann]"),
+ enumval_def_u32(24, "Wireless - 1X-EV [McCann]"),
+ enumval_def_u32(25, "IAPP [IEEE 802.11F][Kerry]"),
+ enumval_def_u32(26, "FTTP - Fiber to the Premises [Nyce]"),
+ enumval_def_u32(27, "Wireless - IEEE 802.16 [IEEE 802.16]"),
+ enumval_def_u32(28, "Wireless - IEEE 802.20 [IEEE 802.20]"),
+ enumval_def_u32(29, "Wireless - IEEE 802.22 [IEEE 802.22]"),
+ enumval_def_u32(30, "PPPoA - PPP over ATM [RFC4603]"),
+ enumval_def_u32(31, "PPPoEoA - PPP over Ethernet over ATM [RFC4603]"),
+ enumval_def_u32(32, "PPPoEoE - PPP over Ethernet over Ethernet [RFC4603]"),
+ enumval_def_u32(33, "PPPoEoVLAN - PPP over Ethernet over VLAN [RFC4603]"),
+ enumval_def_u32(34, "PPPoEoQinQ - PPP over Ethernet over IEEE 802.1QinQ [RFC4603]"),
+ enumval_def_u32(35, "xPON - Passive Optical Network [Hublet][Yan]")
+ };
+ struct dict_avp_data data = {
+ 61, /* Code */
+ 0, /* Vendor */
+ "NAS-Port-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Called-Station-Id */
+ {
+ /*
+ The Called-Station-Id AVP (AVP Code 30) is of type UTF8String and
+ allows the NAS to send the ASCII string describing the layer 2
+ address the user contacted in the request. For dialup access, this
+ can be a phone number obtained by using Dialed Number Identification
+ (DNIS) or a similar technology. Note that this may be different from
+ the phone number the call comes in on. For use with IEEE 802 access,
+ the Called-Station-Id MAY contain a MAC address formatted as
+ described in [RAD802.1X]. It SHOULD only be present in
+ authentication and/or authorization requests.
+
+ If the Auth-Request-Type AVP is set to authorization-only and the
+ User-Name AVP is absent, the Diameter Server MAY perform
+ authorization based on this field. This can be used by a NAS to
+ request whether a call should be answered based on the DNIS.
+ */
+ struct dict_avp_data data = {
+ 30, /* Code */
+ 0, /* Vendor */
+ "Called-Station-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Calling-Station-Id */
+ {
+ /*
+ The Calling-Station-Id AVP (AVP Code 31) is of type UTF8String and
+ allows the NAS to send the ASCII string describing the layer 2
+ address from which the user connected in the request. For dialup
+ access, this is the phone number the call came from, using Automatic
+ Number Identification (ANI) or a similar technology. For use with
+ IEEE 802 access, the Calling-Station-Id AVP MAY contain a MAC
+ address, formated as described in [RAD802.1X]. It SHOULD only be
+ present in authentication and/or authorization requests.
+
+ If the Auth-Request-Type AVP is set to authorization-only and the
+ User-Name AVP is absent, the Diameter Server MAY perform
+ authorization based on this field. This can be used by a NAS to
+ request whether a call should be answered based on the layer 2
+ address (ANI, MAC Address, etc.)
+ */
+ struct dict_avp_data data = {
+ 31, /* Code */
+ 0, /* Vendor */
+ "Calling-Station-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Connect-Info */
+ {
+ /*
+ The Connect-Info AVP (AVP Code 77) is of type UTF8String and is sent
+ in the AA-Request message or ACR STOP message. When sent in the
+ Access-Request, it indicates the nature of the user's connection.
+ The connection speed SHOULD be included at the beginning of the first
+ Connect-Info AVP in the message. If the transmit and receive
+ connection speeds differ, both may be included in the first AVP with
+ the transmit speed listed first (the speed the NAS modem transmits
+ at), then a slash (/), then the receive speed, and then other
+ optional information.
+
+ For example: "28800 V42BIS/LAPM" or "52000/31200 V90"
+
+ More than one Connect-Info attribute may be present in an
+ Accounting-Request packet to accommodate expected efforts by the ITU
+ to have modems report more connection information in a standard
+ format that might exceed 252 octets.
+
+ If sent in the ACR STOP, this attribute may summarize statistics
+ relating to session quality. For example, in IEEE 802.11, the
+ Connect-Info attribute may contain information on the number of link
+ layer retransmissions. The exact format of this attribute is
+ implementation specific.
+ */
+ struct dict_avp_data data = {
+ 77, /* Code */
+ 0, /* Vendor */
+ "Connect-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Originating-Line-Info */
+ {
+ /*
+ The Originating-Line-Info AVP (AVP Code 94) is of type OctetString
+ and is sent by the NAS system to convey information about the origin
+ of the call from an SS7 system.
+
+ The originating line information (OLI) element indicates the nature
+ and/or characteristics of the line from which a call originated
+ (e.g., pay phone, hotel, cellular). Telephone companies are starting
+ to offer OLI to their customers as an option over Primary Rate
+ Interface (PRI). Internet Service Providers (ISPs) can use OLI in
+ addition to Called-Station-Id and Calling-Station-Id attributes to
+ differentiate customer calls and to define different services.
+
+ The Value field contains two octets (00 - 99). ANSI T1.113 and
+ BELLCORE 394 can be used for additional information about these
+ values and their use. For more information on current assignment
+ values, see [http://www.nanpa.com/number_resource_info/ani_ii_assignments.html].
+
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_OCTETSTRING, "Enumerated(Originating-Line-Info)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_os( 2, "00", "Plain Old Telephone Service (POTS)"),
+ enumval_def_os( 2, "01", "Multiparty Line (more than 2)"),
+ enumval_def_os( 2, "02", "ANI Failure"),
+ enumval_def_os( 2, "06", "Station Level Rating"),
+ enumval_def_os( 2, "07", "Special Operator Handling Required"),
+ enumval_def_os( 2, "20", "Automatic Identified Outward Dialing (AIOD)"),
+ enumval_def_os( 2, "23", "Coin or Non-Coin"),
+ enumval_def_os( 2, "24", "Toll Free Service (Non-Pay Origination)"),
+ enumval_def_os( 2, "25", "Toll Free Service (Pay Origination)"),
+ enumval_def_os( 2, "27", "Toll Free Service (Coin Control Origination)"),
+ enumval_def_os( 2, "29", "Prison/Inmate Service"),
+ enumval_def_os( 2, "30", "Intercept (Blank)"),
+ enumval_def_os( 2, "31", "Intercept (Trouble)"),
+ enumval_def_os( 2, "32", "Intercept (Regular)"),
+ enumval_def_os( 2, "34", "Telco Operator Handled Call"),
+ enumval_def_os( 2, "52", "Outward Wide Area Telecommunications Service (OUTWATS)"),
+ enumval_def_os( 2, "60", "Telecommunications Relay Service (TRS)(Unrestricted)"),
+ enumval_def_os( 2, "61", "Cellular/Wireless PCS (Type 1)"),
+ enumval_def_os( 2, "62", "Cellular/Wireless PCS (Type 2)"),
+ enumval_def_os( 2, "63", "Cellular/Wireless PCS (Roaming)"),
+ enumval_def_os( 2, "66", "TRS (Hotel)"),
+ enumval_def_os( 2, "67", "TRS (Restricted)"),
+ enumval_def_os( 2, "70", "Pay Station, No Coin Control"),
+ enumval_def_os( 2, "93", "Access for Private Virtual Network Service")
+ };
+ struct dict_avp_data data = {
+ 94, /* Code */
+ 0, /* Vendor */
+ "Originating-Line-Info", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Reply-Message */
+ {
+ /*
+ The Reply-Message AVP (AVP Code 18) is of type UTF8String and
+ contains text that MAY be displayed to the user. When used in an
+ AA-Answer message with a successful Result-Code AVP, it indicates
+ success. When found in an AAA message with a Result-Code other than
+ DIAMETER_SUCCESS, the AVP contains a failure message.
+
+ The Reply-Message AVP MAY indicate dialog text to prompt the user
+ before another AA-Request attempt. When used in an AA-Answer with a
+ Result-Code of DIAMETER_MULTI_ROUND_AUTH or in an Re-Auth-Request
+ message, it MAY contain a dialog text to prompt the user for a
+ response.
+
+ Multiple Reply-Messages MAY be included, and if any are displayed,
+ they MUST be displayed in the same order as they appear in the
+ Diameter message.
+ */
+ struct dict_avp_data data = {
+ 18, /* Code */
+ 0, /* Vendor */
+ "Reply-Message", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+/********************************
+ * NAS Authentication AVPs *
+ ********************************/
+ /* User-Password */
+ {
+ /*
+ The User-Password AVP (AVP Code 2) is of type OctetString and
+ contains the password of the user to be authenticated, or the user's
+ input in a multi-round authentication exchange.
+
+ The User-Password AVP contains a user password or one-time password
+ and therefore represents sensitive information. As required in
+ [BASE], Diameter messages are encrypted by using IPsec or TLS.
+ Unless this AVP is used for one-time passwords, the User-Password AVP
+ SHOULD NOT be used in untrusted proxy environments without encrypting
+ it by using end-to-end security techniques, such as the proposed CMS
+ Security [DiamCMS].
+
+ The clear-text password (prior to encryption) MUST NOT be longer than
+ 128 bytes in length.
+ */
+ struct dict_avp_data data = {
+ 2, /* Code */
+ 0, /* Vendor */
+ "User-Password", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Password-Retry */
+ {
+ /*
+ The Password-Retry AVP (AVP Code 75) is of type Unsigned32 and MAY be
+ included in the AA-Answer if the Result-Code indicates an
+ authentication failure. The value of this AVP indicates how many
+ authentication attempts a user is permitted before being
+ disconnected. This AVP is primarily intended for use when the
+ Framed-Protocol AVP (see section 6.10.1) is set to ARAP.
+ */
+ struct dict_avp_data data = {
+ 75, /* Code */
+ 0, /* Vendor */
+ "Password-Retry", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Prompt */
+ {
+ /*
+ The Prompt AVP (AVP Code 76) is of type Enumerated and MAY be present
+ in the AA-Answer message. When present, it is used by the NAS to
+ determine whether the user's response, when entered, should be
+ echoed.
+
+ The supported values are listed in http://www.iana.org/assignments/radius-types
+ Sub-registry: Values for RADIUS Attribute 76, Prompt
+ Reference: [RFC2869]
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Prompt)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "No Echo [RFC2869]"),
+ enumval_def_u32( 1, "Echo [RFC2869]")
+ };
+ struct dict_avp_data data = {
+ 76, /* Code */
+ 0, /* Vendor */
+ "Prompt", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* CHAP-Algorithm */
+ {
+ /*
+ The CHAP-Algorithm AVP (AVP Code 403) is of type Enumerated and
+ contains the algorithm identifier used in the computation of the CHAP
+ response [PPPCHAP]. The following values are currently supported:
+
+ CHAP with MD5 5
+ The CHAP response is computed by using the procedure described
+ in [PPPCHAP]. This algorithm requires that the CHAP-Response
+ AVP MUST be present in the CHAP-Auth AVP.
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(CHAP-Algorithm)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 5, "CHAP with MD5")
+ };
+ struct dict_avp_data adata = {
+ 403, /* Code */
+ 0, /* Vendor */
+ "CHAP-Algorithm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &adata , type, NULL);
+ }
+
+ /* CHAP-Ident */
+ {
+ /*
+ The CHAP-Ident AVP (AVP Code 404) is of type OctetString and contains
+ the 1 octet CHAP Identifier used in the computation of the CHAP
+ response [PPPCHAP].
+ */
+ struct dict_avp_data adata = {
+ 404, /* Code */
+ 0, /* Vendor */
+ "CHAP-Ident", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , NULL, NULL);
+ }
+
+ /* CHAP-Response */
+ {
+ /*
+ The CHAP-Response AVP (AVP Code 405) is of type OctetString and
+ contains the 16 octet authentication data provided by the user in
+ response to the CHAP challenge [PPPCHAP].
+ */
+ struct dict_avp_data adata = {
+ 405, /* Code */
+ 0, /* Vendor */
+ "CHAP-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , NULL, NULL);
+ }
+
+ /* CHAP-Auth */
+ {
+ /*
+ The CHAP-Auth AVP (AVP Code 402) is of type Grouped and contains the
+ information necessary to authenticate a user using the PPP
+ Challenge-Handshake Authentication Protocol (CHAP) [PPPCHAP]. If the
+ CHAP-Auth AVP is found in a message, the CHAP-Challenge AVP MUST be
+ present as well. The optional AVPs containing the CHAP response
+ depend upon the value of the CHAP-Algorithm AVP. The grouped AVP has
+ the following ABNF grammar:
+
+ CHAP-Auth ::= < AVP Header: 402 >
+ { CHAP-Algorithm }
+ { CHAP-Ident }
+ [ CHAP-Response ]
+ * [ AVP ]
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 402, /* Code */
+ 0, /* Vendor */
+ "CHAP-Auth", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "CHAP-Algorithm", RULE_REQUIRED, -1, 1 }
+ ,{ "CHAP-Ident", RULE_REQUIRED, -1, 1 }
+ ,{ "CHAP-Response", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* CHAP-Challenge */
+ {
+ /*
+ The CHAP-Challenge AVP (AVP Code 60) is of type OctetString and
+ contains the CHAP Challenge sent by the NAS to the CHAP peer
+ [PPPCHAP].
+ */
+ struct dict_avp_data data = {
+ 60, /* Code */
+ 0, /* Vendor */
+ "CHAP-Challenge", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* ARAP-Password */
+ {
+ /*
+ The ARAP-Password AVP (AVP Code 70) is of type OctetString and is
+ only present when the Framed-Protocol AVP (see section 6.10.1) is
+ included in the message and is set to ARAP. This AVP MUST NOT be
+ present if either the User-Password or the CHAP-Auth AVP is present.
+ See [RADIUSExt] for more information on the contents of this AVP.
+ */
+ struct dict_avp_data data = {
+ 70, /* Code */
+ 0, /* Vendor */
+ "ARAP-Password", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* ARAP-Challenge-Response */
+ {
+ /*
+ The ARAP-Challenge-Response AVP (AVP Code 84) is of type OctetString
+ and is only present when the Framed-Protocol AVP (see section 6.10.1)
+ is included in the message and is set to ARAP. This AVP contains an
+ 8 octet response to the dial-in client's challenge. The RADIUS
+ server calculates this value by taking the dial-in client's challenge
+ from the high-order 8 octets of the ARAP-Password AVP and performing
+ DES encryption on this value with the authenticating user's password
+ as the key. If the user's password is fewer than 8 octets in length,
+ the password is padded at the end with NULL octets to a length of 8
+ before it is used as a key.
+ */
+ struct dict_avp_data data = {
+ 84, /* Code */
+ 0, /* Vendor */
+ "ARAP-Challenge-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* ARAP-Security */
+ {
+ /*
+ The ARAP-Security AVP (AVP Code 73) is of type Unsigned32 and MAY be
+ present in the AA-Answer message if the Framed-Protocol AVP (see
+ section 6.10.1) is set to the value of ARAP, and the Result-Code AVP
+ is set to DIAMETER_MULTI_ROUND_AUTH. See [RADIUSExt] for more
+ information on the format of this AVP.
+ */
+ struct dict_avp_data data = {
+ 73, /* Code */
+ 0, /* Vendor */
+ "ARAP-Security", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* ARAP-Security-Data */
+ {
+ /*
+ The ARAP-Security-Data AVP (AVP Code 74) is of type OctetString and MAY be
+ present in the AA-Request or AA-Answer message if the Framed-Protocol
+ AVP is set to the value of ARAP, and the Result-Code AVP is set to
+ DIAMETER_MULTI_ROUND_AUTH. This AVP contains the security module
+ challenge or response associated with the ARAP Security Module
+ specified in ARAP-Security.
+ */
+ struct dict_avp_data data = {
+ 74, /* Code */
+ 0, /* Vendor */
+ "ARAP-Security-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+/********************************
+ * NAS Authorization AVPs *
+ ********************************/
+ /* Service-Type */
+ {
+ /*
+ The Service-Type AVP (AVP Code 6) is of type Enumerated and contains
+ the type of service the user has requested or the type of service to
+ be provided. One such AVP MAY be present in an authentication and/or
+ authorization request or response. A NAS is not required to
+ implement all of these service types. It MUST treat unknown or
+ unsupported Service-Types received in a response as a failure and end
+ the session with a DIAMETER_INVALID_AVP_VALUE Result-Code.
+
+ When used in a request, the Service-Type AVP SHOULD be considered a
+ hint to the server that the NAS believes the user would prefer the
+ kind of service indicated. The server is not required to honor the
+ hint. Furthermore, if the service specified by the server is
+ supported, but not compatible with the current mode of access, the
+ NAS MUST fail to start the session. The NAS MUST also generate the
+ appropriate error message(s).
+
+ The following values have been defined for the Service-Type AVP. The
+ complete list of defined values can be found in [RADIUS] and
+ [RADIUSTypes].
+
+ Registry Name: Radius Attribute Values
+ Reference: [RFC2865][RFC3575]
+
+ Sub-registry: Values for RADIUS Attribute 6, Service-Type
+ Reference: [RFC2865][RFC3575]
+
+ 1 Login
+ 2 Framed
+ 3 Callback Login
+ 4 Callback Framed
+ 5 Outbound
+ 6 Administrative
+ 7 NAS Prompt
+ 8 Authenticate Only
+ 9 Callback NAS Prompt
+ 10 Call Check
+ 11 Callback Administrative
+ 12 Voice [Chiba]
+ 13 Fax [Chiba]
+ 14 Modem Relay [Chiba]
+ 15 IAPP-Register [IEEE 802.11f][Kerry]
+ 16 IAPP-AP-Check [IEEE 802.11f][Kerry]
+ 17 Authorize Only [RFC3576]
+
+ The following values are further qualified:
+
+ Login 1
+ The user should be connected to a host. The message MAY
+ include additional AVPs defined in sections 6.16 or 6.17.
+
+ Framed 2
+ A Framed Protocol, such as PPP or SLIP, should be started for
+ the User. The message MAY include additional AVPs defined in
+ section 6.10, or section 7 for tunneling services.
+
+ Callback Login 3
+ The user should be disconnected and called back, then connected
+ to a host. The message MAY include additional AVPs defined in
+ this section.
+
+ Callback Framed 4
+ The user should be disconnected and called back, and then a
+ Framed Protocol, such as PPP or SLIP, should be started for the
+ User. The message MAY include additional AVPs defined in
+ section 6.10, or in section 7 for tunneling services.
+
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Service-Type)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 1, "Login"),
+ enumval_def_u32( 2, "Framed"),
+ enumval_def_u32( 3, "Callback Login"),
+ enumval_def_u32( 4, "Callback Framed"),
+ enumval_def_u32( 5, "Outbound"),
+ enumval_def_u32( 6, "Administrative"),
+ enumval_def_u32( 7, "NAS Prompt"),
+ enumval_def_u32( 8, "Authenticate Only"),
+ enumval_def_u32( 9, "Callback NAS Prompt"),
+ enumval_def_u32(10, "Call Check"),
+ enumval_def_u32(11, "Callback Administrative"),
+ enumval_def_u32(12, "Voice [Chiba]"),
+ enumval_def_u32(13, "Fax [Chiba]"),
+ enumval_def_u32(14, "Modem Relay [Chiba]"),
+ enumval_def_u32(15, "IAPP-Register [IEEE 802.11f][Kerry]"),
+ enumval_def_u32(16, "IAPP-AP-Check [IEEE 802.11f][Kerry]"),
+ enumval_def_u32(17, "Authorize Only [RFC3576]")
+ };
+ struct dict_avp_data data = {
+ 6, /* Code */
+ 0, /* Vendor */
+ "Service-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Callback-Number */
+ {
+ /*
+ The Callback-Number AVP (AVP Code 19) is of type UTF8String and
+ contains a dialing string to be used for callback. It MAY be used in
+ an authentication and/or authorization request as a hint to the
+ server that a Callback service is desired, but the server is not
+ required to honor the hint in the corresponding response.
+ */
+ struct dict_avp_data data = {
+ 19, /* Code */
+ 0, /* Vendor */
+ "Callback-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Callback-Id */
+ {
+ /*
+ The Callback-Id AVP (AVP Code 20) is of type UTF8String and contains
+ the name of a place to be called, to be interpreted by the NAS. This
+ AVP MAY be present in an authentication and/or authorization
+ response.
+
+ This AVP is not roaming-friendly as it assumes that the Callback-Id
+ is configured on the NAS. Using the Callback-Number AVP therefore
+ preferable.
+ */
+ struct dict_avp_data data = {
+ 20, /* Code */
+ 0, /* Vendor */
+ "Callback-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Idle-Timeout */
+ {
+ /*
+ The Idle-Timeout AVP (AVP Code 28) is of type Unsigned32 and sets the
+ maximum number of consecutive seconds of idle connection allowable to
+ the user before termination of the session or before a prompt is
+ issued. The default is none, or system specific.
+ */
+ struct dict_avp_data data = {
+ 28, /* Code */
+ 0, /* Vendor */
+ "Idle-Timeout", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Port-Limit */
+ {
+ /*
+ The Port-Limit AVP (AVP Code 62) is of type Unsigned32 and sets the
+ maximum number of ports the NAS provides to the user. It MAY be used
+ in an authentication and/or authorization request as a hint to the
+ server that multilink PPP [PPPMP] service is desired, but the server
+ is not required to honor the hint in the corresponding response.
+ */
+ struct dict_avp_data data = {
+ 62, /* Code */
+ 0, /* Vendor */
+ "Port-Limit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* NAS-Filter-Rule */
+ {
+ /*
+ The NAS-Filter-Rule AVP (AVP Code 400) is of type IPFilterRule and
+ provides filter rules that need to be configured on the NAS for the
+ user. One or more of these AVPs MAY be present in an authorization
+ response.
+ */
+ struct dict_avp_data data = {
+ 400, /* Code */
+ 0, /* Vendor */
+ "NAS-Filter-Rule", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , IPFilterRule_type, NULL);
+ }
+
+ /* Filter-Id */
+ {
+ /*
+ The Filter-Id AVP (AVP Code 11) is of type UTF8String and contains
+ the name of the filter list for this user. Zero or more Filter-Id
+ AVPs MAY be sent in an authorization answer.
+
+ Identifying a filter list by name allows the filter to be used on
+ different NASes without regard to filter-list implementation details.
+ However, this AVP is not roaming friendly, as filter naming differs
+ from one service provider to another.
+
+ In non-RADIUS environments, it is RECOMMENDED that the NAS-Filter-
+ Rule AVP be used instead.
+ */
+ struct dict_avp_data data = {
+ 11, /* Code */
+ 0, /* Vendor */
+ "Filter-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Configuration-Token */
+ {
+ /*
+ The Configuration-Token AVP (AVP Code 78) is of type OctetString and
+ is sent by a Diameter Server to a Diameter Proxy Agent or Translation
+ Agent in an AA-Answer command to indicate a type of user profile to
+ be used. It should not be sent to a Diameter Client (NAS).
+
+ The format of the Data field of this AVP is site specific.
+ */
+ struct dict_avp_data data = {
+ 78, /* Code */
+ 0, /* Vendor */
+ "Configuration-Token", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* QoS-Filter-Rule */
+ {
+ /*
+ The QoS-Filter-Rule AVP (AVP Code 407) is of type QoSFilterRule and
+ provides QoS filter rules that need to be configured on the NAS for
+ the user. One or more such AVPs MAY be present in an authorization
+ response.
+ */
+ struct dict_avp_data data = {
+ 407, /* Code */
+ 0, /* Vendor */
+ "QoS-Filter-Rule", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , QoSFilterRule_type, NULL);
+ }
+
+/*** Framed Access Authorization AVPs ***/
+
+ /* Framed-Protocol */
+ {
+ /*
+ The Framed-Protocol AVP (AVP Code 7) is of type Enumerated and
+ contains the framing to be used for framed access. This AVP MAY be
+ present in both requests and responses. The supported values are
+ listed in [RADIUSTypes].
+
+ Sub-registry: Values for RADIUS Attribute 7, Framed-Protocol
+ Reference: [RFC2865]
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Framed-Protocol)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 1, "PPP"),
+ enumval_def_u32( 2, "SLIP"),
+ enumval_def_u32( 3, "AppleTalk Remote Access Protocol (ARAP)"),
+ enumval_def_u32( 4, "Gandalf proprietary SingleLink/MultiLink protocol"),
+ enumval_def_u32( 5, "Xylogics proprietary IPX/SLIP"),
+ enumval_def_u32( 6, "X.75 Synchronous"),
+ enumval_def_u32( 7, "GPRS PDP Context [Moore]")
+ };
+ struct dict_avp_data data = {
+ 7, /* Code */
+ 0, /* Vendor */
+ "Framed-Protocol", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Framed-Routing */
+ {
+ /*
+ The Framed-Routing AVP (AVP Code 10) is of type Enumerated and
+ contains the routing method for the user when the user is a router to
+ a network. This AVP SHOULD only be present in authorization
+ responses. The supported values are listed in [RADIUSTypes].
+
+ Sub-registry: Values for RADIUS Attribute 10, Framed-Routing
+ Reference: [RFC2865]
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Framed-Routing)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "None"),
+ enumval_def_u32( 1, "Send routing packets"),
+ enumval_def_u32( 2, "Listen for routing packets"),
+ enumval_def_u32( 3, "Send and Listen")
+ };
+ struct dict_avp_data data = {
+ 10, /* Code */
+ 0, /* Vendor */
+ "Framed-Routing", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Framed-MTU */
+ {
+ /*
+ The Framed-MTU AVP (AVP Code 12) is of type Unsigned32 and contains
+ the Maximum Transmission Unit to be configured for the user, when it
+ is not negotiated by some other means (such as PPP). This AVP SHOULD
+ only be present in authorization responses. The MTU value MUST be in
+ the range from 64 to 65535.
+ */
+ struct dict_avp_data data = {
+ 12, /* Code */
+ 0, /* Vendor */
+ "Framed-MTU", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Framed-Compression */
+ {
+ /*
+ The Framed-Compression AVP (AVP Code 13) is of type Enumerated and
+ contains the compression protocol to be used for the link. It MAY be
+ used in an authorization request as a hint to the server that a
+ specific compression type is desired, but the server is not required
+ to honor the hint in the corresponding response.
+
+ More than one compression protocol AVP MAY be sent. The NAS is
+ responsible for applying the proper compression protocol to the
+ appropriate link traffic.
+
+ The supported values are listed in [RADIUSTypes].
+ Sub-registry: Values for RADIUS Attribute 13, Framed-Compression
+ Reference: [RFC2865]
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Framed-Compression)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "None"),
+ enumval_def_u32( 1, "VJ TCP/IP header compression"),
+ enumval_def_u32( 2, "IPX header compression"),
+ enumval_def_u32( 3, "Stac-LZS compression")
+ };
+ struct dict_avp_data data = {
+ 13, /* Code */
+ 0, /* Vendor */
+ "Framed-Compression", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+/*** IP Access Authorization AVPs ***/
+
+ /* Framed-IP-Address */
+ {
+ /*
+ The Framed-IP-Address AVP (AVP Code 8) [RADIUS] is of type
+ OctetString and contains an IPv4 address of the type specified in the
+ attribute value to be configured for the user. It MAY be used in an
+ authorization request as a hint to the server that a specific address
+ is desired, but the server is not required to honor the hint in the
+ corresponding response.
+
+ Two values have special significance: 0xFFFFFFFF and 0xFFFFFFFE. The
+ value 0xFFFFFFFF indicates that the NAS should allow the user to
+ select an address (i.e., negotiated). The value 0xFFFFFFFE indicates
+ that the NAS should select an address for the user (e.g., assigned
+ from a pool of addresses kept by the NAS).
+ */
+ struct dict_avp_data data = {
+ 8, /* Code */
+ 0, /* Vendor */
+ "Framed-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Framed-IP-Netmask */
+ {
+ /*
+ The Framed-IP-Netmask AVP (AVP Code 9) is of type OctetString and
+ contains the four octets of the IPv4 netmask to be configured for the
+ user when the user is a router to a network. It MAY be used in an
+ authorization request as a hint to the server that a specific netmask
+ is desired, but the server is not required to honor the hint in the
+ corresponding response. This AVP MUST be present in a response if
+ the request included this AVP with a value of 0xFFFFFFFF.
+ */
+ struct dict_avp_data data = {
+ 9, /* Code */
+ 0, /* Vendor */
+ "Framed-IP-Netmask", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Framed-Route */
+ {
+ /*
+ The Framed-Route AVP (AVP Code 22) is of type UTF8String and contains
+ the ASCII routing information to be configured for the user on the
+ NAS. Zero or more of these AVPs MAY be present in an authorization
+ response.
+
+ The string MUST contain a destination prefix in dotted quad form
+ optionally followed by a slash and a decimal length specifier stating
+ how many high-order bits of the prefix should be used. This is
+ followed by a space, a gateway address in dotted quad form, a space,
+ and one or more metrics separated by spaces; for example,
+
+ "192.168.1.0/24 192.168.1.1 1".
+
+ The length specifier may be omitted, in which case it should default
+ to 8 bits for class A prefixes, to 16 bits for class B prefixes, and
+ to 24 bits for class C prefixes; for example,
+
+ "192.168.1.0 192.168.1.1 1".
+
+ Whenever the gateway address is specified as "0.0.0.0" the IP address
+ of the user SHOULD be used as the gateway address.
+ */
+ struct dict_avp_data data = {
+ 22, /* Code */
+ 0, /* Vendor */
+ "Framed-Route", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Framed-Pool */
+ {
+ /*
+ The Framed-Pool AVP (AVP Code 88) is of type OctetString and contains
+ the name of an assigned address pool that SHOULD be used to assign an
+ address for the user. If a NAS does not support multiple address
+ pools, the NAS SHOULD ignore this AVP. Address pools are usually
+ used for IP addresses but can be used for other protocols if the NAS
+ supports pools for those protocols.
+
+ Although specified as type OctetString for compatibility with RADIUS
+ [RADIUSExt], the encoding of the Data field SHOULD also conform to
+ the rules for the UTF8String Data Format.
+ */
+ struct dict_avp_data data = {
+ 88, /* Code */
+ 0, /* Vendor */
+ "Framed-Pool", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Framed-Interface-Id */
+ {
+ /*
+ The Framed-Interface-Id AVP (AVP Code 96) is of type Unsigned64 and
+ contains the IPv6 interface identifier to be configured for the user.
+ It MAY be used in authorization requests as a hint to the server that
+ a specific interface id is desired, but the server is not required to
+ honor the hint in the corresponding response.
+ */
+ struct dict_avp_data data = {
+ 96, /* Code */
+ 0, /* Vendor */
+ "Framed-Interface-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Framed-IPv6-Prefix */
+ {
+ /*
+ The Framed-IPv6-Prefix AVP (AVP Code 97) is of type OctetString and
+ contains the IPv6 prefix to be configured for the user. One or more
+ AVPs MAY be used in authorization requests as a hint to the server
+ that specific IPv6 prefixes are desired, but the server is not
+ required to honor the hint in the corresponding response.
+ */
+ struct dict_avp_data data = {
+ 97, /* Code */
+ 0, /* Vendor */
+ "Framed-IPv6-Prefix", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Framed-IPv6-Route */
+ {
+ /*
+ The Framed-IPv6-Route AVP (AVP Code 99) is of type UTF8String and
+ contains the ASCII routing information to be configured for the user
+ on the NAS. Zero or more of these AVPs MAY be present in an
+ authorization response.
+
+ The string MUST contain an IPv6 address prefix followed by a slash
+ and a decimal length specifier stating how many high order bits of
+ the prefix should be used. This is followed by a space, a gateway
+ address in hexadecimal notation, a space, and one or more metrics
+ separated by spaces; for example,
+
+ "2000:0:0:106::/64 2000::106:a00:20ff:fe99:a998 1".
+
+ Whenever the gateway address is the IPv6 unspecified address, the IP
+ address of the user SHOULD be used as the gateway address, such as
+ in:
+
+ "2000:0:0:106::/64 :: 1".
+ */
+ struct dict_avp_data data = {
+ 99, /* Code */
+ 0, /* Vendor */
+ "Framed-IPv6-Route", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Framed-IPv6-Pool */
+ {
+ /*
+ The Framed-IPv6-Pool AVP (AVP Code 100) is of type OctetString and
+ contains the name of an assigned pool that SHOULD be used to assign
+ an IPv6 prefix for the user. If the access device does not support
+ multiple prefix pools, it MUST ignore this AVP.
+
+ Although specified as type OctetString for compatibility with RADIUS
+ [RADIUSIPv6], the encoding of the Data field SHOULD also conform to
+ the rules for the UTF8String Data Format.
+ */
+ struct dict_avp_data data = {
+ 100, /* Code */
+ 0, /* Vendor */
+ "Framed-IPv6-Pool", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+/*** IPX Access ***/
+
+ /* Framed-IPX-Network */
+ {
+ /*
+ The Framed-IPX-Network AVP (AVP Code 23) is of type Unsigned32 and
+ contains the IPX Network number to be configured for the user. It
+ MAY be used in an authorization request as a hint to the server that
+ a specific address is desired, but the server is not required to
+ honor the hint in the corresponding response.
+
+ Two addresses have special significance: 0xFFFFFFFF and 0xFFFFFFFE.
+ The value 0xFFFFFFFF indicates that the NAS should allow the user to
+ select an address (i.e., Negotiated). The value 0xFFFFFFFE indicates
+ that the NAS should select an address for the user (e.g., assign it
+ from a pool of one or more IPX networks kept by the NAS).
+ */
+ struct dict_avp_data data = {
+ 23, /* Code */
+ 0, /* Vendor */
+ "Framed-IPX-Network", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+/*** AppleTalk Network Access ***/
+
+ /* Framed-AppleTalk-Link */
+ {
+ /*
+ The Framed-AppleTalk-Link AVP (AVP Code 37) is of type Unsigned32 and
+ contains the AppleTalk network number that should be used for the
+ serial link to the user, which is another AppleTalk router. This AVP
+ MUST only be present in an authorization response and is never used
+ when the user is not another router.
+
+ Despite the size of the field, values range from 0 to 65,535. The
+ special value of 0 indicates an unnumbered serial link. A value of 1
+ to 65,535 means that the serial line between the NAS and the user
+ should be assigned that value as an AppleTalk network number.
+ */
+ struct dict_avp_data data = {
+ 37, /* Code */
+ 0, /* Vendor */
+ "Framed-AppleTalk-Link", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Framed-AppleTalk-Network */
+ {
+ /*
+ The Framed-AppleTalk-Network AVP (AVP Code 38) is of type Unsigned32
+ and contains the AppleTalk Network number that the NAS should probe
+ to allocate an AppleTalk node for the user. This AVP MUST only be
+ present in an authorization response and is never used when the user
+ is not another router. Multiple instances of this AVP indicate that
+ the NAS may probe, using any of the network numbers specified.
+
+ Despite the size of the field, values range from 0 to 65,535. The
+ special value 0 indicates that the NAS should assign a network for
+ the user, using its default cable range. A value between 1 and
+ 65,535 (inclusive) indicates to the AppleTalk Network that the NAS
+ should probe to find an address for the user.
+ */
+ struct dict_avp_data data = {
+ 38, /* Code */
+ 0, /* Vendor */
+ "Framed-AppleTalk-Network", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Framed-AppleTalk-Zone */
+ {
+ /*
+ The Framed-AppleTalk-Zone AVP (AVP Code 39) is of type OctetString
+ and contains the AppleTalk Default Zone to be used for this user.
+ This AVP MUST only be present in an authorization response. Multiple
+ instances of this AVP in the same message are not allowed.
+
+ The codification of this field's allowed range is outside the scope
+ of this specification.
+ */
+ struct dict_avp_data data = {
+ 39, /* Code */
+ 0, /* Vendor */
+ "Framed-AppleTalk-Zone", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+/*** AppleTalk Remote Access [RFC2869] ***/
+
+ /* ARAP-Features */
+ {
+ /*
+ The ARAP-Features AVP (AVP Code 71) is of type OctetString and MAY be
+ present in the AA-Accept message if the Framed-Protocol AVP is set to
+ the value of ARAP. See [RADIUSExt] for more information about the
+ format of this AVP.
+ */
+ struct dict_avp_data data = {
+ 71, /* Code */
+ 0, /* Vendor */
+ "ARAP-Features", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* ARAP-Zone-Access */
+ {
+ /*
+ The ARAP-Zone-Access AVP (AVP Code 72) is of type Enumerated and MAY
+ be present in the AA-Accept message if the Framed-Protocol AVP is set
+ to the value of ARAP.
+
+ The supported values are listed in [RADIUSTypes] and defined in
+ [RADIUSExt].
+ Sub-registry: Values for RADIUS Attribute 72, ARAP-Zone-Access
+ Reference: [RFC2869]
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(ARAP-Zone-Access)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 1, "Only allow access to default zone [RFC2869]"),
+ enumval_def_u32( 2, "Use zone filter inclusively [RFC2869]"),
+ enumval_def_u32( 3, "Not used [RFC2869]"),
+ enumval_def_u32( 4, "Use zone filter exclusively [RFC2869]")
+ };
+ struct dict_avp_data data = {
+ 72, /* Code */
+ 0, /* Vendor */
+ "ARAP-Zone-Access", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+/*** Non-Framed Access Authorization AVPs ***/
+
+ /* Login-IP-Host */
+ {
+ /*
+ The Login-IP-Host AVP (AVP Code 14) [RADIUS] is of type OctetString
+ and contains the IPv4 address of a host with which to connect the
+ user when the Login-Service AVP is included. It MAY be used in an
+ AA-Request command as a hint to the Diameter Server that a specific
+ host is desired, but the Diameter Server is not required to honor the
+ hint in the AA-Answer.
+
+ Two addresses have special significance: all ones and 0. The value
+ of all ones indicates that the NAS SHOULD allow the user to select an
+ address. The value 0 indicates that the NAS SHOULD select a host to
+ connect the user to.
+ */
+ struct dict_object *type;
+ uint32_t allzeros = 0;
+ uint32_t allones = (uint32_t) -1;
+ struct dict_type_data tdata = { AVP_TYPE_OCTETSTRING, "Enumerated(Login-IP-Host)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_os( 4, &allzeros, "(0) NAS selects the host"),
+ enumval_def_os( 4, &allones , "(1) User selects the address")
+ };
+ struct dict_avp_data data = {
+ 14, /* Code */
+ 0, /* Vendor */
+ "Login-IP-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Login-IPv6-Host */
+ {
+ /*
+ The Login-IPv6-Host AVP (AVP Code 98) [RADIUSIPv6] is of type
+ OctetString and contains the IPv6 address of a host with which to
+ connect the user when the Login-Service AVP is included. It MAY be
+ used in an AA-Request command as a hint to the Diameter Server that a
+ specific host is desired, but the Diameter Server is not required to
+ honor the hint in the AA-Answer.
+
+ Two addresses have special significance:
+
+ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF and 0. The value
+ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF indicates that the NAS SHOULD
+ allow the user to select an address. The value 0 indicates that the
+ NAS SHOULD select a host to connect the user to.
+
+ */
+ struct dict_object *type;
+ unsigned char allzeros[16];
+ unsigned char allones[16];
+ struct dict_type_data tdata = { AVP_TYPE_OCTETSTRING, "Enumerated(Login-IPv6-Host)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_os( 16, &allzeros, "(0) NAS selects the host"),
+ enumval_def_os( 16, &allones , "(1) User selects the address")
+ };
+ struct dict_avp_data data = {
+ 98, /* Code */
+ 0, /* Vendor */
+ "Login-IPv6-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ int i;
+ memset(allzeros, 0, sizeof(allzeros));
+ memset(allones, 0xff, sizeof(allones));
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Login-Service */
+ {
+ /*
+ The Login-Service AVP (AVP Code 15) is of type Enumerated and
+ contains the service that should be used to connect the user to the
+ login host. This AVP SHOULD only be present in authorization
+ responses.
+
+ The supported values are listed in [RADIUSTypes].
+ Sub-registry: Values for RADIUS Attribute 15, Login-Service
+ Reference: [RFC2865]
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Login-Service)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "Telnet"),
+ enumval_def_u32( 1, "Rlogin"),
+ enumval_def_u32( 2, "TCP Clear"),
+ enumval_def_u32( 3, "PortMaster (proprietary)"),
+ enumval_def_u32( 4, "LAT"),
+ enumval_def_u32( 5, "X25-PAD"),
+ enumval_def_u32( 6, "X25-T3POS"),
+ enumval_def_u32( 8, "TCP Clear Quiet (suppresses any NAS-generated connect string)")
+ };
+ struct dict_avp_data data = {
+ 15, /* Code */
+ 0, /* Vendor */
+ "Login-Service", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+/*** TCP Services ***/
+
+ /* Login-TCP-Port */
+ {
+ /*
+ The Login-TCP-Port AVP (AVP Code 16) is of type Unsigned32 and
+ contains the TCP port with which the user is to be connected when the
+ Login-Service AVP is also present. This AVP SHOULD only be present
+ in authorization responses. The value MUST NOT be greater than
+ 65,535.
+ */
+ struct dict_avp_data data = {
+ 16, /* Code */
+ 0, /* Vendor */
+ "Login-TCP-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+/*** LAT Services ***/
+
+ /* Login-LAT-Service */
+ {
+ /*
+ The Login-LAT-Service AVP (AVP Code 34) is of type OctetString and
+ contains the system with which the user is to be connected by LAT.
+ It MAY be used in an authorization request as a hint to the server
+ that a specific service is desired, but the server is not required to
+ honor the hint in the corresponding response. This AVP MUST only be
+ present in the response if the Login-Service AVP states that LAT is
+ desired.
+
+ Administrators use this service attribute when dealing with clustered
+ systems, such as a VAX or Alpha cluster. In these environments,
+ several different time-sharing hosts share the same resources (disks,
+ printers, etc.), and administrators often configure each host to
+ offer access (service) to each of the shared resources. In this
+ case, each host in the cluster advertises its services through LAT
+ broadcasts.
+
+ Sophisticated users often know which service providers (machines) are
+ faster and tend to use a node name when initiating a LAT connection.
+ Some administrators want particular users to use certain machines as
+ a primitive form of load balancing (although LAT knows how to do load
+ balancing itself).
+
+ The String field contains the identity of the LAT service to use.
+ The LAT Architecture allows this string to contain $ (dollar), -
+ (hyphen), . (period), _ (underscore), numerics, upper- and lowercase
+ alphabetics, and the ISO Latin-1 character set extension [ISOLatin].
+ All LAT string comparisons are case insensitive.
+ */
+ struct dict_avp_data data = {
+ 34, /* Code */
+ 0, /* Vendor */
+ "Login-LAT-Service", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Login-LAT-Node */
+ {
+ /*
+ The Login-LAT-Node AVP (AVP Code 35) is of type OctetString and
+ contains the Node with which the user is to be automatically
+ connected by LAT. It MAY be used in an authorization request as a
+ hint to the server that a specific LAT node is desired, but the
+ server is not required to honor the hint in the corresponding
+ response. This AVP MUST only be present in a response if the Login-
+ Service-Type AVP is set to LAT.
+
+ The String field contains the identity of the LAT service to use.
+ The LAT Architecture allows this string to contain $ (dollar), -
+ (hyphen), . (period), _ (underscore), numerics, upper- and lowercase
+ alphabetics, and the ISO Latin-1 character set extension [ISOLatin].
+ All LAT string comparisons are case insensitive.
+ */
+ struct dict_avp_data data = {
+ 35, /* Code */
+ 0, /* Vendor */
+ "Login-LAT-Node", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Login-LAT-Group */
+ {
+ /*
+ The Login-LAT-Group AVP (AVP Code 36) is of type OctetString and
+ contains a string identifying the LAT group codes this user is
+ authorized to use. It MAY be used in an authorization request as a
+ hint to the server that a specific group is desired, but the server
+ is not required to honor the hint in the corresponding response.
+ This AVP MUST only be present in a response if the Login-Service-Type
+ AVP is set to LAT.
+
+ LAT supports 256 different group codes, which LAT uses as a form of
+ access rights. LAT encodes the group codes as a 256-bit bitmap.
+
+ Administrators can assign one or more of the group code bits at the
+ LAT service provider; it will only accept LAT connections that have
+ these group codes set in the bitmap. The administrators assign a
+ bitmap of authorized group codes to each user. LAT gets these from
+ the operating system and uses them in its requests to the service
+ providers.
+
+ The codification of the range of allowed usage of this field is
+ outside the scope of this specification.
+ */
+ struct dict_avp_data data = {
+ 36, /* Code */
+ 0, /* Vendor */
+ "Login-LAT-Group", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Login-LAT-Port */
+ {
+ /*
+ The Login-LAT-Port AVP (AVP Code 63) is of type OctetString and
+ contains the Port with which the user is to be connected by LAT. It
+ MAY be used in an authorization request as a hint to the server that
+ a specific port is desired, but the server is not required to honor
+ the hint in the corresponding response. This AVP MUST only be
+ present in a response if the Login-Service-Type AVP is set to LAT.
+
+ The String field contains the identity of the LAT service to use.
+ The LAT Architecture allows this string to contain $ (dollar), -
+ (hyphen), . (period), _ (underscore), numerics, upper- and lower-case
+ alphabetics, and the ISO Latin-1 character set extension [ISOLatin].
+ All LAT string comparisons are case insensitive.
+ */
+ struct dict_avp_data data = {
+ 63, /* Code */
+ 0, /* Vendor */
+ "Login-LAT-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+/********************************
+ * NAS Tunneling AVPs *
+ ********************************/
+ /* Tunnel-Type */
+ {
+ /*
+ The Tunnel-Type AVP (AVP Code 64) is of type Enumerated and contains
+ the tunneling protocol(s) to be used (in the case of a tunnel
+ initiator) or in use (in the case of a tunnel terminator). It MAY be
+ used in an authorization request as a hint to the server that a
+ specific tunnel type is desired, but the server is not required to
+ honor the hint in the corresponding response.
+
+ The Tunnel-Type AVP SHOULD also be included in Accounting-Request
+ messages.
+
+ A tunnel initiator is not required to implement any of these tunnel
+ types. If a tunnel initiator receives a response that contains only
+ unknown or unsupported Tunnel-Types, the tunnel initiator MUST behave
+ as though a response were received with the Result-Code indicating a
+ failure.
+
+ The supported values are listed in [RADIUSTypes].
+ Sub-registry: Values for RADIUS Attribute 64, Tunnel-Type
+ Reference: [RFC2868]
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Tunnel-Type)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 1, "Point-to-Point Tunneling Protocol (PPTP) [RFC2868]"),
+ enumval_def_u32( 2, "Layer Two Forwarding (L2F) [RFC2868]"),
+ enumval_def_u32( 3, "Layer Two Tunneling Protocol (L2TP) [RFC2868]"),
+ enumval_def_u32( 4, "Ascend Tunnel Management Protocol (ATMP) [RFC2868]"),
+ enumval_def_u32( 5, "Virtual Tunneling Protocol (VTP) [RFC2868]"),
+ enumval_def_u32( 6, "IP Authentication Header in the Tunnel-mode (AH) [RFC2868]"),
+ enumval_def_u32( 7, "IP-in-IP Encapsulation (IP-IP) [RFC2868]"),
+ enumval_def_u32( 8, "Minimal IP-in-IP Encapsulation (MIN-IP-IP) [RFC2868]"),
+ enumval_def_u32( 9, "IP Encapsulating Security Payload in the Tunnel-mode (ESP) [RFC2868]"),
+ enumval_def_u32(10, "Generic Route Encapsulation (GRE) [RFC2868]"),
+ enumval_def_u32(11, "Bay Dial Virtual Services (DVS) [RFC2868]"),
+ enumval_def_u32(12, "IP-in-IP Tunneling [RFC2868]"),
+ enumval_def_u32(13, "Virtual LANs (VLAN) [RFC3580]")
+ };
+ struct dict_avp_data adata = {
+ 64, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &adata , type, NULL);
+ }
+
+ /* Tunnel-Medium-Type */
+ {
+ /*
+ The Tunnel-Medium-Type AVP (AVP Code 65) is of type Enumerated and
+ contains the transport medium to use when creating a tunnel for
+ protocols (such as L2TP) that can operate over multiple transports.
+ It MAY be used in an authorization request as a hint to the server
+ that a specific medium is desired, but the server is not required to
+ honor the hint in the corresponding response.
+
+ The supported values are listed in [RADIUSTypes].
+ Sub-registry: Values for RADIUS Attribute 65, Tunnel-Medium-Type
+ Reference: [RFC2868]
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Tunnel-Medium-Type)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 1, "IPv4 (IP version 4) [RFC2868]"),
+ enumval_def_u32( 2, "IPv6 (IP version 6) [RFC2868]"),
+ enumval_def_u32( 3, "NSAP [RFC2868]"),
+ enumval_def_u32( 4, "HDLC (8-bit multidrop) [RFC2868]"),
+ enumval_def_u32( 5, "BBN 1822 [RFC2868]"),
+ enumval_def_u32( 6, "802 (includes all 802 media plus Ethernet \"canonical format\") [RFC2868]"),
+ enumval_def_u32( 7, "E.163 (POTS) [RFC2868]"),
+ enumval_def_u32( 8, "E.164 (SMDS, Frame Relay, ATM) [RFC2868]"),
+ enumval_def_u32( 9, "F.69 (Telex) [RFC2868]"),
+ enumval_def_u32(10, "X.121 (X.25, Frame Relay) [RFC2868]"),
+ enumval_def_u32(11, "IPX [RFC2868]"),
+ enumval_def_u32(12, "Appletalk [RFC2868]"),
+ enumval_def_u32(13, "Decnet IV [RFC2868]"),
+ enumval_def_u32(14, "Banyan Vines [RFC2868]"),
+ enumval_def_u32(15, "E.164 with NSAP format subaddress [RFC2868]")
+ };
+ struct dict_avp_data adata = {
+ 65, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Medium-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &adata , type, NULL);
+ }
+
+ /* Tunnel-Client-Endpoint */
+ {
+ /*
+ The Tunnel-Client-Endpoint AVP (AVP Code 66) is of type UTF8String
+ and contains the address of the initiator end of the tunnel. It MAY
+ be used in an authorization request as a hint to the server that a
+ specific endpoint is desired, but the server is not required to honor
+ the hint in the corresponding response.
+
+ This AVP SHOULD be included in the corresponding Accounting-Request
+ messages, in which case it indicates the address from which the
+ tunnel was initiated. This AVP, along with the Tunnel-Server-
+ Endpoint and Session-Id AVP [BASE], MAY be used to provide a globally
+ unique means to identify a tunnel for accounting and auditing
+ purposes.
+
+ If Tunnel-Medium-Type is IPv4 (1), then this string is either the
+ fully qualified domain name (FQDN) of the tunnel client machine, or a
+ "dotted-decimal" IP address. Implementations MUST support the
+ dotted-decimal format and SHOULD support the FQDN format for IP
+ addresses.
+
+ If Tunnel-Medium-Type is IPv6 (2), then this string is either the
+ FQDN of the tunnel client machine, or a text representation of the
+ address in either the preferred or alternate form [IPv6Addr].
+ Conforming implementations MUST support the preferred form and SHOULD
+ support both the alternate text form and the FQDN format for IPv6
+ addresses.
+
+ If Tunnel-Medium-Type is neither IPv4 nor IPv6, then this string is a
+ tag referring to configuration data local to the Diameter client that
+ describes the interface or medium-specific client address to use.
+ */
+ struct dict_avp_data adata = {
+ 66, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Client-Endpoint", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , UTF8String_type, NULL);
+ }
+
+ /* Tunnel-Server-Endpoint */
+ {
+ /*
+ The Tunnel-Server-Endpoint AVP (AVP Code 67) is of type UTF8String
+ and contains the address of the server end of the tunnel. It MAY be
+ used in an authorization request as a hint to the server that a
+ specific endpoint is desired, but the server is not required to honor
+ the hint in the corresponding response.
+
+ This AVP SHOULD be included in the corresponding Accounting-Request
+ messages, in which case it indicates the address from which the
+ tunnel was initiated. This AVP, along with the Tunnel-Client-
+ Endpoint and Session-Id AVP [BASE], MAY be used to provide a globally
+ unique means to identify a tunnel for accounting and auditing
+ purposes.
+
+ If Tunnel-Medium-Type is IPv4 (1), then this string is either the
+ fully qualified domain name (FQDN) of the tunnel server machine, or a
+ "dotted-decimal" IP address. Implementations MUST support the
+ dotted-decimal format and SHOULD support the FQDN format for IP
+ addresses.
+
+ If Tunnel-Medium-Type is IPv6 (2), then this string is either the
+ FQDN of the tunnel server machine, or a text representation of the
+ address in either the preferred or alternate form [IPv6Addr].
+ Implementations MUST support the preferred form and SHOULD support
+ both the alternate text form and the FQDN format for IPv6 addresses.
+
+ If Tunnel-Medium-Type is not IPv4 or IPv6, this string is a tag
+ referring to configuration data local to the Diameter client that
+ describes the interface or medium-specific server address to use.
+ */
+ struct dict_avp_data adata = {
+ 67, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Server-Endpoint", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , UTF8String_type, NULL);
+ }
+
+ /* Tunnel-Password */
+ {
+ /*
+ The Tunnel-Password AVP (AVP Code 69) is of type OctetString and may
+ contain a password to be used to authenticate to a remote server.
+ The Tunnel-Password AVP contains sensitive information. This value
+ is not protected in the same manner as RADIUS [RADTunnels].
+
+ As required in [BASE], Diameter messages are encrypted by using IPsec
+ or TLS. The Tunnel-Password AVP SHOULD NOT be used in untrusted
+ proxy environments without encrypting it by using end-to-end security
+ techniques, such as CMS Security [DiamCMS].
+ */
+ struct dict_avp_data adata = {
+ 69, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Password", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , NULL, NULL);
+ }
+
+ /* Tunnel-Private-Group-Id */
+ {
+ /*
+ The Tunnel-Private-Group-Id AVP (AVP Code 81) is of type OctetString
+ and contains the group Id for a particular tunneled session. The
+ Tunnel-Private-Group-Id AVP MAY be included in an authorization
+ request if the tunnel initiator can predetermine the group resulting
+ from a particular connection. It SHOULD be included in the
+ authorization response if this tunnel session is to be treated as
+ belonging to a particular private group. Private groups may be used
+ to associate a tunneled session with a particular group of users.
+ For example, it MAY be used to facilitate routing of unregistered IP
+ addresses through a particular interface. This AVP SHOULD be
+ included in the Accounting-Request messages that pertain to the
+ tunneled session.
+ */
+ struct dict_avp_data adata = {
+ 81, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Private-Group-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , NULL, NULL);
+ }
+
+ /* Tunnel-Assignment-Id */
+ {
+ /*
+ The Tunnel-Assignment-Id AVP (AVP Code 82) is of type OctetString and
+ is used to indicate to the tunnel initiator the particular tunnel to
+ which a session is to be assigned. Some tunneling protocols, such as
+ [PPTP] and [L2TP], allow for sessions between the same two tunnel
+ endpoints to be multiplexed over the same tunnel and also for a given
+ session to use its own dedicated tunnel. This attribute provides a
+ mechanism for Diameter to inform the tunnel initiator (e.g., PAC,
+ LAC) whether to assign the session to a multiplexed tunnel or to a
+ separate tunnel. Furthermore, it allows for sessions sharing
+ multiplexed tunnels to be assigned to different multiplexed tunnels.
+
+ A particular tunneling implementation may assign differing
+ characteristics to particular tunnels. For example, different
+ tunnels may be assigned different QoS parameters. Such tunnels may
+ be used to carry either individual or multiple sessions. The
+ Tunnel-Assignment-Id attribute thus allows the Diameter server to
+ indicate that a particular session is to be assigned to a tunnel
+ providing an appropriate level of service. It is expected that any
+ QoS-related Diameter tunneling attributes defined in the future
+ accompanying this one will be associated by the tunnel initiator with
+ the Id given by this attribute. In the meantime, any semantic given
+ to a particular Id string is a matter left to local configuration in
+ the tunnel initiator.
+
+ The Tunnel-Assignment-Id AVP is of significance only to Diameter and
+ the tunnel initiator. The Id it specifies is only intended to be of
+ local use to Diameter and the tunnel initiator. The Id assigned by
+ the tunnel initiator is not conveyed to the tunnel peer.
+
+ This attribute MAY be included in authorization responses. The
+ tunnel initiator receiving this attribute MAY choose to ignore it and
+ to assign the session to an arbitrary multiplexed or non-multiplexed
+ tunnel between the desired endpoints. This AVP SHOULD also be
+ included in the Accounting-Request messages pertaining to the
+ tunneled session.
+
+ If a tunnel initiator supports the Tunnel-Assignment-Id AVP, then it
+ should assign a session to a tunnel in the following manner:
+
+ - If this AVP is present and a tunnel exists between the
+ specified endpoints with the specified Id, then the session
+ should be assigned to that tunnel.
+
+ - If this AVP is present and no tunnel exists between the
+ specified endpoints with the specified Id, then a new tunnel
+ should be established for the session and the specified Id
+ should be associated with the new tunnel.
+
+ - If this AVP is not present, then the session is assigned to an
+ unnamed tunnel. If an unnamed tunnel does not yet exist
+ between the specified endpoints, then it is established and
+ used for this session and for subsequent ones established
+ without the Tunnel-Assignment-Id attribute. A tunnel initiator
+ MUST NOT assign a session for which a Tunnel-Assignment-Id AVP
+ was not specified to a named tunnel (i.e., one that was
+ initiated by a session specifying this AVP).
+
+ Note that the same Id may be used to name different tunnels if these
+ tunnels are between different endpoints.
+
+ */
+ struct dict_avp_data adata = {
+ 82, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Assignment-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , NULL, NULL);
+ }
+
+ /* Tunnel-Preference */
+ {
+ /*
+ The Tunnel-Preference AVP (AVP Code 83) is of type Unsigned32 and is
+ used to identify the relative preference assigned to each tunnel when
+ more than one set of tunneling AVPs is returned within separate
+ Grouped-AVP AVPs. It MAY be used in an authorization request as a
+ hint to the server that a specific preference is desired, but the
+ server is not required to honor the hint in the corresponding
+ response.
+
+ For example, suppose that AVPs describing two tunnels are returned by
+ the server, one with a Tunnel-Type of PPTP and the other with a
+ Tunnel-Type of L2TP. If the tunnel initiator supports only one of
+ the Tunnel-Types returned, it will initiate a tunnel of that type.
+ If, however, it supports both tunnel protocols, it SHOULD use the
+ value of the Tunnel-Preference AVP to decide which tunnel should be
+ started. The tunnel with the lowest numerical value in the Value
+ field of this AVP SHOULD be given the highest preference. The values
+ assigned to two or more instances of the Tunnel-Preference AVP within
+ a given authorization response MAY be identical. In this case, the
+ tunnel initiator SHOULD use locally configured metrics to decide
+ which set of AVPs to use.
+ */
+ struct dict_avp_data adata = {
+ 83, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Preference", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , NULL, NULL);
+ }
+
+ /* Tunnel-Client-Auth-Id */
+ {
+ /*
+ The Tunnel-Client-Auth-Id AVP (AVP Code 90) is of type UTF8String and
+ specifies the name used by the tunnel initiator during the
+ authentication phase of tunnel establishment. It MAY be used in an
+ authorization request as a hint to the server that a specific
+ preference is desired, but the server is not required to honor the
+ hint in the corresponding response. This AVP MUST be present in the
+ authorization response if an authentication name other than the
+ default is desired. This AVP SHOULD be included in the Accounting-
+ Request messages pertaining to the tunneled session.
+ */
+ struct dict_avp_data adata = {
+ 90, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Client-Auth-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , UTF8String_type, NULL);
+ }
+
+ /* Tunnel-Server-Auth-Id */
+ {
+ /*
+ The Tunnel-Server-Auth-Id AVP (AVP Code 91) is of type UTF8String and
+ specifies the name used by the tunnel terminator during the
+ authentication phase of tunnel establishment. It MAY be used in an
+ authorization request as a hint to the server that a specific
+ preference is desired, but the server is not required to honor the
+ hint in the corresponding response. This AVP MUST be present in the
+ authorization response if an authentication name other than the
+ default is desired. This AVP SHOULD be included in the Accounting-
+ Request messages pertaining to the tunneled session.
+ */
+ struct dict_avp_data adata = {
+ 91, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Server-Auth-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &adata , UTF8String_type, NULL);
+ }
+
+ /* Tunneling */
+ {
+ /*
+ The Tunneling AVP (AVP Code 401) is of type Grouped and contains the
+ following AVPs, used to describe a compulsory tunnel service:
+ [RADTunnels], [RADTunlAcct]. Its data field has the following ABNF
+ grammar:
+
+ Tunneling ::= < AVP Header: 401 >
+ { Tunnel-Type }
+ { Tunnel-Medium-Type }
+ { Tunnel-Client-Endpoint }
+ { Tunnel-Server-Endpoint }
+ [ Tunnel-Preference ]
+ [ Tunnel-Client-Auth-Id ]
+ [ Tunnel-Server-Auth-Id ]
+ [ Tunnel-Assignment-Id ]
+ [ Tunnel-Password ]
+ [ Tunnel-Private-Group-Id ]
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 401, /* Code */
+ 0, /* Vendor */
+ "Tunneling", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "Tunnel-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "Tunnel-Medium-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunnel-Client-Endpoint", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunnel-Server-Endpoint", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunnel-Preference", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunnel-Client-Auth-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunnel-Server-Auth-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunnel-Assignment-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunnel-Password", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunnel-Private-Group-Id", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+/********************************
+ * NAS Accounting AVPs *
+ ********************************/
+ /* Accounting-Input-Octets */
+ {
+ /*
+ The Accounting-Input-Octets AVP (AVP Code 363) is of type Unsigned64
+ and contains the number of octets received from the user.
+
+ For NAS usage, this AVP indicates how many octets have been received
+ from the port in the course of this session. It can only be present
+ in ACR messages with an Accounting-Record-Type of INTERIM_RECORD or
+ STOP_RECORD.
+ */
+ struct dict_avp_data data = {
+ 363, /* Code */
+ 0, /* Vendor */
+ "Accounting-Input-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-Output-Octets */
+ {
+ /*
+ The Accounting-Output-Octets AVP (AVP Code 364) is of type Unsigned64
+ and contains the number of octets sent to the user.
+
+ For NAS usage, this AVP indicates how many octets have been sent to
+ the port in the course of this session. It can only be present in
+ ACR messages with an Accounting-Record-Type of INTERIM_RECORD or
+ STOP_RECORD.
+ */
+ struct dict_avp_data data = {
+ 364, /* Code */
+ 0, /* Vendor */
+ "Accounting-Output-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-Input-Packets */
+ {
+ /*
+ The Accounting-Input-Packets (AVP Code 365) is of type Unsigned64 and
+ contains the number of packets received from the user.
+
+ For NAS usage, this AVP indicates how many packets have been received
+ from the port over the course of a session being provided to a Framed
+ User. It can only be present in ACR messages with an Accounting-
+ Record-Type of INTERIM_RECORD or STOP_RECORD.
+ */
+ struct dict_avp_data data = {
+ 365, /* Code */
+ 0, /* Vendor */
+ "Accounting-Input-Packets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Accounting-Output-Packets */
+ {
+ /*
+ The Accounting-Output-Packets (AVP Code 366) is of type Unsigned64
+ and contains the number of IP packets sent to the user.
+
+ For NAS usage, this AVP indicates how many packets have been sent to
+ the port over the course of a session being provided to a Framed
+ User. It can only be present in ACR messages with an Accounting-
+ Record-Type of INTERIM_RECORD or STOP_RECORD.
+ */
+ struct dict_avp_data data = {
+ 366, /* Code */
+ 0, /* Vendor */
+ "Accounting-Output-Packets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Acct-Session-Time */
+ {
+ /*
+ The Acct-Session-Time AVP (AVP Code 46) is of type Unsigned32 and
+ indicates the length of the current session in seconds. It can only
+ be present in ACR messages with an Accounting-Record-Type of
+ INTERIM_RECORD or STOP_RECORD.
+ */
+ struct dict_avp_data data = {
+ 46, /* Code */
+ 0, /* Vendor */
+ "Acct-Session-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Acct-Authentic */
+ {
+ /*
+ The Acct-Authentic AVP (AVP Code 45) is of type Enumerated and
+ specifies how the user was authenticated. The supported values are
+ listed in [RADIUSTypes].
+ Sub-registry: Values for RADIUS Attribute 45, Acct-Authentic
+ Reference: [RFC2866]
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Acct-Authentic)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 1, "RADIUS"),
+ enumval_def_u32( 2, "Local"),
+ enumval_def_u32( 3, "Remote"),
+ enumval_def_u32( 4, "Diameter")
+ };
+ struct dict_avp_data data = {
+ 45, /* Code */
+ 0, /* Vendor */
+ "Acct-Authentic", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Accounting-Auth-Method */
+ {
+ /*
+ The Accounting-Auth-Method AVP (AVP Code 406) is of type Enumerated.
+ A NAS MAY include this AVP in an Accounting-Request message to
+ indicate the method used to authenticate the user. (Note that this
+ is equivalent to the RADIUS MS-Acct-Auth-Type VSA attribute).
+
+ The following values are defined:
+
+ 1 PAP
+ 2 CHAP
+ 3 MS-CHAP-1
+ 4 MS-CHAP-2
+ 5 EAP
+ 7 None
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Accounting-Auth-Method)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 1, "PAP"),
+ enumval_def_u32( 2, "CHAP"),
+ enumval_def_u32( 3, "MS-CHAP-1"),
+ enumval_def_u32( 4, "MS-CHAP-2"),
+ enumval_def_u32( 5, "EAP"),
+ enumval_def_u32( 7, "None")
+ };
+ struct dict_avp_data data = {
+ 406, /* Code */
+ 0, /* Vendor */
+ "Accounting-Auth-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* Acct-Delay-Time */
+ {
+ /*
+ The Acct-Delay-Time AVP (AVP Code 41) is of type Unsigned32 and
+ indicates the number of seconds the Diameter client has been trying
+ to send the Accounting-Request (ACR). The accounting server may
+ subtract this value from the time when the ACR arrives at the server
+ to calculate the approximate time of the event that caused the ACR to
+ be generated.
+
+ This AVP is not used for retransmissions at the transport level (TCP
+ or SCTP). Rather, it may be used when an ACR command cannot be
+ transmitted because there is no appropriate peer to transmit it to or
+ was rejected because it could not be delivered. In these cases, the
+ command MAY be buffered and transmitted later, when an appropriate
+ peer-connection is available or after sufficient time has passed that
+ the destination-host may be reachable and operational. If the ACR is
+ resent in this way, the Acct-Delay-Time AVP SHOULD be included. The
+ value of this AVP indicates the number of seconds that elapsed
+ between the time of the first attempt at transmission and the current
+ attempt.
+ */
+ struct dict_avp_data data = {
+ 41, /* Code */
+ 0, /* Vendor */
+ "Acct-Delay-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Acct-Link-Count */
+ {
+ /*
+ The Acct-Link-Count AVP (AVP Code 51) is of type Unsigned32 and
+ indicates the total number of links that have been active (current or
+ closed) in a given multilink session at the time the accounting
+ record is generated. This AVP MAY be included in Accounting-Requests
+ for any session that may be part of a multilink service.
+
+ The Acct-Link-Count AVP may be used to make it easier for an
+ accounting server to know when it has all the records for a given
+ multilink service. When the number of Accounting-Requests received
+ with Accounting-Record-Type = STOP_RECORD and with the same Acct-
+ Multi-Session-Id and unique Session-Ids equals the largest value of
+ Acct-Link-Count seen in those Accounting-Requests, all STOP_RECORD
+ Accounting-Requests for that multilink service have been received.
+
+ The following example, showing eight Accounting-Requests, illustrates
+ how the Acct-Link-Count AVP is used. In the table below, only the
+ relevant AVPs are shown, although additional AVPs containing
+ accounting information will be present in the Accounting-Requests.
+
+ Acct-Multi- Accounting- Acct-
+ Session-Id Session-Id Record-Type Link-Count
+ --------------------------------------------------------
+ "...10" "...10" START_RECORD 1
+ "...10" "...11" START_RECORD 2
+ "...10" "...11" STOP_RECORD 2
+ "...10" "...12" START_RECORD 3
+ "...10" "...13" START_RECORD 4
+ "...10" "...12" STOP_RECORD 4
+ "...10" "...13" STOP_RECORD 4
+ "...10" "...10" STOP_RECORD 4
+
+ */
+ struct dict_avp_data data = {
+ 51, /* Code */
+ 0, /* Vendor */
+ "Acct-Link-Count", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Acct-Tunnel-Connection */
+ {
+ /*
+ The Acct-Tunnel-Connection AVP (AVP Code 68) is of type OctetString
+ and contains the identifier assigned to the tunnel session. This
+ AVP, along with the Tunnel-Client-Endpoint and Tunnel-Server-Endpoint
+ AVPs, may be used to provide a means to uniquely identify a tunnel
+ session for auditing purposes.
+
+ The format of the identifier in this AVP depends upon the value of
+ the Tunnel-Type AVP. For example, to identify an L2TP tunnel
+ connection fully, the L2TP Tunnel Id and Call Id might be encoded in
+ this field. The exact encoding of this field is implementation
+ dependent.
+ */
+ struct dict_avp_data data = {
+ 68, /* Code */
+ 0, /* Vendor */
+ "Acct-Tunnel-Connection", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Acct-Tunnel-Packets-Lost */
+ {
+ /*
+ The Acct-Tunnel-Packets-Lost AVP (AVP Code 86) is of type Unsigned32
+ and contains the number of packets lost on a given link.
+ */
+ struct dict_avp_data data = {
+ 86, /* Code */
+ 0, /* Vendor */
+ "Acct-Tunnel-Packets-Lost", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+/***********************************
+ * Compatibility with RADIUS AVPs *
+ ***********************************/
+ /* NAS-Identifier */
+ {
+ /*
+ The NAS-Identifier AVP (AVP Code 32) [RADIUS] is of type UTF8String
+ and contains the identity of the NAS providing service to the user.
+ This AVP SHOULD only be added by a RADIUS/Diameter Translation Agent.
+ When this AVP is present, the Origin-Host AVP identifies the NAS
+ providing service to the user.
+
+ In RADIUS it would be possible for a rogue NAS to forge the NAS-
+ Identifier attribute. Diameter/RADIUS translation agents SHOULD
+ attempt to check a received NAS-Identifier attribute against the
+ source address of the RADIUS packet, by doing an A/AAAA RR query. If
+ the NAS-Identifier attribute contains an FQDN, then such a query
+ would resolve to an IP address matching the source address. However,
+ the NAS-Identifier attribute is not required to contain an FQDN, so
+ such a query could fail. If it fails, an error should be logged, but
+ no action should be taken, other than a reverse lookup on the source
+ address and insert the resulting FQDN into the Route-Record AVP.
+
+ Diameter agents and servers SHOULD check whether a NAS-Identifier AVP
+ corresponds to an entry in the Route-Record AVP. If no match is
+ found, then an error is logged, but no other action is taken.
+ */
+ struct dict_avp_data data = {
+ 32, /* Code */
+ 0, /* Vendor */
+ "NAS-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* NAS-IP-Address */
+ {
+ /*
+ The NAS-IP-Address AVP (AVP Code 4) [RADIUS] is of type OctetString
+ and contains the IP Address of the NAS providing service to the user.
+ This AVP SHOULD only be added by a RADIUS/Diameter Translation Agent.
+ When this AVP is present, the Origin-Host AVP identifies the NAS
+ providing service to the user.
+
+ In RADIUS it would be possible for a rogue NAS to forge the NAS-IP-
+ Address attribute value. Diameter/RADIUS translation agents MUST
+ check a received NAS-IP-Address or NAS-IPv6-Address attribute against
+ the source address of the RADIUS packet. If they do not match and
+ the Diameter/RADIUS translation agent does not know whether the
+ packet was sent by a RADIUS proxy or NAS (e.g., no Proxy-State
+ attribute), then by default it is assumed that the source address
+ corresponds to a RADIUS proxy, and that the NAS Address is behind
+ that proxy, potentially with some additional RADIUS proxies in
+ between. The Diameter/RADIUS translation agent MUST insert entries
+ in the Route-Record AVP corresponding to the apparent route. This
+ implies doing a reverse lookup on the source address and NAS-IP-
+ Address or NAS-IPv6-Address attributes to determine the corresponding
+ FQDNs.
+
+ If the source address and the NAS-IP-Address or NAS-IPv6-Address do
+ not match, and the Diameter/RADIUS translation agent knows that it is
+ talking directly to the NAS (e.g., there are no RADIUS proxies
+ between it and the NAS), then the error should be logged, and the
+ packet MUST be discarded.
+
+ Diameter agents and servers MUST check whether the NAS-IP-Address AVP
+ corresponds to an entry in the Route-Record AVP. This is done by
+ doing a reverse lookup (PTR RR) for the NAS-IP-Address to retrieve
+ the corresponding FQDN, and by checking for a match with the Route-
+ Record AVP. If no match is found, then an error is logged, but no
+ other action is taken.
+ */
+ struct dict_avp_data data = {
+ 4, /* Code */
+ 0, /* Vendor */
+ "NAS-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* NAS-IPv6-Address */
+ {
+ /*
+ The NAS-IPv6-Address AVP (AVP Code 95) [RADIUSIPv6] is of type
+ OctetString and contains the IPv6 Address of the NAS providing
+ service to the user. This AVP SHOULD only be added by a
+ RADIUS/Diameter Translation Agent. When this AVP is present, the
+ Origin-Host AVP identifies the NAS providing service to the user.
+
+ In RADIUS it would be possible for a rogue NAS to forge the NAS-
+ IPv6-Address attribute. Diameter/RADIUS translation agents MUST
+ check a received NAS-IPv6-Address attribute against the source
+ address of the RADIUS packet. If they do not match and the
+ Diameter/RADIUS translation agent does not know whether the packet
+ was sent by a RADIUS proxy or NAS (e.g., no Proxy-State attribute),
+ then by default it is assumed that the source address corresponds to
+ a RADIUS proxy, and that the NAS-IPv6-Address is behind that proxy,
+ potentially with some additional RADIUS proxies in between. The
+ Diameter/RADIUS translation agent MUST insert entries in the Route-
+ Record AVP corresponding to the apparent route. This implies doing a
+ reverse lookup on the source address and NAS-IPv6-Address attributes
+ to determine the corresponding FQDNs.
+
+ If the source address and the NAS-IPv6-Address do not match, and the
+ Diameter/RADIUS translation agent knows that it is talking directly
+ to the NAS (e.g., there are no RADIUS proxies between it and the
+ NAS), then the error should be logged, and the packet MUST be
+ discarded.
+
+ Diameter agents and servers MUST check whether the NAS-IPv6-Address
+ AVP corresponds to an entry in the Route-Record AVP. This is done by
+ doing a reverse lookup (PTR RR) for the NAS-IPv6-Address to retrieve
+ the corresponding FQDN, and by checking for a match with the Record-
+ Route AVP. If no match is found, then an error is logged, but no
+ other action is taken.
+ */
+ struct dict_avp_data data = {
+ 95, /* Code */
+ 0, /* Vendor */
+ "NAS-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* State */
+ {
+ /*
+ The State AVP (AVP Code 24) [RADIUS] is of type OctetString and has
+ two uses in the Diameter NAS application.
+
+ The State AVP MAY be sent by a Diameter Server to a NAS in an AA-
+ Response command that contains a Result-Code of
+ DIAMETER_MULTI_ROUND_AUTH. If so, the NAS MUST return it unmodified
+ in the subsequent AA-Request command.
+
+ The State AVP MAY also be sent by a Diameter Server to a NAS in an
+ AA-Response command that also includes a Termination-Action AVP with
+ the value of AA-REQUEST. If the NAS performs the Termination-Action
+ by sending a new AA-Request command upon termination of the current
+ service, it MUST return the State AVP unmodified in the new request
+ command.
+
+ In either usage, the NAS MUST NOT interpret the AVP locally. Usage
+ of the State AVP is implementation dependent.
+ */
+ struct dict_avp_data data = {
+ 24, /* Code */
+ 0, /* Vendor */
+ "State", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* Termination-Cause mapping */
+ {
+
+ struct dict_object *type;
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32(11, "[RADIUS] User Request"),
+ enumval_def_u32(12, "[RADIUS] Lost Carrier"),
+ enumval_def_u32(13, "[RADIUS] Lost Service"),
+ enumval_def_u32(14, "[RADIUS] Idle Timeout"),
+ enumval_def_u32(15, "[RADIUS] Session Timeout"),
+ enumval_def_u32(16, "[RADIUS] Admin Reset"),
+ enumval_def_u32(17, "[RADIUS] Admin Reboot"),
+ enumval_def_u32(18, "[RADIUS] Port Error"),
+ enumval_def_u32(19, "[RADIUS] NAS Error"),
+ enumval_def_u32(20, "[RADIUS] NAS Request"),
+ enumval_def_u32(21, "[RADIUS] NAS Reboot"),
+ enumval_def_u32(22, "[RADIUS] Port Unneeded"),
+ enumval_def_u32(23, "[RADIUS] Port Preempted"),
+ enumval_def_u32(24, "[RADIUS] Port Suspended"),
+ enumval_def_u32(25, "[RADIUS] Service Unavailable"),
+ enumval_def_u32(26, "[RADIUS] Callback"),
+ enumval_def_u32(27, "[RADIUS] User Error"),
+ enumval_def_u32(28, "[RADIUS] Host Request"),
+ enumval_def_u32(29, "[RADIUS] Supplicant Restart"),
+ enumval_def_u32(30, "[RADIUS] Reauthentication Failure"),
+ enumval_def_u32(31, "[RADIUS] Port Reinit"),
+ enumval_def_u32(32, "[RADIUS] Port Disabled")
+ };
+ int i;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Enumerated(Termination-Cause)", &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+
+ }
+
+ /* Origin-AAA-Protocol */
+ {
+ /*
+ The Origin-AAA-Protocol AVP (AVP Code 408) is of the type Enumerated
+ and should be inserted in a Diameter message translated by a gateway
+ system from another AAA protocol, such as RADIUS. It identifies the
+ source protocol of the message to the Diameter system receiving the
+ message.
+
+ The supported values are:
+
+ 1 RADIUS
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(Origin-AAA-Protocol)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 1, "RADIUS")
+ };
+ struct dict_avp_data data = {
+ 408, /* Code */
+ 0, /* Vendor */
+ "Origin-AAA-Protocol", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ }
+
+/********************/
+/* Commands section */
+/********************/
+ {
+ /* To avoid defining global variables for all the AVP that we use here, we do search the dictionary in each sub-block.
+ * This is far from optimal, but the code is clearer like this, and the time it requires at execution is not noticeable.
+ */
+
+ /* AA-Request (AAR) Command */
+ {
+ /*
+ The AA-Request (AAR), which is indicated by setting the Command-Code
+ field to 265 and the 'R' bit in the Command Flags field, is used to
+ request authentication and/or authorization for a given NAS user.
+ The type of request is identified through the Auth-Request-Type AVP
+ [BASE]. The recommended value for most RADIUS interoperabily
+ situations is AUTHORIZE_AUTHENTICATE.
+
+ If Authentication is requested, the User-Name attribute SHOULD be
+ present, as well as any additional authentication AVPs that would
+ carry the password information. A request for authorization SHOULD
+ only include the information from which the authorization will be
+ performed, such as the User-Name, Called-Station-Id, or Calling-
+ Station-Id AVPs. All requests SHOULD contain AVPs uniquely
+ identifying the source of the call, such as Origin-Host and NAS-Port.
+ Certain networks MAY use different AVPs for authorization purposes.
+ A request for authorization will include some AVPs defined in section
+ 6.
+
+ It is possible for a single session to be authorized first and then
+ for an authentication request to follow.
+
+ This AA-Request message MAY be the result of a multi-round
+ authentication exchange, which occurs when the AA-Answer message is
+ received with the Result-Code AVP set to DIAMETER_MULTI_ROUND_AUTH.
+ A subsequent AAR message SHOULD be sent, with the User-Password AVP
+ that includes the user's response to the prompt, and MUST include any
+ State AVPs that were present in the AAA message.
+
+ Message Format
+ <AA-Request> ::= < Diameter Header: 265, REQ, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { Auth-Request-Type }
+ [ Destination-Host ]
+ [ NAS-Identifier ]
+ [ NAS-IP-Address ]
+ [ NAS-IPv6-Address ]
+ [ NAS-Port ]
+ [ NAS-Port-Id ]
+ [ NAS-Port-Type ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ [ Port-Limit ]
+ [ User-Name ]
+ [ User-Password ]
+ [ Service-Type ]
+ [ State ]
+ [ Authorization-Lifetime ]
+ [ Auth-Grace-Period ]
+ [ Auth-Session-State ]
+ [ Callback-Number ]
+ [ Called-Station-Id ]
+ [ Calling-Station-Id ]
+ [ Originating-Line-Info ]
+ [ Connect-Info ]
+ [ CHAP-Auth ]
+ [ CHAP-Challenge ]
+ * [ Framed-Compression ]
+ [ Framed-Interface-Id ]
+ [ Framed-IP-Address ]
+ * [ Framed-IPv6-Prefix ]
+ [ Framed-IP-Netmask ]
+ [ Framed-MTU ]
+ [ Framed-Protocol ]
+ [ ARAP-Password ]
+ [ ARAP-Security ]
+ * [ ARAP-Security-Data ]
+ * [ Login-IP-Host ]
+ * [ Login-IPv6-Host ]
+ [ Login-LAT-Group ]
+ [ Login-LAT-Node ]
+ [ Login-LAT-Port ]
+ [ Login-LAT-Service ]
+ * [ Tunneling ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 265, /* Code */
+ "AA-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Request-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Identifier", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IPv6-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Port-Limit", RULE_OPTIONAL, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "User-Password", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Session-State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Callback-Number", RULE_OPTIONAL, -1, 1 }
+ ,{ "Called-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Calling-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Originating-Line-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "Connect-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "CHAP-Auth", RULE_OPTIONAL, -1, 1 }
+ ,{ "CHAP-Challenge", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Compression", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-Interface-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Prefix", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-IP-Netmask", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-MTU", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "ARAP-Password", RULE_OPTIONAL, -1, 1 }
+ ,{ "ARAP-Security", RULE_OPTIONAL, -1, 1 }
+ ,{ "ARAP-Security-Data", RULE_OPTIONAL, -1,-1 }
+ ,{ "Login-IP-Host", RULE_OPTIONAL, -1,-1 }
+ ,{ "Login-IPv6-Host", RULE_OPTIONAL, -1,-1 }
+ ,{ "Login-LAT-Group", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-LAT-Node", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-LAT-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-LAT-Service", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunneling", RULE_OPTIONAL, -1,-1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1,-1 }
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , nasreq, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* AA-Answer (AAA) Command */
+ {
+ /*
+ The AA-Answer (AAA) message is indicated by setting the Command-Code
+ field to 265 and clearing the 'R' bit in the Command Flags field. It
+ is sent in response to the AA-Request (AAR) message. If
+ authorization was requested, a successful response will include the
+ authorization AVPs appropriate for the service being provided, as
+ defined in section 6.
+
+ For authentication exchanges requiring more than a single round trip,
+ the server MUST set the Result-Code AVP to DIAMETER_MULTI_ROUND_AUTH.
+ An AAA message with this result code MAY include one Reply-Message or
+ more and MAY include zero or one State AVPs.
+
+ If the Reply-Message AVP was present, the network access server
+ SHOULD send the text to the user's client to display to the user,
+ instructing the client to prompt the user for a response. For
+ example, this capability can be achieved in PPP via PAP. If the
+ access client is unable to prompt the user for a new response, it
+ MUST treat the AA-Answer (AAA) with the Reply-Message AVP as an error
+ and deny access.
+
+ Message Format
+
+ <AA-Answer> ::= < Diameter Header: 265, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Auth-Request-Type }
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ [ User-Name ]
+ [ Service-Type ]
+ * [ Class ]
+ * [ Configuration-Token ]
+ [ Acct-Interim-Interval ]
+ [ Error-Message ]
+ [ Error-Reporting-Host ]
+ * [ Failed-AVP ]
+ [ Idle-Timeout ]
+ [ Authorization-Lifetime ]
+ [ Auth-Grace-Period ]
+ [ Auth-Session-State ]
+ [ Re-Auth-Request-Type ]
+ [ Multi-Round-Time-Out ]
+ [ Session-Timeout ]
+ [ State ]
+ * [ Reply-Message ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ * [ Filter-Id ]
+ [ Password-Retry ]
+ [ Port-Limit ]
+ [ Prompt ]
+ [ ARAP-Challenge-Response ]
+ [ ARAP-Features ]
+ [ ARAP-Security ]
+ * [ ARAP-Security-Data ]
+ [ ARAP-Zone-Access ]
+ [ Callback-Id ]
+ [ Callback-Number ]
+ [ Framed-Appletalk-Link ]
+ * [ Framed-Appletalk-Network ]
+ [ Framed-Appletalk-Zone ]
+ * [ Framed-Compression ]
+ [ Framed-Interface-Id ]
+ [ Framed-IP-Address ]
+ * [ Framed-IPv6-Prefix ]
+ [ Framed-IPv6-Pool ]
+ * [ Framed-IPv6-Route ]
+ [ Framed-IP-Netmask ]
+ * [ Framed-Route ]
+ [ Framed-Pool ]
+ [ Framed-IPX-Network ]
+ [ Framed-MTU ]
+ [ Framed-Protocol ]
+ [ Framed-Routing ]
+ * [ Login-IP-Host ]
+ * [ Login-IPv6-Host ]
+ [ Login-LAT-Group ]
+ [ Login-LAT-Node ]
+ [ Login-LAT-Port ]
+ [ Login-LAT-Service ]
+ [ Login-Service ]
+ [ Login-TCP-Port ]
+ * [ NAS-Filter-Rule ]
+ * [ QoS-Filter-Rule ]
+ * [ Tunneling ]
+ * [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 265, /* Code */
+ "AA-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Request-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Class", RULE_OPTIONAL, -1,-1 }
+ ,{ "Configuration-Token", RULE_OPTIONAL, -1,-1 }
+ ,{ "Acct-Interim-Interval", RULE_OPTIONAL, -1, 1 }
+ ,{ "Error-Message", RULE_OPTIONAL, -1, 1 }
+ ,{ "Error-Reporting-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Failed-AVP", RULE_OPTIONAL, -1,-1 }
+ ,{ "Idle-Timeout", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Session-State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Re-Auth-Request-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Multi-Round-Time-Out", RULE_OPTIONAL, -1, 1 }
+ ,{ "Session-Timeout", RULE_OPTIONAL, -1, 1 }
+ ,{ "State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Reply-Message", RULE_OPTIONAL, -1,-1 }
+ ,{ "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "Origin-State-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Filter-Id", RULE_OPTIONAL, -1,-1 }
+ ,{ "Password-Retry", RULE_OPTIONAL, -1, 1 }
+ ,{ "Port-Limit", RULE_OPTIONAL, -1, 1 }
+ ,{ "Prompt", RULE_OPTIONAL, -1, 1 }
+ ,{ "ARAP-Challenge-Response", RULE_OPTIONAL, -1, 1 }
+ ,{ "ARAP-Features", RULE_OPTIONAL, -1, 1 }
+ ,{ "ARAP-Security", RULE_OPTIONAL, -1, 1 }
+ ,{ "ARAP-Security-Data", RULE_OPTIONAL, -1,-1 }
+ ,{ "ARAP-Zone-Access", RULE_OPTIONAL, -1, 1 }
+ ,{ "Callback-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Callback-Number", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-AppleTalk-Link", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-AppleTalk-Network", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-AppleTalk-Zone", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Compression", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-Interface-Id", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Prefix", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-IPv6-Pool", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Route", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-IP-Netmask", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-Route", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-Pool", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPX-Network", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-MTU", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Routing", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-IP-Host", RULE_OPTIONAL, -1,-1 }
+ ,{ "Login-IPv6-Host", RULE_OPTIONAL, -1,-1 }
+ ,{ "Login-LAT-Group", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-LAT-Node", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-LAT-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-LAT-Service", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-Service", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-TCP-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Filter-Rule", RULE_OPTIONAL, -1,-1 }
+ ,{ "QoS-Filter-Rule", RULE_OPTIONAL, -1,-1 }
+ ,{ "Tunneling", RULE_OPTIONAL, -1,-1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1,-1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1,-1 }
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , nasreq, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Re-Auth-Request */
+ {
+ /*
+ Add additional rules of the ABNF (compared to Base definition):
+
+ <RA-Request> ::= < Diameter Header: 258, REQ, PXY >
+ < Session-Id >
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { Destination-Host }
+ { Auth-Application-Id }
+ { Re-Auth-Request-Type }
+ [ User-Name ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ [ NAS-Identifier ]
+ [ NAS-IP-Address ]
+ [ NAS-IPv6-Address ]
+ [ NAS-Port ]
+ [ NAS-Port-Id ]
+ [ NAS-Port-Type ]
+ [ Service-Type ]
+ [ Framed-IP-Address ]
+ [ Framed-IPv6-Prefix ]
+ [ Framed-Interface-Id ]
+ [ Called-Station-Id ]
+ [ Calling-Station-Id ]
+ [ Originating-Line-Info ]
+ [ Acct-Session-Id ]
+ [ Acct-Multi-Session-Id ]
+ [ State ]
+ * [ Class ]
+ [ Reply-Message ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct local_rules_definition rules[] =
+ { { "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Identifier", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IPv6-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Prefix", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Interface-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Called-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Calling-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Originating-Line-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Session-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Multi-Session-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Class", RULE_OPTIONAL, -1,-1 }
+ ,{ "Reply-Message", RULE_OPTIONAL, -1,-1 }
+ };
+
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Request", &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Re-Auth-Answer */
+ {
+ /*
+ Add additional rules of the ABNF (compared to Base definition):
+
+
+ <RA-Answer> ::= < Diameter Header: 258, PXY >
+ < Session-Id >
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ [ User-Name ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ [ Error-Message ]
+ [ Error-Reporting-Host ]
+ * [ Failed-AVP ]
+ * [ Redirected-Host ]
+ [ Redirected-Host-Usage ]
+ [ Redirected-Host-Cache-Time ]
+ [ Service-Type ]
+ * [ Configuration-Token ]
+ [ Idle-Timeout ]
+ [ Authorization-Lifetime ]
+ [ Auth-Grace-Period ]
+ [ Re-Auth-Request-Type ]
+ [ State ]
+ * [ Class ]
+ * [ Reply-Message ]
+ [ Prompt ]
+ * [ Proxy-Info ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct local_rules_definition rules[] =
+ { { "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Configuration-Token", RULE_OPTIONAL, -1,-1 }
+ ,{ "Idle-Timeout", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Re-Auth-Request-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Class", RULE_OPTIONAL, -1,-1 }
+ ,{ "Reply-Message", RULE_OPTIONAL, -1,-1 }
+ ,{ "Prompt", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Re-Auth-Answer", &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Session-Termination-Request */
+ {
+ /*
+ Add additional rules of the ABNF (compared to Base definition):
+
+
+ <ST-Request> ::= < Diameter Header: 275, REQ, PXY >
+ < Session-Id >
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { Auth-Application-Id }
+ { Termination-Cause }
+ [ User-Name ]
+ [ Destination-Host ]
+ * [ Class ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct local_rules_definition rules[] =
+ { { "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Request", &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Session-Termination-Answer */
+ {
+ /*
+ Add additional rules of the ABNF (compared to Base definition):
+
+ <ST-Answer> ::= < Diameter Header: 275, PXY >
+ < Session-Id >
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ [ User-Name ]
+ * [ Class ]
+ [ Error-Message ]
+ [ Error-Reporting-Host ]
+ * [ Failed-AVP ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ * [ Redirect-Host ]
+ [ Redirect-Host-Usase ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct local_rules_definition rules[] =
+ { { "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Session-Termination-Answer", &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Abort-Session-Request */
+ {
+ /*
+ Add additional rules of the ABNF (compared to Base definition):
+
+ <AS-Request> ::= < Diameter Header: 274, REQ, PXY >
+ < Session-Id >
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { Destination-Host }
+ { Auth-Application-Id }
+ [ User-Name ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ [ NAS-Identifier ]
+ [ NAS-IP-Address ]
+ [ NAS-IPv6-Address ]
+ [ NAS-Port ]
+ [ NAS-Port-Id ]
+ [ NAS-Port-Type ]
+ [ Service-Type ]
+ [ Framed-IP-Address ]
+ [ Framed-IPv6-Prefix ]
+ [ Framed-Interface-Id ]
+ [ Called-Station-Id ]
+ [ Calling-Station-Id ]
+ [ Originating-Line-Info ]
+ [ Acct-Session-Id ]
+ [ Acct-Multi-Session-Id ]
+ [ State ]
+ * [ Class ]
+ * [ Reply-Message ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+ */
+ struct dict_object * cmd;
+ struct local_rules_definition rules[] =
+ { { "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Identifier", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IPv6-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Prefix", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Interface-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Called-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Calling-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Originating-Line-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Session-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Multi-Session-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "State", RULE_OPTIONAL, -1, 1 }
+ ,{ "Class", RULE_OPTIONAL, -1,-1 }
+ ,{ "Reply-Message", RULE_OPTIONAL, -1,-1 }
+ };
+
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Abort-Session-Request", &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Abort-Session-Answer */
+ {
+ /*
+ Add additional rules of the ABNF (compared to Base definition):
+
+ <AS-Answer> ::= < Diameter Header: 274, PXY >
+ < Session-Id >
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ [ User-Name ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ [ State]
+ [ Error-Message ]
+ [ Error-Reporting-Host ]
+ * [ Failed-AVP ]
+ * [ Redirected-Host ]
+ [ Redirected-Host-Usage ]
+ [ Redirected-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct local_rules_definition rules[] =
+ { { "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "State", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Abort-Session-Answer", &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Accounting-Request */
+ {
+ /*
+ Add additional rules of the ABNF (compared to Base definition):
+
+ <AC-Request> ::= < Diameter Header: 271, REQ, PXY >
+ < Session-Id >
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { Accounting-Record-Type }
+ { Accounting-Record-Number }
+ [ Acct-Application-Id ]
+ [ Vendor-Specific-Application-Id ]
+ [ User-Name ]
+ [ Accounting-Sub-Session-Id ]
+ [ Acct-Session-Id ]
+ [ Acct-Multi-Session-Id ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ [ Destination-Host ]
+ [ Event-Timestamp ]
+ [ Acct-Delay-Time ]
+ [ NAS-Identifier ]
+ [ NAS-IP-Address ]
+ [ NAS-IPv6-Address ]
+ [ NAS-Port ]
+ [ NAS-Port-Id ]
+ [ NAS-Port-Type ]
+ * [ Class ]
+ [ Service-Type ]
+ [ Termination-Cause ]
+ [ Accounting-Input-Octets ]
+ [ Accounting-Input-Packets ]
+ [ Accounting-Output-Octets ]
+ [ Accounting-Output-Packets ]
+ [ Acct-Authentic ]
+ [ Accounting-Auth-Method ]
+ [ Acct-Link-Count ]
+ [ Acct-Session-Time ]
+ [ Acct-Tunnel-Connection ]
+ [ Acct-Tunnel-Packets-Lost ]
+ [ Callback-Id ]
+ [ Callback-Number ]
+ [ Called-Station-Id ]
+ [ Calling-Station-Id ]
+ * [ Connection-Info ]
+ [ Originating-Line-Info ]
+ [ Authorization-Lifetime ]
+ [ Session-Timeout ]
+ [ Idle-Timeout ]
+ [ Port-Limit ]
+ [ Accounting-Realtime-Required ]
+ [ Acct-Interim-Interval ]
+ * [ Filter-Id ]
+ * [ NAS-Filter-Rule ]
+ * [ Qos-Filter-Rule ]
+ [ Framed-AppleTalk-Link ]
+ [ Framed-AppleTalk-Network ]
+ [ Framed-AppleTalk-Zone ]
+ [ Framed-Compression ]
+ [ Framed-Interface-Id ]
+ [ Framed-IP-Address ]
+ [ Framed-IP-Netmask ]
+ * [ Framed-IPv6-Prefix ]
+ [ Framed-IPv6-Pool ]
+ * [ Framed-IPv6-Route ]
+ [ Framed-IPX-Network ]
+ [ Framed-MTU ]
+ [ Framed-Pool ]
+ [ Framed-Protocol ]
+ * [ Framed-Route ]
+ [ Framed-Routing ]
+ * [ Login-IP-Host ]
+ * [ Login-IPv6-Host ]
+ [ Login-LAT-Group ]
+ [ Login-LAT-Node ]
+ [ Login-LAT-Port ]
+ [ Login-LAT-Service ]
+ [ Login-Service ]
+ [ Login-TCP-Port ]
+ * [ Tunneling ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct local_rules_definition rules[] =
+ { { "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Delay-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Identifier", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IPv6-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Class", RULE_OPTIONAL, -1,-1 }
+ ,{ "Service-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Termination-Cause", RULE_OPTIONAL, -1, 1 }
+ ,{ "Accounting-Input-Octets", RULE_OPTIONAL, -1, 1 }
+ ,{ "Accounting-Input-Packets", RULE_OPTIONAL, -1, 1 }
+ ,{ "Accounting-Output-Octets", RULE_OPTIONAL, -1, 1 }
+ ,{ "Accounting-Output-Packets", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Authentic", RULE_OPTIONAL, -1, 1 }
+ ,{ "Accounting-Auth-Method", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Link-Count", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Session-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Tunnel-Connection", RULE_OPTIONAL, -1, 1 }
+ ,{ "Acct-Tunnel-Packets-Lost", RULE_OPTIONAL, -1, 1 }
+ ,{ "Callback-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Callback-Number", RULE_OPTIONAL, -1, 1 }
+ ,{ "Called-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Calling-Station-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Connect-Info", RULE_OPTIONAL, -1,-1 }
+ ,{ "Originating-Line-Info", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Session-Timeout", RULE_OPTIONAL, -1, 1 }
+ ,{ "Idle-Timeout", RULE_OPTIONAL, -1, 1 }
+ ,{ "Port-Limit", RULE_OPTIONAL, -1, 1 }
+ ,{ "Filter-Id", RULE_OPTIONAL, -1,-1 }
+ ,{ "NAS-Filter-Rule", RULE_OPTIONAL, -1,-1 }
+ ,{ "QoS-Filter-Rule", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-AppleTalk-Link", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-AppleTalk-Network", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-AppleTalk-Zone", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Compression", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Interface-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Prefix", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-IPv6-Pool", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPv6-Route", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-IP-Netmask", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Route", RULE_OPTIONAL, -1,-1 }
+ ,{ "Framed-Pool", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-IPX-Network", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-MTU", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "Framed-Routing", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-IP-Host", RULE_OPTIONAL, -1,-1 }
+ ,{ "Login-IPv6-Host", RULE_OPTIONAL, -1,-1 }
+ ,{ "Login-LAT-Group", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-LAT-Node", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-LAT-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-LAT-Service", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-Service", RULE_OPTIONAL, -1, 1 }
+ ,{ "Login-TCP-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "Tunneling", RULE_OPTIONAL, -1,-1 }
+ };
+
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Accounting-Request", &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Accounting-Answer */
+ {
+ /*
+ Add additional rules of the ABNF (compared to Base definition):
+
+ <AC-Answer> ::= < Diameter Header: 271, PXY >
+ < Session-Id >
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ { Accounting-Record-Type }
+ { Accounting-Record-Number }
+ [ Acct-Application-Id ]
+ [ Vendor-Specific-Application-Id ]
+ [ User-Name ]
+ [ Accounting-Sub-Session-Id ]
+ [ Acct-Session-Id ]
+ [ Acct-Multi-Session-Id ]
+ [ Event-Timestamp ]
+ [ Error-Message ]
+ [ Error-Reporting-Host ]
+ * [ Failed-AVP ]
+ [ Origin-AAA-Protocol ]
+ [ Origin-State-Id ]
+ [ NAS-Identifier ]
+ [ NAS-IP-Address ]
+ [ NAS-IPv6-Address ]
+ [ NAS-Port ]
+ [ NAS-Port-Id ]
+ [ NAS-Port-Type ]
+ [ Service-Type ]
+ [ Termination-Cause ]
+ [ Accounting-Realtime-Required ]
+ [ Acct-Interim-Interval ]
+ * [ Class ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+ */
+ struct dict_object * cmd;
+ struct local_rules_definition rules[] =
+ { { "Origin-AAA-Protocol", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Identifier", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IP-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-IPv6-Address", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "NAS-Port-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Service-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Termination-Cause", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_search( DICT_COMMAND, CMD_BY_NAME, "Accounting-Answer", &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for NASREQ' initialized");
+ return 0;
+}
+
+EXTENSION_ENTRY("dict_nasreq", dnr_entry);
diff --git a/extensions/dict_rfc4004_avps/CMakeLists.txt b/extensions/dict_rfc4004_avps/CMakeLists.txt
new file mode 100644
index 0000000..43b6936
--- /dev/null
+++ b/extensions/dict_rfc4004_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc4004_avps extension
+PROJECT("dict_rfc4004_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc4004_avps dict_rfc4004_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc4004_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC4004_AVPS)
+
+
+
diff --git a/extensions/dict_rfc4004_avps/dict_rfc4004_avps.c b/extensions/dict_rfc4004_avps/dict_rfc4004_avps.c
new file mode 100644
index 0000000..d030c42
--- /dev/null
+++ b/extensions/dict_rfc4004_avps/dict_rfc4004_avps.c
@@ -0,0 +1,655 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc4004_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.43
+
+const char *rfc4004_avps_proto_ver = PROTO_VER;
+const double rfc4004_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc4004_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* MIP-Reg-Request */
+ {
+ struct dict_avp_data data = {
+ 320, /* Code */
+ 0, /* Vendor */
+ "MIP-Reg-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Reg-Reply */
+ {
+ struct dict_avp_data data = {
+ 321, /* Code */
+ 0, /* Vendor */
+ "MIP-Reg-Reply", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Mobile-Node-Address */
+ {
+ struct dict_avp_data data = {
+ 333, /* Code */
+ 0, /* Vendor */
+ "MIP-Mobile-Node-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* MIP-Home-Agent-Address */
+ {
+ struct dict_avp_data data = {
+ 334, /* Code */
+ 0, /* Vendor */
+ "MIP-Home-Agent-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* MIP-Candidate-Home-Agent-Host */
+ {
+ struct dict_avp_data data = {
+ 336, /* Code */
+ 0, /* Vendor */
+ "MIP-Candidate-Home-Agent-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* MIP-Feature-Vector */
+ {
+ struct dict_avp_data data = {
+ 337, /* Code */
+ 0, /* Vendor */
+ "MIP-Feature-Vector", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Auth-Input-Data-Length */
+ {
+ struct dict_avp_data data = {
+ 338, /* Code */
+ 0, /* Vendor */
+ "MIP-Auth-Input-Data-Length", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Authenticator-Length */
+ {
+ struct dict_avp_data data = {
+ 339, /* Code */
+ 0, /* Vendor */
+ "MIP-Authenticator-Length", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Authenticator-Offset */
+ {
+ struct dict_avp_data data = {
+ 340, /* Code */
+ 0, /* Vendor */
+ "MIP-Authenticator-Offset", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-MN-AAA-SPI */
+ {
+ struct dict_avp_data data = {
+ 341, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-AAA-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Filter-Rule */
+ {
+ struct dict_avp_data data = {
+ 342, /* Code */
+ 0, /* Vendor */
+ "MIP-Filter-Rule", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+ /* MIP-FA-Challenge */
+ {
+ struct dict_avp_data data = {
+ 344, /* Code */
+ 0, /* Vendor */
+ "MIP-FA-Challenge", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Home-Agent-Host */
+ {
+ struct dict_avp_data data = {
+ 348, /* Code */
+ 0, /* Vendor */
+ "MIP-Home-Agent-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* MIP-FA-to-HA-SPI */
+ {
+ struct dict_avp_data data = {
+ 318, /* Code */
+ 0, /* Vendor */
+ "MIP-FA-to-HA-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-FA-to-MN-SPI */
+ {
+ struct dict_avp_data data = {
+ 319, /* Code */
+ 0, /* Vendor */
+ "MIP-FA-to-MN-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-HA-to-FA-SPI */
+ {
+ struct dict_avp_data data = {
+ 323, /* Code */
+ 0, /* Vendor */
+ "MIP-HA-to-FA-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Nonce */
+ {
+ struct dict_avp_data data = {
+ 335, /* Code */
+ 0, /* Vendor */
+ "MIP-Nonce", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Session-Key */
+ {
+ struct dict_avp_data data = {
+ 343, /* Code */
+ 0, /* Vendor */
+ "MIP-Session-Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Algorithm-Type */
+ {
+ struct dict_avp_data data = {
+ 345, /* Code */
+ 0, /* Vendor */
+ "MIP-Algorithm-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Algorithm-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "HMAC-SHA-1", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MIP-Replay-Mode */
+ {
+ struct dict_avp_data data = {
+ 346, /* Code */
+ 0, /* Vendor */
+ "MIP-Replay-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP-Replay-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "None", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "Timestamps", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "Nonces", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MIP-MSA-Lifetime */
+ {
+ struct dict_avp_data data = {
+ 367, /* Code */
+ 0, /* Vendor */
+ "MIP-MSA-Lifetime", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-FA-to-HA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 328, /* Code */
+ 0, /* Vendor */
+ "MIP-FA-to-HA-MSA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MIP-MN-to-FA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 325, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-to-FA-MSA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MIP-Originating-Foreign-AAA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 347, /* Code */
+ 0, /* Vendor */
+ "MIP-Originating-Foreign-AAA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MIP-HA-to-MN-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 332, /* Code */
+ 0, /* Vendor */
+ "MIP-HA-to-MN-MSA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MIP-MN-AAA-Auth */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 322, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-AAA-Auth", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MIP-FA-to-MN-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 326, /* Code */
+ 0, /* Vendor */
+ "MIP-FA-to-MN-MSA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MIP-HA-to-FA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 329, /* Code */
+ 0, /* Vendor */
+ "MIP-HA-to-FA-MSA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MIP-MN-to-HA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 331, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-to-HA-MSA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc4004_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* MIP-FA-to-HA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP-FA-to-HA-MSA"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-FA-to-HA-SPI"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Algorithm-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Session-Key"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MIP-MN-to-FA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP-MN-to-FA-MSA"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-Algorithm-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Nonce"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MIP-Originating-Foreign-AAA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP-Originating-Foreign-AAA"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Origin-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Origin-Host"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MIP-HA-to-MN-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP-HA-to-MN-MSA"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-Algorithm-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Replay-Mode"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Session-Key"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MIP-MN-AAA-Auth */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP-MN-AAA-Auth"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-MN-AAA-SPI"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Auth-Input-Data-Length"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Authenticator-Length"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Authenticator-Offset"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MIP-FA-to-MN-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP-FA-to-MN-MSA"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-FA-to-MN-SPI"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Algorithm-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Session-Key"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MIP-HA-to-FA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP-HA-to-FA-MSA"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-HA-to-FA-SPI"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Algorithm-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Session-Key"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MIP-MN-to-HA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP-MN-to-HA-MSA"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-Algorithm-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Replay-Mode"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Nonce"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc4004_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc4004_avps_load_defs(conffile);
+ return dict_rfc4004_avps_load_rules(conffile);
+}
+
+const char* dict_rfc4004_avps_proto_ver(char * conffile) {
+ return rfc4004_avps_proto_ver;
+}
+
+const double dict_rfc4004_avps_gen_ts(char * conffile) {
+ return rfc4004_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc4004_avps", dict_rfc4004_avps_load_defs, dict_rfc4004_avps_load_rules);
+
+
+
diff --git a/extensions/dict_rfc4004_avps/rfc4004_avps.did b/extensions/dict_rfc4004_avps/rfc4004_avps.did
new file mode 100644
index 0000000..5c6effd
--- /dev/null
+++ b/extensions/dict_rfc4004_avps/rfc4004_avps.did
@@ -0,0 +1 @@
+dict_rfc4004_avps
diff --git a/extensions/dict_rfc4006bis_avps/CMakeLists.txt b/extensions/dict_rfc4006bis_avps/CMakeLists.txt
new file mode 100644
index 0000000..9302ae9
--- /dev/null
+++ b/extensions/dict_rfc4006bis_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc4006bis_avps extension
+PROJECT("dict_rfc4006bis_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc4006bis_avps dict_rfc4006bis_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc4006bis_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC4006BIS_AVPS)
+
+
+
diff --git a/extensions/dict_rfc4006bis_avps/dict_rfc4006bis_avps.c b/extensions/dict_rfc4006bis_avps/dict_rfc4006bis_avps.c
new file mode 100644
index 0000000..45ec31e
--- /dev/null
+++ b/extensions/dict_rfc4006bis_avps/dict_rfc4006bis_avps.c
@@ -0,0 +1,1419 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc4006bis_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.49
+
+const char *rfc4006bis_avps_proto_ver = PROTO_VER;
+const double rfc4006bis_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc4006bis_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* CC-Correlation-Id */
+ {
+ struct dict_avp_data data = {
+ 411, /* Code */
+ 0, /* Vendor */
+ "CC-Correlation-Id", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CC-Input-Octets */
+ {
+ struct dict_avp_data data = {
+ 412, /* Code */
+ 0, /* Vendor */
+ "CC-Input-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CC-Output-Octets */
+ {
+ struct dict_avp_data data = {
+ 414, /* Code */
+ 0, /* Vendor */
+ "CC-Output-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CC-Request-Number */
+ {
+ struct dict_avp_data data = {
+ 415, /* Code */
+ 0, /* Vendor */
+ "CC-Request-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CC-Request-Type */
+ {
+ struct dict_avp_data data = {
+ 416, /* Code */
+ 0, /* Vendor */
+ "CC-Request-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CC-Request-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "INITIAL_REQUEST", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "UPDATE_REQUEST", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "TERMINATION_REQUEST", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "EVENT_REQUEST", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CC-Service-Specific-Units */
+ {
+ struct dict_avp_data data = {
+ 417, /* Code */
+ 0, /* Vendor */
+ "CC-Service-Specific-Units", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CC-Session-Failover */
+ {
+ struct dict_avp_data data = {
+ 418, /* Code */
+ 0, /* Vendor */
+ "CC-Session-Failover", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CC-Session-Failover)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "FAILOVER_NOT_SUPPORTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "FAILOVER_SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CC-Sub-Session-Id */
+ {
+ struct dict_avp_data data = {
+ 419, /* Code */
+ 0, /* Vendor */
+ "CC-Sub-Session-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CC-Time */
+ {
+ struct dict_avp_data data = {
+ 420, /* Code */
+ 0, /* Vendor */
+ "CC-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CC-Total-Octets */
+ {
+ struct dict_avp_data data = {
+ 421, /* Code */
+ 0, /* Vendor */
+ "CC-Total-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CC-Unit-Type */
+ {
+ struct dict_avp_data data = {
+ 454, /* Code */
+ 0, /* Vendor */
+ "CC-Unit-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CC-Unit-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TIME", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MONEY", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "TOTAL_OCTETS", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "INPUT_OCTETS", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "OUTPUT_OCTETS", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "SERVICE_SPECIFIC_UNITS", { .i32=5 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Check-Balance-Result */
+ {
+ struct dict_avp_data data = {
+ 422, /* Code */
+ 0, /* Vendor */
+ "Check-Balance-Result", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Check-Balance-Result)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ENOUGH_CREDIT", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NO_CREDIT", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Cost-Unit */
+ {
+ struct dict_avp_data data = {
+ 424, /* Code */
+ 0, /* Vendor */
+ "Cost-Unit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Credit-Control */
+ {
+ struct dict_avp_data data = {
+ 426, /* Code */
+ 0, /* Vendor */
+ "Credit-Control", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Credit-Control)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CREDIT_AUTHORIZATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "RE_AUTHORIZATION", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Credit-Control-Failure-Handling */
+ {
+ struct dict_avp_data data = {
+ 427, /* Code */
+ 0, /* Vendor */
+ "Credit-Control-Failure-Handling", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Credit-Control-Failure-Handling)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TERMINATE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CONTINUE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "RETRY_AND_TERMINATE", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Currency-Code */
+ {
+ struct dict_avp_data data = {
+ 425, /* Code */
+ 0, /* Vendor */
+ "Currency-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Direct-Debiting-Failure-Handling */
+ {
+ struct dict_avp_data data = {
+ 428, /* Code */
+ 0, /* Vendor */
+ "Direct-Debiting-Failure-Handling", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Direct-Debiting-Failure-Handling)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TERMINATE_OR_BUFFER", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CONTINUE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Exponent */
+ {
+ struct dict_avp_data data = {
+ 429, /* Code */
+ 0, /* Vendor */
+ "Exponent", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Final-Unit-Action */
+ {
+ struct dict_avp_data data = {
+ 449, /* Code */
+ 0, /* Vendor */
+ "Final-Unit-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Final-Unit-Action)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TERMINATE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "REDIRECT", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "RESTRICT_ACCESS", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* G-S-U-Pool-Identifier */
+ {
+ struct dict_avp_data data = {
+ 453, /* Code */
+ 0, /* Vendor */
+ "G-S-U-Pool-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Multiple-Services-Indicator */
+ {
+ struct dict_avp_data data = {
+ 455, /* Code */
+ 0, /* Vendor */
+ "Multiple-Services-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Multiple-Services-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MULTIPLE_SERVICES_NOT_SUPPORTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MULTIPLE_SERVICES_SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Rating-Group */
+ {
+ struct dict_avp_data data = {
+ 432, /* Code */
+ 0, /* Vendor */
+ "Rating-Group", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Redirect-Address-Type */
+ {
+ struct dict_avp_data data = {
+ 433, /* Code */
+ 0, /* Vendor */
+ "Redirect-Address-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Redirect-Address-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "IPv4_Address", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "IPv6_Address", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "URL", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "SIP_URI", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Redirect-Server-Address */
+ {
+ struct dict_avp_data data = {
+ 435, /* Code */
+ 0, /* Vendor */
+ "Redirect-Server-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Redirect-Address-IPAddress */
+ {
+ struct dict_avp_data data = {
+ 99996, /* Code */
+ 0, /* Vendor */
+ "Redirect-Address-IPAddress", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Redirect-Address-URL */
+ {
+ struct dict_avp_data data = {
+ 99997, /* Code */
+ 0, /* Vendor */
+ "Redirect-Address-URL", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Redirect-Address-SIP-URI */
+ {
+ struct dict_avp_data data = {
+ 99998, /* Code */
+ 0, /* Vendor */
+ "Redirect-Address-SIP-URI", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Requested-Action */
+ {
+ struct dict_avp_data data = {
+ 436, /* Code */
+ 0, /* Vendor */
+ "Requested-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Requested-Action)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DIRECT_DEBITING", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "REFUND_ACCOUNT", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "CHECK_BALANCE", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "PRICE_ENQUIRY", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Restriction-Filter-Rule */
+ {
+ struct dict_avp_data data = {
+ 438, /* Code */
+ 0, /* Vendor */
+ "Restriction-Filter-Rule", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+ /* Service-Context-Id */
+ {
+ struct dict_avp_data data = {
+ 461, /* Code */
+ 0, /* Vendor */
+ "Service-Context-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Service-Identifier */
+ {
+ struct dict_avp_data data = {
+ 439, /* Code */
+ 0, /* Vendor */
+ "Service-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-Parameter-Type */
+ {
+ struct dict_avp_data data = {
+ 441, /* Code */
+ 0, /* Vendor */
+ "Service-Parameter-Type", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-Parameter-Value */
+ {
+ struct dict_avp_data data = {
+ 442, /* Code */
+ 0, /* Vendor */
+ "Service-Parameter-Value", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Subscription-Id-Data */
+ {
+ struct dict_avp_data data = {
+ 444, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Subscription-Id-Type */
+ {
+ struct dict_avp_data data = {
+ 450, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Subscription-Id-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "END_USER_E164", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "END_USER_IMSI", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "END_USER_SIP_URI", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "END_USER_NAI", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "END_USER_PRIVATE", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Subscription-Id-E164 */
+ {
+ struct dict_avp_data data = {
+ 99990, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-E164", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Subscription-Id-IMSI */
+ {
+ struct dict_avp_data data = {
+ 99991, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-IMSI", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Subscription-Id-SIP-URI */
+ {
+ struct dict_avp_data data = {
+ 99992, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-SIP-URI", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Subscription-Id-NAI */
+ {
+ struct dict_avp_data data = {
+ 99993, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-NAI", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Subscription-Id-Private */
+ {
+ struct dict_avp_data data = {
+ 99994, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-Private", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Tariff-Change-Usage */
+ {
+ struct dict_avp_data data = {
+ 452, /* Code */
+ 0, /* Vendor */
+ "Tariff-Change-Usage", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Tariff-Change-Usage)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UNIT_BEFORE_TARIFF_CHANGE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "UNIT_AFTER_TARIFF_CHANGE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "UNIT_INDETERMINATE", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Tariff-Time-Change */
+ {
+ struct dict_avp_data data = {
+ 451, /* Code */
+ 0, /* Vendor */
+ "Tariff-Time-Change", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* User-Equipment-Info-Type */
+ {
+ struct dict_avp_data data = {
+ 459, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-Type", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(User-Equipment-Info-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "IMEISV", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MAC", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "EUI64", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "MODIFIED_EUI64", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* User-Equipment-Info-Value */
+ {
+ struct dict_avp_data data = {
+ 460, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-Value", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Equipment-Info-IMEISV */
+ {
+ struct dict_avp_data data = {
+ 99984, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-IMEISV", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Equipment-Info-MAC */
+ {
+ struct dict_avp_data data = {
+ 99985, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-MAC", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Equipment-Info-EUI64 */
+ {
+ struct dict_avp_data data = {
+ 99986, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-EUI64", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Equipment-Info-ModifiedEUI64 */
+ {
+ struct dict_avp_data data = {
+ 99987, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-ModifiedEUI64", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Equipment-Info-IMEI */
+ {
+ struct dict_avp_data data = {
+ 99988, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-IMEI", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Value-Digits */
+ {
+ struct dict_avp_data data = {
+ 447, /* Code */
+ 0, /* Vendor */
+ "Value-Digits", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Validity-Time */
+ {
+ struct dict_avp_data data = {
+ 448, /* Code */
+ 0, /* Vendor */
+ "Validity-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Subscription-Id-Extension */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 99989, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id-Extension", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Subscription-Id */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 443, /* Code */
+ 0, /* Vendor */
+ "Subscription-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Service-Parameter-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 440, /* Code */
+ 0, /* Vendor */
+ "Service-Parameter-Info", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* User-Equipment-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 458, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Unit-Value */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 445, /* Code */
+ 0, /* Vendor */
+ "Unit-Value", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Redirect-Server-Extension */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 99995, /* Code */
+ 0, /* Vendor */
+ "Redirect-Server-Extension", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Redirect-Server */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 434, /* Code */
+ 0, /* Vendor */
+ "Redirect-Server", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* User-Equipment-Info-Extension */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 99983, /* Code */
+ 0, /* Vendor */
+ "User-Equipment-Info-Extension", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* G-S-U-Pool-Reference */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 457, /* Code */
+ 0, /* Vendor */
+ "G-S-U-Pool-Reference", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Final-Unit-Indication */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 430, /* Code */
+ 0, /* Vendor */
+ "Final-Unit-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* CC-Money */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 413, /* Code */
+ 0, /* Vendor */
+ "CC-Money", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Cost-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 423, /* Code */
+ 0, /* Vendor */
+ "Cost-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Used-Service-Unit */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 446, /* Code */
+ 0, /* Vendor */
+ "Used-Service-Unit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Requested-Service-Unit */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 437, /* Code */
+ 0, /* Vendor */
+ "Requested-Service-Unit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Granted-Service-Unit */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 431, /* Code */
+ 0, /* Vendor */
+ "Granted-Service-Unit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* QoS-Final-Unit-Indication */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 99999, /* Code */
+ 0, /* Vendor */
+ "QoS-Final-Unit-Indication", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Multiple-Services-Credit-Control */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 456, /* Code */
+ 0, /* Vendor */
+ "Multiple-Services-Credit-Control", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc4006bis_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Subscription-Id-Extension */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Subscription-Id-Extension"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id-E164"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id-IMSI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id-SIP-URI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id-NAI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id-Private"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Subscription-Id */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Subscription-Id"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id-Data"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Service-Parameter-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Service-Parameter-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Service-Parameter-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Parameter-Value"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* User-Equipment-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "User-Equipment-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info-Value"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Unit-Value */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Unit-Value"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Value-Digits"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Exponent"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Redirect-Server-Extension */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Redirect-Server-Extension"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Redirect-Address-IPAddress"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Address-URL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Address-SIP-URI"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Redirect-Server */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Redirect-Server"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Redirect-Address-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Server-Address"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* User-Equipment-Info-Extension */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "User-Equipment-Info-Extension"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info-IMEISV"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info-MAC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info-EUI64"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info-ModifiedEUI64"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info-IMEI"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* G-S-U-Pool-Reference */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "G-S-U-Pool-Reference"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "G-S-U-Pool-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Unit-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Unit-Value"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Final-Unit-Indication */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Final-Unit-Indication"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Final-Unit-Action"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Restriction-Filter-Rule"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Filter-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Server"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* CC-Money */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "CC-Money"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Unit-Value"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Currency-Code"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Cost-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Cost-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Unit-Value"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Currency-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Cost-Unit"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Used-Service-Unit */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Used-Service-Unit"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Tariff-Change-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Money"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Total-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Input-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Output-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Service-Specific-Units"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Requested-Service-Unit */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Requested-Service-Unit"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "CC-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Money"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Total-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Input-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Output-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Service-Specific-Units"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Granted-Service-Unit */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Granted-Service-Unit"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Tariff-Time-Change"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Money"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Total-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Input-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Output-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Service-Specific-Units"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* QoS-Final-Unit-Indication */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "QoS-Final-Unit-Indication"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Final-Unit-Action"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Filter-Rule"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Filter-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Server-Extension"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Multiple-Services-Credit-Control */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Multiple-Services-Credit-Control"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Granted-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Requested-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Used-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tariff-Change-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Rating-Group"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "G-S-U-Pool-Reference"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Validity-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Final-Unit-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "QoS-Final-Unit-Indication"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc4006bis_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc4006bis_avps_load_defs(conffile);
+ return dict_rfc4006bis_avps_load_rules(conffile);
+}
+
+const char* dict_rfc4006bis_avps_proto_ver(char * conffile) {
+ return rfc4006bis_avps_proto_ver;
+}
+
+const double dict_rfc4006bis_avps_gen_ts(char * conffile) {
+ return rfc4006bis_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc4006bis_avps", dict_rfc4006bis_avps_load_defs, dict_rfc4006bis_avps_load_rules, "dict_rfc7155_avps", "dict_rfc5777_avps");
+
+
+
diff --git a/extensions/dict_rfc4006bis_avps/rfc4006bis_avps.did b/extensions/dict_rfc4006bis_avps/rfc4006bis_avps.did
new file mode 100644
index 0000000..0aad557
--- /dev/null
+++ b/extensions/dict_rfc4006bis_avps/rfc4006bis_avps.did
@@ -0,0 +1,4 @@
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
diff --git a/extensions/dict_rfc4072_avps/CMakeLists.txt b/extensions/dict_rfc4072_avps/CMakeLists.txt
new file mode 100644
index 0000000..d694a90
--- /dev/null
+++ b/extensions/dict_rfc4072_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc4072_avps extension
+PROJECT("dict_rfc4072_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc4072_avps dict_rfc4072_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc4072_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC4072_AVPS)
+
+
+
diff --git a/extensions/dict_rfc4072_avps/dict_rfc4072_avps.c b/extensions/dict_rfc4072_avps/dict_rfc4072_avps.c
new file mode 100644
index 0000000..69d705d
--- /dev/null
+++ b/extensions/dict_rfc4072_avps/dict_rfc4072_avps.c
@@ -0,0 +1,224 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc4072_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.65
+
+const char *rfc4072_avps_proto_ver = PROTO_VER;
+const double rfc4072_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc4072_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* EAP-Payload */
+ {
+ struct dict_avp_data data = {
+ 462, /* Code */
+ 0, /* Vendor */
+ "EAP-Payload", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* EAP-Reissued-Payload */
+ {
+ struct dict_avp_data data = {
+ 463, /* Code */
+ 0, /* Vendor */
+ "EAP-Reissued-Payload", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* EAP-Master-Session-Key */
+ {
+ struct dict_avp_data data = {
+ 464, /* Code */
+ 0, /* Vendor */
+ "EAP-Master-Session-Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* EAP-Key-Name */
+ {
+ struct dict_avp_data data = {
+ 102, /* Code */
+ 0, /* Vendor */
+ "EAP-Key-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Accounting-EAP-Auth-Method */
+ {
+ struct dict_avp_data data = {
+ 465, /* Code */
+ 0, /* Vendor */
+ "Accounting-EAP-Auth-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc4072_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc4072_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc4072_avps_load_defs(conffile);
+ return dict_rfc4072_avps_load_rules(conffile);
+}
+
+const char* dict_rfc4072_avps_proto_ver(char * conffile) {
+ return rfc4072_avps_proto_ver;
+}
+
+const double dict_rfc4072_avps_gen_ts(char * conffile) {
+ return rfc4072_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc4072_avps", dict_rfc4072_avps_load_defs, dict_rfc4072_avps_load_rules, "dict_rfc7155_avps");
+
+
+
diff --git a/extensions/dict_rfc4072_avps/rfc4072_avps.did b/extensions/dict_rfc4072_avps/rfc4072_avps.did
new file mode 100644
index 0000000..feaf759
--- /dev/null
+++ b/extensions/dict_rfc4072_avps/rfc4072_avps.did
@@ -0,0 +1,3 @@
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc4072_avps
diff --git a/extensions/dict_rfc4590_avps/CMakeLists.txt b/extensions/dict_rfc4590_avps/CMakeLists.txt
new file mode 100644
index 0000000..c755961
--- /dev/null
+++ b/extensions/dict_rfc4590_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc4590_avps extension
+PROJECT("dict_rfc4590_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc4590_avps dict_rfc4590_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc4590_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC4590_AVPS)
+
+
+
diff --git a/extensions/dict_rfc4590_avps/dict_rfc4590_avps.c b/extensions/dict_rfc4590_avps/dict_rfc4590_avps.c
new file mode 100644
index 0000000..a09901d
--- /dev/null
+++ b/extensions/dict_rfc4590_avps/dict_rfc4590_avps.c
@@ -0,0 +1,416 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc4590_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.52
+
+const char *rfc4590_avps_proto_ver = PROTO_VER;
+const double rfc4590_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc4590_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Message-Authenticator */
+ {
+ struct dict_avp_data data = {
+ 80, /* Code */
+ 0, /* Vendor */
+ "Message-Authenticator", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Response */
+ {
+ struct dict_avp_data data = {
+ 103, /* Code */
+ 0, /* Vendor */
+ "Digest-Response", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Realm */
+ {
+ struct dict_avp_data data = {
+ 104, /* Code */
+ 0, /* Vendor */
+ "Digest-Realm", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Nonce */
+ {
+ struct dict_avp_data data = {
+ 105, /* Code */
+ 0, /* Vendor */
+ "Digest-Nonce", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Response-Auth */
+ {
+ struct dict_avp_data data = {
+ 106, /* Code */
+ 0, /* Vendor */
+ "Digest-Response-Auth", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Nextnonce */
+ {
+ struct dict_avp_data data = {
+ 107, /* Code */
+ 0, /* Vendor */
+ "Digest-Nextnonce", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Method */
+ {
+ struct dict_avp_data data = {
+ 108, /* Code */
+ 0, /* Vendor */
+ "Digest-Method", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-URI */
+ {
+ struct dict_avp_data data = {
+ 109, /* Code */
+ 0, /* Vendor */
+ "Digest-URI", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-QoP */
+ {
+ struct dict_avp_data data = {
+ 110, /* Code */
+ 0, /* Vendor */
+ "Digest-QoP", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Algorithm */
+ {
+ struct dict_avp_data data = {
+ 111, /* Code */
+ 0, /* Vendor */
+ "Digest-Algorithm", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Entity-Body-Hash */
+ {
+ struct dict_avp_data data = {
+ 112, /* Code */
+ 0, /* Vendor */
+ "Digest-Entity-Body-Hash", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-CNonce */
+ {
+ struct dict_avp_data data = {
+ 113, /* Code */
+ 0, /* Vendor */
+ "Digest-CNonce", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Nonce-Count */
+ {
+ struct dict_avp_data data = {
+ 114, /* Code */
+ 0, /* Vendor */
+ "Digest-Nonce-Count", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Username */
+ {
+ struct dict_avp_data data = {
+ 115, /* Code */
+ 0, /* Vendor */
+ "Digest-Username", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Opaque */
+ {
+ struct dict_avp_data data = {
+ 116, /* Code */
+ 0, /* Vendor */
+ "Digest-Opaque", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Auth-Param */
+ {
+ struct dict_avp_data data = {
+ 117, /* Code */
+ 0, /* Vendor */
+ "Digest-Auth-Param", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-AKA-Auts */
+ {
+ struct dict_avp_data data = {
+ 118, /* Code */
+ 0, /* Vendor */
+ "Digest-AKA-Auts", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Domain */
+ {
+ struct dict_avp_data data = {
+ 119, /* Code */
+ 0, /* Vendor */
+ "Digest-Domain", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-Stale */
+ {
+ struct dict_avp_data data = {
+ 120, /* Code */
+ 0, /* Vendor */
+ "Digest-Stale", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Digest-HA1 */
+ {
+ struct dict_avp_data data = {
+ 121, /* Code */
+ 0, /* Vendor */
+ "Digest-HA1", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SIP-AOR */
+ {
+ struct dict_avp_data data = {
+ 122, /* Code */
+ 0, /* Vendor */
+ "SIP-AOR", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc4590_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc4590_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc4590_avps_load_defs(conffile);
+ return dict_rfc4590_avps_load_rules(conffile);
+}
+
+const char* dict_rfc4590_avps_proto_ver(char * conffile) {
+ return rfc4590_avps_proto_ver;
+}
+
+const double dict_rfc4590_avps_gen_ts(char * conffile) {
+ return rfc4590_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc4590_avps", dict_rfc4590_avps_load_defs, dict_rfc4590_avps_load_rules);
+
+
+
diff --git a/extensions/dict_rfc4590_avps/rfc4590_avps.did b/extensions/dict_rfc4590_avps/rfc4590_avps.did
new file mode 100644
index 0000000..0ef3e08
--- /dev/null
+++ b/extensions/dict_rfc4590_avps/rfc4590_avps.did
@@ -0,0 +1 @@
+dict_rfc4590_avps
diff --git a/extensions/dict_rfc5447_avps/CMakeLists.txt b/extensions/dict_rfc5447_avps/CMakeLists.txt
new file mode 100644
index 0000000..80425cd
--- /dev/null
+++ b/extensions/dict_rfc5447_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc5447_avps extension
+PROJECT("dict_rfc5447_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc5447_avps dict_rfc5447_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc5447_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC5447_AVPS)
+
+
+
diff --git a/extensions/dict_rfc5447_avps/dict_rfc5447_avps.c b/extensions/dict_rfc5447_avps/dict_rfc5447_avps.c
new file mode 100644
index 0000000..a665cf8
--- /dev/null
+++ b/extensions/dict_rfc5447_avps/dict_rfc5447_avps.c
@@ -0,0 +1,216 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc5447_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.54
+
+const char *rfc5447_avps_proto_ver = PROTO_VER;
+const double rfc5447_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc5447_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* MIP6-Feature-Vector */
+ {
+ struct dict_avp_data data = {
+ 124, /* Code */
+ 0, /* Vendor */
+ "MIP6-Feature-Vector", /* Name */
+ AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP6-Home-Link-Prefix */
+ {
+ struct dict_avp_data data = {
+ 125, /* Code */
+ 0, /* Vendor */
+ "MIP6-Home-Link-Prefix", /* Name */
+ AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP6-Agent-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 486, /* Code */
+ 0, /* Vendor */
+ "MIP6-Agent-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc5447_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* MIP6-Agent-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP6-Agent-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-Home-Agent-Address"}, RULE_OPTIONAL, -1, 2 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Home-Agent-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP6-Home-Link-Prefix"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc5447_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc5447_avps_load_defs(conffile);
+ return dict_rfc5447_avps_load_rules(conffile);
+}
+
+const char* dict_rfc5447_avps_proto_ver(char * conffile) {
+ return rfc5447_avps_proto_ver;
+}
+
+const double dict_rfc5447_avps_gen_ts(char * conffile) {
+ return rfc5447_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc5447_avps", dict_rfc5447_avps_load_defs, dict_rfc5447_avps_load_rules, "dict_rfc4004_avps");
+
+
+
diff --git a/extensions/dict_rfc5447_avps/rfc5447_avps.did b/extensions/dict_rfc5447_avps/rfc5447_avps.did
new file mode 100644
index 0000000..8225d5d
--- /dev/null
+++ b/extensions/dict_rfc5447_avps/rfc5447_avps.did
@@ -0,0 +1,2 @@
+dict_rfc4004_avps
+dict_rfc5447_avps
diff --git a/extensions/dict_rfc5580_avps/CMakeLists.txt b/extensions/dict_rfc5580_avps/CMakeLists.txt
new file mode 100644
index 0000000..f1f5034
--- /dev/null
+++ b/extensions/dict_rfc5580_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc5580_avps extension
+PROJECT("dict_rfc5580_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc5580_avps dict_rfc5580_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc5580_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC5580_AVPS)
+
+
+
diff --git a/extensions/dict_rfc5580_avps/dict_rfc5580_avps.c b/extensions/dict_rfc5580_avps/dict_rfc5580_avps.c
new file mode 100644
index 0000000..10f55c1
--- /dev/null
+++ b/extensions/dict_rfc5580_avps/dict_rfc5580_avps.c
@@ -0,0 +1,260 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc5580_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697191.32
+
+const char *rfc5580_avps_proto_ver = PROTO_VER;
+const double rfc5580_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc5580_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Operator-Name */
+ {
+ struct dict_avp_data data = {
+ 126, /* Code */
+ 0, /* Vendor */
+ "Operator-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Location-Information */
+ {
+ struct dict_avp_data data = {
+ 127, /* Code */
+ 0, /* Vendor */
+ "Location-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Location-Data */
+ {
+ struct dict_avp_data data = {
+ 128, /* Code */
+ 0, /* Vendor */
+ "Location-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Basic-Location-Policy-Rules */
+ {
+ struct dict_avp_data data = {
+ 129, /* Code */
+ 0, /* Vendor */
+ "Basic-Location-Policy-Rules", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Extended-Location-Policy-Rules */
+ {
+ struct dict_avp_data data = {
+ 130, /* Code */
+ 0, /* Vendor */
+ "Extended-Location-Policy-Rules", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Location-Capable */
+ {
+ struct dict_avp_data data = {
+ 131, /* Code */
+ 0, /* Vendor */
+ "Location-Capable", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Requested-Location-Info */
+ {
+ struct dict_avp_data data = {
+ 132, /* Code */
+ 0, /* Vendor */
+ "Requested-Location-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Error-Cause */
+ {
+ struct dict_avp_data data = {
+ 101, /* Code */
+ 0, /* Vendor */
+ "Error-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc5580_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc5580_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc5580_avps_load_defs(conffile);
+ return dict_rfc5580_avps_load_rules(conffile);
+}
+
+const char* dict_rfc5580_avps_proto_ver(char * conffile) {
+ return rfc5580_avps_proto_ver;
+}
+
+const double dict_rfc5580_avps_gen_ts(char * conffile) {
+ return rfc5580_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc5580_avps", dict_rfc5580_avps_load_defs, dict_rfc5580_avps_load_rules);
+
+
+
diff --git a/extensions/dict_rfc5580_avps/rfc5580_avps.did b/extensions/dict_rfc5580_avps/rfc5580_avps.did
new file mode 100644
index 0000000..40ca6fb
--- /dev/null
+++ b/extensions/dict_rfc5580_avps/rfc5580_avps.did
@@ -0,0 +1 @@
+dict_rfc5580_avps
diff --git a/extensions/dict_rfc5777_avps/CMakeLists.txt b/extensions/dict_rfc5777_avps/CMakeLists.txt
new file mode 100644
index 0000000..d0573c4
--- /dev/null
+++ b/extensions/dict_rfc5777_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc5777_avps extension
+PROJECT("dict_rfc5777_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc5777_avps dict_rfc5777_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc5777_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC5777_AVPS)
+
+
+
diff --git a/extensions/dict_rfc5777_avps/dict_rfc5777_avps.c b/extensions/dict_rfc5777_avps/dict_rfc5777_avps.c
new file mode 100644
index 0000000..f287963
--- /dev/null
+++ b/extensions/dict_rfc5777_avps/dict_rfc5777_avps.c
@@ -0,0 +1,2077 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc5777_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.56
+
+const char *rfc5777_avps_proto_ver = PROTO_VER;
+const double rfc5777_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc5777_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Filter-Rule-Precedence */
+ {
+ struct dict_avp_data data = {
+ 510, /* Code */
+ 0, /* Vendor */
+ "Filter-Rule-Precedence", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Classifier-ID */
+ {
+ struct dict_avp_data data = {
+ 512, /* Code */
+ 0, /* Vendor */
+ "Classifier-ID", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Protocol */
+ {
+ struct dict_avp_data data = {
+ 513, /* Code */
+ 0, /* Vendor */
+ "Protocol", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Protocol)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "HOPOPT", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ICMP", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "IGMP", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "GGP", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "IPv4", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "ST", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "TCP", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "CBT", { .i32=7 }};
+ struct dict_enumval_data t_9 = { "EGP", { .i32=8 }};
+ struct dict_enumval_data t_10 = { "IGP", { .i32=9 }};
+ struct dict_enumval_data t_11 = { "BBN-RCC-MON", { .i32=10 }};
+ struct dict_enumval_data t_12 = { "NVP-II", { .i32=11 }};
+ struct dict_enumval_data t_13 = { "PUP", { .i32=12 }};
+ struct dict_enumval_data t_14 = { "ARGUS", { .i32=13 }};
+ struct dict_enumval_data t_15 = { "EMCON", { .i32=14 }};
+ struct dict_enumval_data t_16 = { "XNET", { .i32=15 }};
+ struct dict_enumval_data t_17 = { "CHAOS", { .i32=16 }};
+ struct dict_enumval_data t_18 = { "UDP", { .i32=17 }};
+ struct dict_enumval_data t_19 = { "MUX", { .i32=18 }};
+ struct dict_enumval_data t_20 = { "DCN-MEAS", { .i32=19 }};
+ struct dict_enumval_data t_21 = { "HMP", { .i32=20 }};
+ struct dict_enumval_data t_22 = { "PRM", { .i32=21 }};
+ struct dict_enumval_data t_23 = { "XNS-IDP", { .i32=22 }};
+ struct dict_enumval_data t_24 = { "TRUNK-1", { .i32=23 }};
+ struct dict_enumval_data t_25 = { "TRUNK-2", { .i32=24 }};
+ struct dict_enumval_data t_26 = { "LEAF-1", { .i32=25 }};
+ struct dict_enumval_data t_27 = { "LEAF-2", { .i32=26 }};
+ struct dict_enumval_data t_28 = { "RDP", { .i32=27 }};
+ struct dict_enumval_data t_29 = { "IRTP", { .i32=28 }};
+ struct dict_enumval_data t_30 = { "ISO-TP4", { .i32=29 }};
+ struct dict_enumval_data t_31 = { "NETBLT", { .i32=30 }};
+ struct dict_enumval_data t_32 = { "MFE-NSP", { .i32=31 }};
+ struct dict_enumval_data t_33 = { "MERIT-INP", { .i32=32 }};
+ struct dict_enumval_data t_34 = { "DCCP", { .i32=33 }};
+ struct dict_enumval_data t_35 = { "3PC", { .i32=34 }};
+ struct dict_enumval_data t_36 = { "IDPR", { .i32=35 }};
+ struct dict_enumval_data t_37 = { "XTP", { .i32=36 }};
+ struct dict_enumval_data t_38 = { "DDP", { .i32=37 }};
+ struct dict_enumval_data t_39 = { "IDPR-CMTP", { .i32=38 }};
+ struct dict_enumval_data t_40 = { "TPplusplus", { .i32=39 }};
+ struct dict_enumval_data t_41 = { "IL", { .i32=40 }};
+ struct dict_enumval_data t_42 = { "IPv6", { .i32=41 }};
+ struct dict_enumval_data t_43 = { "SDRP", { .i32=42 }};
+ struct dict_enumval_data t_44 = { "IPv6-Route", { .i32=43 }};
+ struct dict_enumval_data t_45 = { "IPv6-Frag", { .i32=44 }};
+ struct dict_enumval_data t_46 = { "IDRP", { .i32=45 }};
+ struct dict_enumval_data t_47 = { "RSVP", { .i32=46 }};
+ struct dict_enumval_data t_48 = { "GRE", { .i32=47 }};
+ struct dict_enumval_data t_49 = { "DSR", { .i32=48 }};
+ struct dict_enumval_data t_50 = { "BNA", { .i32=49 }};
+ struct dict_enumval_data t_51 = { "ESP", { .i32=50 }};
+ struct dict_enumval_data t_52 = { "AH", { .i32=51 }};
+ struct dict_enumval_data t_53 = { "I-NLSP", { .i32=52 }};
+ struct dict_enumval_data t_54 = { "SWIPE", { .i32=53 }};
+ struct dict_enumval_data t_55 = { "NARP", { .i32=54 }};
+ struct dict_enumval_data t_56 = { "MOBILE", { .i32=55 }};
+ struct dict_enumval_data t_57 = { "TLSP", { .i32=56 }};
+ struct dict_enumval_data t_58 = { "SKIP", { .i32=57 }};
+ struct dict_enumval_data t_59 = { "IPv6-ICMP", { .i32=58 }};
+ struct dict_enumval_data t_60 = { "IPv6-NoNxt", { .i32=59 }};
+ struct dict_enumval_data t_61 = { "IPv6-Opts", { .i32=60 }};
+ struct dict_enumval_data t_62 = { "CFTP", { .i32=62 }};
+ struct dict_enumval_data t_63 = { "SAT-EXPAK", { .i32=64 }};
+ struct dict_enumval_data t_64 = { "KRYPTOLAN", { .i32=65 }};
+ struct dict_enumval_data t_65 = { "RVD", { .i32=66 }};
+ struct dict_enumval_data t_66 = { "IPPC", { .i32=67 }};
+ struct dict_enumval_data t_67 = { "SAT-MON", { .i32=69 }};
+ struct dict_enumval_data t_68 = { "VISA", { .i32=70 }};
+ struct dict_enumval_data t_69 = { "IPCV", { .i32=71 }};
+ struct dict_enumval_data t_70 = { "CPNX", { .i32=72 }};
+ struct dict_enumval_data t_71 = { "CPHB", { .i32=73 }};
+ struct dict_enumval_data t_72 = { "WSN", { .i32=74 }};
+ struct dict_enumval_data t_73 = { "PVP", { .i32=75 }};
+ struct dict_enumval_data t_74 = { "BR-SAT-MON", { .i32=76 }};
+ struct dict_enumval_data t_75 = { "SUN-ND", { .i32=77 }};
+ struct dict_enumval_data t_76 = { "WB-MON", { .i32=78 }};
+ struct dict_enumval_data t_77 = { "WB-EXPAK", { .i32=79 }};
+ struct dict_enumval_data t_78 = { "ISO-IP", { .i32=80 }};
+ struct dict_enumval_data t_79 = { "VMTP", { .i32=81 }};
+ struct dict_enumval_data t_80 = { "SECURE-VMTP", { .i32=82 }};
+ struct dict_enumval_data t_81 = { "VINES", { .i32=83 }};
+ struct dict_enumval_data t_82 = { "TTP", { .i32=84 }};
+ struct dict_enumval_data t_83 = { "IPTM", { .i32=84 }};
+ struct dict_enumval_data t_84 = { "NSFNET-IGP", { .i32=85 }};
+ struct dict_enumval_data t_85 = { "DGP", { .i32=86 }};
+ struct dict_enumval_data t_86 = { "TCF", { .i32=87 }};
+ struct dict_enumval_data t_87 = { "EIGRP", { .i32=88 }};
+ struct dict_enumval_data t_88 = { "OSPFIGP", { .i32=89 }};
+ struct dict_enumval_data t_89 = { "Sprite-RPC", { .i32=90 }};
+ struct dict_enumval_data t_90 = { "LARP", { .i32=91 }};
+ struct dict_enumval_data t_91 = { "MTP", { .i32=92 }};
+ struct dict_enumval_data t_92 = { "AX_25", { .i32=93 }};
+ struct dict_enumval_data t_93 = { "IPIP", { .i32=94 }};
+ struct dict_enumval_data t_94 = { "MICP", { .i32=95 }};
+ struct dict_enumval_data t_95 = { "SCC-SP", { .i32=96 }};
+ struct dict_enumval_data t_96 = { "ETHERIP", { .i32=97 }};
+ struct dict_enumval_data t_97 = { "ENCAP", { .i32=98 }};
+ struct dict_enumval_data t_98 = { "GMTP", { .i32=100 }};
+ struct dict_enumval_data t_99 = { "IFMP", { .i32=101 }};
+ struct dict_enumval_data t_100 = { "PNNI", { .i32=102 }};
+ struct dict_enumval_data t_101 = { "PIM", { .i32=103 }};
+ struct dict_enumval_data t_102 = { "ARIS", { .i32=104 }};
+ struct dict_enumval_data t_103 = { "SCPS", { .i32=105 }};
+ struct dict_enumval_data t_104 = { "QNX", { .i32=106 }};
+ struct dict_enumval_data t_105 = { "A_N", { .i32=107 }};
+ struct dict_enumval_data t_106 = { "IPComp", { .i32=108 }};
+ struct dict_enumval_data t_107 = { "SNP", { .i32=109 }};
+ struct dict_enumval_data t_108 = { "Compaq-Peer", { .i32=110 }};
+ struct dict_enumval_data t_109 = { "IPX-in-IP", { .i32=111 }};
+ struct dict_enumval_data t_110 = { "VRRP", { .i32=112 }};
+ struct dict_enumval_data t_111 = { "PGM", { .i32=113 }};
+ struct dict_enumval_data t_112 = { "L2TP", { .i32=115 }};
+ struct dict_enumval_data t_113 = { "DDX", { .i32=116 }};
+ struct dict_enumval_data t_114 = { "IATP", { .i32=117 }};
+ struct dict_enumval_data t_115 = { "STP", { .i32=118 }};
+ struct dict_enumval_data t_116 = { "SRP", { .i32=119 }};
+ struct dict_enumval_data t_117 = { "UTI", { .i32=120 }};
+ struct dict_enumval_data t_118 = { "SMP", { .i32=121 }};
+ struct dict_enumval_data t_119 = { "SM", { .i32=122 }};
+ struct dict_enumval_data t_120 = { "PTP", { .i32=123 }};
+ struct dict_enumval_data t_121 = { "ISISoverIPv4", { .i32=124 }};
+ struct dict_enumval_data t_122 = { "FIRE", { .i32=125 }};
+ struct dict_enumval_data t_123 = { "CRTP", { .i32=126 }};
+ struct dict_enumval_data t_124 = { "CRUDP", { .i32=127 }};
+ struct dict_enumval_data t_125 = { "SSCOPMCE", { .i32=128 }};
+ struct dict_enumval_data t_126 = { "IPLT", { .i32=129 }};
+ struct dict_enumval_data t_127 = { "SPS", { .i32=130 }};
+ struct dict_enumval_data t_128 = { "PIPE", { .i32=131 }};
+ struct dict_enumval_data t_129 = { "SCTP", { .i32=132 }};
+ struct dict_enumval_data t_130 = { "FC", { .i32=133 }};
+ struct dict_enumval_data t_131 = { "RSVP-E2E-IGNORE", { .i32=134 }};
+ struct dict_enumval_data t_132 = { "MobilityHeader", { .i32=135 }};
+ struct dict_enumval_data t_133 = { "UDPLite", { .i32=136 }};
+ struct dict_enumval_data t_134 = { "MPLS-in-IP", { .i32=137 }};
+ struct dict_enumval_data t_135 = { "manet", { .i32=138 }};
+ struct dict_enumval_data t_136 = { "HIP", { .i32=139 }};
+ struct dict_enumval_data t_137 = { "Shim6", { .i32=140 }};
+ struct dict_enumval_data t_138 = { "WESP", { .i32=141 }};
+ struct dict_enumval_data t_139 = { "ROHC", { .i32=142 }};
+ struct dict_enumval_data t_140 = { "Reserved", { .i32=255 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_26, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_27, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_28, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_29, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_30, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_31, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_32, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_33, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_34, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_35, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_36, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_37, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_38, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_39, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_40, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_41, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_42, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_43, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_44, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_45, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_46, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_47, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_48, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_49, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_50, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_51, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_52, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_53, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_54, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_55, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_56, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_57, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_58, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_59, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_60, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_61, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_62, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_63, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_64, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_65, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_66, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_67, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_68, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_69, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_70, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_71, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_72, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_73, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_74, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_75, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_76, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_77, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_78, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_79, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_80, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_81, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_82, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_83, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_84, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_85, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_86, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_87, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_88, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_89, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_90, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_91, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_92, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_93, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_94, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_95, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_96, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_97, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_98, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_99, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_100, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_101, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_102, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_103, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_104, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_105, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_106, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_107, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_108, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_109, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_110, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_111, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_112, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_113, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_114, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_115, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_116, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_117, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_118, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_119, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_120, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_121, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_122, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_123, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_124, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_125, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_126, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_127, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_128, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_129, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_130, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_131, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_132, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_133, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_134, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_135, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_136, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_137, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_138, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_139, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_140, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Direction */
+ {
+ struct dict_avp_data data = {
+ 514, /* Code */
+ 0, /* Vendor */
+ "Direction", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Direction)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "IN", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "OUT", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "BOTH", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Negated */
+ {
+ struct dict_avp_data data = {
+ 517, /* Code */
+ 0, /* Vendor */
+ "Negated", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Negated)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "False", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "True", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* IP-Address */
+ {
+ struct dict_avp_data data = {
+ 518, /* Code */
+ 0, /* Vendor */
+ "IP-Address", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* IP-Address-Start */
+ {
+ struct dict_avp_data data = {
+ 520, /* Code */
+ 0, /* Vendor */
+ "IP-Address-Start", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* IP-Address-End */
+ {
+ struct dict_avp_data data = {
+ 521, /* Code */
+ 0, /* Vendor */
+ "IP-Address-End", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* IP-Bit-Mask-Width */
+ {
+ struct dict_avp_data data = {
+ 523, /* Code */
+ 0, /* Vendor */
+ "IP-Bit-Mask-Width", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MAC-Address */
+ {
+ struct dict_avp_data data = {
+ 524, /* Code */
+ 0, /* Vendor */
+ "MAC-Address", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MAC-Address-Mask-Pattern */
+ {
+ struct dict_avp_data data = {
+ 526, /* Code */
+ 0, /* Vendor */
+ "MAC-Address-Mask-Pattern", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* EUI64-Address */
+ {
+ struct dict_avp_data data = {
+ 527, /* Code */
+ 0, /* Vendor */
+ "EUI64-Address", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* EUI64-Address-Mask-Pattern */
+ {
+ struct dict_avp_data data = {
+ 529, /* Code */
+ 0, /* Vendor */
+ "EUI64-Address-Mask-Pattern", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Port */
+ {
+ struct dict_avp_data data = {
+ 530, /* Code */
+ 0, /* Vendor */
+ "Port", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Port-Start */
+ {
+ struct dict_avp_data data = {
+ 532, /* Code */
+ 0, /* Vendor */
+ "Port-Start", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Port-End */
+ {
+ struct dict_avp_data data = {
+ 533, /* Code */
+ 0, /* Vendor */
+ "Port-End", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Use-Assigned-Address */
+ {
+ struct dict_avp_data data = {
+ 534, /* Code */
+ 0, /* Vendor */
+ "Use-Assigned-Address", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Use-Assigned-Address)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "False", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "True", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Diffserv-Code-Point */
+ {
+ struct dict_avp_data data = {
+ 535, /* Code */
+ 0, /* Vendor */
+ "Diffserv-Code-Point", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Diffserv-Code-Point)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CS0", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CS1", { .i32=8 }};
+ struct dict_enumval_data t_3 = { "CS2", { .i32=16 }};
+ struct dict_enumval_data t_4 = { "CS3", { .i32=24 }};
+ struct dict_enumval_data t_5 = { "CS4", { .i32=32 }};
+ struct dict_enumval_data t_6 = { "CS5", { .i32=40 }};
+ struct dict_enumval_data t_7 = { "CS6", { .i32=48 }};
+ struct dict_enumval_data t_8 = { "CS7", { .i32=56 }};
+ struct dict_enumval_data t_9 = { "AF11", { .i32=10 }};
+ struct dict_enumval_data t_10 = { "AF12", { .i32=12 }};
+ struct dict_enumval_data t_11 = { "AF13", { .i32=14 }};
+ struct dict_enumval_data t_12 = { "AF21", { .i32=18 }};
+ struct dict_enumval_data t_13 = { "AF22", { .i32=20 }};
+ struct dict_enumval_data t_14 = { "AF23", { .i32=22 }};
+ struct dict_enumval_data t_15 = { "AF31", { .i32=26 }};
+ struct dict_enumval_data t_16 = { "AF32", { .i32=28 }};
+ struct dict_enumval_data t_17 = { "AF33", { .i32=30 }};
+ struct dict_enumval_data t_18 = { "AF41", { .i32=34 }};
+ struct dict_enumval_data t_19 = { "AF42", { .i32=36 }};
+ struct dict_enumval_data t_20 = { "AF43", { .i32=38 }};
+ struct dict_enumval_data t_21 = { "EF", { .i32=46 }};
+ struct dict_enumval_data t_22 = { "VOICE_ADMIT", { .i32=44 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Fragmentation-Flag */
+ {
+ struct dict_avp_data data = {
+ 536, /* Code */
+ 0, /* Vendor */
+ "Fragmentation-Flag", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Fragmentation-Flag)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DF", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MF", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* IP-Option-Type */
+ {
+ struct dict_avp_data data = {
+ 538, /* Code */
+ 0, /* Vendor */
+ "IP-Option-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(IP-Option-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "EOOL", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NOP", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "SEC", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "LSR", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "TS", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "E-SEC", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "CIPSO", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "RR", { .i32=7 }};
+ struct dict_enumval_data t_9 = { "SID", { .i32=8 }};
+ struct dict_enumval_data t_10 = { "SSR", { .i32=9 }};
+ struct dict_enumval_data t_11 = { "ZSU", { .i32=10 }};
+ struct dict_enumval_data t_12 = { "MTUP", { .i32=11 }};
+ struct dict_enumval_data t_13 = { "MTUR", { .i32=12 }};
+ struct dict_enumval_data t_14 = { "FINN", { .i32=13 }};
+ struct dict_enumval_data t_15 = { "VISA", { .i32=14 }};
+ struct dict_enumval_data t_16 = { "ENCODE", { .i32=15 }};
+ struct dict_enumval_data t_17 = { "IMITD", { .i32=16 }};
+ struct dict_enumval_data t_18 = { "EIP", { .i32=17 }};
+ struct dict_enumval_data t_19 = { "TR", { .i32=18 }};
+ struct dict_enumval_data t_20 = { "ADDEXT", { .i32=19 }};
+ struct dict_enumval_data t_21 = { "RTRALT", { .i32=20 }};
+ struct dict_enumval_data t_22 = { "SDB", { .i32=21 }};
+ struct dict_enumval_data t_23 = { "DPS", { .i32=23 }};
+ struct dict_enumval_data t_24 = { "UMP", { .i32=24 }};
+ struct dict_enumval_data t_25 = { "QS", { .i32=25 }};
+ struct dict_enumval_data t_26 = { "EXP", { .i32=30 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_26, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* IP-Option-Value */
+ {
+ struct dict_avp_data data = {
+ 539, /* Code */
+ 0, /* Vendor */
+ "IP-Option-Value", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TCP-Option-Type */
+ {
+ struct dict_avp_data data = {
+ 541, /* Code */
+ 0, /* Vendor */
+ "TCP-Option-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(TCP-Option-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "EOL", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NOP", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "MAX_SEG_SZ", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Window_Scale", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "SACK_Permitted", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "SACK", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "Echo", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "Echo_Reply", { .i32=7 }};
+ struct dict_enumval_data t_9 = { "Timestamps", { .i32=8 }};
+ struct dict_enumval_data t_10 = { "PartialOrderConnectionPermitted", { .i32=9 }};
+ struct dict_enumval_data t_11 = { "PartialOrderServiceProfile", { .i32=10 }};
+ struct dict_enumval_data t_12 = { "CC", { .i32=11 }};
+ struct dict_enumval_data t_13 = { "CC_NEW", { .i32=12 }};
+ struct dict_enumval_data t_14 = { "CC_ECHO", { .i32=13 }};
+ struct dict_enumval_data t_15 = { "TCP_Alternate_Checksum_Request", { .i32=14 }};
+ struct dict_enumval_data t_16 = { "TCP_Alternate_Checksum_Data", { .i32=15 }};
+ struct dict_enumval_data t_17 = { "Skeeter", { .i32=16 }};
+ struct dict_enumval_data t_18 = { "Bubba", { .i32=17 }};
+ struct dict_enumval_data t_19 = { "Trailer_Checksum_Option", { .i32=18 }};
+ struct dict_enumval_data t_20 = { "MD5_Signature_Option", { .i32=19 }};
+ struct dict_enumval_data t_21 = { "SCPS_Capabilities", { .i32=20 }};
+ struct dict_enumval_data t_22 = { "Selective_Negative_Acknowledgements", { .i32=21 }};
+ struct dict_enumval_data t_23 = { "Record_Boundaries", { .i32=22 }};
+ struct dict_enumval_data t_24 = { "Corruption_experienced", { .i32=23 }};
+ struct dict_enumval_data t_25 = { "SNAP", { .i32=24 }};
+ struct dict_enumval_data t_26 = { "TCP_Compression_Filter", { .i32=26 }};
+ struct dict_enumval_data t_27 = { "Quick-Start_Response", { .i32=27 }};
+ struct dict_enumval_data t_28 = { "User_Timeout_Option", { .i32=28 }};
+ struct dict_enumval_data t_29 = { "TCP_Authentication_Option", { .i32=29 }};
+ struct dict_enumval_data t_30 = { "Multipath_TCP", { .i32=30 }};
+ struct dict_enumval_data t_31 = { "Reserved1", { .i32=31 }};
+ struct dict_enumval_data t_32 = { "Reserved2", { .i32=32 }};
+ struct dict_enumval_data t_33 = { "Reserved3", { .i32=33 }};
+ struct dict_enumval_data t_34 = { "TCP_Fast_Open_Cookie", { .i32=34 }};
+ struct dict_enumval_data t_35 = { "Reserved4", { .i32=69 }};
+ struct dict_enumval_data t_36 = { "Reserved5", { .i32=70 }};
+ struct dict_enumval_data t_37 = { "Reserved6", { .i32=76 }};
+ struct dict_enumval_data t_38 = { "Reserved7", { .i32=77 }};
+ struct dict_enumval_data t_39 = { "Reserved8", { .i32=78 }};
+ struct dict_enumval_data t_40 = { "RFC3692-style_Experiment_1", { .i32=253 }};
+ struct dict_enumval_data t_41 = { "RFC3692-style_Experiment_2", { .i32=254 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_26, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_27, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_28, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_29, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_30, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_31, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_32, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_33, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_34, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_35, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_36, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_37, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_38, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_39, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_40, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_41, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* TCP-Option-Value */
+ {
+ struct dict_avp_data data = {
+ 542, /* Code */
+ 0, /* Vendor */
+ "TCP-Option-Value", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TCP-Flag-Type */
+ {
+ struct dict_avp_data data = {
+ 544, /* Code */
+ 0, /* Vendor */
+ "TCP-Flag-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ICMP-Type-Number */
+ {
+ struct dict_avp_data data = {
+ 546, /* Code */
+ 0, /* Vendor */
+ "ICMP-Type-Number", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(ICMP-Type-Number)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Echo_Reply", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Destination_Unreachable", { .i32=3 }};
+ struct dict_enumval_data t_3 = { "Source_Quench", { .i32=4 }};
+ struct dict_enumval_data t_4 = { "Redirect", { .i32=5 }};
+ struct dict_enumval_data t_5 = { "Alternate_Host_Address", { .i32=6 }};
+ struct dict_enumval_data t_6 = { "Echo", { .i32=8 }};
+ struct dict_enumval_data t_7 = { "Router_Advertisement", { .i32=9 }};
+ struct dict_enumval_data t_8 = { "Router_Solicitation", { .i32=10 }};
+ struct dict_enumval_data t_9 = { "Time_Exceeded", { .i32=11 }};
+ struct dict_enumval_data t_10 = { "Parameter_Problem", { .i32=12 }};
+ struct dict_enumval_data t_11 = { "Timestamp", { .i32=13 }};
+ struct dict_enumval_data t_12 = { "Timestamp_Reply", { .i32=14 }};
+ struct dict_enumval_data t_13 = { "Information_Request", { .i32=15 }};
+ struct dict_enumval_data t_14 = { "Information_Reply", { .i32=16 }};
+ struct dict_enumval_data t_15 = { "Address_Mask_Request", { .i32=17 }};
+ struct dict_enumval_data t_16 = { "Address_Mask_Reply", { .i32=18 }};
+ struct dict_enumval_data t_17 = { "Traceroute", { .i32=30 }};
+ struct dict_enumval_data t_18 = { "Datagram_Conversion_Error", { .i32=31 }};
+ struct dict_enumval_data t_19 = { "Mobile_Host_Redirect", { .i32=32 }};
+ struct dict_enumval_data t_20 = { "IPv6_Where-Are-You", { .i32=33 }};
+ struct dict_enumval_data t_21 = { "IPv6_I-Am-Here", { .i32=34 }};
+ struct dict_enumval_data t_22 = { "Mobile_Registration_Request", { .i32=35 }};
+ struct dict_enumval_data t_23 = { "Mobile_Registration_Reply", { .i32=36 }};
+ struct dict_enumval_data t_24 = { "Domain_Name_Request", { .i32=37 }};
+ struct dict_enumval_data t_25 = { "Domain_Name_Reply", { .i32=38 }};
+ struct dict_enumval_data t_26 = { "SKIP", { .i32=39 }};
+ struct dict_enumval_data t_27 = { "Photuris", { .i32=40 }};
+ struct dict_enumval_data t_28 = { "ICMP_messages_utilized_by_experimental", { .i32=41 }};
+ struct dict_enumval_data t_29 = { "RFC3692-style_Experiment_1", { .i32=253 }};
+ struct dict_enumval_data t_30 = { "RFC3692-style_Experiment_2", { .i32=254 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_26, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_27, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_28, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_29, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_30, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ICMP-Code */
+ {
+ struct dict_avp_data data = {
+ 547, /* Code */
+ 0, /* Vendor */
+ "ICMP-Code", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(ICMP-Code)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Echo_Reply", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Destination_Unreachable", { .i32=3 }};
+ struct dict_enumval_data t_3 = { "Source_Quench", { .i32=4 }};
+ struct dict_enumval_data t_4 = { "Redirect", { .i32=5 }};
+ struct dict_enumval_data t_5 = { "Alternate_Host_Address", { .i32=6 }};
+ struct dict_enumval_data t_6 = { "Echo", { .i32=8 }};
+ struct dict_enumval_data t_7 = { "Router_Advertisement", { .i32=9 }};
+ struct dict_enumval_data t_8 = { "Router_Solicitation", { .i32=10 }};
+ struct dict_enumval_data t_9 = { "Time_Exceeded", { .i32=11 }};
+ struct dict_enumval_data t_10 = { "Parameter_Problem", { .i32=12 }};
+ struct dict_enumval_data t_11 = { "Timestamp", { .i32=13 }};
+ struct dict_enumval_data t_12 = { "Timestamp_Reply", { .i32=14 }};
+ struct dict_enumval_data t_13 = { "Information_Request", { .i32=15 }};
+ struct dict_enumval_data t_14 = { "Information_Reply", { .i32=16 }};
+ struct dict_enumval_data t_15 = { "Address_Mask_Request", { .i32=17 }};
+ struct dict_enumval_data t_16 = { "Address_Mask_Reply", { .i32=18 }};
+ struct dict_enumval_data t_17 = { "Traceroute", { .i32=30 }};
+ struct dict_enumval_data t_18 = { "Datagram_Conversion_Error", { .i32=31 }};
+ struct dict_enumval_data t_19 = { "Mobile_Host_Redirect", { .i32=32 }};
+ struct dict_enumval_data t_20 = { "IPv6_Where-Are-You", { .i32=33 }};
+ struct dict_enumval_data t_21 = { "IPv6_I-Am-Here", { .i32=34 }};
+ struct dict_enumval_data t_22 = { "Mobile_Registration_Request", { .i32=35 }};
+ struct dict_enumval_data t_23 = { "Mobile_Registration_Reply", { .i32=36 }};
+ struct dict_enumval_data t_24 = { "Domain_Name_Request", { .i32=37 }};
+ struct dict_enumval_data t_25 = { "Domain_Name_Reply", { .i32=38 }};
+ struct dict_enumval_data t_26 = { "SKIP", { .i32=39 }};
+ struct dict_enumval_data t_27 = { "Photuris", { .i32=40 }};
+ struct dict_enumval_data t_28 = { "ICMP_messages_utilized_by_experimental", { .i32=41 }};
+ struct dict_enumval_data t_29 = { "RFC3692-style_Experiment_1", { .i32=253 }};
+ struct dict_enumval_data t_30 = { "RFC3692-style_Experiment_2", { .i32=254 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_26, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_27, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_28, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_29, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_30, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ETH-Ether-Type */
+ {
+ struct dict_avp_data data = {
+ 550, /* Code */
+ 0, /* Vendor */
+ "ETH-Ether-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ETH-SAP */
+ {
+ struct dict_avp_data data = {
+ 551, /* Code */
+ 0, /* Vendor */
+ "ETH-SAP", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* S-VID-Start */
+ {
+ struct dict_avp_data data = {
+ 553, /* Code */
+ 0, /* Vendor */
+ "S-VID-Start", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* S-VID-End */
+ {
+ struct dict_avp_data data = {
+ 554, /* Code */
+ 0, /* Vendor */
+ "S-VID-End", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* C-VID-Start */
+ {
+ struct dict_avp_data data = {
+ 555, /* Code */
+ 0, /* Vendor */
+ "C-VID-Start", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* C-VID-End */
+ {
+ struct dict_avp_data data = {
+ 556, /* Code */
+ 0, /* Vendor */
+ "C-VID-End", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Low-User-Priority */
+ {
+ struct dict_avp_data data = {
+ 558, /* Code */
+ 0, /* Vendor */
+ "Low-User-Priority", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* High-User-Priority */
+ {
+ struct dict_avp_data data = {
+ 559, /* Code */
+ 0, /* Vendor */
+ "High-User-Priority", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Time-Of-Day-Start */
+ {
+ struct dict_avp_data data = {
+ 561, /* Code */
+ 0, /* Vendor */
+ "Time-Of-Day-Start", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Time-Of-Day-End */
+ {
+ struct dict_avp_data data = {
+ 562, /* Code */
+ 0, /* Vendor */
+ "Time-Of-Day-End", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Day-Of-Week-Mask */
+ {
+ struct dict_avp_data data = {
+ 563, /* Code */
+ 0, /* Vendor */
+ "Day-Of-Week-Mask", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Day-Of-Month-Mask */
+ {
+ struct dict_avp_data data = {
+ 564, /* Code */
+ 0, /* Vendor */
+ "Day-Of-Month-Mask", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Month-Of-Year-Mask */
+ {
+ struct dict_avp_data data = {
+ 565, /* Code */
+ 0, /* Vendor */
+ "Month-Of-Year-Mask", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Absolute-Start-Time */
+ {
+ struct dict_avp_data data = {
+ 566, /* Code */
+ 0, /* Vendor */
+ "Absolute-Start-Time", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Absolute-Start-Fractional-Seconds */
+ {
+ struct dict_avp_data data = {
+ 567, /* Code */
+ 0, /* Vendor */
+ "Absolute-Start-Fractional-Seconds", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Absolute-End-Time */
+ {
+ struct dict_avp_data data = {
+ 568, /* Code */
+ 0, /* Vendor */
+ "Absolute-End-Time", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Absolute-End-Fractional-Seconds */
+ {
+ struct dict_avp_data data = {
+ 569, /* Code */
+ 0, /* Vendor */
+ "Absolute-End-Fractional-Seconds", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Timezone-Flag */
+ {
+ struct dict_avp_data data = {
+ 570, /* Code */
+ 0, /* Vendor */
+ "Timezone-Flag", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Timezone-Flag)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UTC", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "LOCAL", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "OFFSET", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Timezone-Offset */
+ {
+ struct dict_avp_data data = {
+ 571, /* Code */
+ 0, /* Vendor */
+ "Timezone-Offset", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Treatment-Action */
+ {
+ struct dict_avp_data data = {
+ 572, /* Code */
+ 0, /* Vendor */
+ "Treatment-Action", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Treatment-Action)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "drop", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "shape", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "mark", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "permit", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* QoS-Profile-Id */
+ {
+ struct dict_avp_data data = {
+ 573, /* Code */
+ 0, /* Vendor */
+ "QoS-Profile-Id", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* QoS-Semantics */
+ {
+ struct dict_avp_data data = {
+ 575, /* Code */
+ 0, /* Vendor */
+ "QoS-Semantics", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(QoS-Semantics)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "QoS_Desired", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "QoS_Available", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "QoS_Delivered", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Minimum_QoS", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "QoS_Authorized", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* QoS-Parameters */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 576, /* Code */
+ 0, /* Vendor */
+ "QoS-Parameters", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ETH-Proto-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 549, /* Code */
+ 0, /* Vendor */
+ "ETH-Proto-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* VLAN-ID-Range */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 552, /* Code */
+ 0, /* Vendor */
+ "VLAN-ID-Range", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* IP-Option */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 537, /* Code */
+ 0, /* Vendor */
+ "IP-Option", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* IP-Address-Mask */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 522, /* Code */
+ 0, /* Vendor */
+ "IP-Address-Mask", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Time-Of-Day-Condition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 560, /* Code */
+ 0, /* Vendor */
+ "Time-Of-Day-Condition", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TCP-Option */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 540, /* Code */
+ 0, /* Vendor */
+ "TCP-Option", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MAC-Address-Mask */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 525, /* Code */
+ 0, /* Vendor */
+ "MAC-Address-Mask", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TCP-Flags */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 543, /* Code */
+ 0, /* Vendor */
+ "TCP-Flags", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Port-Range */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 531, /* Code */
+ 0, /* Vendor */
+ "Port-Range", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ICMP-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 545, /* Code */
+ 0, /* Vendor */
+ "ICMP-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* User-Priority-Range */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 557, /* Code */
+ 0, /* Vendor */
+ "User-Priority-Range", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* QoS-Profile-Template */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 574, /* Code */
+ 0, /* Vendor */
+ "QoS-Profile-Template", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* IP-Address-Range */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 519, /* Code */
+ 0, /* Vendor */
+ "IP-Address-Range", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* EUI64-Address-Mask */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 528, /* Code */
+ 0, /* Vendor */
+ "EUI64-Address-Mask", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* From-Spec */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 515, /* Code */
+ 0, /* Vendor */
+ "From-Spec", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Excess-Treatment */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 577, /* Code */
+ 0, /* Vendor */
+ "Excess-Treatment", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ETH-Option */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 548, /* Code */
+ 0, /* Vendor */
+ "ETH-Option", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* To-Spec */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 516, /* Code */
+ 0, /* Vendor */
+ "To-Spec", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* QoS-Capability */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 578, /* Code */
+ 0, /* Vendor */
+ "QoS-Capability", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Classifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 511, /* Code */
+ 0, /* Vendor */
+ "Classifier", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Filter-Rule */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 509, /* Code */
+ 0, /* Vendor */
+ "Filter-Rule", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* QoS-Resources */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 508, /* Code */
+ 0, /* Vendor */
+ "QoS-Resources", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc5777_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* QoS-Parameters */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "QoS-Parameters"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ETH-Proto-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "ETH-Proto-Type"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "ETH-Ether-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "ETH-SAP"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* VLAN-ID-Range */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "VLAN-ID-Range"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "S-VID-Start"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "S-VID-End"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "C-VID-Start"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "C-VID-End"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* IP-Option */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "IP-Option"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "IP-Option-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "IP-Option-Value"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Negated"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* IP-Address-Mask */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "IP-Address-Mask"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "IP-Address"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "IP-Bit-Mask-Width"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Time-Of-Day-Condition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Time-Of-Day-Condition"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Time-Of-Day-Start"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Time-Of-Day-End"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Day-Of-Week-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Day-Of-Month-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Month-Of-Year-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Absolute-Start-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Absolute-End-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Timezone-Flag"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TCP-Option */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "TCP-Option"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "TCP-Option-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "TCP-Option-Value"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Negated"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MAC-Address-Mask */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MAC-Address-Mask"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MAC-Address"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MAC-Address-Mask-Pattern"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TCP-Flags */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "TCP-Flags"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "TCP-Flag-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Negated"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Port-Range */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Port-Range"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Port-Start"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Port-End"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ICMP-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "ICMP-Type"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "ICMP-Type-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "ICMP-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Negated"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* User-Priority-Range */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "User-Priority-Range"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Low-User-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "High-User-Priority"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* QoS-Profile-Template */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "QoS-Profile-Template"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Vendor-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "QoS-Profile-Id"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* IP-Address-Range */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "IP-Address-Range"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "IP-Address-Start"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "IP-Address-End"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* EUI64-Address-Mask */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "EUI64-Address-Mask"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "EUI64-Address"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "EUI64-Address-Mask-Pattern"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* From-Spec */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "From-Spec"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "IP-Address-Range"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "IP-Address-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MAC-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MAC-Address-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "EUI64-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "EUI64-Address-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Port-Range"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Negated"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Use-Assigned-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Excess-Treatment */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Excess-Treatment"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Treatment-Action"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "QoS-Profile-Template"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "QoS-Parameters"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ETH-Option */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "ETH-Option"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "ETH-Proto-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "VLAN-ID-Range"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Priority-Range"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* To-Spec */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "To-Spec"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "IP-Address-Range"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "IP-Address-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MAC-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MAC-Address-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "EUI64-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "EUI64-Address-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Port-Range"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Negated"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Use-Assigned-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* QoS-Capability */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "QoS-Capability"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "QoS-Profile-Template"}, RULE_REQUIRED, 1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Classifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Classifier"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Classifier-ID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Direction"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "From-Spec"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "To-Spec"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Diffserv-Code-Point"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Fragmentation-Flag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "IP-Option"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "TCP-Option"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "TCP-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "ICMP-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "ETH-Option"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Filter-Rule */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Filter-Rule"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Filter-Rule-Precedence"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Classifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Time-Of-Day-Condition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Treatment-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "QoS-Semantics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "QoS-Profile-Template"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "QoS-Parameters"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Excess-Treatment"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* QoS-Resources */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "QoS-Resources"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Filter-Rule"}, RULE_REQUIRED, 1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc5777_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc5777_avps_load_defs(conffile);
+ return dict_rfc5777_avps_load_rules(conffile);
+}
+
+const char* dict_rfc5777_avps_proto_ver(char * conffile) {
+ return rfc5777_avps_proto_ver;
+}
+
+const double dict_rfc5777_avps_gen_ts(char * conffile) {
+ return rfc5777_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc5777_avps", dict_rfc5777_avps_load_defs, dict_rfc5777_avps_load_rules);
+
+
+
diff --git a/extensions/dict_rfc5777_avps/rfc5777_avps.did b/extensions/dict_rfc5777_avps/rfc5777_avps.did
new file mode 100644
index 0000000..d94dddb
--- /dev/null
+++ b/extensions/dict_rfc5777_avps/rfc5777_avps.did
@@ -0,0 +1 @@
+dict_rfc5777_avps
diff --git a/extensions/dict_rfc5778_avps/CMakeLists.txt b/extensions/dict_rfc5778_avps/CMakeLists.txt
new file mode 100644
index 0000000..06abe56
--- /dev/null
+++ b/extensions/dict_rfc5778_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc5778_avps extension
+PROJECT("dict_rfc5778_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc5778_avps dict_rfc5778_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc5778_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC5778_AVPS)
+
+
+
diff --git a/extensions/dict_rfc5778_avps/dict_rfc5778_avps.c b/extensions/dict_rfc5778_avps/dict_rfc5778_avps.c
new file mode 100644
index 0000000..8d88569
--- /dev/null
+++ b/extensions/dict_rfc5778_avps/dict_rfc5778_avps.c
@@ -0,0 +1,286 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc5778_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.61
+
+const char *rfc5778_avps_proto_ver = PROTO_VER;
+const double rfc5778_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc5778_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Service-Selection */
+ {
+ struct dict_avp_data data = {
+ 493, /* Code */
+ 0, /* Vendor */
+ "Service-Selection", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* MIP-MN-HA-SPI */
+ {
+ struct dict_avp_data data = {
+ 491, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-HA-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Careof-Address */
+ {
+ struct dict_avp_data data = {
+ 487, /* Code */
+ 0, /* Vendor */
+ "MIP-Careof-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* MIP-Authenticator */
+ {
+ struct dict_avp_data data = {
+ 488, /* Code */
+ 0, /* Vendor */
+ "MIP-Authenticator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-MAC-Mobility-Data */
+ {
+ struct dict_avp_data data = {
+ 489, /* Code */
+ 0, /* Vendor */
+ "MIP-MAC-Mobility-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 490, /* Code */
+ 0, /* Vendor */
+ "MIP-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP6-Auth-Mode */
+ {
+ struct dict_avp_data data = {
+ 494, /* Code */
+ 0, /* Vendor */
+ "MIP6-Auth-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(MIP6-Auth-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MN_HA", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "MN_AAA", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MIP-MN-HA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 492, /* Code */
+ 0, /* Vendor */
+ "MIP-MN-HA-MSA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc5778_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* MIP-MN-HA-MSA */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "MIP-MN-HA-MSA"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-Session-Key"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-MSA-Lifetime"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-MN-HA-SPI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Algorithm-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Replay-Mode"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc5778_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc5778_avps_load_defs(conffile);
+ return dict_rfc5778_avps_load_rules(conffile);
+}
+
+const char* dict_rfc5778_avps_proto_ver(char * conffile) {
+ return rfc5778_avps_proto_ver;
+}
+
+const double dict_rfc5778_avps_gen_ts(char * conffile) {
+ return rfc5778_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc5778_avps", dict_rfc5778_avps_load_defs, dict_rfc5778_avps_load_rules, "dict_rfc7155_avps", "dict_rfc5447_avps", "dict_rfc5777_avps", "dict_rfc4004_avps");
+
+
+
diff --git a/extensions/dict_rfc5778_avps/rfc5778_avps.did b/extensions/dict_rfc5778_avps/rfc5778_avps.did
new file mode 100644
index 0000000..0db426a
--- /dev/null
+++ b/extensions/dict_rfc5778_avps/rfc5778_avps.did
@@ -0,0 +1,5 @@
+dict_rfc7155_avps
+dict_rfc5777_avps
+dict_rfc5447_avps
+dict_rfc4004_avps
+dict_rfc5778_avps
diff --git a/extensions/dict_rfc6734_avps/CMakeLists.txt b/extensions/dict_rfc6734_avps/CMakeLists.txt
new file mode 100644
index 0000000..581d6f4
--- /dev/null
+++ b/extensions/dict_rfc6734_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc6734_avps extension
+PROJECT("dict_rfc6734_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc6734_avps dict_rfc6734_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc6734_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC6734_AVPS)
+
+
+
diff --git a/extensions/dict_rfc6734_avps/dict_rfc6734_avps.c b/extensions/dict_rfc6734_avps/dict_rfc6734_avps.c
new file mode 100644
index 0000000..c78dcd7
--- /dev/null
+++ b/extensions/dict_rfc6734_avps/dict_rfc6734_avps.c
@@ -0,0 +1,264 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc6734_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.62
+
+const char *rfc6734_avps_proto_ver = PROTO_VER;
+const double rfc6734_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc6734_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Key-Type */
+ {
+ struct dict_avp_data data = {
+ 582, /* Code */
+ 0, /* Vendor */
+ "Key-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Key-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DSRK", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "rRK", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "rMSK", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Keying-Material */
+ {
+ struct dict_avp_data data = {
+ 583, /* Code */
+ 0, /* Vendor */
+ "Keying-Material", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Key-Lifetime */
+ {
+ struct dict_avp_data data = {
+ 584, /* Code */
+ 0, /* Vendor */
+ "Key-Lifetime", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Key-SPI */
+ {
+ struct dict_avp_data data = {
+ 585, /* Code */
+ 0, /* Vendor */
+ "Key-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Key-Name */
+ {
+ struct dict_avp_data data = {
+ 586, /* Code */
+ 0, /* Vendor */
+ "Key-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Key */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 581, /* Code */
+ 0, /* Vendor */
+ "Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc6734_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Key */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Key"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Key-Type"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Keying-Material"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Key-Lifetime"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Key-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Key-SPI"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc6734_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc6734_avps_load_defs(conffile);
+ return dict_rfc6734_avps_load_rules(conffile);
+}
+
+const char* dict_rfc6734_avps_proto_ver(char * conffile) {
+ return rfc6734_avps_proto_ver;
+}
+
+const double dict_rfc6734_avps_gen_ts(char * conffile) {
+ return rfc6734_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc6734_avps", dict_rfc6734_avps_load_defs, dict_rfc6734_avps_load_rules);
+
+
+
diff --git a/extensions/dict_rfc6734_avps/rfc6734_avps.did b/extensions/dict_rfc6734_avps/rfc6734_avps.did
new file mode 100644
index 0000000..efbfb52
--- /dev/null
+++ b/extensions/dict_rfc6734_avps/rfc6734_avps.did
@@ -0,0 +1 @@
+dict_rfc6734_avps
diff --git a/extensions/dict_rfc6942_avps/CMakeLists.txt b/extensions/dict_rfc6942_avps/CMakeLists.txt
new file mode 100644
index 0000000..efb9e5f
--- /dev/null
+++ b/extensions/dict_rfc6942_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc6942_avps extension
+PROJECT("dict_rfc6942_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc6942_avps dict_rfc6942_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc6942_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC6942_AVPS)
+
+
+
diff --git a/extensions/dict_rfc6942_avps/dict_rfc6942_avps.c b/extensions/dict_rfc6942_avps/dict_rfc6942_avps.c
new file mode 100644
index 0000000..8145e9e
--- /dev/null
+++ b/extensions/dict_rfc6942_avps/dict_rfc6942_avps.c
@@ -0,0 +1,202 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc6942_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697191.32
+
+const char *rfc6942_avps_proto_ver = PROTO_VER;
+const double rfc6942_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc6942_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* ERP-Realm */
+ {
+ struct dict_avp_data data = {
+ 619, /* Code */
+ 0, /* Vendor */
+ "ERP-Realm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* ERP-RK-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 618, /* Code */
+ 0, /* Vendor */
+ "ERP-RK-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc6942_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* ERP-RK-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "ERP-RK-Request"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "ERP-Realm"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc6942_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc6942_avps_load_defs(conffile);
+ return dict_rfc6942_avps_load_rules(conffile);
+}
+
+const char* dict_rfc6942_avps_proto_ver(char * conffile) {
+ return rfc6942_avps_proto_ver;
+}
+
+const double dict_rfc6942_avps_gen_ts(char * conffile) {
+ return rfc6942_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc6942_avps", dict_rfc6942_avps_load_defs, dict_rfc6942_avps_load_rules, "dict_rfc6734_avps");
+
+
+
diff --git a/extensions/dict_rfc6942_avps/rfc6942_avps.did b/extensions/dict_rfc6942_avps/rfc6942_avps.did
new file mode 100644
index 0000000..1724c7b
--- /dev/null
+++ b/extensions/dict_rfc6942_avps/rfc6942_avps.did
@@ -0,0 +1,2 @@
+dict_rfc6734_avps
+dict_rfc6942_avps
diff --git a/extensions/dict_rfc7155_avps/CMakeLists.txt b/extensions/dict_rfc7155_avps/CMakeLists.txt
new file mode 100644
index 0000000..ed14e01
--- /dev/null
+++ b/extensions/dict_rfc7155_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc7155_avps extension
+PROJECT("dict_rfc7155_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc7155_avps dict_rfc7155_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc7155_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC7155_AVPS)
+
+
+
diff --git a/extensions/dict_rfc7155_avps/dict_rfc7155_avps.c b/extensions/dict_rfc7155_avps/dict_rfc7155_avps.c
new file mode 100644
index 0000000..f8f3f17
--- /dev/null
+++ b/extensions/dict_rfc7155_avps/dict_rfc7155_avps.c
@@ -0,0 +1,1634 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc7155_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.67
+
+const char *rfc7155_avps_proto_ver = PROTO_VER;
+const double rfc7155_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc7155_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* Derived AVP types section */
+ {
+ /* QoSFilterRule */
+ {
+ /*
+ The QosFilterRule format is derived from the OctetString AVP Base
+ Format. It uses the ASCII charset. Packets may be marked or
+ metered based on the following information:
+
+ Direction (in or out)
+ Source and destination IP address (possibly masked)
+ Protocol
+ Source and destination port (lists or ranges)
+ DSCP values (no mask or range)
+
+ Rules for the appropriate direction are evaluated in order; the
+ first matched rule terminates the evaluation. Each packet is
+ evaluated once. If no rule matches, the packet is treated as best
+ effort. An access device unable to interpret or apply a QoS rule
+ SHOULD NOT terminate the session.
+
+ QoSFilterRule filters MUST follow the following format:
+
+ action dir proto from src to dst [options]
+
+ tag - Mark packet with a specific DSCP
+ [DIFFSERV]. The DSCP option MUST be
+ included.
+ meter - Meter traffic. The metering options
+ MUST be included.
+
+ dir The format is as described under IPFilterRule.
+
+ proto The format is as described under IPFilterRule.
+
+ src and dst The format is as described under IPFilterRule.
+
+ options:
+
+ DSCP <color>
+ Color values as defined in [DIFFSERV]. Exact
+ matching of DSCP values is required (no masks or
+ ranges).
+
+ metering <rate> <color_under> <color_over>
+ The metering option provides Assured Forwarding,
+ as defined in [DIFFSERVAF], and MUST be present
+ if the action is set to meter. The rate option is
+ the throughput, in bits per second, used
+ by the access device to mark packets. Traffic
+ over the rate is marked with the color_over
+ codepoint, and traffic under the rate is marked
+ with the color_under codepoint. The color_under
+ and color_over options contain the drop
+ preferences and MUST conform to the recommended
+ codepoint keywords described in [DIFFSERVAF]
+ (e.g., AF13).
+
+ The metering option also supports the strict
+ limit on traffic required by Expedited
+ Forwarding, as defined in [DIFFSERVEF]. The
+ color_over option may contain the keyword "drop"
+ to prevent forwarding of traffic that exceeds the
+ rate parameter.
+
+ The rule syntax is a modified subset of ipfw(8) from FreeBSD,
+ and the ipfw.c code may provide a useful base for
+ implementations.
+ */
+ struct dict_type_data data = { AVP_TYPE_OCTETSTRING, "QoSFilterRule" , NULL , NULL };
+ CHECK_dict_new( DICT_TYPE, &data , NULL, NULL);
+ }
+
+ }
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+ struct dict_object * QoSFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "QoSFilterRule", &QoSFilterRule_type);
+ /* NAS-Port */
+ {
+ struct dict_avp_data data = {
+ 5, /* Code */
+ 0, /* Vendor */
+ "NAS-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* NAS-Port-Id */
+ {
+ struct dict_avp_data data = {
+ 87, /* Code */
+ 0, /* Vendor */
+ "NAS-Port-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* NAS-Port-Type */
+ {
+ struct dict_avp_data data = {
+ 61, /* Code */
+ 0, /* Vendor */
+ "NAS-Port-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(NAS-Port-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ASYNC", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SYNC", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "ISDN_SYNC", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "ISDN_ASYNC_V120", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "ISDN_ASYNC_V110", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "VIRTUAL", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "PIAFS", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "HDLC_CLEAR_CHANNEL", { .i32=7 }};
+ struct dict_enumval_data t_9 = { "X25", { .i32=8 }};
+ struct dict_enumval_data t_10 = { "X75", { .i32=9 }};
+ struct dict_enumval_data t_11 = { "G.3_FAX", { .i32=10 }};
+ struct dict_enumval_data t_12 = { "SDSL_SYMMETRIC_DSL", { .i32=11 }};
+ struct dict_enumval_data t_13 = { "IDSL_ISDN_DIGITAL_SUBSCRIBER_LINE", { .i32=14 }};
+ struct dict_enumval_data t_14 = { "ETHERNET", { .i32=15 }};
+ struct dict_enumval_data t_15 = { "XDSL_DIGITAL_SUBSCRIBER_LINE_OF_UNKNOWN_TYPE", { .i32=16 }};
+ struct dict_enumval_data t_16 = { "CABLE", { .i32=17 }};
+ struct dict_enumval_data t_17 = { "WIRELESS_OTHER", { .i32=18 }};
+ struct dict_enumval_data t_18 = { "WIRELESS_IEEE_802.11", { .i32=19 }};
+ struct dict_enumval_data t_19 = { "TOKEN_RING", { .i32=20 }};
+ struct dict_enumval_data t_20 = { "FDDI", { .i32=21 }};
+ struct dict_enumval_data t_21 = { "WIRELESS_CDMA2000", { .i32=22 }};
+ struct dict_enumval_data t_22 = { "WIRELESS_UMTS", { .i32=23 }};
+ struct dict_enumval_data t_23 = { "WIRELESS_1X_EV", { .i32=24 }};
+ struct dict_enumval_data t_24 = { "IAPP", { .i32=25 }};
+ struct dict_enumval_data t_25 = { "FTTP_FIBER_TO_THE_PREMISES", { .i32=26 }};
+ struct dict_enumval_data t_26 = { "WIRELESS_IEEE_802.16", { .i32=27 }};
+ struct dict_enumval_data t_27 = { "WIRELESS_IEEE_802.20", { .i32=28 }};
+ struct dict_enumval_data t_28 = { "WIRELESS_IEEE_802.22", { .i32=29 }};
+ struct dict_enumval_data t_29 = { "PPPOA_PPP_OVER_ATM", { .i32=30 }};
+ struct dict_enumval_data t_30 = { "PPPOEOA_PPP_OVER_ETHERNET_OVER_ATM", { .i32=31 }};
+ struct dict_enumval_data t_31 = { "PPPOEOE_PPP_OVER_ETHERNET_OVER_ETHERNET", { .i32=32 }};
+ struct dict_enumval_data t_32 = { "PPPOEOVLAN_PPP_OVER_ETHERNET_OVER_VLAN", { .i32=33 }};
+ struct dict_enumval_data t_33 = { "PPPOEOQINQ_PPP_OVER_ETHERNET_OVER_IEEE_802.1QINQ", { .i32=34 }};
+ struct dict_enumval_data t_34 = { "XPON_PASSIVE_OPTICAL_NETWORK", { .i32=35 }};
+ struct dict_enumval_data t_35 = { "WIRELESS_XGP", { .i32=36 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_26, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_27, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_28, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_29, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_30, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_31, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_32, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_33, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_34, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_35, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Called-Station-Id */
+ {
+ struct dict_avp_data data = {
+ 30, /* Code */
+ 0, /* Vendor */
+ "Called-Station-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Calling-Station-Id */
+ {
+ struct dict_avp_data data = {
+ 31, /* Code */
+ 0, /* Vendor */
+ "Calling-Station-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Connect-Info */
+ {
+ struct dict_avp_data data = {
+ 77, /* Code */
+ 0, /* Vendor */
+ "Connect-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Originating-Line-Info */
+ {
+ struct dict_avp_data data = {
+ 94, /* Code */
+ 0, /* Vendor */
+ "Originating-Line-Info", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Reply-Message */
+ {
+ struct dict_avp_data data = {
+ 18, /* Code */
+ 0, /* Vendor */
+ "Reply-Message", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* User-Password */
+ {
+ struct dict_avp_data data = {
+ 2, /* Code */
+ 0, /* Vendor */
+ "User-Password", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Password-Retry */
+ {
+ struct dict_avp_data data = {
+ 75, /* Code */
+ 0, /* Vendor */
+ "Password-Retry", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Prompt */
+ {
+ struct dict_avp_data data = {
+ 76, /* Code */
+ 0, /* Vendor */
+ "Prompt", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Prompt)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NO_ECHO", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ECHO", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CHAP-Algorithm */
+ {
+ struct dict_avp_data data = {
+ 403, /* Code */
+ 0, /* Vendor */
+ "CHAP-Algorithm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(CHAP-Algorithm)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CHAP_WITH_MD5", { .i32=5 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CHAP-Ident */
+ {
+ struct dict_avp_data data = {
+ 404, /* Code */
+ 0, /* Vendor */
+ "CHAP-Ident", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CHAP-Response */
+ {
+ struct dict_avp_data data = {
+ 405, /* Code */
+ 0, /* Vendor */
+ "CHAP-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CHAP-Challenge */
+ {
+ struct dict_avp_data data = {
+ 60, /* Code */
+ 0, /* Vendor */
+ "CHAP-Challenge", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ARAP-Password */
+ {
+ struct dict_avp_data data = {
+ 70, /* Code */
+ 0, /* Vendor */
+ "ARAP-Password", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ARAP-Challenge-Response */
+ {
+ struct dict_avp_data data = {
+ 84, /* Code */
+ 0, /* Vendor */
+ "ARAP-Challenge-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ARAP-Security */
+ {
+ struct dict_avp_data data = {
+ 73, /* Code */
+ 0, /* Vendor */
+ "ARAP-Security", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ARAP-Security-Data */
+ {
+ struct dict_avp_data data = {
+ 74, /* Code */
+ 0, /* Vendor */
+ "ARAP-Security-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-Type */
+ {
+ struct dict_avp_data data = {
+ 6, /* Code */
+ 0, /* Vendor */
+ "Service-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Service-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UNKNOWN", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "LOGIN", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "FRAMED", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "CALLBACK_LOGIN", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "CALLBACK_FRAMED", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "OUTBOUND", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "ADMINISTRATIVE", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "NAS_PROMPT", { .i32=7 }};
+ struct dict_enumval_data t_9 = { "AUTHENTICATE_ONLY", { .i32=8 }};
+ struct dict_enumval_data t_10 = { "CALLBACK_NAS_PROMPT", { .i32=9 }};
+ struct dict_enumval_data t_11 = { "CALL_CHECK", { .i32=10 }};
+ struct dict_enumval_data t_12 = { "CALLBACK_ADMINISTRATIVE", { .i32=11 }};
+ struct dict_enumval_data t_13 = { "VOICE", { .i32=12 }};
+ struct dict_enumval_data t_14 = { "FAX", { .i32=13 }};
+ struct dict_enumval_data t_15 = { "MODEM_RELAY", { .i32=14 }};
+ struct dict_enumval_data t_16 = { "IAPP_REGISTER", { .i32=15 }};
+ struct dict_enumval_data t_17 = { "IAPP_AP_CHECK", { .i32=16 }};
+ struct dict_enumval_data t_18 = { "AUTHORIZE_ONLY", { .i32=17 }};
+ struct dict_enumval_data t_19 = { "FRAMED_MANAGEMENT", { .i32=18 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Callback-Number */
+ {
+ struct dict_avp_data data = {
+ 19, /* Code */
+ 0, /* Vendor */
+ "Callback-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Callback-Id */
+ {
+ struct dict_avp_data data = {
+ 20, /* Code */
+ 0, /* Vendor */
+ "Callback-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Idle-Timeout */
+ {
+ struct dict_avp_data data = {
+ 28, /* Code */
+ 0, /* Vendor */
+ "Idle-Timeout", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Port-Limit */
+ {
+ struct dict_avp_data data = {
+ 62, /* Code */
+ 0, /* Vendor */
+ "Port-Limit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* NAS-Filter-Rule */
+ {
+ struct dict_avp_data data = {
+ 400, /* Code */
+ 0, /* Vendor */
+ "NAS-Filter-Rule", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+ /* Filter-Id */
+ {
+ struct dict_avp_data data = {
+ 11, /* Code */
+ 0, /* Vendor */
+ "Filter-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Configuration-Token */
+ {
+ struct dict_avp_data data = {
+ 78, /* Code */
+ 0, /* Vendor */
+ "Configuration-Token", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* QoS-Filter-Rule */
+ {
+ struct dict_avp_data data = {
+ 407, /* Code */
+ 0, /* Vendor */
+ "QoS-Filter-Rule", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, QoSFilterRule_type, NULL);
+ };
+ /* Framed-Protocol */
+ {
+ struct dict_avp_data data = {
+ 7, /* Code */
+ 0, /* Vendor */
+ "Framed-Protocol", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Framed-Protocol)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PPP", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "SLIP", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "ARAP", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "GANDALF", { .i32=4 }};
+ struct dict_enumval_data t_5 = { "XYLOGICS", { .i32=5 }};
+ struct dict_enumval_data t_6 = { "X.75", { .i32=6 }};
+ struct dict_enumval_data t_7 = { "GPRS_PDP_CONTEXT", { .i32=7 }};
+ struct dict_enumval_data t_8 = { "ASCEND_ARA", { .i32=255 }};
+ struct dict_enumval_data t_9 = { "MPP", { .i32=256 }};
+ struct dict_enumval_data t_10 = { "EURAW", { .i32=257 }};
+ struct dict_enumval_data t_11 = { "EUUI", { .i32=258 }};
+ struct dict_enumval_data t_12 = { "X25", { .i32=259 }};
+ struct dict_enumval_data t_13 = { "COMB", { .i32=260 }};
+ struct dict_enumval_data t_14 = { "FR", { .i32=261 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Framed-Routing */
+ {
+ struct dict_avp_data data = {
+ 10, /* Code */
+ 0, /* Vendor */
+ "Framed-Routing", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Framed-Routing)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NONE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SEND_ROUTING_PACKETS", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "LISTEN_FOR_ROUTING_PACKETS", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "SEND_AND_LISTEN", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Framed-MTU */
+ {
+ struct dict_avp_data data = {
+ 12, /* Code */
+ 0, /* Vendor */
+ "Framed-MTU", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Framed-Compression */
+ {
+ struct dict_avp_data data = {
+ 13, /* Code */
+ 0, /* Vendor */
+ "Framed-Compression", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Framed-Compression)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NONE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "IPX_HEADER_COMPRESSION", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "STAC_LZS_COMPRESSION", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Framed-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 8, /* Code */
+ 0, /* Vendor */
+ "Framed-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Framed-IP-Netmask */
+ {
+ struct dict_avp_data data = {
+ 9, /* Code */
+ 0, /* Vendor */
+ "Framed-IP-Netmask", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Framed-Route */
+ {
+ struct dict_avp_data data = {
+ 22, /* Code */
+ 0, /* Vendor */
+ "Framed-Route", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Framed-Pool */
+ {
+ struct dict_avp_data data = {
+ 88, /* Code */
+ 0, /* Vendor */
+ "Framed-Pool", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Framed-Interface-Id */
+ {
+ struct dict_avp_data data = {
+ 96, /* Code */
+ 0, /* Vendor */
+ "Framed-Interface-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Framed-IPv6-Prefix */
+ {
+ struct dict_avp_data data = {
+ 97, /* Code */
+ 0, /* Vendor */
+ "Framed-IPv6-Prefix", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Framed-IPv6-Route */
+ {
+ struct dict_avp_data data = {
+ 99, /* Code */
+ 0, /* Vendor */
+ "Framed-IPv6-Route", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Framed-IPv6-Pool */
+ {
+ struct dict_avp_data data = {
+ 100, /* Code */
+ 0, /* Vendor */
+ "Framed-IPv6-Pool", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Framed-IPX-Network */
+ {
+ struct dict_avp_data data = {
+ 23, /* Code */
+ 0, /* Vendor */
+ "Framed-IPX-Network", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Framed-Appletalk-Link */
+ {
+ struct dict_avp_data data = {
+ 37, /* Code */
+ 0, /* Vendor */
+ "Framed-Appletalk-Link", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Framed-Appletalk-Network */
+ {
+ struct dict_avp_data data = {
+ 38, /* Code */
+ 0, /* Vendor */
+ "Framed-Appletalk-Network", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Framed-Appletalk-Zone */
+ {
+ struct dict_avp_data data = {
+ 39, /* Code */
+ 0, /* Vendor */
+ "Framed-Appletalk-Zone", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ARAP-Features */
+ {
+ struct dict_avp_data data = {
+ 71, /* Code */
+ 0, /* Vendor */
+ "ARAP-Features", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ARAP-Zone-Access */
+ {
+ struct dict_avp_data data = {
+ 72, /* Code */
+ 0, /* Vendor */
+ "ARAP-Zone-Access", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(ARAP-Zone-Access)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ONLY_ALLOW_ACCESS_TO_DEFAULT_ZONE", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "USE_ZONE_FILTER_INCLUSIVELY", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "USE_ZONE_FILTER_EXCLUSIVELY", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Login-IP-Host */
+ {
+ struct dict_avp_data data = {
+ 14, /* Code */
+ 0, /* Vendor */
+ "Login-IP-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Login-IPv6-Host */
+ {
+ struct dict_avp_data data = {
+ 98, /* Code */
+ 0, /* Vendor */
+ "Login-IPv6-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Login-Service */
+ {
+ struct dict_avp_data data = {
+ 15, /* Code */
+ 0, /* Vendor */
+ "Login-Service", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Login-Service)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TELNET", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "RLOGIN", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "TCP_CLEAR", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "PORTMASTER", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "LAT", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "X25_PAD", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "X25_T3POS", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "UNASSIGNED", { .i32=7 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Login-TCP-Port */
+ {
+ struct dict_avp_data data = {
+ 16, /* Code */
+ 0, /* Vendor */
+ "Login-TCP-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Login-LAT-Service */
+ {
+ struct dict_avp_data data = {
+ 34, /* Code */
+ 0, /* Vendor */
+ "Login-LAT-Service", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Login-LAT-Node */
+ {
+ struct dict_avp_data data = {
+ 35, /* Code */
+ 0, /* Vendor */
+ "Login-LAT-Node", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Login-LAT-Group */
+ {
+ struct dict_avp_data data = {
+ 36, /* Code */
+ 0, /* Vendor */
+ "Login-LAT-Group", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Login-LAT-Port */
+ {
+ struct dict_avp_data data = {
+ 63, /* Code */
+ 0, /* Vendor */
+ "Login-LAT-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Tunnel-Type */
+ {
+ struct dict_avp_data data = {
+ 64, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Tunnel-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PPTP", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "L2F", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "L2TP", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "ATMP", { .i32=4 }};
+ struct dict_enumval_data t_5 = { "VTP", { .i32=5 }};
+ struct dict_enumval_data t_6 = { "AH", { .i32=6 }};
+ struct dict_enumval_data t_7 = { "IP_IP_ENCAP", { .i32=7 }};
+ struct dict_enumval_data t_8 = { "MIN_IP_IP", { .i32=8 }};
+ struct dict_enumval_data t_9 = { "ESP", { .i32=9 }};
+ struct dict_enumval_data t_10 = { "GRE", { .i32=10 }};
+ struct dict_enumval_data t_11 = { "DVS", { .i32=11 }};
+ struct dict_enumval_data t_12 = { "IP_IN_IP_TUNNELING", { .i32=12 }};
+ struct dict_enumval_data t_13 = { "VLAN", { .i32=13 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Tunnel-Medium-Type */
+ {
+ struct dict_avp_data data = {
+ 65, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Medium-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Tunnel-Medium-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "IPV4", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "IPV6", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "NSAP", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "HDLC", { .i32=4 }};
+ struct dict_enumval_data t_5 = { "BBN", { .i32=5 }};
+ struct dict_enumval_data t_6 = { "IEEE_802", { .i32=6 }};
+ struct dict_enumval_data t_7 = { "E_163", { .i32=7 }};
+ struct dict_enumval_data t_8 = { "E_164", { .i32=8 }};
+ struct dict_enumval_data t_9 = { "F_69", { .i32=9 }};
+ struct dict_enumval_data t_10 = { "X_121", { .i32=10 }};
+ struct dict_enumval_data t_11 = { "IPX", { .i32=11 }};
+ struct dict_enumval_data t_12 = { "APPLETALK_802", { .i32=12 }};
+ struct dict_enumval_data t_13 = { "DECNET4", { .i32=13 }};
+ struct dict_enumval_data t_14 = { "VINES", { .i32=14 }};
+ struct dict_enumval_data t_15 = { "E_164_NSAP", { .i32=15 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Tunnel-Client-Endpoint */
+ {
+ struct dict_avp_data data = {
+ 66, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Client-Endpoint", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Tunnel-Server-Endpoint */
+ {
+ struct dict_avp_data data = {
+ 67, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Server-Endpoint", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Tunnel-Password */
+ {
+ struct dict_avp_data data = {
+ 69, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Password", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Tunnel-Private-Group-Id */
+ {
+ struct dict_avp_data data = {
+ 81, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Private-Group-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Tunnel-Assignment-Id */
+ {
+ struct dict_avp_data data = {
+ 82, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Assignment-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Tunnel-Preference */
+ {
+ struct dict_avp_data data = {
+ 83, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Preference", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Tunnel-Client-Auth-Id */
+ {
+ struct dict_avp_data data = {
+ 90, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Client-Auth-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Tunnel-Server-Auth-Id */
+ {
+ struct dict_avp_data data = {
+ 91, /* Code */
+ 0, /* Vendor */
+ "Tunnel-Server-Auth-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Accounting-Input-Octets */
+ {
+ struct dict_avp_data data = {
+ 363, /* Code */
+ 0, /* Vendor */
+ "Accounting-Input-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Accounting-Output-Octets */
+ {
+ struct dict_avp_data data = {
+ 364, /* Code */
+ 0, /* Vendor */
+ "Accounting-Output-Octets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Accounting-Input-Packets */
+ {
+ struct dict_avp_data data = {
+ 365, /* Code */
+ 0, /* Vendor */
+ "Accounting-Input-Packets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Accounting-Output-Packets */
+ {
+ struct dict_avp_data data = {
+ 366, /* Code */
+ 0, /* Vendor */
+ "Accounting-Output-Packets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Acct-Session-Time */
+ {
+ struct dict_avp_data data = {
+ 46, /* Code */
+ 0, /* Vendor */
+ "Acct-Session-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Acct-Authentic */
+ {
+ struct dict_avp_data data = {
+ 45, /* Code */
+ 0, /* Vendor */
+ "Acct-Authentic", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Acct-Authentic)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NONE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "RADIUS", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "LOCAL", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "REMOTE", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "DIAMETER", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Accounting-Auth-Method */
+ {
+ struct dict_avp_data data = {
+ 406, /* Code */
+ 0, /* Vendor */
+ "Accounting-Auth-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Accounting-Auth-Method)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PAP", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "CHAP", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "MS_CHAP_1", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "MS_CHAP_2", { .i32=4 }};
+ struct dict_enumval_data t_5 = { "EAP", { .i32=5 }};
+ struct dict_enumval_data t_6 = { "UNDEFINED", { .i32=6 }};
+ struct dict_enumval_data t_7 = { "NONE", { .i32=7 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Acct-Delay-Time */
+ {
+ struct dict_avp_data data = {
+ 41, /* Code */
+ 0, /* Vendor */
+ "Acct-Delay-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Acct-Link-Count */
+ {
+ struct dict_avp_data data = {
+ 51, /* Code */
+ 0, /* Vendor */
+ "Acct-Link-Count", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Acct-Tunnel-Connection */
+ {
+ struct dict_avp_data data = {
+ 68, /* Code */
+ 0, /* Vendor */
+ "Acct-Tunnel-Connection", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Acct-Tunnel-Packets-Lost */
+ {
+ struct dict_avp_data data = {
+ 86, /* Code */
+ 0, /* Vendor */
+ "Acct-Tunnel-Packets-Lost", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* NAS-Identifier */
+ {
+ struct dict_avp_data data = {
+ 32, /* Code */
+ 0, /* Vendor */
+ "NAS-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* NAS-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 4, /* Code */
+ 0, /* Vendor */
+ "NAS-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* NAS-IPv6-Address */
+ {
+ struct dict_avp_data data = {
+ 95, /* Code */
+ 0, /* Vendor */
+ "NAS-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Origin-AAA-Protocol */
+ {
+ struct dict_avp_data data = {
+ 408, /* Code */
+ 0, /* Vendor */
+ "Origin-AAA-Protocol", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Origin-AAA-Protocol)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "RADIUS", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* State */
+ {
+ struct dict_avp_data data = {
+ 24, /* Code */
+ 0, /* Vendor */
+ "State", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Redirect-Host */
+ {
+ struct dict_avp_data data = {
+ 292, /* Code */
+ 0, /* Vendor */
+ "Redirect-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterURI_type, NULL);
+ };
+ /* Redirect-Host-Usage */
+ {
+ struct dict_avp_data data = {
+ 261, /* Code */
+ 0, /* Vendor */
+ "Redirect-Host-Usage", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(Redirect-Host-Usage)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DONT_CACHE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ALL_SESSION", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "ALL_REALM", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "REALM_AND_APPLICATION", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "ALL_APPLICATION", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "ALL_HOST", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "ALL_USER", { .i32=6 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Redirect-Max-Cache-Time */
+ {
+ struct dict_avp_data data = {
+ 262, /* Code */
+ 0, /* Vendor */
+ "Redirect-Max-Cache-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Tunneling */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 401, /* Code */
+ 0, /* Vendor */
+ "Tunneling", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* CHAP-Auth */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 402, /* Code */
+ 0, /* Vendor */
+ "CHAP-Auth", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc7155_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Tunneling */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "Tunneling"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Medium-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Client-Endpoint"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Server-Endpoint"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Preference"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Client-Auth-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Server-Auth-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Assignment-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Password"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tunnel-Private-Group-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* CHAP-Auth */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "CHAP-Auth"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "CHAP-Algorithm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CHAP-Ident"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CHAP-Response"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc7155_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc7155_avps_load_defs(conffile);
+ return dict_rfc7155_avps_load_rules(conffile);
+}
+
+const char* dict_rfc7155_avps_proto_ver(char * conffile) {
+ return rfc7155_avps_proto_ver;
+}
+
+const double dict_rfc7155_avps_gen_ts(char * conffile) {
+ return rfc7155_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc7155_avps", dict_rfc7155_avps_load_defs, dict_rfc7155_avps_load_rules, "dict_rfc4004_avps");
+
+
+
diff --git a/extensions/dict_rfc7155_avps/rfc7155_avps.did b/extensions/dict_rfc7155_avps/rfc7155_avps.did
new file mode 100644
index 0000000..b774d5e
--- /dev/null
+++ b/extensions/dict_rfc7155_avps/rfc7155_avps.did
@@ -0,0 +1,2 @@
+dict_rfc4004_avps
+dict_rfc7155_avps
diff --git a/extensions/dict_rfc7683_avps/CMakeLists.txt b/extensions/dict_rfc7683_avps/CMakeLists.txt
new file mode 100644
index 0000000..5e5966b
--- /dev/null
+++ b/extensions/dict_rfc7683_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc7683_avps extension
+PROJECT("dict_rfc7683_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc7683_avps dict_rfc7683_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc7683_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC7683_AVPS)
+
+
+
diff --git a/extensions/dict_rfc7683_avps/dict_rfc7683_avps.c b/extensions/dict_rfc7683_avps/dict_rfc7683_avps.c
new file mode 100644
index 0000000..431b677
--- /dev/null
+++ b/extensions/dict_rfc7683_avps/dict_rfc7683_avps.c
@@ -0,0 +1,291 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc7683_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.69
+
+const char *rfc7683_avps_proto_ver = PROTO_VER;
+const double rfc7683_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc7683_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* OC-Feature-Vector */
+ {
+ struct dict_avp_data data = {
+ 622, /* Code */
+ 0, /* Vendor */
+ "OC-Feature-Vector", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* OC-Sequence-Number */
+ {
+ struct dict_avp_data data = {
+ 624, /* Code */
+ 0, /* Vendor */
+ "OC-Sequence-Number", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* OC-Validity-Duration */
+ {
+ struct dict_avp_data data = {
+ 625, /* Code */
+ 0, /* Vendor */
+ "OC-Validity-Duration", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* OC-Report-Type */
+ {
+ struct dict_avp_data data = {
+ 626, /* Code */
+ 0, /* Vendor */
+ "OC-Report-Type", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(OC-Report-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "HOST_REPORT", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "REALM_REPORT", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Texas", { .i32=75034 }};
+ struct dict_enumval_data t_4 = { "CA", { .i32=95134 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* OC-Reduction-Percentage */
+ {
+ struct dict_avp_data data = {
+ 627, /* Code */
+ 0, /* Vendor */
+ "OC-Reduction-Percentage", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* OC-Supported-Features */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 621, /* Code */
+ 0, /* Vendor */
+ "OC-Supported-Features", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* OC-OLR */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 623, /* Code */
+ 0, /* Vendor */
+ "OC-OLR", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc7683_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* OC-Supported-Features */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "OC-Supported-Features"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "OC-Feature-Vector"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* OC-OLR */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 0, .avp_name = "OC-OLR"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "OC-Sequence-Number"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Report-Type"}, RULE_FIXED_HEAD, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Reduction-Percentage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "OC-Validity-Duration"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc7683_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc7683_avps_load_defs(conffile);
+ return dict_rfc7683_avps_load_rules(conffile);
+}
+
+const char* dict_rfc7683_avps_proto_ver(char * conffile) {
+ return rfc7683_avps_proto_ver;
+}
+
+const double dict_rfc7683_avps_gen_ts(char * conffile) {
+ return rfc7683_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc7683_avps", dict_rfc7683_avps_load_defs, dict_rfc7683_avps_load_rules);
+
+
+
diff --git a/extensions/dict_rfc7683_avps/rfc7683_avps.did b/extensions/dict_rfc7683_avps/rfc7683_avps.did
new file mode 100644
index 0000000..926b149
--- /dev/null
+++ b/extensions/dict_rfc7683_avps/rfc7683_avps.did
@@ -0,0 +1 @@
+dict_rfc7683_avps
diff --git a/extensions/dict_rfc7944_avps/CMakeLists.txt b/extensions/dict_rfc7944_avps/CMakeLists.txt
new file mode 100644
index 0000000..8df8df8
--- /dev/null
+++ b/extensions/dict_rfc7944_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_rfc7944_avps extension
+PROJECT("dict_rfc7944_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_rfc7944_avps dict_rfc7944_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_rfc7944_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-RFC7944_AVPS)
+
+
+
diff --git a/extensions/dict_rfc7944_avps/dict_rfc7944_avps.c b/extensions/dict_rfc7944_avps/dict_rfc7944_avps.c
new file mode 100644
index 0000000..6c1bd17
--- /dev/null
+++ b/extensions/dict_rfc7944_avps/dict_rfc7944_avps.c
@@ -0,0 +1,212 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in rfc7944_avps.
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "unspecified"
+#define GEN_DATE 1506697143.69
+
+const char *rfc7944_avps_proto_ver = PROTO_VER;
+const double rfc7944_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_rfc7944_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* DRMP */
+ {
+ struct dict_avp_data data = {
+ 301, /* Code */
+ 0, /* Vendor */
+ "DRMP", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "Enumerated(DRMP)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PRIORITY_15", { .i32=15 }};
+ struct dict_enumval_data t_2 = { "PRIORITY_14", { .i32=14 }};
+ struct dict_enumval_data t_3 = { "PRIORITY_13", { .i32=13 }};
+ struct dict_enumval_data t_4 = { "PRIORITY_12", { .i32=12 }};
+ struct dict_enumval_data t_5 = { "PRIORITY_11", { .i32=11 }};
+ struct dict_enumval_data t_6 = { "PRIORITY_10", { .i32=10 }};
+ struct dict_enumval_data t_7 = { "PRIORITY_9", { .i32=9 }};
+ struct dict_enumval_data t_8 = { "PRIORITY_8", { .i32=8 }};
+ struct dict_enumval_data t_9 = { "PRIORITY_7", { .i32=7 }};
+ struct dict_enumval_data t_10 = { "PRIORITY_6", { .i32=6 }};
+ struct dict_enumval_data t_11 = { "PRIORITY_5", { .i32=5 }};
+ struct dict_enumval_data t_12 = { "PRIORITY_4", { .i32=4 }};
+ struct dict_enumval_data t_13 = { "PRIORITY_3", { .i32=3 }};
+ struct dict_enumval_data t_14 = { "PRIORITY_2", { .i32=2 }};
+ struct dict_enumval_data t_15 = { "PRIORITY_1", { .i32=1 }};
+ struct dict_enumval_data t_16 = { "PRIORITY_0", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_rfc7944_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for rfc7944_avps (None)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_rfc7944_avps_load_defs(conffile);
+ return dict_rfc7944_avps_load_rules(conffile);
+}
+
+const char* dict_rfc7944_avps_proto_ver(char * conffile) {
+ return rfc7944_avps_proto_ver;
+}
+
+const double dict_rfc7944_avps_gen_ts(char * conffile) {
+ return rfc7944_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_rfc7944_avps", dict_rfc7944_avps_load_defs, dict_rfc7944_avps_load_rules);
+
+
+
diff --git a/extensions/dict_rfc7944_avps/rfc7944_avps.did b/extensions/dict_rfc7944_avps/rfc7944_avps.did
new file mode 100644
index 0000000..bce475a
--- /dev/null
+++ b/extensions/dict_rfc7944_avps/rfc7944_avps.did
@@ -0,0 +1 @@
+dict_rfc7944_avps
diff --git a/extensions/dict_sip/CMakeLists.txt b/extensions/dict_sip/CMakeLists.txt
new file mode 100644
index 0000000..03409d7
--- /dev/null
+++ b/extensions/dict_sip/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The dict_sip extension
+PROJECT("Diameter SIP (RFC4740) dictionary definitions" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_sip dict_sip.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_sip
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-dictionary-RFC4740)
diff --git a/extensions/dict_sip/dict_sip.c b/extensions/dict_sip/dict_sip.c
new file mode 100644
index 0000000..636c0cb
--- /dev/null
+++ b/extensions/dict_sip/dict_sip.c
@@ -0,0 +1,2952 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+#include <freeDiameter/extension.h>
+
+
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+ CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ char *avp_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME, \
+ (_rulearray)[__ar].avp_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
+ return ENOENT; \
+ } \
+ CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
+ { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_name ); \
+ return EINVAL; \
+ } ); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+
+int ds_dict_init(char * conffile)
+{
+ struct dict_object * sip;
+ {
+ struct dict_application_data data = { 6, "Diameter Session Initiation Protocol (SIP) Application" };
+ CHECK_dict_new( DICT_APPLICATION, &data , NULL, &sip);
+ }
+
+ /* AVP section */
+ {
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterURI_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+
+ /* Digest AVPs (from RADIUS) */
+
+ /* Digest-Response */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 103, /* Code */
+ 0, /* Vendor */
+ "Digest-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Realm */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 104, /* Code */
+ 0, /* Vendor */
+ "Digest-Realm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Nonce */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 105, /* Code */
+ 0, /* Vendor */
+ "Digest-Nonce", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Response-Auth */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 106, /* Code */
+ 0, /* Vendor */
+ "Digest-Response-Auth", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Nextnonce */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 107, /* Code */
+ 0, /* Vendor */
+ "Digest-Nextnonce", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Method */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 108, /* Code */
+ 0, /* Vendor */
+ "Digest-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-URI */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 109, /* Code */
+ 0, /* Vendor */
+ "Digest-URI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-QoP */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 110, /* Code */
+ 0, /* Vendor */
+ "Digest-QoP", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Algorithm */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 111, /* Code */
+ 0, /* Vendor */
+ "Digest-Algorithm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Entity-Body-Hash */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 112, /* Code */
+ 0, /* Vendor */
+ "Digest-Entity-Body-Hash", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-CNonce */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 113, /* Code */
+ 0, /* Vendor */
+ "Digest-CNonce", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Nonce-Count */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 114, /* Code */
+ 0, /* Vendor */
+ "Digest-Nonce-Count", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Username */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 115, /* Code */
+ 0, /* Vendor */
+ "Digest-Username", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Opaque */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 116, /* Code */
+ 0, /* Vendor */
+ "Digest-Opaque", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Auth-Param */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 117, /* Code */
+ 0, /* Vendor */
+ "Digest-Auth-Param", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-AKA-Auts */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 118, /* Code */
+ 0, /* Vendor */
+ "Digest-AKA-Auts", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Domain */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 119, /* Code */
+ 0, /* Vendor */
+ "Digest-Domain", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-Stale */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 120, /* Code */
+ 0, /* Vendor */
+ "Digest-Stale", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* Digest-HA1 */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 121, /* Code */
+ 0, /* Vendor */
+ "Digest-HA1", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+ /* SIP-AOR */
+ {
+ /*
+
+ */
+
+ struct dict_avp_data data = {
+ 122, /* Code */
+ 0, /* Vendor */
+ "SIP-AOR", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+
+ /* Diameter SIP AVPs*/
+ /* SIP-Accounting-Server-URI*/
+ {
+ /*
+ The SIP-Accounting-Server-URI AVP (AVP Code 369) is of type
+ DiameterURI. This AVP contains the address of a Diameter server that
+ is able to receive SIP-session-related accounting information.
+ */
+
+ struct dict_avp_data data = {
+ 369, /* Code */
+ 0, /* Vendor */
+ "SIP-Accounting-Server-URI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , DiameterURI_type, NULL);
+ }
+ /* SIP-Credit-Control-Server-URI */
+ {
+ /*
+ The SIP-Credit-Control-Server-URI AVP (AVP Code 370) is of type
+ DiameterURI. This AVP contains the address of a Diameter server that
+ is able to authorize real-time credit control usage. The Diameter
+ Credit-Control Application [RFC4006] may be used for this purpose.
+
+
+ */
+
+ struct dict_avp_data data = {
+ 370, /* Code */
+ 0, /* Vendor */
+ "SIP-Credit-Control-Server-URI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , DiameterURI_type, NULL);
+ }
+
+ /* SIP-Accounting-Information */
+ {
+ /*
+ The SIP-Accounting-Information (AVP Code 368) is of type Grouped, and
+ contains the Diameter addresses of those nodes that are able to
+ collect accounting information.
+
+ The SIP-Accounting-Information AVP is defined as follows (per the
+ grouped-avp-def of RFC 3588 [RFC3588]):
+
+ SIP-Accounting-Information ::= < AVP Header: 368 >
+ * [ SIP-Accounting-Server-URI ]
+ * [ SIP-Credit-Control-Server-URI ]
+ * [ AVP]
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 368, /* Code */
+ 0, /* Vendor */
+ "SIP-Accounting-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "SIP-Accounting-Server-URI", RULE_OPTIONAL, -1, -1 }
+ ,{ "SIP-Credit-Control-Server-URI", RULE_OPTIONAL, -1, -1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* SIP-Server-URI */
+ {
+ /*
+ The SIP-Server-URI AVP (AVP Code 371) is of type UTF8String. This
+ AVP contains a SIP or SIPS URI (as defined in RFC 3261 [RFC3261])
+ that identifies a SIP server.
+ */
+
+ struct dict_avp_data data = {
+ 371, /* Code */
+ 0, /* Vendor */
+ "SIP-Server-URI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* SIP-Mandatory-Capability */
+ {
+ /*
+ The SIP-Mandatory-Capability AVP (AVP Code 373) is of type
+ Unsigned32. The value represents a certain capability (or set of
+ capabilities) that have to be fulfilled by the SIP server allocated
+ to the user.
+
+ The semantics of the different values are not standardized, as it is
+ a matter of the administrative network to allocate its own semantics
+ within its own network. Each value has to represent a single
+ capability within the administrative network.
+
+ */
+
+ struct dict_avp_data data = {
+ 373, /* Code */
+ 0, /* Vendor */
+ "SIP-Mandatory-Capability", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+ /* SIP-Optional-Capability */
+ {
+ /*
+ The SIP-Optional-Capability AVP (AVP Code 374) is of type Unsigned32.
+ The value represents a certain capability (or set of capabilities)
+ that, optionally, may be fulfilled by the SIP server allocated to the
+ user.
+
+ The semantics of the different values are not standardized, as it is
+ a matter of the administrative network to allocate its own semantics
+ within its own network. Each value has to represent a single
+ capability within the administrative network.
+
+ */
+
+ struct dict_avp_data data = {
+ 374, /* Code */
+ 0, /* Vendor */
+ "SIP-Optional-Capability", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+
+ /* SIP-Server-Capabilities */
+ {
+ /*
+ The SIP-Server-Capabilities AVP (AVP Code 372) is of type Grouped.
+ The Diameter indicates in this AVP the requirements for a particular
+ SIP capability, so that the Diameter client (SIP server) is able to
+ select another appropriate SIP server to serve the user.
+
+ The SIP-Server-Capabilities AVP allows a Diameter client (SIP server)
+ to select another SIP server for triggering or executing services to
+ the user. A user may have enabled some services that require the
+ implementation of certain capabilities in the SIP server that
+ triggers or executes those services. For example, the SIP server
+ that triggers or executes services to this user may need to implement
+ SIP servlets [JSR-000116], Call Processing Language (CPL) [RFC3880],
+ or any other kind of capability. Or perhaps that user belongs to a
+ premium users group that has a certain stringent quality-of-service
+ agreement that requires a fast SIP server. The capabilities required
+ or recommended to a given user are conveyed in the
+ SIP-Server-Capabilities AVP. When it receives them, the Diameter
+ client (SIP server) that does the SIP server selection needs to have
+ the means to find out available SIP servers that meet the required or
+ optional capabilities. Such means are outside the scope of this
+ specification.
+
+ Note that the SIP-Server-Capabilities AVP assists the Diameter client
+ (SIP server) to produce a subset of all the available SIP servers to
+ be allocated to the user in the Home Realm; this is the subset that
+ conforms the requirements of capabilities on a per-user basis.
+ Typically this subset will be formed of more than a single SIP
+ server, so once the subset of those SIP servers is identified, it is
+ possible that several instances of these SIP servers exist, in which
+ case the Diameter client (SIP server) should choose one particular
+ SIP server to execute and trigger services to this user. It is
+ expected that at this point the SIP server (Diameter client) will
+ follow the procedures of RFC 3263 [RFC3263] to allocate one SIP
+ server to the user.
+
+ The SIP-Server-Capabilities AVP is defined as follows (per the
+ grouped-avp-def of RFC 3588 [RFC3588]):
+
+ SIP-Server-Capabilities ::= < AVP Header: 372 >
+ * [ SIP-Mandatory-Capability ]
+ * [ SIP-Optional-Capability ]
+ * [ SIP-Server-URI ]
+ * [ AVP ]
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 372, /* Code */
+ 0, /* Vendor */
+ "SIP-Server-Capabilities", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "SIP-Mandatory-Capability", RULE_OPTIONAL, -1, -1 }
+ ,{ "SIP-Optional-Capability", RULE_OPTIONAL, -1, -1 }
+ ,{ "SIP-Server-URI", RULE_OPTIONAL, -1, -1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+
+ /* SIP-Server-Assignment-Type */
+ {
+ /*
+ The SIP-Server-Assignment-Type AVP (AVP Code 375) is of type
+ Enumerated and indicates the type of server update being performed in
+ a Diameter Server-Assignment-Request (SAR) operation. The following
+ values are defined:
+
+
+ o NO_ASSIGNMENT (0)
+ The Diameter client uses this value to request the user profile of
+ a SIP AOR, without affecting the registration state of that
+ identity.
+
+ o REGISTRATION (1)
+ First SIP registration of a SIP AOR.
+
+ o RE_REGISTRATION (2)
+ Subsequent SIP registration of a SIP AOR.
+
+ o UNREGISTERED_USER (3)
+ The SIP server has received a SIP request (e.g., SIP INVITE)
+ addressed for a SIP AOR that is not registered.
+
+ o TIMEOUT_DEREGISTRATION (4)
+ The SIP registration timer of an identity has expired.
+
+ o USER_DEREGISTRATION (5)
+ The SIP server has received a request to deregister a SIP AOR.
+
+ o TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME (6)
+ The SIP registration timer of an identity has expired. The SIP
+ server keeps the user data stored and requests the Diameter server
+ to store the SIP server address.
+
+ o USER_DEREGISTRATION_STORE_SERVER_NAME (7)
+ The SIP server has received a user-initiated deregistration
+ request. The SIP server keeps the user data stored and requests
+ the Diameter server to store the SIP server address.
+
+ o ADMINISTRATIVE_DEREGISTRATION (8)
+ The SIP server, due to administrative reasons, has deregistered a
+ SIP AOR.
+
+ o AUTHENTICATION_FAILURE (9)
+ The authentication of a user has failed.
+
+ o AUTHENTICATION_TIMEOUT (10)
+ The authentication timer has expired.
+
+ o DEREGISTRATION_TOO_MUCH_DATA (11)
+ The SIP server has requested user profile information from the
+ Diameter server and has received a volume of data higher than it
+ can accept.
+
+ */
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(SIP-Server-Assignment-Type)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "NO_ASSIGNMENT"),
+ enumval_def_u32( 1, "REGISTRATION"),
+ enumval_def_u32( 2, "RE_REGISTRATION"),
+ enumval_def_u32( 3, "UNREGISTERED_USER"),
+ enumval_def_u32( 4, "TIMEOUT_DEREGISTRATION"),
+ enumval_def_u32( 5, "USER_DEREGISTRATION"),
+ enumval_def_u32( 6, "TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME"),
+ enumval_def_u32( 7, "USER_DEREGISTRATION_STORE_SERVER_NAME"),
+ enumval_def_u32( 8, "ADMINISTRATIVE_DEREGISTRATION"),
+ enumval_def_u32( 9, "AUTHENTICATION_FAILURE"),
+ enumval_def_u32( 10, "AUTHENTICATION_TIMEOUT"),
+ enumval_def_u32( 11, "DEREGISTRATION_TOO_MUCH_DATA")
+ };
+ struct dict_avp_data data = {
+ 375, /* Code */
+ 0, /* Vendor */
+ "SIP-Server-Assignment-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+
+ /* SIP-Authenticate */
+ {
+ /*
+ The SIP-Authenticate AVP (AVP Code 379) is of type Grouped and
+ contains a reconstruction of either the SIP WWW-Authenticate or
+ Proxy-Authentication header fields specified in RFC 2617 [RFC2617]
+ for the HTTP Digest authentication scheme. Additionally, the AVP may
+ include a Digest-HA1 AVP that contains H(A1) (as defined in RFC 2617
+ [RFC2617]). H(A1) allows the Diameter client to create an expected
+ response and compare it with the Digest response received from the
+ SIP UA.
+ The SIP-Authenticate AVP is defined as follows (per the
+ grouped-avp-def of RFC 3588 [RFC3588]):
+
+ SIP-Authenticate ::= < AVP Header: 379 >
+ { Digest-Realm }
+ { Digest-Nonce }
+ [ Digest-Domain ]
+ [ Digest-Opaque ]
+ [ Digest-Stale ]
+ [ Digest-Algorithm ]
+ [ Digest-QoP ]
+ [ Digest-HA1]
+ * [ Digest-Auth-Param ]
+ * [ AVP ]
+
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 379, /* Code */
+ 0, /* Vendor */
+ "SIP-Authenticate", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "Digest-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Digest-Nonce", RULE_REQUIRED, -1, 1 }
+ ,{ "Digest-Domain", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Opaque", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Stale", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Algorithm", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-QoP", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-HA1", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Auth-Param", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SIP-Authorization */
+ {
+ /*
+ The SIP-Authorization AVP (AVP Code 380) is of type Grouped and
+ contains a reconstruction of either the SIP Authorization or
+ Proxy-Authorization header fields specified in RFC 2617 [RFC2617] for
+ the HTTP Digest authentication scheme.
+
+ The SIP-Authorization AVP is defined as follows (per the
+ grouped-avp-def of RFC 3588 [RFC3588]):
+
+ SIP-Authorization ::= < AVP Header: 380 >
+ { Digest-Username }
+ { Digest-Realm }
+ { Digest-Nonce }
+ { Digest-URI }
+ { Digest-Response }
+ [ Digest-Algorithm ]
+ [ Digest-CNonce ]
+ [ Digest-Opaque ]
+ [ Digest-QoP ]
+ [ Digest-Nonce-Count ]
+ [ Digest-Method]
+ [ Digest-Entity-Body-Hash ]
+ * [ Digest-Auth-Param ]
+ * [ AVP ]
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 380, /* Code */
+ 0, /* Vendor */
+ "SIP-Authorization", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "Digest-Username", RULE_REQUIRED, -1, 1 }
+ ,{ "Digest-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Digest-Nonce", RULE_REQUIRED, -1, 1 }
+ ,{ "Digest-URI", RULE_REQUIRED, -1, 1 }
+ ,{ "Digest-Response", RULE_REQUIRED, -1, 1 }
+ ,{ "Digest-Algorithm", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-CNonce", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Opaque", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-QoP", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Nonce-Count", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Method", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Entity-Body-Hash", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Auth-Param", RULE_OPTIONAL, -1, -1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SIP-Authentication-Info */
+ {
+ /*
+ The SIP-Authentication-Info AVP (AVP Code 381) is of type Grouped and
+ contains a reconstruction of the SIP Authentication-Info header
+ specified in RFC 2617 [RFC2617] for the HTTP Digest authentication
+ scheme.
+ The SIP-Authentication-Info AVP is defined as follows (per the
+ grouped-avp-def of RFC 3588 [RFC3588]):
+
+ SIP-Authentication-Info ::= < AVP Header: 381 >
+ [ Digest-Nextnonce ]
+ [ Digest-QoP ]
+ [ Digest-Response-Auth ]
+ [ Digest-CNonce ]
+ [ Digest-Nonce-Count ]
+ * [ AVP ]
+
+ Note that, in some cases, the Digest-Response-Auth AVP cannot be
+ calculated at the Diameter server, but has to be calculated at the
+ Diameter client (SIP server). For example, if the value of the
+ quality of protection (qop) parameter in Digest is set to "auth-int",
+ then the response-digest (rspauth parameter value in Digest) is
+ calculated with the hash of the body of the SIP response, which is
+ not available at the Diameter server. In this case, the Diameter
+ client (SIP server) must calculate the response-digest once the body
+ of the SIP response is calculated.
+
+ Therefore, a value of "auth-int" in the Digest-QoP AVP of the
+ SIP-Authentication-Info AVP indicates that the Diameter client (SIP
+ server) MUST compute the Digest "rspauth" parameter value at the
+ Diameter client (SIP server).
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 381, /* Code */
+ 0, /* Vendor */
+ "SIP-Authentication-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "Digest-Nextnonce", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-QoP", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Response-Auth", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-CNonce", RULE_OPTIONAL, -1, 1 }
+ ,{ "Digest-Nonce-Count", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SIP-Authentication-Scheme */
+ {
+ /*
+ The SIP-Authentication-Scheme AVP (AVP Code 377) is of type
+ Enumerated and indicates the authentication scheme used in the
+ authentication of SIP services. RFC 2617 identifies this value as an
+ "auth-scheme" (see Section 1.2 of RFC 2617 [RFC2617]). The only
+ currently defined value is:
+
+ o DIGEST (0) to indicate HTTP Digest authentication as specified in
+ RFC 2617 [RFC2617] Section 3.2.1. Derivative work is also
+ considered Digest authentication scheme, as long as the
+ "auth-scheme" is identified as Digest in the SIP headers carrying
+ the HTTP authentication. This includes, e.g., the HTTP Digest
+ authentication using AKA [RFC3310].
+
+ Each HTTP Digest directive (parameter) is transported in a
+ corresponding AVP, whose name follows the pattern Digest-*. The
+ Digest-* AVPs are RADIUS attributes imported from the RADIUS
+ Extension for Digest Authentication [RFC4590] namespace, allowing a
+ smooth transition between RADIUS and Diameter applications supporting
+ SIP. The Diameter SIP application goes a step further by grouping
+ the Digest-* AVPs into the SIP-Authenticate, SIP-Authorization, and
+ SIP-Authentication-Info grouped AVPs that correspond to the SIP WWW-
+ Authenticate/Proxy-Authentication, Authorization/Proxy-Authorization,
+ and Authentication-Info headers fields, respectively.
+
+ Note: Due to the fact that HTTP Digest authentication [RFC2617] is
+ the only mandatory authentication mechanism in SIP, this memo only
+ provides support for HTTP Digest authentication and derivative
+ work such as HTTP Digest authentication using AKA [RFC3310].
+ Extensions to this memo can register new values and new AVPs to
+ provide support for other authentication schemes or extensions to
+ HTTP Digest authentication.
+
+ Note: Although RFC 2617 [RFC2617] defines the Basic and Digest
+ schemes for authenticating HTTP requests, RFC 3261 [RFC3261] only
+ imports HTTP Digest as a mechanism to provide authentication in
+ SIP.
+
+ Due to syntactic requirements, HTTP Digest authentication has to
+ escape quote characters in contents of HTTP Digest directives. When
+ translating directives into Digest-* AVPs, the Diameter client or
+ server removes the surrounding quotes where present, as required by
+ the syntax of the Digest-* attributes defined in the "RADIUS
+ Extension for Digest Authentication" [RFC4590].
+
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(SIP-Authentication-Scheme)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "DIGEST")
+ };
+ struct dict_avp_data data = {
+ 377, /* Code */
+ 0, /* Vendor */
+ "SIP-Authentication-Scheme", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+ /* SIP-Item-Number */
+ {
+ /*
+ The SIP-Item-Number (AVP Code 378) is of type Unsigned32 and is
+ included in a SIP-Auth-Data-Item grouped AVP in circumstances where
+ there are multiple occurrences of SIP-Auth-Data-Item AVPs and the
+ order of processing is relevant. The AVP indicates the order in
+ which the Grouped SIP-Auth-Data-Item should be processed. Lower
+ values of the SIP-Item-Number AVP indicate that the whole
+ SIP-Auth-Data-Item SHOULD be processed before other
+ SIP-Auth-Data-Item AVPs that contain higher values in the
+ SIP-Item-Number AVP.
+
+ */
+
+ struct dict_avp_data data = {
+ 378, /* Code */
+ 0, /* Vendor */
+ "SIP-Item-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+ /* SIP-Auth-Data-Item */
+ {
+ /*
+ The SIP-Auth-Data-Item (AVP Code 376) is of type Grouped and contains
+ the authentication and/or authorization information pertaining to a
+ user.
+
+ When the Diameter server uses the grouped SIP-Auth-Data-Item AVP to
+ include a SIP-Authenticate AVP, the Diameter server MUST send a
+ maximum of one authentication data item (e.g., in case the SIP
+ request contained several credentials). Section 11 contains a
+ detailed discussion and normative text of the case when a SIP request
+ contains several credentials.
+
+ The SIP-Auth-Data-Item AVP is defined as follows (per the
+ grouped-avp-def of RFC 3588 [RFC3588]):
+
+ SIP-Auth-Data-Item ::= < AVP Header: 376 >
+ { SIP-Authentication-Scheme }
+ [ SIP-Item-Number ]
+ [ SIP-Authenticate ]
+ [ SIP-Authorization ]
+ [ SIP-Authentication-Info ]
+ * [ AVP ]
+
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 376, /* Code */
+ 0, /* Vendor */
+ "SIP-Auth-Data-Item", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "SIP-Authentication-Scheme",RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-Item-Number", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Authenticate", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Authorization", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Authentication-Info", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SIP-Number-Auth-Items */
+ {
+ /*
+ The SIP-Number-Auth-Items AVP (AVP Code 382) is of type Unsigned32
+ and indicates the number of authentication and/or authorization
+ credentials that the Diameter server included in a Diameter message.
+
+ When the AVP is present in a request, it indicates the number of
+ SIP-Auth-Data-Items the Diameter client is requesting. This can be
+ used, for instance, when the SIP server is requesting several
+ pre-calculated authentication credentials. In the answer message,
+ the SIP-Number-Auth-Items AVP indicates the actual number of items
+ that the Diameter server included.
+
+ */
+
+ struct dict_avp_data data = {
+ 382, /* Code */
+ 0, /* Vendor */
+ "SIP-Number-Auth-Items", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* SIP-Reason-Code */
+ {
+ /*
+ The SIP-Reason-Code AVP (AVP Code 384) is of type Enumerated and
+ defines the reason for the network initiated deregistration. The
+ following values are defined:
+
+ o PERMANENT_TERMINATION (0)
+ o NEW_SIP_SERVER_ASSIGNED (1)
+ o SIP_SERVER_CHANGE (2)
+ o REMOVE_SIP_SERVER (3)
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(SIP-Reason-Code)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "PERMANENT_TERMINATION"),
+ enumval_def_u32( 1, "NEW_SIP_SERVER_ASSIGNED"),
+ enumval_def_u32( 2, "SIP_SERVER_CHANGE"),
+ enumval_def_u32( 3, "REMOVE_SIP_SERVER")
+ };
+ struct dict_avp_data data = {
+ 384, /* Code */
+ 0, /* Vendor */
+ "SIP-Reason-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+
+ /* SIP-Reason-Info */
+ {
+ /*
+ The SIP-Reason-Info AVP (AVP Code 385) is of type UTF8String and
+ contains textual information that can be rendered to the user, about
+ the reason for a deregistration.
+
+ */
+
+ struct dict_avp_data data = {
+ 385, /* Code */
+ 0, /* Vendor */
+ "SIP-Reason-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+
+ /* SIP-Deregistration-Reason */
+ {
+ /*
+ The SIP-Deregistration-Reason AVP (AVP Code 383) is of type Grouped
+ and indicates the reason for a deregistration operation.
+
+ The SIP-Deregistration-Reason AVP is defined as follows (per the
+ grouped-avp-def of RFC 3588 [RFC3588]):
+
+ SIP-Deregistration-Reason ::= < AVP Header: 383 >
+ { SIP-Reason-Code }
+ [ SIP-Reason-Info ]
+ * [ AVP ]
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 383, /* Code */
+ 0, /* Vendor */
+ "SIP-Deregistration-Reason", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "SIP-Reason-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-Reason-Info", RULE_OPTIONAL, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+
+ /* SIP-Visited-Network-Id */
+ {
+ /*
+ The SIP-Visited-Network-Id AVP (AVP Code 386) is of type UTF8String.
+ This AVP contains an identifier that helps the home network identify
+ the visited network (e.g., the visited network domain name), in order
+ to authorize roaming to that visited network.
+
+ */
+
+ struct dict_avp_data data = {
+ 386, /* Code */
+ 0, /* Vendor */
+ "SIP-Visited-Network-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+ /* SIP-User-Authorization-Type */
+ {
+ /*
+ The SIP-User-Authorization-Type AVP (AVP Code 387) is of type
+ Enumerated and indicates the type of user authorization being
+ performed in a User Authorization operation, i.e., the Diameter
+ User-Authorization-Request (UAR) command. The following values are
+ defined:
+
+ o REGISTRATION (0)
+ This value is used for initial registration or re-registration.
+ This is the default value.
+
+ o DEREGISTRATION (1)
+ This value is used for deregistration.
+
+ o REGISTRATION_AND_CAPABILITIES (2)
+ This value is used for initial registration or re-registration
+ when the SIP server explicitly requests the Diameter server to get
+ capability information. This capability information helps the SIP
+ server to allocate another SIP server to serve the user.
+
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(SIP-User-Authorization-Type)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "REGISTRATION"),
+ enumval_def_u32( 1, "DEREGISTRATION"),
+ enumval_def_u32( 2, "REGISTRATION_AND_CAPABILITIES")
+ };
+ struct dict_avp_data data = {
+ 387, /* Code */
+ 0, /* Vendor */
+ "SIP-User-Authorization-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+ /* SIP-Supported-User-Data-Type */
+ {
+ /*
+ The SIP-Supported-User-Data-Type AVP (AVP Code 388) is of type
+ UTF8String and contains a string that identifies the type of
+ supported user data (user profile, see SIP-User-Data AVP
+ (Section 9.12)) supported in the node. The AVP can be repeated, if
+ the SIP server supports several user data types. In case of
+ repetition, the Diameter client should order the different instances
+ of this AVP according to its preferences.
+
+ When the Diameter client inserts this AVP in a SAR message, it allows
+ the Diameter client to provide an indication to the Diameter server
+ of the types of user data supported by the SIP server. The Diameter
+ server, upon inspection of these AVPs, will return a suitable
+ SIP-User-Data AVP (Section 9.12) of the type indicated in the
+ SIP-User-Data-Type AVP (Section 9.12.1).
+
+ */
+
+ struct dict_avp_data data = {
+ 388, /* Code */
+ 0, /* Vendor */
+ "SIP-Supported-User-Data-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+ /* SIP-User-Data-Type */
+ {
+ /*
+ The SIP-User-Data-Type AVP (AVP Code 390) is of type UTF8String and
+ contains a string that identifies the type of user data included in
+ the SIP-User-Data-Type AVP (Section 9.12).
+
+ This document does not specify a convention to characterize the type
+ of user data contained in the SIP-User-Data-Type AVP (Section 9.12). It
+ is believed that in most cases this feature will be used in
+ environments controlled by a network administrator who can configure
+ both the client and server to assign the same value type at the
+ client and server. It is also RECOMMENDED that organizations
+ developing their own profile of SIP-User-Data-Type AVP (Section 9.12)
+ allocate a type based on their canonical DNS name. For instance,
+ organization "example.com" can define several types of SIP-User-Data
+ and allocate the types "type1.dsa.example.com",
+ "type2.dsa.example.com", and so on. This convention will avoid a
+ clash in the allocation of types of SIP-User-Data-Type AVP (Section 9.12).
+
+ */
+
+ struct dict_avp_data data = {
+ 390, /* Code */
+ 0, /* Vendor */
+ "SIP-User-Data-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+ /* SIP-User-Data-Contents */
+ {
+ /*
+ The SIP-User-Data-Contents AVP (AVP Code 391) is of type OctetString.
+ The Diameter peers do not need to understand the value of this AVP.
+
+ The AVP contains the user profile data required for a SIP server to
+ give service to the user.
+
+
+ */
+
+ struct dict_avp_data data = {
+ 391, /* Code */
+ 0, /* Vendor */
+ "SIP-User-Data-Contents", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
+ }
+
+ /* SIP-User-Data */
+ {
+ /*
+ The SIP-User-Data AVP (AVP Code 389) is of type Grouped. This AVP
+ allows the Diameter server to transport user-specific data, such as a
+ user profile, to the SIP server (in the Diameter client). The
+ Diameter server selects a type of user data that is understood by the
+ SIP server in the Diameter client, and has been indicated in a
+ SIP-Supported-User-Data-Type AVP. In case the Diameter client
+ indicated support for several types of user data, the Diameter server
+ SHOULD choose the first type supported by the client.
+
+ The SIP-User-Data grouped AVP contains a SIP-User-Data-Type AVP that
+ indicates the type of user data included in the
+ SIP-User-Data-Contents-AVP.
+
+ The SIP-User-Data AVP is defined as follows (per the grouped-avp-def
+ of RFC 3588 [RFC3588]):
+
+
+ SIP-User-Data ::= < AVP Header: 389 >
+ { SIP-User-Data-Type }
+ { SIP-User-Data-Contents }
+ * [ AVP ]
+
+ */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 389, /* Code */
+ 0, /* Vendor */
+ "SIP-User-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ struct local_rules_definition rules[] =
+ { { "SIP-User-Data-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-User-Data-Contents", RULE_REQUIRED, -1, 1 }
+ };
+
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SIP-User-Data-Already-Available */
+ {
+ /*
+ The SIP-User-Data-Already-Available AVP (AVP Code 392) is of type
+ Enumerated and gives an indication to the Diameter server about
+ whether the Diameter client (SIP server) already received the portion
+ of the user profile needed in order to serve the user. The following
+ values are defined:
+
+ o USER_DATA_NOT_AVAILABLE (0)
+ The Diameter client (SIP server) does not have the data that it
+ needs to serve the user.
+
+ o USER_DATA_ALREADY_AVAILABLE (1)
+ The Diameter client (SIP server) already has received the data
+ that it needs to serve the user.
+
+
+ */
+
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_UNSIGNED32, "Enumerated(SIP-User-Data-Already-Available)" , NULL, NULL};
+ struct dict_enumval_data tvals[] = {
+ enumval_def_u32( 0, "USER_DATA_NOT_AVAILABLE"),
+ enumval_def_u32( 1, "USER_DATA_ALREADY_AVAILABLE")
+ };
+ struct dict_avp_data data = {
+ 392, /* Code */
+ 0, /* Vendor */
+ "SIP-User-Data-Already-Available", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ int i;
+ /* Create the Enumerated type, enumerated values, and the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata , NULL, &type);
+ for (i = 0; i < sizeof(tvals) / sizeof(tvals[0]); i++) {
+ CHECK_dict_new( DICT_ENUMVAL, &tvals[i], type, NULL);
+ }
+ CHECK_dict_new( DICT_AVP, &data , type, NULL);
+ }
+ /* SIP-Method */
+ {
+ /*
+ The SIP-Method-AVP (AVP Code 393) is of type UTF8String and contains
+ the method of the SIP request that triggered the Diameter message.
+ The Diameter server MUST use this AVP solely for authorization of SIP
+ requests, and MUST NOT use it to compute the Digest authentication.
+ To compute the Digest authentication, the Diameter server MUST use
+ the Digest-Method AVP instead.
+
+
+ */
+
+ struct dict_avp_data data = {
+ 393, /* Code */
+ 0, /* Vendor */
+ "SIP-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , UTF8String_type, NULL);
+ }
+ /* Complement of Result-Code AVP values */
+ {
+ struct dict_object * resultcode_data_type;
+ CHECK_dict_search(DICT_TYPE,TYPE_BY_NAME,"Enumerated(Result-Code)",&resultcode_data_type);
+
+
+ {
+
+ /* Success */
+ {
+ /* 2003 */
+ {
+ /*
+ The user was not previously registered. The Diameter server has
+ now authorized the registration.
+ */
+ struct dict_enumval_data error_code = { "DIAMETER_FIRST_REGISTRATION", { .u32 = 2003 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 2004 */
+ {
+ /*
+ The user is already registered. The Diameter server has now
+ authorized the re-registration.
+
+ */
+ struct dict_enumval_data error_code = { "DIAMETER_SUBSEQUENT_REGISTRATION", { .u32 = 2004 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 2005 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_UNREGISTERED_SERVICE", { .u32 = 2005 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 2006 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED", { .u32 = 2006 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 2007 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_SERVER_SELECTION", { .u32 = 2007 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 2008 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_SUCCESS_AUTH_SENT_SERVER_NOT_STORED", { .u32 = 2008 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ }
+ /* Transient Failures */
+ {
+ /* 4013 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_USER_NAME_REQUIRED", { .u32 = 4013 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ }
+ /* Permanent Failures */
+ {
+ /* 5032 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_ERROR_USER_UNKNOWN", { .u32 = 5032 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 5033 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_ERROR_IDENTITIES_DONT_MATCH", { .u32 = 5033 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 5034 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_ERROR_IDENTITY_NOT_REGISTERED", { .u32 = 5034 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 5035 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_ERROR_ROAMING_NOT_ALLOWED", { .u32 = 5035 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 5036 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_ERROR_IDENTITY_ALREADY_REGISTERED", { .u32 = 5036 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 5037 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_ERROR_AUTH_SCHEME_NOT_SUPPORTED", { .u32 = 5037 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 5038 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_ERROR_IN_ASSIGNMENT_TYPE", { .u32 = 5038 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 5039 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_ERROR_TOO_MUCH_DATA", { .u32 = 5039 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ /* 5040 */
+ {
+ struct dict_enumval_data error_code = { "DIAMETER_ERROR_NOT SUPPORTED_USER_DATA", { .u32 = 5040 }};
+ CHECK_dict_new( DICT_ENUMVAL, &error_code , resultcode_data_type, NULL);
+ }
+ }
+ }
+
+
+ }
+ }
+ /* Command section */
+ {
+ /* User-Authorization-Request (UAR) Command */
+ {
+ /*
+ The User-Authorization-Request (UAR) is indicated by the Command-Code
+ set to 283 and the Command Flags' 'R' bit set. The Diameter client
+ in a SIP server sends this command to the Diameter server to request
+ authorization for the SIP User Agent to route a SIP REGISTER request.
+ Because the SIP REGISTER request implicitly carries a permission to
+ bind an AOR to a contact address, the Diameter client uses the
+ Diameter UAR as a first authorization request towards the Diameter
+ server to authorize the registration. For instance, the Diameter
+ server can verify that the AOR is a legitimate user of the realm.
+
+ The Diameter client in the SIP server requests authorization for one
+ of the possible values defined in the SIP-User-Authorization-Type AVP
+ (Section 9.10).
+
+ The user name used for authentication of the user is conveyed in a
+ User-Name AVP (defined in the Diameter base protocol, RFC 3588
+ [RFC3588]). The location of the authentication user name in the SIP
+ REGISTER request varies depending on the authentication mechanism.
+ When the authentication mechanism is HTTP Digest as defined in RFC
+ 2617 [RFC2617], the authentication user name is found in the
+ "username" directive of the SIP Authorization header field value.
+ This Diameter SIP application only provides support for HTTP Digest
+ authentication in SIP; other authentication mechanisms are not
+ currently supported.
+
+ The SIP or SIPS URI to be registered is conveyed in the SIP-AOR AVP
+ (Section 9.8). Typically this SIP or SIPS URI is found in the To
+ header field value of the SIP REGISTER request that triggered the
+ Diameter UAR message.
+
+ The SIP-Visited-Network-Id AVP indicates the network that is
+ providing SIP services (e.g., SIP proxy functionality or any other
+ kind of services) to the SIP User Agent.
+
+ The Message Format of the UAR command is as follows:
+
+ <UAR> ::= < Diameter Header: 283, REQ, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { SIP-AOR }
+ [ Destination-Host ]
+ [ User-Name ]
+ [ SIP-Visited-Network-Id ]
+ [ SIP-User-Authorization-Type ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 283, /* Code */
+ "User-Authorization-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-AOR", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Visited-Network-Id", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-User-Authorization-Type", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* User-Authorization-Answer (UAA) Command */
+ {
+ /*
+ The User-Authorization-Answer (UAA) is indicated by the Command-Code
+ set to 283 and the Command Flags' 'R' bit cleared. The Diameter
+ server sends this command in response to a previously received
+ Diameter User-Authorization-Request (UAR) command. The Diameter
+ server indicates the result of the requested registration
+ authorization. Additionally, the Diameter server may indicate a
+ collection of SIP capabilities that assists the Diameter client to
+ select a SIP proxy to the AOR under registration.
+
+
+ In addition to the values already defined in RFC 3588 [RFC3588], the
+ Result-Code AVP may contain one of the values defined in
+ Section 10.1.
+
+ Whenever the Diameter server fails to process the Diameter UAR
+ message, it MUST stop processing and return the relevant error in the
+ Diameter UAA message. When there is success in the process, the
+ Diameter server MUST set the code to DIAMETER_SUCCESS in the Diameter
+ UAA message.
+
+ If the Diameter server requires a User-Name AVP value to process the
+ Diameter UAR request, but the Diameter UAR message did not contain a
+ User-Name AVP value, the Diameter server MUST set the Result-Code AVP
+ value to DIAMETER_USER_NAME_REQUIRED (see Section 10.1.2) and return
+ it in a Diameter UAA message. Upon reception of this Diameter UAA
+ message with the Result-Code AVP value set to
+ DIAMETER_USER_NAME_REQUIRED, the SIP server typically requests
+ authentication by sending a SIP 401 (Unauthorized) or SIP 407 (Proxy
+ Authentication Required) response back to the originator.
+
+ When the authorization procedure succeeds, the Diameter server
+ constructs a User-Authorization-Answer (UAA) message that MUST
+ include (1) the address of the SIP server already assigned to the
+ user name, (2) the capabilities needed by the SIP server (Diameter
+ client) to select another SIP server for the user, or (3) a
+ combination of the previous two options.
+
+ If the Diameter server is already aware of a SIP server allocated to
+ the user, the Diameter UAA message contains the address of that SIP
+ server.
+
+ The Diameter UAA message contains the capabilities required by a SIP
+ server to trigger and execute services. It is required that these
+ capabilities are present in the Diameter UAA message due to the
+ possibility that the Diameter client (in the SIP server) allocates a
+ different SIP server to trigger and execute services for that
+ particular user.
+
+ If a User-Name AVP is present in the Diameter UAR message, then the
+ Diameter server MUST verify the existence of the user in the realm,
+ i.e., the User-Name AVP value is a valid user within that realm. If
+ the Diameter server does not recognize the user name received in the
+ User-Name AVP, the Diameter server MUST build a Diameter User-
+ Authorization-Answer (UAA) message and MUST set the Result-Code AVP
+ to DIAMETER_ERROR_USER_UNKNOWN.
+
+
+ If a User-Name AVP is present in the Diameter UAR message, then the
+ Diameter server MUST authorize that User-Name AVP value is able to
+ register the SIP or SIPS URI included in the SIP-AOR AVP. If this
+ authorization fails, the Diameter server must set the Result-Code AVP
+ to DIAMETER_ERROR_IDENTITIES_DONT_MATCH and send it in a Diameter
+ User-Authorization-Answer (UAA) message.
+
+ Note: Correlation between User-Name and SIP-AOR AVP values is
+ required in order to avoid registration of a SIP-AOR allocated to
+ another user.
+
+ If there is a SIP-Visited-Network-Id AVP in the Diameter UAR message,
+ and the SIP-User-Authorization-Type AVP value received in the
+ Diameter UAR message is set to REGISTRATION or REGISTRATION&
+ CAPABILITIES, then the Diameter server SHOULD verify whether the user
+ is allowed to roam into the network specified in the
+ SIP-Visited-Network-Id AVP in the Diameter UAR message. If the user
+ is not allowed to roam into that network, the Diameter AAA server
+ MUST set the Result-Code AVP value in the Diameter UAA message to
+ DIAMETER_ERROR_ROAMING_NOT_ALLOWED.
+
+ If the SIP-User-Authorization-Type AVP value received in the Diameter
+ UAR message is set to REGISTRATION or REGISTRATION&CAPABILITIES, then
+ the Diameter server SHOULD verify whether the SIP-AOR AVP value is
+ authorized to register in the Home Realm. Where the SIP AOR is not
+ authorized to register in the Home Realm, the Diameter server MUST
+ set the Result-Code AVP to DIAMETER_AUTHORIZATION_REJECTED and send
+ it in a Diameter UAA message.
+
+ When the SIP-User-Authorization-Type AVP is not present in the
+ Diameter UAR message, or when it is present and its value is set to
+ REGISTRATION, then:
+
+ o If the Diameter server is not aware of any previous registration
+ of the user name (including registrations of other SIP AORs
+ allocated to the same user name), then the Diameter server does
+ not know of any SIP server allocated to the user. In this case,
+ the Diameter server MUST set the Result-Code AVP value to
+ DIAMETER_FIRST_REGISTRATION in the Diameter UAA message, and the
+ Diameter server SHOULD include the required SIP server
+ capabilities in the SIP-Server-Capabilities AVP value in the
+ Diameter UAA message. The SIP-Server-Capabilities AVP assists the
+ Diameter client (SIP server) to select an appropriate SIP server
+ for the user, according to the required capabilities.
+
+ o In some cases, the Diameter server is aware of a previously
+ assigned SIP server for the same or different SIP AORs allocated
+ to the same user name. In these cases, re-assignment of a new SIP
+ server may or may not be needed, depending on the capabilities of
+ the SIP server. The Diameter server MUST always include the
+ allocated SIP server URI in the SIP-Server-URI AVP of the UAA
+ message. If the Diameter server does not return the SIP
+ capabilities, the Diameter server MUST set the Result-Code AVP in
+ the Diameter UAA message to DIAMETER_SUBSEQUENT_REGISTRATION.
+ Otherwise (i.e., if the Diameter server includes a
+ SIP-Server-Capabilities AVP), then the Diameter server MUST set
+ the Result-Code AVP in the Diameter UAA message to
+ DIAMETER_SERVER_SELECTION. Then the Diameter client determines,
+ based on the received information, whether it needs to select a
+ new SIP server.
+
+ When the SIP-User-Authorization-Type AVP value received in the
+ Diameter UAR message is set to REGISTRATION&CAPABILITIES, then
+ Diameter Server MUST return the list of capabilities in the
+ SIP-Server-Capabilities AVP value of the Diameter UAA message, it
+ MUST set the Result-Code to DIAMETER_SUCCESS, and it MUST NOT return
+ a SIP-Server-URI AVP. The SIP-Server-Capabilities AVP enables the
+ SIP server (Diameter client) to select another appropriate SIP server
+ for invoking and executing services for the user, depending on the
+ required capabilities. The Diameter server MAY leave the list of
+ capabilities empty to indicate that any SIP server can be selected.
+
+ When the SIP-User-Authorization-Type AVP value received in the
+ Diameter UAR message is set to DEREGISTRATION, then:
+
+ o If the Diameter server is aware of a SIP server assigned to the
+ SIP AOR under deregistration, the Diameter server MUST set the
+ Result-Code AVP to DIAMETER_SUCCESS and MUST set the
+ SIP-Server-URI AVP value to the known SIP server, and return them
+ in the Diameter UAA message.
+
+ o If the Diameter server is not aware of a SIP server assigned to
+ the SIP AOR under deregistration, then the Diameter server MUST
+ set the Result-Code AVP in the Diameter UAA message to
+ DIAMETER_ERROR_IDENTITY_NOT_REGISTERED.
+
+ The Message Format of the UAA command is as follows:
+
+ <UAA> ::= < Diameter Header: 283, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Auth-Session-State }
+ { Result-Code }
+ { Origin-Host }
+ { Origin-Realm }
+ [ SIP-Server-URI ]
+ [ SIP-Server-Capabilities ]
+ [ Authorization-Lifetime ]
+ [ Auth-Grace-Period ]
+ [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 283, /* Code */
+ "User-Authorization-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-Server-URI", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Server-Capabilities", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Multimedia-Auth-Request (MAR) Command */
+ {
+ /*
+
+ The Multimedia-Auth-Request (MAR) command is indicated by the
+ Command-Code set to 286 and the Command Flags' 'R' bit set. The
+ Diameter client in a SIP server sends this command to the Diameter
+ server to request that the Diameter server authenticate and authorize
+ a user attempt to use some SIP service (in this context, SIP service
+ can be something as simple as a SIP subscription or using the proxy
+ services for a SIP request).
+
+ The MAR command may also register the SIP server's own URI to the
+ Diameter server, so that future LIR/LIA messages can return this URI.
+ If the SIP server is acting as a SIP registrar (see examples in
+ Sections 6.2 and 6.3), its Diameter client MUST include a SIP-
+ Server-URI AVP in the MAR command. In any other cases (see example
+ in Section 6.4), its Diameter client MUST NOT include a SIP-Server-
+ URI AVP in the MAR command.
+
+ The SIP-Method AVP MUST include the SIP method name of the SIP
+ request that triggered this Diameter MAR message. The Diameter
+ server can use this AVP to authorize some SIP requests depending on
+ the method.
+
+ The Diameter MAR message MUST include a SIP-AOR AVP. The SIP-AOR AVP
+ indicates the target of the SIP request. The value of the AVP is
+ extracted from different places in SIP request, depending on the
+ semantics of the SIP request. For SIP REGISTER messages the SIP-AOR
+ AVP value indicates the intended public user identity under
+ registration, and it is the SIP or SIPS URI populated in the To
+ header field value (addr-spec as per RFC 3261 [RFC3261]) of the SIP
+ REGISTER request. For other types of SIP requests, such as INVITE,
+ SUBSCRIBE, MESSAGE, etc., the SIP-AOR AVP value indicates the
+ intended destination of the request. This is typically populated in
+ the Request-URI of the SIP request. Extracting the SIP-AOR AVP value
+ from the proper SIP header field is the Diameter client's
+ responsibility. Extensions to SIP (new SIP methods or new semantics)
+ may require the SIP-AOR to be extracted from other parts of the
+ request.
+
+ If the SIP request includes some sort of authentication information,
+ the Diameter client MUST include the user name, extracted from the
+ authentication information of the SIP request, in the User-Name AVP
+ value.
+
+ The Message Format of the MAR command is as follows:
+
+ <MAR> ::= < Diameter Header: 286, REQ, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { SIP-AOR }
+ { SIP-Method }
+ [ Destination-Host ]
+ [ User-Name ]
+ [ SIP-Server-URI ]
+ [ SIP-Number-Auth-Items ]
+ [ SIP-Auth-Data-Item ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 286, /* Code */
+ "Multimedia-Auth-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-AOR", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-Method", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Server-URI", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Number-Auth-Items", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Auth-Data-Item", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ /* Multimedia-Auth-Answer (MAA) Command */
+ {
+ /*
+
+ The Multimedia-Auth-Answer (MAA) is indicated by the Command-Code set
+ to 286 and the Command Flags' 'R' bit cleared. The Diameter server
+ sends this command in response to a previously received Diameter
+ Multimedia-Auth-Request (MAR) command.
+
+ In addition to the values already defined in RFC 3588 [RFC3588], the
+ Result-Code AVP may contain one of the values defined in
+ Section 10.1.
+
+ If the Diameter server requires a User-Name AVP value to process the
+ Diameter MAR request, but the Diameter MAR message did not contain a
+ User-Name AVP value, the Diameter server MUST set the Result-Code AVP
+ value to DIAMETER_USER_NAME_REQUIRED (see Section 10.1.2) and return
+ it in a Diameter MAA message. The Diameter server MAY include a
+ SIP-Number-Auth-Items AVP and one or more SIP-Auth-Data-Item AVPs
+ with authentication information (e.g., a challenge). Upon reception
+ of this Diameter MAA message with the Result-Code AVP value set to
+ DIAMETER_USER_NAME_REQUIRED, the SIP server typically requests
+ authentication by generating a SIP 401 (Unauthorized) or SIP 407
+ (Proxy Authentication Required) response back to the originator.
+
+ If the User-Name AVP is present in the Diameter MAR message, the
+ Diameter server MUST verify the existence of the user in the realm,
+ i.e., the User-Name AVP value is a valid user within that realm. If
+ the Diameter server does not recognize the user name received in the
+ User-Name AVP, the Diameter server MUST build a Diameter
+ Multimedia-Auth-Answer (MAA) message and MUST set the Result-Code AVP
+ to DIAMETER_ERROR_USER_UNKNOWN.
+
+ If the SIP-Methods AVP value of the Diameter MAR message is set to
+ REGISTER and a User-Name AVP is present, then the Diameter server
+ MUST authorize that User-Name AVP value is able to use the URI
+ included in the SIP-AOR AVP. If this authorization fails, the
+ Diameter server must set the Result-Code AVP to
+ DIAMETER_ERROR_IDENTITIES_DONT_MATCH and send it in a Diameter
+ Multimedia-Auth-Answer (MAA) message.
+
+ Note: Correlation between User-Name and SIP-AOR AVP values is only
+ required for SIP REGISTER request, to prevent a user from
+ registering a SIP-AOR allocated to another user. In other types
+ of SIP requests (e.g., INVITE), the SIP-AOR indicates the intended
+ destination of the request, rather than the originator of it.
+
+ The Diameter server MUST verify whether the authentication scheme
+ (SIP-Authentication-Scheme AVP value) indicated in the grouped
+ SIP-Auth-Data-Item AVP is supported or not. If that authentication
+ scheme is not supported, then the Diameter server MUST set the
+ Result-Code AVP to DIAMETER_ERROR_AUTH_SCHEME_NOT_SUPPORTED and send
+ it in a Diameter Multimedia-Auth-Answer (MAA) message.
+
+ If the SIP-Number-Auth-Items AVP is present in the Diameter MAR
+ message, it indicates the number of authentication data items that
+ the Diameter client is requesting. It is RECOMMENDED that the
+ Diameter server, when building the Diameter MAA message, includes a
+ number of SIP-Auth-Data-Item AVPs that are a subset of the
+ authentication data items requested by the Diameter client in the
+ SIP-Number-Auth-Items AVP value of the Diameter MAR message.
+
+ If the SIP-Server-URI AVP is present in the Diameter MAR message,
+ then the Diameter server MUST compare the stored SIP server (assigned
+ to the user) with the SIP-Server-URI AVP value (received in the
+ Diameter MAR message). If they don't match, the Diameter server MUST
+ temporarily save the newly received SIP server assigned to the user,
+ and MUST set an "authentication pending" flag for the user. If they
+ match, the Diameter server shall clear the "authentication pending"
+ flag for the user.
+
+ In any other situation, if there is a success in processing the
+ Diameter MAR command and the Diameter server stored the
+ SIP-Server-URI, the Diameter server MUST set the Result-Code AVP
+ value to DIAMETER_SUCCESS and return it in a Diameter MAA message.
+
+ If there is a success in processing the Diameter MAR command, but the
+ Diameter server does not store the SIP-Server-URI because the AVP was
+ not present in the Diameter MAR command, then the Diameter server
+ MUST set the Result-Code AVP value to either:
+
+ 1. DIAMETER_SUCCESS_AUTH_SENT_SERVER_NOT_STORED, if the Diameter
+ server is sending authentication credentials to create a
+ challenge.
+
+ 2. DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED, if the Diameter server
+ successfully authenticated the user and authorized the SIP server
+ to proceed with the SIP request.
+
+ Otherwise, the Diameter server MUST set the Result-Code AVP value to
+ DIAMETER_UNABLE_TO_COMPLY, and it MUST NOT include any
+ SIP-Auth-Data-Item AVP.
+
+ The Message Format of the MAA command is as follows:
+
+ <MAA> ::= < Diameter Header: 286, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Result-Code }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ [ User-Name ]
+ [ SIP-AOR ]
+ [ SIP-Number-Auth-Items ]
+ * [ SIP-Auth-Data-Item ]
+ [ Authorization-Lifetime ]
+ [ Auth-Grace-Period ]
+ [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 286, /* Code */
+ "Multimedia-Auth-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-AOR", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Number-Auth-Items", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Auth-Data-Item", RULE_OPTIONAL, -1, -1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ /* Server-Assignment-Request (SAR) Command */
+ {
+ /*
+
+ The Server-Assignment-Request (SAR) command is indicated by the
+ Command-Code set to 284 and the Command Flags' 'R' bit set. The
+ Diameter client in a SIP server sends this command to the Diameter
+ server to indicate the completion of the authentication process and
+ to request that the Diameter server store the URI of the SIP server
+ that is currently serving the user. The main functions of the
+ Diameter SAR command are to inform the Diameter server of the URI of
+ the SIP server allocated to the user, and to store or clear it from
+ the Diameter server. Additionally, the Diameter client can request
+ to download the user profile or part of it.
+
+ During the registration procedure, a SIP server becomes assigned to
+ the user. The Diameter client in the assigned SIP server MUST
+ include its own URI in the SIP-Server-URI AVP of the
+ Server-Assignment-Request (SAR) Diameter message and send it to the
+ Diameter server. The Diameter server then becomes aware of the
+ allocation of the SIP server to the user name and the server's URI.
+
+ The Diameter client in the SIP server MAY send a Diameter SAR message
+ because of other reasons. These reasons are identified in the
+ SIP-Server-Assignment-Type AVP (Section 9.4) value. For instance, a
+ Diameter client in a SIP server may contact the Diameter server to
+ request deregistration of a user, to inform the Diameter server of an
+ authentication failure, or just to download the user profile. For a
+ complete description of all the SIP-Server-Assignment-Type AVP
+ values, see Section 9.4.
+
+ Typically the reception of a SIP REGISTER request in a SIP server
+ will trigger the Diameter client in the SIP server to send the
+ Diameter SAR message. However, if a SIP server is receiving other
+ SIP request, such as INVITE, and the SIP server does not have the
+ user profile, the Diameter client in the SIP server may send the
+ Diameter SAR message to the Diameter server in order to download the
+ user profile and make the Diameter server aware of the SIP server
+ assigned to the user.
+ The user profile is an important piece of information that dictates
+ the behavior of the SIP server when triggering or providing services
+ for the user. Typically the user profile is divided into:
+
+ o Services to be rendered to the user when the user is registered
+ and initiates a SIP request.
+
+ o Services to be rendered to the user when the user is registered
+ and a SIP request destined to that user arrives to the SIP proxy.
+
+ o Services to be rendered to the user when the user is not
+ registered and a SIP request destined to that user arrives to the
+ SIP proxy.
+
+ The SIP-Server-Assignment-Type AVP indicates the reason why the
+ Diameter client (SIP server) contacted the Diameter server. If the
+ Diameter client sets the SIP-Server-Assignment-Type AVP value to
+ REGISTRATION, RE_REGISTRATION, UNREGISTERED_USER, NO_ASSIGNMENT,
+ AUTHENTICATION_FAILURE or AUTHENTICATION_TIMEOUT, the Diameter client
+ MUST include exactly one SIP-AOR AVP in the Diameter SAR message.
+
+ The SAR message MAY contain zero or more SIP-Supported-User-Data-Type
+ AVPs. Each of them contains a type of user data understood by the
+ SIP server. This allows the Diameter client to provide an indication
+ to the Diameter server of the different format of user data
+ understood by the SIP server. The Diameter server uses this
+ information to select one or more SIP-User-Data AVPs that will be
+ included in the SAA message.
+
+ The Message Format of the SAR command is as follows:
+
+ <SAR> ::= < Diameter Header: 284, REQ, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { SIP-Server-Assignment-Type }
+ { SIP-User-Data-Already-Available }
+ [ Destination-Host ]
+ [ User-Name ]
+ [ SIP-Server-URI ]
+ * [ SIP-Supported-User-Data-Type ]
+ * [ SIP-AOR ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 284, /* Code */
+ "Server-Assignment-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-Server-Assignment-Type", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-User-Data-Already-Available", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Server-URI", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Supported-User-Data-Type", RULE_OPTIONAL, -1, -1 }
+ ,{ "SIP-AOR", RULE_OPTIONAL, -1, -1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ /* Server-Assignment-Answer (SAA) Command */
+ {
+ /*
+
+ The Server-Assignment-Answer (SAA) is indicated by the Command-Code
+ set to 284 and the Command Flags' 'R' bit cleared. The Diameter
+ server sends this command in response to a previously received
+ Diameter Server-Assignment-Request (SAR) command. The response may
+ include the user profile or part of it, if requested.
+
+ In addition to the values already defined in RFC 3588 [RFC3588], the
+ Result-Code AVP may contain one of the values defined in
+ Section 10.1.
+
+ The Result-Code AVP value in the Diameter SAA message may indicate a
+ success or an error in the execution of the Diameter SAR command. If
+ Result-Code AVP value in the Diameter SAA message does not contain an
+ error code, the SAA message MAY include one or more SIP-User-Data
+ AVPs that typically contain the profile of the user, indicating
+ services that the SIP server can provide to that user.
+
+ The Diameter server MAY include one or more
+ SIP-Supported-User-Data-Type AVPs, each one identifying a type of
+ user data format supported in the Diameter server. If there is not a
+ common supported user data type between the Diameter client and the
+ Diameter server, the Diameter server SHOULD declare its list of
+ supported user data types by including one or more
+ SIP-Supported-User-Data-Type AVPs in a Diameter SAA message. This
+ indication is merely for debugging reasons, since there is not a
+ fallback mechanism that allows the Diameter client to retrieve the
+ profile in a supported format.
+
+ If the Diameter server requires a User-Name AVP value to process the
+ Diameter SAR request, but the Diameter SAR message did not contain a
+ User-Name AVP value, the Diameter server MUST set the Result-Code AVP
+ value to DIAMETER_USER_NAME_REQUIRED (see Section 10.1.2) and return
+ it in a Diameter SAA message. Upon reception of this Diameter SAA
+ message with the Result-Code AVP value set to
+ DIAMETER_USER_NAME_REQUIRED, the SIP server typically requests
+ authentication by generating a SIP 401 (Unauthorized) or SIP 407
+ (Proxy Authentication Required) response back to the originator.
+
+ If the User-Name AVP is included in the Diameter SAR message, upon
+ reception of the Diameter SAR message, the Diameter server MUST
+ verify the existence of the user in the realm, i.e., the User-Name
+ AVP value is a valid user within that realm. If the Diameter server
+ does not recognize the user name received in the User-Name AVP, the
+ Diameter server MUST build a Diameter Server-Assignment-Answer (SAA)
+ message and MUST set the Result-Code AVP to
+ DIAMETER_ERROR_USER_UNKNOWN.
+ Then the Diameter server MUST authorize that User-Name AVP value is a
+ valid authentication name for the SIP or SIPS URI included in the
+ SIP-AOR AVP of the Diameter SAR message. If this authorization
+ fails, the Diameter server must set the Result-Code AVP to
+ DIAMETER_ERROR_IDENTITIES_DONT_MATCH and send it in a Diameter
+ Server-Assignment-Answer (SAA) message.
+
+ After successful execution of the Diameter SAR command, the Diameter
+ server MUST clear the "authentication pending" flag and SHOULD move
+ the temporarily stored SIP server URI to permanent storage.
+
+ The actions of the Diameter server upon reception of the Diameter SAR
+ message depend on the value of the SIP-Server-Assignment-Type:
+
+ o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
+ message is set to REGISTRATION or RE_REGISTRATION, the Diameter
+ server SHOULD verify that there is only one SIP-AOR AVP.
+ Otherwise, the Diameter server MUST answer with a Diameter SAA
+ message with the Result-Code AVP value set to
+ DIAMETER_AVP_OCCURS_TOO_MANY_TIMES and MUST NOT include any
+ SIP-User-Data AVP. If there is only one SIP-AOR AVP and if the
+ SIP-User-Data-Already-Available AVP value is set to
+ USER_DATA_NOT_AVAILABLE, then the Diameter server SHOULD include
+ one or more user profile data with the SIP or SIPS URI (SIP-AOR
+ AVP) and all other SIP identities associated with that AVP in the
+ SIP-User-Data AVP value of the Diameter SAA message. On selecting
+ the type of user data, the Diameter server SHOULD take into
+ account the supported formats at the SIP server
+ (SIP-Supported-User-Data-Type AVP in the SAR message) and the
+ local policy. Additionally, the Diameter server MUST set the
+ Result-Code AVP value to DIAMETER_SUCCESS in the Diameter SAA
+ message. The Diameter server considers the SIP AOR authenticated
+ and registered.
+
+ o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
+ message is set to UNREGISTERED_USER, then the Diameter server MUST
+ store the SIP server address included in the SIP-Server-URI AVP
+ value. The Diameter server will return the SIP server address in
+ Diameter Location-Info-Answer (LIA) messages. If the
+ SIP-User-Data-Already-Available AVP value is set to
+ USER_DATA_NOT_AVAILABLE, then the Diameter server SHOULD include
+ one or more user profile data associated with the SIP or SIPS URI
+ (SIP-AOR AVP) and associated identities in the SIP-User-Data AVP
+ value of the Diameter SAA message. On selecting the type of user
+ data, the Diameter server SHOULD take into account the supported
+ formats at the SIP server (SIP-Supported-User-Data-Type AVP in the
+ SAR message) and the local policy. The Diameter server MUST set
+ the Result-Code AVP value to DIAMETER_SUCCESS. The Diameter
+ server considers the SIP AOR UNREGISTERED, but with a SIP server
+ allocated to trigger and provide services for unregistered users.
+ Note that in case of UNREGISTERED_USER (SIP-Server-Assignment-Type
+ AVP), the Diameter server MUST verify that there is only one
+ SIP-AOR AVP. Otherwise, the Diameter server MUST answer the
+ Diameter SAR message with a Diameter SAA message, and it MUST set
+ the Result-Code AVP value to DIAMETER_AVP_OCCURS_TOO_MANY_TIMES
+ and MUST NOT include any SIP-User-Data AVP.
+ If the User-Name AVP was not present in the Diameter SAR message
+ and the SIP-AOR is not known for the Diameter server, the Diameter
+ server MUST NOT include a User-Name AVP in the Diameter SAA
+ message and MUST set the Result-Code AVP value to
+ DIAMETER_ERROR_USER_UNKNOWN.
+
+ o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
+ message is set to TIMEOUT_DEREGISTRATION, USER_DEREGISTRATION,
+ DEREGISTRATION_TOO_MUCH_DATA, or ADMINISTRATIVE_DEREGISTRATION,
+ the Diameter server MUST clear the SIP server address associated
+ with all SIP AORs indicated in each of the SIP-AOR AVP values
+ included in the Diameter SAR message. The Diameter server
+ considers all of these SIP AORs as not registered. The Diameter
+ server MUST set the Result-Code AVP value to DIAMETER_SUCCESS in
+ the Diameter SAA message.
+
+ o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
+ message is set to TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME or
+ USER_DEREGISTRATION_STORE_SERVER_NAME, the Diameter server MAY
+ keep the SIP server address associated with the SIP AORs included
+ in the SIP-AOR AVP values of the Diameter SAR message, even though
+ the SIP AORs become unregistered. This feature allows a SIP
+ server to request that the Diameter server remain an assigned SIP
+ server for those SIP AORs (SIP-AOR AVP values) allocated to the
+ same user name, and avoid SIP server assignment. The Diameter
+ server MUST consider all these SIP AORs as not registered. If the
+ Diameter server honors the request of the Diameter client (SIP
+ server) to remain as an allocated SIP server, then the Diameter
+ server MUST keep the SIP server assigned to those SIP AORs
+ allocated to the username and MUST set the Result-Code AVP value
+ to DIAMETER_SUCCESS in the Diameter SAA message. Otherwise, when
+ the Diameter server does not honor the request of the Diameter
+ client (SIP server) to remain as an allocated SIP server, the
+ Diameter server MUST clear the SIP server name assigned to those
+ SIP AORs and it MUST set the Result-Code AVP value to
+ DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED in the Diameter SAA
+ message.
+ o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
+ message is set to NO_ASSIGNMENT, the Diameter server SHOULD first
+ verify that the SIP-Server-URI AVP value in the Diameter SAR
+ message is the same URI as the one assigned to the SIP-AOR AVP
+ value. If they differ, then the Diameter server MUST set the
+ Result-Code AVP value to DIAMETER_UNABLE_TO_COMPLY in the Diameter
+ SAA message. Otherwise, if the SIP-User-Data-Already-Available
+ AVP value is set to USER_DATA_NOT_AVAILABLE, then the Diameter
+ server SHOULD include the user profile data with the SIP or SIPS
+ URI (SIP-AOR AVP) and all other SIP identities associated with
+ that AVP in the SIP-User-Data AVP value of the Diameter SAA
+ message. On selecting the type of user data, the Diameter server
+ SHOULD take into account the supported formats at the SIP server
+ (SIP-Supported-User-Data-Type AVP in the SAR message) and the
+ local policy.
+
+ o If the SIP-Server-Assignment-Type AVP value in the Diameter SAR
+ message is set to AUTHENTICATION_FAILURE or
+ AUTHENTICATION_TIMEOUT, the Diameter server MUST verify that there
+ is exactly one SIP-AOR AVP in the Diameter SAR message. If the
+ number of occurrences of the SIP-AOR AVP is not exactly one, the
+ Diameter server MUST set the Result-Code AVP value to
+ DIAMETER_AVP_OCCURS_TOO_MANY_TIMES in the Diameter SAA message,
+ and SHOULD not take further actions. If there is exactly one
+ SIP-AOR AVP in the Diameter SAR message, the Diameter server MUST
+ clear the address of the SIP server assigned to the SIP AOR
+ allocated to the user name, and the Diameter server MUST set the
+ Result-Code AVP value to DIAMETER_SUCCESS in the Diameter SAA
+ message. The Diameter server MUST consider the SIP AOR as not
+ registered.
+
+ The Message Format of the SAA command is as follows:
+
+ <SAA> ::= < Diameter Header: 284, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Result-Code }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ * [ SIP-User-Data ]
+ [ SIP-Accounting-Information ]
+ * [ SIP-Supported-User-Data-Type ]
+ [ User-Name ]
+ [ Auth-Grace-Period ]
+ [ Authorization-Lifetime ]
+ [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+
+
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 284, /* Code */
+ "Server-Assignment-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-User-Data", RULE_OPTIONAL, -1, -1 }
+ ,{ "SIP-Accounting-Information", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Supported-User-Data-Type", RULE_OPTIONAL, -1, -1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ /* Location-Info-Request (LIR) Command */
+ {
+ /*
+
+ The Location-Info-Request (LIR) is indicated by the Command-Code set
+ to 285 and the Command Flags' 'R' bit set. The Diameter client in a
+ SIP server sends this command to the Diameter server to request
+ routing information, e.g., the URI of the SIP server assigned to the
+ SIP-AOR AVP value allocated to the users.
+
+ The Message Format of the LIR command is as follows:
+
+ <LIR> ::= < Diameter Header: 285, REQ, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { SIP-AOR }
+ [ Destination-Host ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 285, /* Code */
+ "Location-Info-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-AOR", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ /* Location-Info-Answer (LIA) Command */
+ {
+ /*
+ The Location-Info-Answer (LIA) is indicated by the Command-Code set
+ to 285 and the Command Flags' 'R' bit cleared. The Diameter server
+ sends this command in response to a previously received Diameter
+ Location-Info-Request (LIR) command.
+
+ In addition to the values already defined in RFC 3588 [RFC3588], the
+ Result-Code AVP may contain one of the values defined in
+ Section 10.1. When the Diameter server finds an error in processing
+ the Diameter LIR message, the Diameter server MUST stop the process
+ of the message and answer with a Diameter LIA message that includes
+ the appropriate error code in the Result-Code AVP value. When there
+ is no error, the Diameter server MUST set the Result-Code AVP value
+ to DIAMETER_SUCCESS in the Diameter LIA message.
+
+ One of the errors that the Diameter server may find is that the
+ SIP-AOR AVP value is not a valid user in the realm. In such cases,
+ the Diameter server MUST set the Result-Code AVP value to
+ DIAMETER_ERROR_USER_UNKNOWN and return it in a Diameter LIA message.
+
+ If the Diameter server cannot process the Diameter LIR command, e.g.,
+ due to a database error, the Diameter server MUST set the Result-Code
+ AVP value to DIAMETER_UNABLE_TO_COMPLY and return it in a Diameter
+ LIA message. The Diameter server MUST NOT include any SIP-Server-URI
+ or SIP-Server-Capabilities AVP in the Diameter LIA message.
+
+ The Diameter server may or may not be aware of a SIP server assigned
+ to the SIP-AOR AVP value included in the Diameter LIR message. If
+ the Diameter server is aware of a SIP server allocated to that
+ particular user, the Diameter server MUST include the URI of such SIP
+ server in the SIP-Server-URI AVP and return it in a Diameter LIA
+ message. This is typically the situation when the user is either
+ registered, or unregistered but a SIP server is still assigned to the
+ user.
+
+ When the Diameter server is not aware of a SIP server allocated to
+ the user (typically the case when the user unregistered), the
+ Result-Code AVP value in the Diameter LIA message depends on whether
+ the Diameter server is aware that the user has services defined for
+ unregistered users:
+
+ o Those users who have services defined for unregistered users may
+ require the allocation of a SIP server to trigger and perhaps
+ execute those services. Therefore, when the Diameter server is
+ not aware of an assigned SIP server, but the user has services
+ defined for unregistered users, the Diameter server MUST set the
+ Result-Code AVP value to DIAMETER_UNREGISTERED_SERVICE and return
+ it in a Diameter LIA message. The Diameter server MAY also
+ include a SIP-Server-Capabilities AVP to facilitate the SIP server
+ (Diameter client) with the selection of an appropriate SIP server
+ with the required capabilities. Absence of the SIP-Server-
+ Capabilities AVP indicates to the SIP server (Diameter client)
+ that any SIP server is suitable to be allocated for the user.
+
+ o Those users who do not have service defined for unregistered users
+ do not require further processing. The Diameter server MUST set
+ the Result-Code AVP value to
+ DIAMETER_ERROR_IDENTITY_NOT_REGISTERED and return it to the
+ Diameter client in a Diameter LIA message. The SIP server
+ (Diameter client) may return the appropriate SIP response (e.g.,
+ 480 (Temporarily unavailable)) to the original SIP request.
+
+ The Message Format of the LIA command is as follows:
+
+ <LIA> ::= < Diameter Header: 285, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Result-Code }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ [ SIP-Server-URI ]
+ [ SIP-Server-Capabilities ]
+ [ Auth-Grace-Period ]
+ [ Authorization-Lifetime ]
+ [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 285, /* Code */
+ "Location-Info-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-Server-URI", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-Server-Capabilities", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ /* Registration-Termination-Request (RTR) Command */
+ {
+ /*
+ The Registration-Termination-Request (RTR) command is indicated by
+ the Command-Code set to 287 and the Command Flags' 'R' bit set. The
+ Diameter server sends this command to the Diameter client in a SIP
+ server to indicate to the SIP server that one or more SIP AORs have
+ to be deregistered. The command allows an operator to
+ administratively cancel the registration of a user from a centralized
+ Diameter server.
+
+ The Diameter server has the capability to initiate the deregistration
+ of a user and inform the SIP server by means of the Diameter RTR
+ command. The Diameter server can decide whether only one SIP AOR is
+ going to be deregistered, a list of SIP AORs, or all the SIP AORs
+ allocated to the user.
+
+ The absence of a SIP-AOR AVP in the Diameter RTR message indicates
+ that all the SIP AORs allocated to the user identified by the
+ User-Name AVP are being deregistered.
+
+ The Diameter server MUST include a SIP-Deregistration-Reason AVP
+ value to indicate the reason for the deregistration.
+
+ The Message Format of the RTR command is as follows:
+
+ <RTR> ::= < Diameter Header: 287, REQ, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Host }
+ { SIP-Deregistration-Reason }
+ [ Destination-Realm ]
+ [ User-Name ]
+ * [ SIP-AOR ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+
+
+
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 287, /* Code */
+ "Registration-Termination-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-Deregistration-Reason",RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_OPTIONAL, -1, 1 }
+ ,{ "User-Name", RULE_OPTIONAL, -1, 1 }
+ ,{ "SIP-AOR", RULE_REQUIRED, -1, -1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ /* Registration-Termination-Answer (RTA) Command */
+ {
+ /*
+ The Registration-Termination-Answer (RTA) is indicated by the
+ Command-Code set to 287 and the Command Flags' 'R' bit cleared. The
+ Diameter client sends this command in response to a previously
+ received Diameter Registration-Termination-Request (RTR) command.
+
+ In addition to the values already defined in RFC 3588 [RFC3588], the
+ Result-Code AVP may contain one of the values defined in
+ Section 10.1.
+
+ If the SIP server (Diameter client) requires a User-Name AVP value to
+ process the Diameter RTR request, but the Diameter RTR message did
+ not contain a User-Name AVP value, the Diameter client MUST set the
+ Result-Code AVP value to DIAMETER_USER_NAME_REQUIRED (see Section
+ 10.1.2) and return it in a Diameter RTA message.
+
+ The SIP server (Diameter client) applies the administrative
+ deregistration to each of the URIs included in each of the SIP-AOR
+ AVP values, or, if there is no SIP-AOR AVP present in the Diameter
+ RTR request, to all the URIs allocated to the User-Name AVP value.
+
+ The value of the SIP-Deregistration-Reason AVP in the Diameter RTR
+ command has an effect on the actions performed at the SIP server
+ (Diameter client):
+
+ o If the value is set to PERMANENT_TERMINATION, then the user has
+ terminated his/her registration to the realm. If informing the
+ interested parties (e.g., subscribers to the "reg" event
+ [RFC3680]) about the administrative deregistration is supported
+ through SIP procedures, the SIP server (Diameter client) will do
+ so. The Diameter Client in the SIP Server SHOULD NOT request a
+ new user registration. The SIP server clears the registration
+ state of the deregistered AORs.
+
+ o If the value is set to NEW_SIP_SERVER_ASSIGNED, the Diameter
+ server informs the SIP server (Diameter client) that a new SIP
+ server has been allocated to the user, due to some reason. The
+ SIP server, if supported through SIP procedures, will inform the
+ interested parties (e.g., subscribers to the "reg" event
+ [RFC3680]) about the administrative deregistration at this SIP
+ server. The Diameter client in the SIP server SHOULD NOT request
+ a new user registration. The SIP server clears the registration
+ state of the deregistered SIP AORs.
+
+ o If the value is set to SIP_SERVER_CHANGE, the Diameter server
+ informs the SIP server (Diameter client) that a new SIP server has
+ to be allocated to the user, e.g., due to user's capabilities
+ requiring a new SIP server, or not enough resources in the current
+ SIP server. If informing the interested parties about the
+ administrative deregistration is supported through SIP procedures
+ (e.g., subscriptions to the "reg" event [RFC3680]), the SIP server
+ will do so. The Diameter client in the SIP Server SHOULD NOT
+ request a new user registration. The SIP server clears the
+ registration state of the deregistered SIP AORs.
+
+ o If the value is set to REMOVE_SIP_SERVER, the Diameter server
+ informs the SIP server (Diameter client) that the SIP server will
+ no longer be bound in the Diameter server with that user. The SIP
+ server can delete all data related to the user.
+
+ The Message Format of the RTA command is as follows:
+
+ <RTA> ::= < Diameter Header: 287, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Result-Code }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ [ Authorization-Lifetime ]
+ [ Auth-Grace-Period ]
+ [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 287, /* Code */
+ "Registration-Termination-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+
+ /* Push-Profile-Request (PPR) Command */
+ {
+ /*
+ The Push-Profile-Request (PPR) command is indicated by the
+ Command-Code set to 288 and the Command Flags' 'R' bit set. The
+ Diameter server sends this command to the Diameter client in a SIP
+ server to update either the user profile of an already registered
+ user in that SIP server or the SIP accounting information. This
+ allows an operator to modify the data of a user profile or the
+ accounting information and push it to the SIP server where the user
+ is registered.
+
+ Each user has a user profile associated with him/her and other
+ accounting information. The profile or the accounting information
+ may change with time, e.g., due to addition of new services to the
+ user. When the user profile or the accounting information changes,
+ the Diameter server sends a Diameter Push-Profile-Request (PPR)
+ command to the Diameter client in a SIP server, in order to start
+ applying those new services.
+
+ A PPR command MAY contain a SIP-Accounting-Information AVP that
+ updates the addresses of the accounting servers. Changes in the
+ addresses of the accounting servers take effect immediately. The
+ Diameter client SHOULD close any existing accounting session with the
+ existing server and start providing accounting information to the
+ newly acquired accounting server.
+
+ A PPR command MAY contain zero or more SIP-User-Data AVP values
+ containing the new user profile. On selecting the type of user data,
+ the Diameter server SHOULD take into account the supported formats at
+ the SIP server (SIP-Supported-User-Data-Type AVP sent in a previous
+ SAR message) and the local policy.
+
+ The User-Name AVP indicates the user to whom the profile is
+ applicable.
+
+ The Message Format of the PPR command is as follows:
+
+ <PPR> ::= < Diameter Header: 288, REQ, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ { Destination-Realm }
+ { User-Name }
+ * [ SIP-User-Data ]
+ [ SIP-Accounting-Information ]
+ [ Destination-Host ]
+ [ Authorization-Lifetime ]
+ [ Auth-Grace-Period ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 288, /* Code */
+ "Push-Profile-Request", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Destination-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "User-Name", RULE_REQUIRED, -1, 1 }
+ ,{ "SIP-User-Data", RULE_OPTIONAL, -1, -1 }
+ ,{ "SIP-Accounting-Information", RULE_OPTIONAL, -1, 1 }
+ ,{ "Destination-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Authorization-Lifetime", RULE_OPTIONAL, -1, 1 }
+ ,{ "Auth-Grace-Period", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ /* Push-Profile-Answer (PPA) Command */
+ {
+ /*
+
+
+ The Push-Profile-Answer (PPA) is indicated by the Command-Code set to
+ 288 and the Command Flags' 'R' bit cleared. The Diameter client
+ sends this command in response to a previously received Diameter
+ Push-Profile-Request (PPR) command.
+
+ In addition to the values already defined in RFC 3588 [RFC3588], the
+ Result-Code AVP may contain one of the values defined in
+ Section 10.1.
+
+ If there is no error when processing the received Diameter PPR
+ message, the SIP server (Diameter client) MUST download the received
+ user profile from the SIP-User-Data AVP values in the Diameter PPR
+ message and store it associated with the user specified in the
+ User-Name AVP value.
+
+ If the SIP server does not recognize or does not support some of the
+ data transferred in the SIP-User-Data AVP values, the Diameter client
+ in the SIP server MUST return a Diameter PPA message that includes a
+ Result-Code AVP set to the value DIAMETER_ERROR_NOT_SUPPORTED_USER_DATA.
+
+ If the SIP server (Diameter client) receives a Diameter PPR message
+ with a User-Name AVP that is unknown, the Diameter client MUST set
+ the Result-Code AVP value to DIAMETER_ERROR_USER_UNKNOWN and MUST
+ return it to the Diameter server in a Diameter PPA message.
+
+ If the SIP server (Diameter client) receives in the
+ SIP-User-Data-Content AVP value (of the grouped SIP-User-Data AVP)
+ more data than it can accept, it MUST set the Result-Code AVP value
+ to DIAMETER_ERROR_TOO_MUCH_DATA and MUST return it to the Diameter
+ server in a Diameter PPA message. The SIP server MUST NOT override
+ the existing user profile with the one received in the PPR message.
+
+ If the Diameter server receives the Result-Code AVP value set to
+ DIAMETER_ERROR_TOO_MUCH_DATA in a Diameter PPA message, it SHOULD
+ force a new re-registration of the user by sending to the Diameter
+ client a Diameter Registration-Termination-Request (RTR) with the
+ SIP-Deregistration-Reason AVP value set to SIP_SERVER_CHANGE. This
+ will force a re-registration of the user and will trigger a selection
+ of a new SIP server.
+
+ If the Diameter client is not able to honor the command, for any
+ other reason, it MUST set the Result-Code AVP value to
+ DIAMETER_UNABLE_TO_COMPLY and it MUST return it in a Diameter PPA
+ message.
+
+ The Message Format of the PPA command is as follows:
+
+ <PPA> ::= < Diameter Header: 288, PXY >
+ < Session-Id >
+ { Auth-Application-Id }
+ { Result-Code }
+ { Auth-Session-State }
+ { Origin-Host }
+ { Origin-Realm }
+ [ Redirect-Host ]
+ [ Redirect-Host-Usage ]
+ [ Redirect-Max-Cache-Time ]
+ * [ Proxy-Info ]
+ * [ Route-Record ]
+ * [ AVP ]
+
+
+
+ */
+ struct dict_object * cmd;
+ struct dict_cmd_data data = {
+ 288, /* Code */
+ "Push-Profile-Answer", /* Name */
+ CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
+ CMD_FLAG_PROXIABLE /* Fixed flag values */
+ };
+ struct local_rules_definition rules[] =
+ { { "Session-Id", RULE_FIXED_HEAD, -1, 1 }
+ ,{ "Auth-Application-Id", RULE_REQUIRED, -1, 1 }
+ ,{ "Result-Code", RULE_REQUIRED, -1, 1 }
+ ,{ "Auth-Session-State", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Host", RULE_REQUIRED, -1, 1 }
+ ,{ "Origin-Realm", RULE_REQUIRED, -1, 1 }
+ ,{ "Redirect-Host", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Host-Usage", RULE_OPTIONAL, -1, 1 }
+ ,{ "Redirect-Max-Cache-Time", RULE_OPTIONAL, -1, 1 }
+ ,{ "Proxy-Info", RULE_OPTIONAL, -1, -1 }
+ ,{ "Route-Record", RULE_OPTIONAL, -1, -1 }
+
+ };
+
+ CHECK_dict_new( DICT_COMMAND, &data , sip, &cmd);
+ PARSE_loc_rules( rules, cmd );
+ }
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for SIP' initialized");
+ return 0;
+}
+EXTENSION_ENTRY("dict_sip", ds_dict_init);
diff --git a/extensions/dict_ts29061_avps/CMakeLists.txt b/extensions/dict_ts29061_avps/CMakeLists.txt
new file mode 100644
index 0000000..d3858df
--- /dev/null
+++ b/extensions/dict_ts29061_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29061_avps extension
+PROJECT("dict_ts29061_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29061_avps dict_ts29061_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29061_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29061_AVPS)
+
+
+
diff --git a/extensions/dict_ts29061_avps/dict_ts29061_avps.c b/extensions/dict_ts29061_avps/dict_ts29061_avps.c
new file mode 100644
index 0000000..1e2ba8e
--- /dev/null
+++ b/extensions/dict_ts29061_avps/dict_ts29061_avps.c
@@ -0,0 +1,1022 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29061_avps (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697184.9
+
+const char *ts29061_avps_proto_ver = PROTO_VER;
+const double ts29061_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29061_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* 3GPP-IMSI */
+ {
+ struct dict_avp_data data = {
+ 1, /* Code */
+ 10415, /* Vendor */
+ "3GPP-IMSI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* 3GPP-Charging-Id */
+ {
+ struct dict_avp_data data = {
+ 2, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Charging-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-PDP-Type */
+ {
+ struct dict_avp_data data = {
+ 3, /* Code */
+ 10415, /* Vendor */
+ "3GPP-PDP-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(3GPP-PDP-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Ipv4", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PPP", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Ipv6", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Ipv4v6", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "Non-IP", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* 3GPP-CG-Address */
+ {
+ struct dict_avp_data data = {
+ 4, /* Code */
+ 10415, /* Vendor */
+ "3GPP-CG-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-GPRS-Negotiated-QoS-Profile */
+ {
+ struct dict_avp_data data = {
+ 5, /* Code */
+ 10415, /* Vendor */
+ "3GPP-GPRS-Negotiated-QoS-Profile", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* 3GPP-SGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 6, /* Code */
+ 10415, /* Vendor */
+ "3GPP-SGSN-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-GGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 7, /* Code */
+ 10415, /* Vendor */
+ "3GPP-GGSN-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-IMSI-MCC-MNC */
+ {
+ struct dict_avp_data data = {
+ 8, /* Code */
+ 10415, /* Vendor */
+ "3GPP-IMSI-MCC-MNC", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* 3GPP-GGSN-MCC-MNC */
+ {
+ struct dict_avp_data data = {
+ 9, /* Code */
+ 10415, /* Vendor */
+ "3GPP-GGSN-MCC-MNC", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* 3GPP-NSAPI */
+ {
+ struct dict_avp_data data = {
+ 10, /* Code */
+ 10415, /* Vendor */
+ "3GPP-NSAPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-Selection-Mode */
+ {
+ struct dict_avp_data data = {
+ 12, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Selection-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* 3GPP-Charging-Characteristics */
+ {
+ struct dict_avp_data data = {
+ 13, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Charging-Characteristics", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* 3GPP-CG-Ipv6-Address */
+ {
+ struct dict_avp_data data = {
+ 14, /* Code */
+ 10415, /* Vendor */
+ "3GPP-CG-Ipv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-SGSN-Ipv6-Address */
+ {
+ struct dict_avp_data data = {
+ 15, /* Code */
+ 10415, /* Vendor */
+ "3GPP-SGSN-Ipv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-GGSN-Ipv6-Address */
+ {
+ struct dict_avp_data data = {
+ 16, /* Code */
+ 10415, /* Vendor */
+ "3GPP-GGSN-Ipv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-Ipv6-DNS-Servers */
+ {
+ struct dict_avp_data data = {
+ 17, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Ipv6-DNS-Servers", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-SGSN-MCC-MNC */
+ {
+ struct dict_avp_data data = {
+ 18, /* Code */
+ 10415, /* Vendor */
+ "3GPP-SGSN-MCC-MNC", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* 3GPP-IMEISV */
+ {
+ struct dict_avp_data data = {
+ 20, /* Code */
+ 10415, /* Vendor */
+ "3GPP-IMEISV", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-RAT-Type */
+ {
+ struct dict_avp_data data = {
+ 21, /* Code */
+ 10415, /* Vendor */
+ "3GPP-RAT-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-User-Location-Info */
+ {
+ struct dict_avp_data data = {
+ 22, /* Code */
+ 10415, /* Vendor */
+ "3GPP-User-Location-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-MS-TimeZone */
+ {
+ struct dict_avp_data data = {
+ 23, /* Code */
+ 10415, /* Vendor */
+ "3GPP-MS-TimeZone", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-CAMEL-Charging-Info */
+ {
+ struct dict_avp_data data = {
+ 24, /* Code */
+ 10415, /* Vendor */
+ "3GPP-CAMEL-Charging-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-Packet-Filter */
+ {
+ struct dict_avp_data data = {
+ 25, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Packet-Filter", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-Negotiated-DSCP */
+ {
+ struct dict_avp_data data = {
+ 26, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Negotiated-DSCP", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-Allocate-IP-Type */
+ {
+ struct dict_avp_data data = {
+ 27, /* Code */
+ 10415, /* Vendor */
+ "3GPP-Allocate-IP-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TWAN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 29, /* Code */
+ 10415, /* Vendor */
+ "TWAN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP-User-Location-Info-Time */
+ {
+ struct dict_avp_data data = {
+ 30, /* Code */
+ 10415, /* Vendor */
+ "3GPP-User-Location-Info-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TMGI */
+ {
+ struct dict_avp_data data = {
+ 900, /* Code */
+ 10415, /* Vendor */
+ "TMGI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Required-MBMS-Bearer-Capabilities */
+ {
+ struct dict_avp_data data = {
+ 901, /* Code */
+ 10415, /* Vendor */
+ "Required-MBMS-Bearer-Capabilities", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* MBMS-StartStop-Indication */
+ {
+ struct dict_avp_data data = {
+ 902, /* Code */
+ 10415, /* Vendor */
+ "MBMS-StartStop-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-StartStop-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "START", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "STOP", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "UPDATE", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "HEARTBEAT", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-Service-Area */
+ {
+ struct dict_avp_data data = {
+ 903, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Service-Area", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Session-Duration */
+ {
+ struct dict_avp_data data = {
+ 904, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Session-Duration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Alternative-APN */
+ {
+ struct dict_avp_data data = {
+ 905, /* Code */
+ 10415, /* Vendor */
+ "Alternative-APN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* MBMS-Service-Type */
+ {
+ struct dict_avp_data data = {
+ 906, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Service-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-Service-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MULTICAST", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "BROADCAST", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-2G-3G-Indicator */
+ {
+ struct dict_avp_data data = {
+ 907, /* Code */
+ 10415, /* Vendor */
+ "MBMS-2G-3G-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-2G-3G-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "G_AND_3G", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-Session-Identity */
+ {
+ struct dict_avp_data data = {
+ 908, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Session-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RAI */
+ {
+ struct dict_avp_data data = {
+ 909, /* Code */
+ 10415, /* Vendor */
+ "RAI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Additional-MBMS-Trace-Info */
+ {
+ struct dict_avp_data data = {
+ 910, /* Code */
+ 10415, /* Vendor */
+ "Additional-MBMS-Trace-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Time-To-Data-Transfer */
+ {
+ struct dict_avp_data data = {
+ 911, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Time-To-Data-Transfer", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Session-Repetition-Number */
+ {
+ struct dict_avp_data data = {
+ 912, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Session-Repetition-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Required-QoS */
+ {
+ struct dict_avp_data data = {
+ 913, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Required-QoS", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* MBMS-Counting-Information */
+ {
+ struct dict_avp_data data = {
+ 914, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Counting-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-Counting-Information)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "COUNTING_NOT_APPLICABLE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "COUNTING_APPLICABLE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-User-Data-Mode-Indication */
+ {
+ struct dict_avp_data data = {
+ 915, /* Code */
+ 10415, /* Vendor */
+ "MBMS-User-Data-Mode-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-User-Data-Mode-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Unicast", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Multicast_and_Unicast", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-GGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 916, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GGSN-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-GGSN-Ipv6-Address */
+ {
+ struct dict_avp_data data = {
+ 917, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GGSN-Ipv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-BMSC-SSM-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 918, /* Code */
+ 10415, /* Vendor */
+ "MBMS-BMSC-SSM-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-BMSC-SSM-Ipv6-Address */
+ {
+ struct dict_avp_data data = {
+ 919, /* Code */
+ 10415, /* Vendor */
+ "MBMS-BMSC-SSM-Ipv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Flow-Identifier */
+ {
+ struct dict_avp_data data = {
+ 920, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Flow-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CN-IP-Multicast-Distribution */
+ {
+ struct dict_avp_data data = {
+ 921, /* Code */
+ 10415, /* Vendor */
+ "CN-IP-Multicast-Distribution", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CN-IP-Multicast-Distribution)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NO_IP_MULTICAST", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "IP_MULTICAST", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-HC-Indicator */
+ {
+ struct dict_avp_data data = {
+ 922, /* Code */
+ 10415, /* Vendor */
+ "MBMS-HC-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-HC-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "General", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Re_Auth_Request_Command", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Usage_of_RADIUS_at_the_Pk_Reference_Point", { .i32=18 }};
+ struct dict_enumval_data t_4 = { "Usage_of_Diameter_on_Mz_interface", { .i32=19 }};
+ struct dict_enumval_data t_5 = { "RE_Auth_Answer_Command", { .i32=2 }};
+ struct dict_enumval_data t_6 = { "Usage_of_Diameter_on_SGmb_interface", { .i32=20 }};
+ struct dict_enumval_data t_7 = { "Session_Termination_Request_Command", { .i32=3 }};
+ struct dict_enumval_data t_8 = { "Session_Termination_Answer_Command", { .i32=4 }};
+ struct dict_enumval_data t_9 = { "Abort_Session_Request_Command", { .i32=5 }};
+ struct dict_enumval_data t_10 = { "Abort_Session_Answer_Command", { .i32=6 }};
+ struct dict_enumval_data t_11 = { "Gmb_specific_Experimental_Result_Code_AVP_values", { .i32=8 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-Access-Indicator */
+ {
+ struct dict_avp_data data = {
+ 923, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Access-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-Access-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UTRAN", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "E_UTRAN", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "UTRAN_AND_E_UTRAN", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-GW-SSM-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 924, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GW-SSM-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-GW-SSM-Ipv6-Address */
+ {
+ struct dict_avp_data data = {
+ 925, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GW-SSM-Ipv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-BMSC-SSM-UDP-Port */
+ {
+ struct dict_avp_data data = {
+ 926, /* Code */
+ 10415, /* Vendor */
+ "MBMS-BMSC-SSM-UDP-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-GW-UDP-Port */
+ {
+ struct dict_avp_data data = {
+ 927, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GW-UDP-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-GW-UDP-Port-Indicator */
+ {
+ struct dict_avp_data data = {
+ 928, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GW-UDP-Port-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-GW-UDP-Port-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UDP_PORT_REQUIRED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-Data-Transfer-Start */
+ {
+ struct dict_avp_data data = {
+ 929, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Data-Transfer-Start", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Data-Transfer-Stop */
+ {
+ struct dict_avp_data data = {
+ 930, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Data-Transfer-Stop", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Flag */
+ {
+ struct dict_avp_data data = {
+ 931, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Flag", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Restart-Counter */
+ {
+ struct dict_avp_data data = {
+ 932, /* Code */
+ 10415, /* Vendor */
+ "Restart-Counter", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Diagnostic-Info */
+ {
+ struct dict_avp_data data = {
+ 933, /* Code */
+ 10415, /* Vendor */
+ "Diagnostic-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Cell-List */
+ {
+ struct dict_avp_data data = {
+ 934, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Cell-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29061_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29061_avps (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29061_avps_load_defs(conffile);
+ return dict_ts29061_avps_load_rules(conffile);
+}
+
+const char* dict_ts29061_avps_proto_ver(char * conffile) {
+ return ts29061_avps_proto_ver;
+}
+
+const double dict_ts29061_avps_gen_ts(char * conffile) {
+ return ts29061_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29061_avps", dict_ts29061_avps_load_defs, dict_ts29061_avps_load_rules, "dict_ts29468_avps", "dict_ts29212_avps", "dict_ts29229_avps", "dict_ts29336_avps", "dict_rfc7155_avps");
+
+
+
diff --git a/extensions/dict_ts29061_avps/ts29061_avps.did b/extensions/dict_ts29061_avps/ts29061_avps.did
new file mode 100644
index 0000000..1616278
--- /dev/null
+++ b/extensions/dict_ts29061_avps/ts29061_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29337_avps
+dict_3gpp2_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_ts29338_avps
+dict_ts29173_avps
+dict_ts29336_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_draftload_avps
+dict_etsi283034_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29212_avps
+dict_ts29061_avps
diff --git a/extensions/dict_ts29128_avps/CMakeLists.txt b/extensions/dict_ts29128_avps/CMakeLists.txt
new file mode 100644
index 0000000..d6f3a30
--- /dev/null
+++ b/extensions/dict_ts29128_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29128_avps extension
+PROJECT("dict_ts29128_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29128_avps dict_ts29128_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29128_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29128_AVPS)
+
+
+
diff --git a/extensions/dict_ts29128_avps/dict_ts29128_avps.c b/extensions/dict_ts29128_avps/dict_ts29128_avps.c
new file mode 100644
index 0000000..2dad78a
--- /dev/null
+++ b/extensions/dict_ts29128_avps/dict_ts29128_avps.c
@@ -0,0 +1,502 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29128_avps (e20).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e20"
+#define GEN_DATE 1506697139.86
+
+const char *ts29128_avps_proto_ver = PROTO_VER;
+const double ts29128_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29128_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Cause-Type */
+ {
+ struct dict_avp_data data = {
+ 4301, /* Code */
+ 10415, /* Vendor */
+ "Cause-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* S1AP-Cause */
+ {
+ struct dict_avp_data data = {
+ 4302, /* Code */
+ 10415, /* Vendor */
+ "S1AP-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RANAP-Cause */
+ {
+ struct dict_avp_data data = {
+ 4303, /* Code */
+ 10415, /* Vendor */
+ "RANAP-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* BSSGP-Cause */
+ {
+ struct dict_avp_data data = {
+ 4309, /* Code */
+ 10415, /* Vendor */
+ "BSSGP-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* GMM-Cause */
+ {
+ struct dict_avp_data data = {
+ 4304, /* Code */
+ 10415, /* Vendor */
+ "GMM-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Cause */
+ {
+ struct dict_avp_data data = {
+ 4305, /* Code */
+ 10415, /* Vendor */
+ "SM-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UE-Count */
+ {
+ struct dict_avp_data data = {
+ 4308, /* Code */
+ 10415, /* Vendor */
+ "UE-Count", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Connection-Action */
+ {
+ struct dict_avp_data data = {
+ 4314, /* Code */
+ 10415, /* Vendor */
+ "Connection-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Non-IP-Data */
+ {
+ struct dict_avp_data data = {
+ 4315, /* Code */
+ 10415, /* Vendor */
+ "Non-IP-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Uplink-Rate-Limit */
+ {
+ struct dict_avp_data data = {
+ 4311, /* Code */
+ 10415, /* Vendor */
+ "Uplink-Rate-Limit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Downlink-Rate-Limit */
+ {
+ struct dict_avp_data data = {
+ 4312, /* Code */
+ 10415, /* Vendor */
+ "Downlink-Rate-Limit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Extended-PCO */
+ {
+ struct dict_avp_data data = {
+ 4313, /* Code */
+ 10415, /* Vendor */
+ "Extended-PCO", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SCEF-Wait-Time */
+ {
+ struct dict_avp_data data = {
+ 4316, /* Code */
+ 10415, /* Vendor */
+ "SCEF-Wait-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* CMR-Flags */
+ {
+ struct dict_avp_data data = {
+ 4317, /* Code */
+ 10415, /* Vendor */
+ "CMR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Counter-Value */
+ {
+ struct dict_avp_data data = {
+ 4319, /* Code */
+ 10415, /* Vendor */
+ "Counter-Value", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RRC-Counter-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 4320, /* Code */
+ 10415, /* Vendor */
+ "RRC-Counter-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Communication-Failure-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4300, /* Code */
+ 10415, /* Vendor */
+ "Communication-Failure-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* RRC-Cause-Counter */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4318, /* Code */
+ 10415, /* Vendor */
+ "RRC-Cause-Counter", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Serving-PLMN-Rate-Control */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4310, /* Code */
+ 10415, /* Vendor */
+ "Serving-PLMN-Rate-Control", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Number-Of-UE-Per-Location-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4307, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-UE-Per-Location-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Number-Of-UE-Per-Location-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4306, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-UE-Per-Location-Configuration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29128_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Communication-Failure-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Communication-Failure-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Cause-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "S1AP-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RANAP-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "BSSGP-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GMM-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Cause"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* RRC-Cause-Counter */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "RRC-Cause-Counter"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Counter-Value"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RRC-Counter-Timestamp"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Serving-PLMN-Rate-Control */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Serving-PLMN-Rate-Control"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Uplink-Rate-Limit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Downlink-Rate-Limit"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Number-Of-UE-Per-Location-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Number-Of-UE-Per-Location-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "EPS-Location-Information"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Count"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Number-Of-UE-Per-Location-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Number-Of-UE-Per-Location-Configuration"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "EPS-Location-Information"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29128_avps (e20)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29128_avps_load_defs(conffile);
+ return dict_ts29128_avps_load_rules(conffile);
+}
+
+const char* dict_ts29128_avps_proto_ver(char * conffile) {
+ return ts29128_avps_proto_ver;
+}
+
+const double dict_ts29128_avps_gen_ts(char * conffile) {
+ return ts29128_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29128_avps", dict_ts29128_avps_load_defs, dict_ts29128_avps_load_rules, "dict_ts32299_avps", "dict_ts29272_avps", "dict_ts29336_avps", "dict_ts29212_avps", "dict_ts29338_avps", "dict_ts29229_avps", "dict_ts29061_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc5778_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29128_avps/ts29128_avps.did b/extensions/dict_ts29128_avps/ts29128_avps.did
new file mode 100644
index 0000000..ef80f79
--- /dev/null
+++ b/extensions/dict_ts29128_avps/ts29128_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29338_avps
+dict_ts29343_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29128_avps
diff --git a/extensions/dict_ts29154_avps/CMakeLists.txt b/extensions/dict_ts29154_avps/CMakeLists.txt
new file mode 100644
index 0000000..5d5b8fc
--- /dev/null
+++ b/extensions/dict_ts29154_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29154_avps extension
+PROJECT("dict_ts29154_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29154_avps dict_ts29154_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29154_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29154_AVPS)
+
+
+
diff --git a/extensions/dict_ts29154_avps/dict_ts29154_avps.c b/extensions/dict_ts29154_avps/dict_ts29154_avps.c
new file mode 100644
index 0000000..02dae3d
--- /dev/null
+++ b/extensions/dict_ts29154_avps/dict_ts29154_avps.c
@@ -0,0 +1,313 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29154_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697149.99
+
+const char *ts29154_avps_proto_ver = PROTO_VER;
+const double ts29154_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29154_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Network-Area-Info-List */
+ {
+ struct dict_avp_data data = {
+ 4201, /* Code */
+ 10415, /* Vendor */
+ "Network-Area-Info-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Number-Of-UEs */
+ {
+ struct dict_avp_data data = {
+ 4209, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-UEs", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Reference-Id */
+ {
+ struct dict_avp_data data = {
+ 4202, /* Code */
+ 10415, /* Vendor */
+ "Reference-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Transfer-Request-Type */
+ {
+ struct dict_avp_data data = {
+ 4203, /* Code */
+ 10415, /* Vendor */
+ "Transfer-Request-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Transfer-End-Time */
+ {
+ struct dict_avp_data data = {
+ 4205, /* Code */
+ 10415, /* Vendor */
+ "Transfer-End-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Transfer-Policy-Id */
+ {
+ struct dict_avp_data data = {
+ 4208, /* Code */
+ 10415, /* Vendor */
+ "Transfer-Policy-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Transfer-Start-Time */
+ {
+ struct dict_avp_data data = {
+ 4206, /* Code */
+ 10415, /* Vendor */
+ "Transfer-Start-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Time-Window */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4204, /* Code */
+ 10415, /* Vendor */
+ "Time-Window", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Transfer-Policy */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4207, /* Code */
+ 10415, /* Vendor */
+ "Transfer-Policy", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29154_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Time-Window */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Time-Window"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Transfer-Start-Time"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Transfer-End-Time"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Transfer-Policy */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Transfer-Policy"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Transfer-Policy-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Window"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Rating-Group"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-UL"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29154_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29154_avps_load_defs(conffile);
+ return dict_ts29154_avps_load_rules(conffile);
+}
+
+const char* dict_ts29154_avps_proto_ver(char * conffile) {
+ return ts29154_avps_proto_ver;
+}
+
+const double dict_ts29154_avps_gen_ts(char * conffile) {
+ return ts29154_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29154_avps", dict_ts29154_avps_load_defs, dict_ts29154_avps_load_rules, "dict_ts29215_avps", "dict_ts29214_avps", "dict_ts29229_avps", "dict_rfc7683_avps", "dict_rfc4006bis_avps", "dict_draftload_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29154_avps/ts29154_avps.did b/extensions/dict_ts29154_avps/ts29154_avps.did
new file mode 100644
index 0000000..1a8b394
--- /dev/null
+++ b/extensions/dict_ts29154_avps/ts29154_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29214_avps
+dict_ts29468_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_ts29212_avps
+dict_ts29215_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29154_avps
diff --git a/extensions/dict_ts29173_avps/CMakeLists.txt b/extensions/dict_ts29173_avps/CMakeLists.txt
new file mode 100644
index 0000000..7ea8b5c
--- /dev/null
+++ b/extensions/dict_ts29173_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29173_avps extension
+PROJECT("dict_ts29173_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29173_avps dict_ts29173_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29173_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29173_AVPS)
+
+
+
diff --git a/extensions/dict_ts29173_avps/dict_ts29173_avps.c b/extensions/dict_ts29173_avps/dict_ts29173_avps.c
new file mode 100644
index 0000000..d82e53d
--- /dev/null
+++ b/extensions/dict_ts29173_avps/dict_ts29173_avps.c
@@ -0,0 +1,360 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29173_avps (e00).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e00"
+#define GEN_DATE 1506697172.2
+
+const char *ts29173_avps_proto_ver = PROTO_VER;
+const double ts29173_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29173_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* LMSI */
+ {
+ struct dict_avp_data data = {
+ 2400, /* Code */
+ 10415, /* Vendor */
+ "LMSI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MME-Name */
+ {
+ struct dict_avp_data data = {
+ 2402, /* Code */
+ 10415, /* Vendor */
+ "MME-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* MSC-Number */
+ {
+ struct dict_avp_data data = {
+ 2403, /* Code */
+ 10415, /* Vendor */
+ "MSC-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* LCS-Capabilities-Sets */
+ {
+ struct dict_avp_data data = {
+ 2404, /* Code */
+ 10415, /* Vendor */
+ "LCS-Capabilities-Sets", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* GMLC-Address */
+ {
+ struct dict_avp_data data = {
+ 2405, /* Code */
+ 10415, /* Vendor */
+ "GMLC-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* PPR-Address */
+ {
+ struct dict_avp_data data = {
+ 2407, /* Code */
+ 10415, /* Vendor */
+ "PPR-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* MME-Realm */
+ {
+ struct dict_avp_data data = {
+ 2408, /* Code */
+ 10415, /* Vendor */
+ "MME-Realm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* SGSN-Name */
+ {
+ struct dict_avp_data data = {
+ 2409, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* SGSN-Realm */
+ {
+ struct dict_avp_data data = {
+ 2410, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Realm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* RIA-Flags */
+ {
+ struct dict_avp_data data = {
+ 2411, /* Code */
+ 10415, /* Vendor */
+ "RIA-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Additional-Serving-Node */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2406, /* Code */
+ 10415, /* Vendor */
+ "Additional-Serving-Node", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Serving-Node */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2401, /* Code */
+ 10415, /* Vendor */
+ "Serving-Node", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29173_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Additional-Serving-Node */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Additional-Serving-Node"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Realm"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Realm"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSC-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-AAA-Server-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Capabilities-Sets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GMLC-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Serving-Node */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Serving-Node"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Realm"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Realm"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSC-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-AAA-Server-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Capabilities-Sets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GMLC-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29173_avps (e00)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29173_avps_load_defs(conffile);
+ return dict_ts29173_avps_load_rules(conffile);
+}
+
+const char* dict_ts29173_avps_proto_ver(char * conffile) {
+ return ts29173_avps_proto_ver;
+}
+
+const double dict_ts29173_avps_gen_ts(char * conffile) {
+ return ts29173_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29173_avps", dict_ts29173_avps_load_defs, dict_ts29173_avps_load_rules, "dict_ts29272_avps", "dict_ts29273_avps", "dict_ts29329_avps", "dict_ts29229_avps");
+
+
+
diff --git a/extensions/dict_ts29173_avps/ts29173_avps.did b/extensions/dict_ts29173_avps/ts29173_avps.did
new file mode 100644
index 0000000..3b61556
--- /dev/null
+++ b/extensions/dict_ts29173_avps/ts29173_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29337_avps
+dict_3gpp2_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_ts29338_avps
+dict_ts29336_avps
+dict_ts29368_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29173_avps
diff --git a/extensions/dict_ts29212_avps/CMakeLists.txt b/extensions/dict_ts29212_avps/CMakeLists.txt
new file mode 100644
index 0000000..0ede9a0
--- /dev/null
+++ b/extensions/dict_ts29212_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29212_avps extension
+PROJECT("dict_ts29212_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29212_avps dict_ts29212_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29212_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29212_AVPS)
+
+
+
diff --git a/extensions/dict_ts29212_avps/dict_ts29212_avps.c b/extensions/dict_ts29212_avps/dict_ts29212_avps.c
new file mode 100644
index 0000000..f0012be
--- /dev/null
+++ b/extensions/dict_ts29212_avps/dict_ts29212_avps.c
@@ -0,0 +1,3148 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29212_avps (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697181.97
+
+const char *ts29212_avps_proto_ver = PROTO_VER;
+const double ts29212_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29212_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* 3GPP-PS-Data-Off-Status */
+ {
+ struct dict_avp_data data = {
+ 2847, /* Code */
+ 10415, /* Vendor */
+ "3GPP-PS-Data-Off-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(3GPP-PS-Data-Off-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ACTIVE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "INACTIVE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Access-Availability-Change-Reason */
+ {
+ struct dict_avp_data data = {
+ 2833, /* Code */
+ 10415, /* Vendor */
+ "Access-Availability-Change-Reason", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* AN-GW-Address */
+ {
+ struct dict_avp_data data = {
+ 1050, /* Code */
+ 10415, /* Vendor */
+ "AN-GW-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* AN-GW-Status */
+ {
+ struct dict_avp_data data = {
+ 2811, /* Code */
+ 10415, /* Vendor */
+ "AN-GW-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AN-GW-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "AN_GW_FAILED", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* APN-Aggregate-Max-Bitrate-DL */
+ {
+ struct dict_avp_data data = {
+ 1040, /* Code */
+ 10415, /* Vendor */
+ "APN-Aggregate-Max-Bitrate-DL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* APN-Aggregate-Max-Bitrate-UL */
+ {
+ struct dict_avp_data data = {
+ 1041, /* Code */
+ 10415, /* Vendor */
+ "APN-Aggregate-Max-Bitrate-UL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Bearer-Control-Mode */
+ {
+ struct dict_avp_data data = {
+ 1023, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Control-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Bearer-Control-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UE_ONLY", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "RESERVED", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "UE_NW", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Bearer-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1020, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Bearer-Operation */
+ {
+ struct dict_avp_data data = {
+ 1021, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Operation", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Bearer-Operation)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TERMINATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ESTABLISHMENT", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "MODIFICATION", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Bearer-Usage */
+ {
+ struct dict_avp_data data = {
+ 1000, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Usage", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Bearer-Usage)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "GENERAL", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "IMS_SIGNALLING", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Charging-Correlation-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1073, /* Code */
+ 10415, /* Vendor */
+ "Charging-Correlation-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Charging-Correlation-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CHARGING_IDENTIFIER_REQUIRED", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Charging-Rule-Base-Name */
+ {
+ struct dict_avp_data data = {
+ 1004, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Base-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Charging-Rule-Name */
+ {
+ struct dict_avp_data data = {
+ 1005, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CoA-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 1035, /* Code */
+ 10415, /* Vendor */
+ "CoA-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Credit-Management-Status */
+ {
+ struct dict_avp_data data = {
+ 1082, /* Code */
+ 10415, /* Vendor */
+ "Credit-Management-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CSG-Information-Reporting */
+ {
+ struct dict_avp_data data = {
+ 1071, /* Code */
+ 10415, /* Vendor */
+ "CSG-Information-Reporting", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CSG-Information-Reporting)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CHANGE_CSG_CELL", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CHANGE_CSG_SUBSCRIBED_HYBRID_CELL", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "CHANGE_CSG_UNSUBSCRIBED_HYBRID_CELL", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Default-Access */
+ {
+ struct dict_avp_data data = {
+ 2829, /* Code */
+ 10415, /* Vendor */
+ "Default-Access", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Default-Access)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "GPP_GPRS", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "DOCSIS", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "xDSL", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "WiMAX", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "GPP2", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "GPP_EPS", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "Non_3GPP_EPS", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "FBA", { .i32=7 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Default-Bearer-Indication */
+ {
+ struct dict_avp_data data = {
+ 2844, /* Code */
+ 10415, /* Vendor */
+ "Default-Bearer-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Default-Bearer-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "BIND_TO_DEF_BEARER", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "BIND_TO_APPLICABLE_BEARER", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Default-QoS-Name */
+ {
+ struct dict_avp_data data = {
+ 2817, /* Code */
+ 10415, /* Vendor */
+ "Default-QoS-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Event-Trigger */
+ {
+ struct dict_avp_data data = {
+ 1006, /* Code */
+ 10415, /* Vendor */
+ "Event-Trigger", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Event-Trigger)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SGSN_CHANGE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "QOS_CHANGE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "QOS_CHANGE_EXCEEDING_AUTHORIZATION", { .i32=11 }};
+ struct dict_enumval_data t_4 = { "RAI_CHANGE", { .i32=12 }};
+ struct dict_enumval_data t_5 = { "USER_LOCATION_CHANGE", { .i32=13 }};
+ struct dict_enumval_data t_6 = { "NO_EVENT_TRIGGERS", { .i32=14 }};
+ struct dict_enumval_data t_7 = { "OUT_OF_CREDIT", { .i32=15 }};
+ struct dict_enumval_data t_8 = { "REALLOCATION_OF_CREDIT", { .i32=16 }};
+ struct dict_enumval_data t_9 = { "REVALIDATION_TIMEOUT", { .i32=17 }};
+ struct dict_enumval_data t_10 = { "UE_IP_ADDRESS_ALLOCATE", { .i32=18 }};
+ struct dict_enumval_data t_11 = { "UE_IP_ADDRESS_RELEASE", { .i32=19 }};
+ struct dict_enumval_data t_12 = { "RAT_CHANGE", { .i32=2 }};
+ struct dict_enumval_data t_13 = { "DEFAULT_EPS_BEARER_QOS_CHANGE", { .i32=20 }};
+ struct dict_enumval_data t_14 = { "AN_GW_CHANGE", { .i32=21 }};
+ struct dict_enumval_data t_15 = { "SUCCESSFUL_RESOURCE_ALLOCATION", { .i32=22 }};
+ struct dict_enumval_data t_16 = { "RESOURCE_MODIFICATION_REQUEST", { .i32=23 }};
+ struct dict_enumval_data t_17 = { "PGW_TRACE_CONTROL", { .i32=24 }};
+ struct dict_enumval_data t_18 = { "UE_TIME_ZONE_CHANGE", { .i32=25 }};
+ struct dict_enumval_data t_19 = { "TAI_CHANGE", { .i32=26 }};
+ struct dict_enumval_data t_20 = { "ECGI_CHANGE", { .i32=27 }};
+ struct dict_enumval_data t_21 = { "CHARGING_CORRELATION_EXCHANGE", { .i32=28 }};
+ struct dict_enumval_data t_22 = { "APN_AMBR_MODIFICATION_FAILURE", { .i32=29 }};
+ struct dict_enumval_data t_23 = { "TFT_CHANGE", { .i32=3 }};
+ struct dict_enumval_data t_24 = { "USER_CSG_INFORMATION_CHANGE", { .i32=30 }};
+ struct dict_enumval_data t_25 = { "USAGE_REPORT", { .i32=33 }};
+ struct dict_enumval_data t_26 = { "DEFAULT_EPS_BEARER_QOS_MODIFICATION_FAILURE", { .i32=34 }};
+ struct dict_enumval_data t_27 = { "USER_CSG_HYBRID_SUBSCRIBED_INFORMATION_CHANGE", { .i32=35 }};
+ struct dict_enumval_data t_28 = { "HYBRID_UNSUBSCRIBED_INFORMATION_CHANGE", { .i32=36 }};
+ struct dict_enumval_data t_29 = { "ROUTING_RULE_CHANGE", { .i32=37 }};
+ struct dict_enumval_data t_30 = { "APPLICATION_START", { .i32=39 }};
+ struct dict_enumval_data t_31 = { "PLMN_CHANGE", { .i32=4 }};
+ struct dict_enumval_data t_32 = { "APPLICATION_STOP", { .i32=40 }};
+ struct dict_enumval_data t_33 = { "CS_TO_PS_HANDOVER", { .i32=42 }};
+ struct dict_enumval_data t_34 = { "UE_LOCAL_IP_ADDRESS_CHANGE", { .i32=43 }};
+ struct dict_enumval_data t_35 = { "NB_LOCAL_IP_ADDRESS_CHANGE", { .i32=44 }};
+ struct dict_enumval_data t_36 = { "ACCESS_NETWORK_INFO_REPORT", { .i32=45 }};
+ struct dict_enumval_data t_37 = { "CREDIT_MANAGEMENT_SESSION_FAILURE", { .i32=46 }};
+ struct dict_enumval_data t_38 = { "DEFAULT_QOS_CHANGE", { .i32=47 }};
+ struct dict_enumval_data t_39 = { "CHANGE_OF_UE_PRESENCE_IN_PRESENCE_REPORTING_AREA_REPORT", { .i32=48 }};
+ struct dict_enumval_data t_40 = { "ADDITION_OF_ACCESS", { .i32=49 }};
+ struct dict_enumval_data t_41 = { "LOSS_OF_BEARER", { .i32=5 }};
+ struct dict_enumval_data t_42 = { "REMOVAL_OF_ACCESS", { .i32=50 }};
+ struct dict_enumval_data t_43 = { "UNAVAILABLITY_OF_ACCESS", { .i32=51 }};
+ struct dict_enumval_data t_44 = { "AVAILABLITY_OF_ACCESS", { .i32=52 }};
+ struct dict_enumval_data t_45 = { "RESOURCE_RELEASE", { .i32=53 }};
+ struct dict_enumval_data t_46 = { "ENODEB_CHANGE", { .i32=54 }};
+ struct dict_enumval_data t_47 = { "GPP_PS_DATA_OFF_CHANGE", { .i32=55 }};
+ struct dict_enumval_data t_48 = { "RECOVERY_OF_BEARER", { .i32=6 }};
+ struct dict_enumval_data t_49 = { "IP_CAN_CHANGE", { .i32=7 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_26, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_27, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_28, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_29, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_30, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_31, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_32, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_33, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_34, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_35, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_36, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_37, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_38, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_39, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_40, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_41, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_42, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_43, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_44, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_45, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_46, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_47, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_48, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_49, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Execution-Time */
+ {
+ struct dict_avp_data data = {
+ 2839, /* Code */
+ 10415, /* Vendor */
+ "Execution-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Flow-Direction */
+ {
+ struct dict_avp_data data = {
+ 1080, /* Code */
+ 10415, /* Vendor */
+ "Flow-Direction", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Flow-Direction)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UNSPECIFIED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "DOWNLINK", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "UPLINK", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "BIDIRECTIONAL", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Flow-Label */
+ {
+ struct dict_avp_data data = {
+ 1057, /* Code */
+ 10415, /* Vendor */
+ "Flow-Label", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Guaranteed-Bitrate-DL */
+ {
+ struct dict_avp_data data = {
+ 1025, /* Code */
+ 10415, /* Vendor */
+ "Guaranteed-Bitrate-DL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Guaranteed-Bitrate-UL */
+ {
+ struct dict_avp_data data = {
+ 1026, /* Code */
+ 10415, /* Vendor */
+ "Guaranteed-Bitrate-UL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* HeNB-Local-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 2804, /* Code */
+ 10415, /* Vendor */
+ "HeNB-Local-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* IP-CAN-Session-Charging-Scope */
+ {
+ struct dict_avp_data data = {
+ 2827, /* Code */
+ 10415, /* Vendor */
+ "IP-CAN-Session-Charging-Scope", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IP-CAN-Session-Charging-Scope)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "IP_CAN_SESSION_SCOPE", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* IP-CAN-Type */
+ {
+ struct dict_avp_data data = {
+ 1027, /* Code */
+ 10415, /* Vendor */
+ "IP-CAN-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IP-CAN-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "GPP_GPRS", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "DOCSIS", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "xDSL", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "WiMAX", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "GPP2", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "GPP_EPS", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "Non_3GPP_EPS", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "FBA", { .i32=7 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Metering-Method */
+ {
+ struct dict_avp_data data = {
+ 1007, /* Code */
+ 10415, /* Vendor */
+ "Metering-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Metering-Method)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DURATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "VOLUME", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "DURATION_VOLUME", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "EVENT", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Monitoring-Flags */
+ {
+ struct dict_avp_data data = {
+ 2828, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Monitoring-Key */
+ {
+ struct dict_avp_data data = {
+ 1066, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Mute-Notification */
+ {
+ struct dict_avp_data data = {
+ 2809, /* Code */
+ 10415, /* Vendor */
+ "Mute-Notification", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Mute-Notification)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MUTE_REQUIRED", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Monitoring-Time */
+ {
+ struct dict_avp_data data = {
+ 2810, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* NBIFOM-Mode */
+ {
+ struct dict_avp_data data = {
+ 2830, /* Code */
+ 10415, /* Vendor */
+ "NBIFOM-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(NBIFOM-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UE_INITIATED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NETWORK_INITIATED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* NBIFOM-Support */
+ {
+ struct dict_avp_data data = {
+ 2831, /* Code */
+ 10415, /* Vendor */
+ "NBIFOM-Support", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(NBIFOM-Support)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NBIFOM_NOT_SUPPORTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NBIFOM_SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* NetLoc-Access-Support */
+ {
+ struct dict_avp_data data = {
+ 2824, /* Code */
+ 10415, /* Vendor */
+ "NetLoc-Access-Support", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Network-Request-Support */
+ {
+ struct dict_avp_data data = {
+ 1024, /* Code */
+ 10415, /* Vendor */
+ "Network-Request-Support", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Network-Request-Support)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NETWORK_REQUEST_NOT_SUPPORTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NETWORK_REQUEST_SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Offline */
+ {
+ struct dict_avp_data data = {
+ 1008, /* Code */
+ 10415, /* Vendor */
+ "Offline", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Offline)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DISABLE_OFFLINE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ENABLE_OFFLINE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Online */
+ {
+ struct dict_avp_data data = {
+ 1009, /* Code */
+ 10415, /* Vendor */
+ "Online", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Online)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DISABLE_ONLINE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ENABLE_ONLINE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Packet-Filter-Content */
+ {
+ struct dict_avp_data data = {
+ 1059, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Content", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+ /* Packet-Filter-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1060, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Packet-Filter-Operation */
+ {
+ struct dict_avp_data data = {
+ 1062, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Operation", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Packet-Filter-Operation)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DELETION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ADDITION", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "MODIFICATION", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Packet-Filter-Usage */
+ {
+ struct dict_avp_data data = {
+ 1072, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Usage", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Packet-Filter-Usage)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SEND_TO_UE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PCC-Rule-Status */
+ {
+ struct dict_avp_data data = {
+ 1019, /* Code */
+ 10415, /* Vendor */
+ "PCC-Rule-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PCC-Rule-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ACTIVE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "INACTIVE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "TEMPORARILY_INACTIVE", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PDN-Connection-ID */
+ {
+ struct dict_avp_data data = {
+ 1065, /* Code */
+ 10415, /* Vendor */
+ "PDN-Connection-ID", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Precedence */
+ {
+ struct dict_avp_data data = {
+ 1010, /* Code */
+ 10415, /* Vendor */
+ "Precedence", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Pre-emption-Capability */
+ {
+ struct dict_avp_data data = {
+ 1047, /* Code */
+ 10415, /* Vendor */
+ "Pre-emption-Capability", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Pre-emption-Capability)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PRE_EMPTION_CAPABILITY_ENABLED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PRE_EMPTION_CAPABILITY_DISABLED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Pre-emption-Vulnerability */
+ {
+ struct dict_avp_data data = {
+ 1048, /* Code */
+ 10415, /* Vendor */
+ "Pre-emption-Vulnerability", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Pre-emption-Vulnerability)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PRE_EMPTION_VULNERABILITY_ENABLED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PRE_EMPTION_VULNERABILITY_DISABLED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Presence-Reporting-Area-Elements-List */
+ {
+ struct dict_avp_data data = {
+ 2820, /* Code */
+ 10415, /* Vendor */
+ "Presence-Reporting-Area-Elements-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Presence-Reporting-Area-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2821, /* Code */
+ 10415, /* Vendor */
+ "Presence-Reporting-Area-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Presence-Reporting-Area-Status */
+ {
+ struct dict_avp_data data = {
+ 2823, /* Code */
+ 10415, /* Vendor */
+ "Presence-Reporting-Area-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Priority-Level */
+ {
+ struct dict_avp_data data = {
+ 1046, /* Code */
+ 10415, /* Vendor */
+ "Priority-Level", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PS-to-CS-Session-Continuity */
+ {
+ struct dict_avp_data data = {
+ 1099, /* Code */
+ 10415, /* Vendor */
+ "PS-to-CS-Session-Continuity", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PS-to-CS-Session-Continuity)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "VIDEO_PS2CS_CONT_CANDIDATE", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* QoS-Class-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1028, /* Code */
+ 10415, /* Vendor */
+ "QoS-Class-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(QoS-Class-Identifier)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "QCI_1", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "QCI_2", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "QCI_3", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "QCI_4", { .i32=4 }};
+ struct dict_enumval_data t_5 = { "QCI_5", { .i32=5 }};
+ struct dict_enumval_data t_6 = { "QCI_6", { .i32=6 }};
+ struct dict_enumval_data t_7 = { "QCI_65", { .i32=65 }};
+ struct dict_enumval_data t_8 = { "QCI_66", { .i32=66 }};
+ struct dict_enumval_data t_9 = { "QCI_69", { .i32=69 }};
+ struct dict_enumval_data t_10 = { "QCI_7", { .i32=7 }};
+ struct dict_enumval_data t_11 = { "QCI_70", { .i32=70 }};
+ struct dict_enumval_data t_12 = { "QCI_75", { .i32=75 }};
+ struct dict_enumval_data t_13 = { "QCI_79", { .i32=79 }};
+ struct dict_enumval_data t_14 = { "QCI_8", { .i32=8 }};
+ struct dict_enumval_data t_15 = { "QCI_9", { .i32=9 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* QoS-Negotiation */
+ {
+ struct dict_avp_data data = {
+ 1029, /* Code */
+ 10415, /* Vendor */
+ "QoS-Negotiation", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(QoS-Negotiation)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NO_QoS_NEGOTIATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "QoS_NEGOTIATION_SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* QoS-Upgrade */
+ {
+ struct dict_avp_data data = {
+ 1030, /* Code */
+ 10415, /* Vendor */
+ "QoS-Upgrade", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(QoS-Upgrade)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "QoS_UPGRADE_NOT_SUPPORTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "QoS_UPGRADE_SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* RAN-NAS-Release-Cause */
+ {
+ struct dict_avp_data data = {
+ 2819, /* Code */
+ 10415, /* Vendor */
+ "RAN-NAS-Release-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RAN-Rule-Support */
+ {
+ struct dict_avp_data data = {
+ 2832, /* Code */
+ 10415, /* Vendor */
+ "RAN-Rule-Support", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RAT-Type */
+ {
+ struct dict_avp_data data = {
+ 1032, /* Code */
+ 10415, /* Vendor */
+ "RAT-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(RAT-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "WLAN", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "VIRTUAL", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Redirect-Support */
+ {
+ struct dict_avp_data data = {
+ 1086, /* Code */
+ 10415, /* Vendor */
+ "Redirect-Support", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Redirect-Support)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "REDIRECTION_DISABLED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "REDIRECTION_ENABLED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Removal-Of-Access */
+ {
+ struct dict_avp_data data = {
+ 2842, /* Code */
+ 10415, /* Vendor */
+ "Removal-Of-Access", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Removal-Of-Access)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "REMOVAL_OF_ACCESS", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Reporting-Level */
+ {
+ struct dict_avp_data data = {
+ 1011, /* Code */
+ 10415, /* Vendor */
+ "Reporting-Level", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Reporting-Level)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SERVICE_IDENTIFIER_LEVEL", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "RATING_GROUP_LEVEL", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "SPONSORED_CONNECTIVITY_LEVEL", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Resource-Allocation-Notification */
+ {
+ struct dict_avp_data data = {
+ 1063, /* Code */
+ 10415, /* Vendor */
+ "Resource-Allocation-Notification", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Resource-Allocation-Notification)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ENABLE_NOTIFICATION", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Resource-Release-Notification */
+ {
+ struct dict_avp_data data = {
+ 2841, /* Code */
+ 10415, /* Vendor */
+ "Resource-Release-Notification", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Resource-Release-Notification)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ENABLE_NOTIFICATION", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Revalidation-Time */
+ {
+ struct dict_avp_data data = {
+ 1042, /* Code */
+ 10415, /* Vendor */
+ "Revalidation-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Routing-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 1079, /* Code */
+ 10415, /* Vendor */
+ "Routing-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Routing-Rule-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1077, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Routing-Rule-Failure-Code */
+ {
+ struct dict_avp_data data = {
+ 2834, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Failure-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Rule-Activation-Time */
+ {
+ struct dict_avp_data data = {
+ 1043, /* Code */
+ 10415, /* Vendor */
+ "Rule-Activation-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Rule-Deactivation-Time */
+ {
+ struct dict_avp_data data = {
+ 1044, /* Code */
+ 10415, /* Vendor */
+ "Rule-Deactivation-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Rule-Failure-Code */
+ {
+ struct dict_avp_data data = {
+ 1031, /* Code */
+ 10415, /* Vendor */
+ "Rule-Failure-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Rule-Failure-Code)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UNKNOWN_RULE_NAME", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "RESOURCE_ALLOCATION_FAILURE", { .i32=10 }};
+ struct dict_enumval_data t_3 = { "UNSUCCESSFUL_QOS_VALIDATION", { .i32=11 }};
+ struct dict_enumval_data t_4 = { "INCORRECT_FLOW_INFORMATION", { .i32=12 }};
+ struct dict_enumval_data t_5 = { "PS_TO_CS_HANDOVER", { .i32=13 }};
+ struct dict_enumval_data t_6 = { "TDF_APPLICATION_IDENTIFIER_ERROR", { .i32=14 }};
+ struct dict_enumval_data t_7 = { "NO_BEARER_BOUND", { .i32=15 }};
+ struct dict_enumval_data t_8 = { "FILTER_RESTRICTIONS", { .i32=16 }};
+ struct dict_enumval_data t_9 = { "AN_GW_FAILED", { .i32=17 }};
+ struct dict_enumval_data t_10 = { "MISSING_REDIRECT_SERVER_ADDRESS", { .i32=18 }};
+ struct dict_enumval_data t_11 = { "CM_END_USER_SERVICE_DENIED", { .i32=19 }};
+ struct dict_enumval_data t_12 = { "RATING_GROUP_ERROR", { .i32=2 }};
+ struct dict_enumval_data t_13 = { "CM_CREDIT_CONTROL_NOT_APPLICABLE", { .i32=20 }};
+ struct dict_enumval_data t_14 = { "CM_AUTHORIZATION_REJECTED", { .i32=21 }};
+ struct dict_enumval_data t_15 = { "CM_USER_UNKNOWN", { .i32=22 }};
+ struct dict_enumval_data t_16 = { "CM_RATING_FAILED", { .i32=23 }};
+ struct dict_enumval_data t_17 = { "ROUTING_RULE_REJECTION", { .i32=24 }};
+ struct dict_enumval_data t_18 = { "NO_NBIFOM_SUPPORT", { .i32=25 }};
+ struct dict_enumval_data t_19 = { "SERVICE_IDENTIFIER_ERROR", { .i32=3 }};
+ struct dict_enumval_data t_20 = { "GW_PCEF_MALFUNCTION", { .i32=4 }};
+ struct dict_enumval_data t_21 = { "RESOURCES_LIMITATION", { .i32=5 }};
+ struct dict_enumval_data t_22 = { "MAX_NR_BEARERS_REACHED", { .i32=6 }};
+ struct dict_enumval_data t_23 = { "UNKNOWN_BEARER_ID", { .i32=7 }};
+ struct dict_enumval_data t_24 = { "MISSING_BEARER_ID", { .i32=8 }};
+ struct dict_enumval_data t_25 = { "MISSING_FLOW_INFORMATION", { .i32=9 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Security-Parameter-Index */
+ {
+ struct dict_avp_data data = {
+ 1056, /* Code */
+ 10415, /* Vendor */
+ "Security-Parameter-Index", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Session-Release-Cause */
+ {
+ struct dict_avp_data data = {
+ 1045, /* Code */
+ 10415, /* Vendor */
+ "Session-Release-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Release-Cause)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UNSPECIFIED_REASON", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "UE_SUBSCRIPTION_REASON", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "INSUFFICIENT_SERVER_RESOURCES", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "IP_CAN_SESSION_TERMINATION", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "UE_IP_ADDRESS_RELEASE", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* TCP-Source-Port */
+ {
+ struct dict_avp_data data = {
+ 2843, /* Code */
+ 10415, /* Vendor */
+ "TCP-Source-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TDF-Application-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1088, /* Code */
+ 10415, /* Vendor */
+ "TDF-Application-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TDF-Application-Instance-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2802, /* Code */
+ 10415, /* Vendor */
+ "TDF-Application-Instance-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TDF-Destination-Host */
+ {
+ struct dict_avp_data data = {
+ 1089, /* Code */
+ 10415, /* Vendor */
+ "TDF-Destination-Host", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* TDF-Destination-Realm */
+ {
+ struct dict_avp_data data = {
+ 1090, /* Code */
+ 10415, /* Vendor */
+ "TDF-Destination-Realm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* TDF-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 1091, /* Code */
+ 10415, /* Vendor */
+ "TDF-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* TFT-Filter */
+ {
+ struct dict_avp_data data = {
+ 1012, /* Code */
+ 10415, /* Vendor */
+ "TFT-Filter", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+ /* Traffic-Steering-Policy-Identifier-DL */
+ {
+ struct dict_avp_data data = {
+ 2836, /* Code */
+ 10415, /* Vendor */
+ "Traffic-Steering-Policy-Identifier-DL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Traffic-Steering-Policy-Identifier-UL */
+ {
+ struct dict_avp_data data = {
+ 2837, /* Code */
+ 10415, /* Vendor */
+ "Traffic-Steering-Policy-Identifier-UL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ToS-Traffic-Class */
+ {
+ struct dict_avp_data data = {
+ 1014, /* Code */
+ 10415, /* Vendor */
+ "ToS-Traffic-Class", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Tunnel-Header-Filter */
+ {
+ struct dict_avp_data data = {
+ 1036, /* Code */
+ 10415, /* Vendor */
+ "Tunnel-Header-Filter", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+ /* Tunnel-Header-Length */
+ {
+ struct dict_avp_data data = {
+ 1037, /* Code */
+ 10415, /* Vendor */
+ "Tunnel-Header-Length", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UDP-Source-Port */
+ {
+ struct dict_avp_data data = {
+ 2806, /* Code */
+ 10415, /* Vendor */
+ "UDP-Source-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UE-Local-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 2805, /* Code */
+ 10415, /* Vendor */
+ "UE-Local-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Usage-Monitoring-Level */
+ {
+ struct dict_avp_data data = {
+ 1068, /* Code */
+ 10415, /* Vendor */
+ "Usage-Monitoring-Level", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Usage-Monitoring-Level)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SESSION_LEVEL", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PCC_RULE_LEVEL", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "ADC_RULE_LEVEL", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Usage-Monitoring-Report */
+ {
+ struct dict_avp_data data = {
+ 1069, /* Code */
+ 10415, /* Vendor */
+ "Usage-Monitoring-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Usage-Monitoring-Report)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "USAGE_MONITORING_REPORT_REQUIRED", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Usage-Monitoring-Support */
+ {
+ struct dict_avp_data data = {
+ 1070, /* Code */
+ 10415, /* Vendor */
+ "Usage-Monitoring-Support", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Usage-Monitoring-Support)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "USAGE_MONITORING_DISABLED", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* User-Location-Info-Time */
+ {
+ struct dict_avp_data data = {
+ 2812, /* Code */
+ 10415, /* Vendor */
+ "User-Location-Info-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* PCSCF-Restoration-Indication */
+ {
+ struct dict_avp_data data = {
+ 2826, /* Code */
+ 10415, /* Vendor */
+ "PCSCF-Restoration-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* QoS-Rule-Name */
+ {
+ struct dict_avp_data data = {
+ 1054, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* QoS-Rule-Base-Name */
+ {
+ struct dict_avp_data data = {
+ 1074, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Base-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Session-Linking-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1064, /* Code */
+ 10415, /* Vendor */
+ "Session-Linking-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Linking-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UE_ONLY", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "RESERVED", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "UE_NW", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ADC-Rule-Base-Name */
+ {
+ struct dict_avp_data data = {
+ 1095, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Base-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* ADC-Rule-Name */
+ {
+ struct dict_avp_data data = {
+ 1096, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Request-Type */
+ {
+ struct dict_avp_data data = {
+ 2838, /* Code */
+ 10415, /* Vendor */
+ "Request-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CS-Service-QoS-Request-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2807, /* Code */
+ 10415, /* Vendor */
+ "CS-Service-QoS-Request-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CS-Service-QoS-Request-Operation */
+ {
+ struct dict_avp_data data = {
+ 2808, /* Code */
+ 10415, /* Vendor */
+ "CS-Service-QoS-Request-Operation", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CS-Service-QoS-Request-Operation)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DELETION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MODIFICATION", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CS-Service-Resource-Failure-Cause */
+ {
+ struct dict_avp_data data = {
+ 2814, /* Code */
+ 10415, /* Vendor */
+ "CS-Service-Resource-Failure-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CS-Service-Resource-Failure-Cause)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "RESOURCE_RELEASED", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CS-Service-Resource-Result-Operation */
+ {
+ struct dict_avp_data data = {
+ 2815, /* Code */
+ 10415, /* Vendor */
+ "CS-Service-Resource-Result-Operation", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CS-Service-Resource-Result-Operation)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DELETION", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Charging-Rule-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1002, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Remove", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* QoS-Rule-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1055, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Redirect-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1085, /* Code */
+ 10415, /* Vendor */
+ "Redirect-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* PRA-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2846, /* Code */
+ 10415, /* Vendor */
+ "PRA-Remove", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Flow-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1058, /* Code */
+ 10415, /* Vendor */
+ "Flow-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Tunnel-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1038, /* Code */
+ 10415, /* Vendor */
+ "Tunnel-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TDF-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1087, /* Code */
+ 10415, /* Vendor */
+ "TDF-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Routing-Rule-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1075, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Remove", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* CS-Service-Resource-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2813, /* Code */
+ 10415, /* Vendor */
+ "CS-Service-Resource-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Presence-Reporting-Area-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2822, /* Code */
+ 10415, /* Vendor */
+ "Presence-Reporting-Area-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Conditional-APN-Aggregate-Max-Bitrate */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2818, /* Code */
+ 10415, /* Vendor */
+ "Conditional-APN-Aggregate-Max-Bitrate", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Access-Network-Charging-Identifier-Gx */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1022, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Charging-Identifier-Gx", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Allocation-Retention-Priority */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1034, /* Code */
+ 10415, /* Vendor */
+ "Allocation-Retention-Priority", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* QoS-Rule-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1052, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Remove", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Routing-Rule-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2835, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TFT-Packet-Filter-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1013, /* Code */
+ 10415, /* Vendor */
+ "TFT-Packet-Filter-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Fixed-User-Location-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2825, /* Code */
+ 10415, /* Vendor */
+ "Fixed-User-Location-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Default-QoS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2816, /* Code */
+ 10415, /* Vendor */
+ "Default-QoS-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Packet-Filter-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1061, /* Code */
+ 10415, /* Vendor */
+ "Packet-Filter-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Routing-Filter */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1078, /* Code */
+ 10415, /* Vendor */
+ "Routing-Filter", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ADC-Rule-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1093, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Remove", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* QoS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1016, /* Code */
+ 10415, /* Vendor */
+ "QoS-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* PRA-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2845, /* Code */
+ 10415, /* Vendor */
+ "PRA-Install", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Routing-Rule-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1076, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Definition", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Default-EPS-Bearer-QoS */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1049, /* Code */
+ 10415, /* Vendor */
+ "Default-EPS-Bearer-QoS", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* CoA-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1039, /* Code */
+ 10415, /* Vendor */
+ "CoA-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Application-Detection-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1098, /* Code */
+ 10415, /* Vendor */
+ "Application-Detection-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Conditional-Policy-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2840, /* Code */
+ 10415, /* Vendor */
+ "Conditional-Policy-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Charging-Rule-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1003, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Definition", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Routing-Rule-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1081, /* Code */
+ 10415, /* Vendor */
+ "Routing-Rule-Install", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ADC-Rule-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1094, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Definition", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ADC-Rule-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1097, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* QoS-Rule-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1053, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Definition", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Charging-Rule-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1018, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Event-Report-Indication */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1033, /* Code */
+ 10415, /* Vendor */
+ "Event-Report-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Charging-Rule-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1001, /* Code */
+ 10415, /* Vendor */
+ "Charging-Rule-Install", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* QoS-Rule-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1051, /* Code */
+ 10415, /* Vendor */
+ "QoS-Rule-Install", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ADC-Rule-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1092, /* Code */
+ 10415, /* Vendor */
+ "ADC-Rule-Install", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Usage-Monitoring-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1067, /* Code */
+ 10415, /* Vendor */
+ "Usage-Monitoring-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29212_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Charging-Rule-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Charging-Rule-Remove"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Required-Access-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Resource-Release-Notification"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* QoS-Rule-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "QoS-Rule-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PCC-Rule-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rule-Failure-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-Version"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Redirect-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Redirect-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Redirect-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Address-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Redirect-Server-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* PRA-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "PRA-Remove"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Flow-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Flow-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Flow-Description"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ToS-Traffic-Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Security-Parameter-Index"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Label"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Direction"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Tunnel-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Tunnel-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Tunnel-Header-Length"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TDF-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TDF-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TDF-Destination-Realm"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TDF-Destination-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TDF-IP-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Routing-Rule-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Routing-Rule-Remove"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* CS-Service-Resource-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "CS-Service-Resource-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "CS-Service-QoS-Request-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CS-Service-Resource-Result-Operation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CS-Service-Resource-Failure-Cause"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Presence-Reporting-Area-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Elements-List"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Conditional-APN-Aggregate-Max-Bitrate */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Conditional-APN-Aggregate-Max-Bitrate"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "APN-Aggregate-Max-Bitrate-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Aggregate-Max-Bitrate-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Access-Network-Charging-Identifier-Gx */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier-Gx"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier-Value"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Session-Charging-Scope"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Allocation-Retention-Priority */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Allocation-Retention-Priority"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Priority-Level"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Pre-emption-Capability"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Pre-emption-Vulnerability"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* QoS-Rule-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "QoS-Rule-Remove"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Required-Access-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Routing-Rule-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Routing-Rule-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PCC-Rule-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Failure-Code"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TFT-Packet-Filter-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TFT-Packet-Filter-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Precedence"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TFT-Filter"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ToS-Traffic-Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Security-Parameter-Index"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Label"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Direction"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Fixed-User-Location-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Fixed-User-Location-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "BSSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Logical-Access-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Physical-Access-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Default-QoS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Default-QoS-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Class-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-QoS-Name"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Packet-Filter-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Packet-Filter-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Precedence"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Content"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ToS-Traffic-Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Security-Parameter-Index"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Label"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Direction"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Routing-Filter */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Routing-Filter"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Flow-Description"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Direction"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ToS-Traffic-Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Security-Parameter-Index"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Label"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ADC-Rule-Remove */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ADC-Rule-Remove"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* QoS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "QoS-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Class-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Guaranteed-Bitrate-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Guaranteed-Bitrate-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Allocation-Retention-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Aggregate-Max-Bitrate-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Aggregate-Max-Bitrate-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Conditional-APN-Aggregate-Max-Bitrate"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* PRA-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "PRA-Install"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Routing-Rule-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Routing-Rule-Definition"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Filter"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Precedence"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Default-EPS-Bearer-QoS */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Default-EPS-Bearer-QoS"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Class-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Allocation-Retention-Priority"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* CoA-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "CoA-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Tunnel-Information"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CoA-IP-Address"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Application-Detection-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Application-Detection-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TDF-Application-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TDF-Application-Instance-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Conditional-Policy-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Conditional-Policy-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Execution-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-EPS-Bearer-QoS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Aggregate-Max-Bitrate-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Aggregate-Max-Bitrate-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Conditional-APN-Aggregate-Max-Bitrate"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Charging-Rule-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Charging-Rule-Definition"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Rating-Group"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-Bearer-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TDF-Application-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-to-CS-Session-Continuity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reporting-Level"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Online"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Offline"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Metering-Method"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Precedence"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AF-Charging-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flows"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Key"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Redirect-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Mute-Notification"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AF-Signalling-Protocol"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sponsor-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Service-Provider-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Required-Access-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sharing-Key-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sharing-Key-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Traffic-Steering-Policy-Identifier-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Traffic-Steering-Policy-Identifier-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-Version"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Routing-Rule-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Routing-Rule-Install"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Definition"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ADC-Rule-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ADC-Rule-Definition"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TDF-Application-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Rating-Group"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reporting-Level"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Online"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Offline"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Metering-Method"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Precedence"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Key"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sponsor-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Service-Provider-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Redirect-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Mute-Notification"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Traffic-Steering-Policy-Identifier-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Traffic-Steering-Policy-Identifier-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ToS-Traffic-Class"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ADC-Rule-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ADC-Rule-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PCC-Rule-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rule-Failure-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Final-Unit-Indication"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* QoS-Rule-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "QoS-Rule-Definition"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Precedence"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Required-Access-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sharing-Key-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sharing-Key-UL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-Version"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Charging-Rule-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Charging-Rule-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PCC-Rule-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rule-Failure-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Final-Unit-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAN-NAS-Release-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-Version"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Event-Report-Indication */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "AN-Trusted"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Reference"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 5535, .avp_name = "3GPP2-BSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "HeNB-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UDP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Charging-Rule-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Charging-Rule-Install"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Definition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rule-Activation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rule-Deactivation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Resource-Allocation-Notification"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Correlation-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* QoS-Rule-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "QoS-Rule-Install"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Definition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Tunnel-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier-Value"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Resource-Allocation-Notification"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rule-Activation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rule-Deactivation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-GGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-GGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "UDP-Source-Port"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ADC-Rule-Install */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ADC-Rule-Install"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Definition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rule-Activation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rule-Deactivation-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Usage-Monitoring-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Key"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Granted-Service-Unit"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 0, .avp_name = "Used-Service-Unit"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "Quota-Consumption-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Level"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Support"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29212_avps (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29212_avps_load_defs(conffile);
+ return dict_ts29212_avps_load_rules(conffile);
+}
+
+const char* dict_ts29212_avps_proto_ver(char * conffile) {
+ return ts29212_avps_proto_ver;
+}
+
+const double dict_ts29212_avps_gen_ts(char * conffile) {
+ return ts29212_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29212_avps", dict_ts29212_avps_load_defs, dict_ts29212_avps_load_rules, "dict_ts32299_avps", "dict_ts29273_avps", "dict_ts29214_avps", "dict_ts29272_avps", "dict_ts29229_avps", "dict_rfc4006bis_avps", "dict_ts29061_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7155_avps", "dict_etsi283034_avps", "dict_3gpp2_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29212_avps/ts29212_avps.did b/extensions/dict_ts29212_avps/ts29212_avps.did
new file mode 100644
index 0000000..eb5c09b
--- /dev/null
+++ b/extensions/dict_ts29212_avps/ts29212_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29212_avps
diff --git a/extensions/dict_ts29214_avps/CMakeLists.txt b/extensions/dict_ts29214_avps/CMakeLists.txt
new file mode 100644
index 0000000..9cbcecc
--- /dev/null
+++ b/extensions/dict_ts29214_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29214_avps extension
+PROJECT("dict_ts29214_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29214_avps dict_ts29214_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29214_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29214_AVPS)
+
+
+
diff --git a/extensions/dict_ts29214_avps/dict_ts29214_avps.c b/extensions/dict_ts29214_avps/dict_ts29214_avps.c
new file mode 100644
index 0000000..734a5c8
--- /dev/null
+++ b/extensions/dict_ts29214_avps/dict_ts29214_avps.c
@@ -0,0 +1,1031 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29214_avps (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697136.73
+
+const char *ts29214_avps_proto_ver = PROTO_VER;
+const double ts29214_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29214_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Abort-Cause */
+ {
+ struct dict_avp_data data = {
+ 500, /* Code */
+ 10415, /* Vendor */
+ "Abort-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Abort-Cause)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "BEARER_RELEASED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "INSUFFICIENT_SERVER_RESOURCES", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "INSUFFICIENT_BEARER_RESOURCES", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "PS_TO_CS_HANDOVER", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "DISALLOWED", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Access-Network-Charging-Address */
+ {
+ struct dict_avp_data data = {
+ 501, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Charging-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Access-Network-Charging-Identifier-Value */
+ {
+ struct dict_avp_data data = {
+ 503, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Charging-Identifier-Value", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* AF-Application-Identifier */
+ {
+ struct dict_avp_data data = {
+ 504, /* Code */
+ 10415, /* Vendor */
+ "AF-Application-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* AF-Charging-Identifier */
+ {
+ struct dict_avp_data data = {
+ 505, /* Code */
+ 10415, /* Vendor */
+ "AF-Charging-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* AF-Requested-Data */
+ {
+ struct dict_avp_data data = {
+ 551, /* Code */
+ 10415, /* Vendor */
+ "AF-Requested-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* AF-Signalling-Protocol */
+ {
+ struct dict_avp_data data = {
+ 529, /* Code */
+ 10415, /* Vendor */
+ "AF-Signalling-Protocol", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AF-Signalling-Protocol)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NO_INFORMATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SIP", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Application-Service-Provider-Identity */
+ {
+ struct dict_avp_data data = {
+ 532, /* Code */
+ 10415, /* Vendor */
+ "Application-Service-Provider-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Pre-emption-Control-Info */
+ {
+ struct dict_avp_data data = {
+ 553, /* Code */
+ 10415, /* Vendor */
+ "Pre-emption-Control-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Codec-Data */
+ {
+ struct dict_avp_data data = {
+ 524, /* Code */
+ 10415, /* Vendor */
+ "Codec-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Content-Version */
+ {
+ struct dict_avp_data data = {
+ 552, /* Code */
+ 10415, /* Vendor */
+ "Content-Version", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Flow-Description */
+ {
+ struct dict_avp_data data = {
+ 507, /* Code */
+ 10415, /* Vendor */
+ "Flow-Description", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, IPFilterRule_type, NULL);
+ };
+ /* Flow-Number */
+ {
+ struct dict_avp_data data = {
+ 509, /* Code */
+ 10415, /* Vendor */
+ "Flow-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Flow-Status */
+ {
+ struct dict_avp_data data = {
+ 511, /* Code */
+ 10415, /* Vendor */
+ "Flow-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Flow-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ENABLED_UPLINK", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ENABLED_DOWNLINK", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "ENABLED", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "DISABLED", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "REMOVED", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Flow-Usage */
+ {
+ struct dict_avp_data data = {
+ 512, /* Code */
+ 10415, /* Vendor */
+ "Flow-Usage", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Flow-Usage)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NO_INFORMATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "RTCP", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "AF_SIGNALLING", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* GCS-Identifier */
+ {
+ struct dict_avp_data data = {
+ 538, /* Code */
+ 10415, /* Vendor */
+ "GCS-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* IP-Domain-Id */
+ {
+ struct dict_avp_data data = {
+ 537, /* Code */
+ 10415, /* Vendor */
+ "IP-Domain-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Max-Requested-Bandwidth-DL */
+ {
+ struct dict_avp_data data = {
+ 515, /* Code */
+ 10415, /* Vendor */
+ "Max-Requested-Bandwidth-DL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Max-Requested-Bandwidth-UL */
+ {
+ struct dict_avp_data data = {
+ 516, /* Code */
+ 10415, /* Vendor */
+ "Max-Requested-Bandwidth-UL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Max-Supported-Bandwidth-DL */
+ {
+ struct dict_avp_data data = {
+ 543, /* Code */
+ 10415, /* Vendor */
+ "Max-Supported-Bandwidth-DL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Max-Supported-Bandwidth-UL */
+ {
+ struct dict_avp_data data = {
+ 544, /* Code */
+ 10415, /* Vendor */
+ "Max-Supported-Bandwidth-UL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MCPTT-Identifier */
+ {
+ struct dict_avp_data data = {
+ 547, /* Code */
+ 10415, /* Vendor */
+ "MCPTT-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Media-Component-Number */
+ {
+ struct dict_avp_data data = {
+ 518, /* Code */
+ 10415, /* Vendor */
+ "Media-Component-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Media-Component-Status */
+ {
+ struct dict_avp_data data = {
+ 549, /* Code */
+ 10415, /* Vendor */
+ "Media-Component-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Media-Type */
+ {
+ struct dict_avp_data data = {
+ 520, /* Code */
+ 10415, /* Vendor */
+ "Media-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Media-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "AUDIO", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "VIDEO", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "DATA", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "APPLICATION", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "CONTROL", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "TEXT", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "MESSAGE", { .i32=6 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MPS-Identifier */
+ {
+ struct dict_avp_data data = {
+ 528, /* Code */
+ 10415, /* Vendor */
+ "MPS-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Min-Desired-Bandwidth-DL */
+ {
+ struct dict_avp_data data = {
+ 545, /* Code */
+ 10415, /* Vendor */
+ "Min-Desired-Bandwidth-DL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Min-Desired-Bandwidth-UL */
+ {
+ struct dict_avp_data data = {
+ 546, /* Code */
+ 10415, /* Vendor */
+ "Min-Desired-Bandwidth-UL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Min-Requested-Bandwidth-DL */
+ {
+ struct dict_avp_data data = {
+ 534, /* Code */
+ 10415, /* Vendor */
+ "Min-Requested-Bandwidth-DL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Min-Requested-Bandwidth-UL */
+ {
+ struct dict_avp_data data = {
+ 535, /* Code */
+ 10415, /* Vendor */
+ "Min-Requested-Bandwidth-UL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Priority-Sharing-Indicator */
+ {
+ struct dict_avp_data data = {
+ 550, /* Code */
+ 10415, /* Vendor */
+ "Priority-Sharing-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Priority-Sharing-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PRIORITY_SHARING_ENABLED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PRIORITY_SHARING_DISABLED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* RR-Bandwidth */
+ {
+ struct dict_avp_data data = {
+ 521, /* Code */
+ 10415, /* Vendor */
+ "RR-Bandwidth", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RS-Bandwidth */
+ {
+ struct dict_avp_data data = {
+ 522, /* Code */
+ 10415, /* Vendor */
+ "RS-Bandwidth", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-Authorization-Info */
+ {
+ struct dict_avp_data data = {
+ 548, /* Code */
+ 10415, /* Vendor */
+ "Service-Authorization-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-URN */
+ {
+ struct dict_avp_data data = {
+ 525, /* Code */
+ 10415, /* Vendor */
+ "Service-URN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-Info-Status */
+ {
+ struct dict_avp_data data = {
+ 527, /* Code */
+ 10415, /* Vendor */
+ "Service-Info-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Service-Info-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "FINAL_SERVICE_INFORMATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PRELIMINARY_SERVICE_INFORMATION", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Sharing-Key-DL */
+ {
+ struct dict_avp_data data = {
+ 539, /* Code */
+ 10415, /* Vendor */
+ "Sharing-Key-DL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Sharing-Key-UL */
+ {
+ struct dict_avp_data data = {
+ 540, /* Code */
+ 10415, /* Vendor */
+ "Sharing-Key-UL", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Specific-Action */
+ {
+ struct dict_avp_data data = {
+ 513, /* Code */
+ 10415, /* Vendor */
+ "Specific-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Specific-Action)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Void", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CHARGING_CORRELATION_EXCHANGE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "INDICATION_OF_LIMITED_PCC_DEPLOYMENT", { .i32=10 }};
+ struct dict_enumval_data t_4 = { "USAGE_REPORT", { .i32=11 }};
+ struct dict_enumval_data t_5 = { "ACCESS_NETWORK_INFO_REPORT", { .i32=12 }};
+ struct dict_enumval_data t_6 = { "INDICATION_OF_RECOVERY_FROM_LIMITED_PCC_DEPLOYMENT", { .i32=13 }};
+ struct dict_enumval_data t_7 = { "INDICATION_OF_ACCESS_NETWORK_INFO_REPORTING_FAILURE", { .i32=14 }};
+ struct dict_enumval_data t_8 = { "INDICATION_OF_TRANSFER_POLICY_EXPIRED", { .i32=15 }};
+ struct dict_enumval_data t_9 = { "PLMN_CHANGE", { .i32=16 }};
+ struct dict_enumval_data t_10 = { "INDICATION_OF_LOSS_OF_BEARER", { .i32=2 }};
+ struct dict_enumval_data t_11 = { "INDICATION_OF_RECOVERY_OF_BEARER", { .i32=3 }};
+ struct dict_enumval_data t_12 = { "INDICATION_OF_RELEASE_OF_BEARER", { .i32=4 }};
+ struct dict_enumval_data t_13 = { "Void2", { .i32=5 }};
+ struct dict_enumval_data t_14 = { "IP_CAN_CHANGE", { .i32=6 }};
+ struct dict_enumval_data t_15 = { "INDICATION_OF_OUT_OF_CREDIT", { .i32=7 }};
+ struct dict_enumval_data t_16 = { "INDICATION_OF_SUCCESSFUL_RESOURCES_ALLOCATION", { .i32=8 }};
+ struct dict_enumval_data t_17 = { "INDICATION_OF_FAILED_RESOURCES_ALLOCATION", { .i32=9 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SIP-Forking-Indication */
+ {
+ struct dict_avp_data data = {
+ 523, /* Code */
+ 10415, /* Vendor */
+ "SIP-Forking-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SIP-Forking-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SINGLE_DIALOGUE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SEVERAL_DIALOGUES", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Sponsor-Identity */
+ {
+ struct dict_avp_data data = {
+ 531, /* Code */
+ 10415, /* Vendor */
+ "Sponsor-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Sponsoring-Action */
+ {
+ struct dict_avp_data data = {
+ 542, /* Code */
+ 10415, /* Vendor */
+ "Sponsoring-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Sponsoring-Action)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DISABLE_SPONSORING", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ENABLE_SPONSORING", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Required-Access-Info */
+ {
+ struct dict_avp_data data = {
+ 536, /* Code */
+ 10415, /* Vendor */
+ "Required-Access-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Required-Access-Info)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "USER_LOCATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MS_TIME_ZONE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Rx-Request-Type */
+ {
+ struct dict_avp_data data = {
+ 533, /* Code */
+ 10415, /* Vendor */
+ "Rx-Request-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Rx-Request-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "INITIAL_REQUEST", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "UPDATE_REQUEST", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "PCSCF_RESTORATION", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Retry-Interval */
+ {
+ struct dict_avp_data data = {
+ 541, /* Code */
+ 10415, /* Vendor */
+ "Retry-Interval", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Media-Sub-Component */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 519, /* Code */
+ 10415, /* Vendor */
+ "Media-Sub-Component", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Flows */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 510, /* Code */
+ 10415, /* Vendor */
+ "Flows", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Media-Component-Description */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 517, /* Code */
+ 10415, /* Vendor */
+ "Media-Component-Description", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Access-Network-Charging-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 502, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Charging-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Acceptable-Service-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 526, /* Code */
+ 10415, /* Vendor */
+ "Acceptable-Service-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Sponsored-Connectivity-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 530, /* Code */
+ 10415, /* Vendor */
+ "Sponsored-Connectivity-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29214_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Media-Sub-Component */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Media-Sub-Component"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Flow-Number"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Flows */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Flows"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Media-Component-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flow-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-Version"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Final-Unit-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Media-Component-Status"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Media-Component-Description */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Media-Component-Description"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Media-Component-Number"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Access-Network-Charging-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier-Value"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flows"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Acceptable-Service-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Acceptable-Service-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Media-Component-Description"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-DL"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-UL"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Sponsored-Connectivity-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Sponsored-Connectivity-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Sponsor-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Service-Provider-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Granted-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Used-Service-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sponsoring-Action"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29214_avps (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29214_avps_load_defs(conffile);
+ return dict_ts29214_avps_load_rules(conffile);
+}
+
+const char* dict_ts29214_avps_proto_ver(char * conffile) {
+ return ts29214_avps_proto_ver;
+}
+
+const double dict_ts29214_avps_gen_ts(char * conffile) {
+ return ts29214_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29214_avps", dict_ts29214_avps_load_defs, dict_ts29214_avps_load_rules, "dict_ts29273_avps", "dict_ts29212_avps", "dict_ts29229_avps", "dict_ts29154_avps", "dict_ts29061_avps", "dict_rfc4006bis_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7155_avps", "dict_etsi283034_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29214_avps/ts29214_avps.did b/extensions/dict_ts29214_avps/ts29214_avps.did
new file mode 100644
index 0000000..b62bcfc
--- /dev/null
+++ b/extensions/dict_ts29214_avps/ts29214_avps.did
@@ -0,0 +1,37 @@
+dict_ts29154_avps
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_ts29212_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc7944_avps
+dict_ts29214_avps
diff --git a/extensions/dict_ts29215_avps/CMakeLists.txt b/extensions/dict_ts29215_avps/CMakeLists.txt
new file mode 100644
index 0000000..b7cd4f3
--- /dev/null
+++ b/extensions/dict_ts29215_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29215_avps extension
+PROJECT("dict_ts29215_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29215_avps dict_ts29215_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29215_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29215_AVPS)
+
+
+
diff --git a/extensions/dict_ts29215_avps/dict_ts29215_avps.c b/extensions/dict_ts29215_avps/dict_ts29215_avps.c
new file mode 100644
index 0000000..ea3f1ec
--- /dev/null
+++ b/extensions/dict_ts29215_avps/dict_ts29215_avps.c
@@ -0,0 +1,416 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29215_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697191.31
+
+const char *ts29215_avps_proto_ver = PROTO_VER;
+const double ts29215_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29215_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* DRA-Deployment */
+ {
+ struct dict_avp_data data = {
+ 2206, /* Code */
+ 10415, /* Vendor */
+ "DRA-Deployment", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(DRA-Deployment)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DRA_Deployed", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Multiple-BBERF-Action */
+ {
+ struct dict_avp_data data = {
+ 2204, /* Code */
+ 10415, /* Vendor */
+ "Multiple-BBERF-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Multiple-BBERF-Action)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ESTABLISHMENT", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "TERMINATION", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Subsession-Id */
+ {
+ struct dict_avp_data data = {
+ 2202, /* Code */
+ 10415, /* Vendor */
+ "Subsession-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Subsession-Operation */
+ {
+ struct dict_avp_data data = {
+ 2203, /* Code */
+ 10415, /* Vendor */
+ "Subsession-Operation", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Subsession-Operation)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TERMINATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ESTABLISHMENT", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "MODIFICATION", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* DRA-Binding */
+ {
+ struct dict_avp_data data = {
+ 2208, /* Code */
+ 10415, /* Vendor */
+ "DRA-Binding", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(DRA-Binding)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DRA_BINDING_DELETION", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PCRF-Address */
+ {
+ struct dict_avp_data data = {
+ 2207, /* Code */
+ 10415, /* Vendor */
+ "PCRF-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* UE-Local-IPv6-Prefix */
+ {
+ struct dict_avp_data data = {
+ 2205, /* Code */
+ 10415, /* Vendor */
+ "UE-Local-IPv6-Prefix", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Subsession-Enforcement-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2201, /* Code */
+ 10415, /* Vendor */
+ "Subsession-Enforcement-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Subsession-Decision-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2200, /* Code */
+ 10415, /* Vendor */
+ "Subsession-Decision-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29215_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Subsession-Enforcement-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Subsession-Enforcement-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Subsession-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subsession-Operation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Operation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Packet-Filter-Operation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CoA-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Connection-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TFT-Packet-Filter-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Online"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Offline"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Credit-Management-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Detection-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-Ipv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 5535, .avp_name = "3GPP2-BSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-EPS-Bearer-QoS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-Access"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Availability-Change-Reason"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Network-Request-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Location-Info-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Logical-Access-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Physical-Access-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Multiple-BBERF-Action"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier-Gx"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Linking-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "HeNB-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Local-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Local-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UDP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Status"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Subsession-Decision-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Subsession-Decision-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Subsession-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AN-GW-Address"}, RULE_OPTIONAL, 0, 2 },
+ { { .avp_vendor = 0, .avp_name = "Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Experimental-Result-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Report-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Install"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Rule-Remove"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-EPS-Bearer-QoS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Monitoring-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Release-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Control-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Revalidation-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Default-Access"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAN-Rule-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Rule-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Removal-Of-Access"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-CAN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Online"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Offline"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29215_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29215_avps_load_defs(conffile);
+ return dict_ts29215_avps_load_rules(conffile);
+}
+
+const char* dict_ts29215_avps_proto_ver(char * conffile) {
+ return ts29215_avps_proto_ver;
+}
+
+const double dict_ts29215_avps_gen_ts(char * conffile) {
+ return ts29215_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29215_avps", dict_ts29215_avps_load_defs, dict_ts29215_avps_load_rules, "dict_ts32299_avps", "dict_ts29212_avps", "dict_ts29214_avps", "dict_ts29229_avps", "dict_ts29061_avps", "dict_rfc4006bis_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7155_avps", "dict_etsi283034_avps", "dict_3gpp2_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29215_avps/ts29215_avps.did b/extensions/dict_ts29215_avps/ts29215_avps.did
new file mode 100644
index 0000000..0287b82
--- /dev/null
+++ b/extensions/dict_ts29215_avps/ts29215_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29468_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_ts29212_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29215_avps
diff --git a/extensions/dict_ts29217_avps/CMakeLists.txt b/extensions/dict_ts29217_avps/CMakeLists.txt
new file mode 100644
index 0000000..b8a004b
--- /dev/null
+++ b/extensions/dict_ts29217_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29217_avps extension
+PROJECT("dict_ts29217_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29217_avps dict_ts29217_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29217_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29217_AVPS)
+
+
+
diff --git a/extensions/dict_ts29217_avps/dict_ts29217_avps.c b/extensions/dict_ts29217_avps/dict_ts29217_avps.c
new file mode 100644
index 0000000..acb9fa6
--- /dev/null
+++ b/extensions/dict_ts29217_avps/dict_ts29217_avps.c
@@ -0,0 +1,403 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29217_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697175.31
+
+const char *ts29217_avps_proto_ver = PROTO_VER;
+const double ts29217_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29217_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Congestion-Level-Range */
+ {
+ struct dict_avp_data data = {
+ 4003, /* Code */
+ 10415, /* Vendor */
+ "Congestion-Level-Range", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Congestion-Level-Set-Id */
+ {
+ struct dict_avp_data data = {
+ 4004, /* Code */
+ 10415, /* Vendor */
+ "Congestion-Level-Set-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Congestion-Level-Value */
+ {
+ struct dict_avp_data data = {
+ 4005, /* Code */
+ 10415, /* Vendor */
+ "Congestion-Level-Value", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Conditional-Restriction */
+ {
+ struct dict_avp_data data = {
+ 4007, /* Code */
+ 10415, /* Vendor */
+ "Conditional-Restriction", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* eNodeB-Id */
+ {
+ struct dict_avp_data data = {
+ 4008, /* Code */
+ 10415, /* Vendor */
+ "eNodeB-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* IMSI-List */
+ {
+ struct dict_avp_data data = {
+ 4009, /* Code */
+ 10415, /* Vendor */
+ "IMSI-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RCAF-Id */
+ {
+ struct dict_avp_data data = {
+ 4010, /* Code */
+ 10415, /* Vendor */
+ "RCAF-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* Reporting-Restriction */
+ {
+ struct dict_avp_data data = {
+ 4011, /* Code */
+ 10415, /* Vendor */
+ "Reporting-Restriction", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RUCI-Action */
+ {
+ struct dict_avp_data data = {
+ 4012, /* Code */
+ 10415, /* Vendor */
+ "RUCI-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Extended-eNodeB-Id */
+ {
+ struct dict_avp_data data = {
+ 4013, /* Code */
+ 10415, /* Vendor */
+ "Extended-eNodeB-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Congestion-Level-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4002, /* Code */
+ 10415, /* Vendor */
+ "Congestion-Level-Definition", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Congestion-Location-Id */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4006, /* Code */
+ 10415, /* Vendor */
+ "Congestion-Location-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Aggregated-Congestion-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4000, /* Code */
+ 10415, /* Vendor */
+ "Aggregated-Congestion-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Aggregated-RUCI-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4001, /* Code */
+ 10415, /* Vendor */
+ "Aggregated-RUCI-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29217_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Congestion-Level-Definition */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Congestion-Level-Definition"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Congestion-Level-Set-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Congestion-Level-Range"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Congestion-Location-Id */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Congestion-Location-Id"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "eNodeB-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Extended-eNodeB-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Aggregated-Congestion-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Aggregated-Congestion-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Congestion-Location-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMSI-List"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Aggregated-RUCI-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Aggregated-RUCI-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Aggregated-Congestion-Info"}, RULE_REQUIRED, 1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Congestion-Level-Value"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Congestion-Level-Set-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29217_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29217_avps_load_defs(conffile);
+ return dict_ts29217_avps_load_rules(conffile);
+}
+
+const char* dict_ts29217_avps_proto_ver(char * conffile) {
+ return ts29217_avps_proto_ver;
+}
+
+const double dict_ts29217_avps_gen_ts(char * conffile) {
+ return ts29217_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29217_avps", dict_ts29217_avps_load_defs, dict_ts29217_avps_load_rules, "dict_ts29215_avps", "dict_ts29229_avps", "dict_ts29061_avps", "dict_rfc4006bis_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7944_avps", "dict_rfc7155_avps");
+
+
+
diff --git a/extensions/dict_ts29217_avps/ts29217_avps.did b/extensions/dict_ts29217_avps/ts29217_avps.did
new file mode 100644
index 0000000..40e96aa
--- /dev/null
+++ b/extensions/dict_ts29217_avps/ts29217_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29468_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_ts29212_avps
+dict_ts29215_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29217_avps
diff --git a/extensions/dict_ts29229_avps/CMakeLists.txt b/extensions/dict_ts29229_avps/CMakeLists.txt
new file mode 100644
index 0000000..e0fc692
--- /dev/null
+++ b/extensions/dict_ts29229_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29229_avps extension
+PROJECT("dict_ts29229_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29229_avps dict_ts29229_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29229_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29229_AVPS)
+
+
+
diff --git a/extensions/dict_ts29229_avps/dict_ts29229_avps.c b/extensions/dict_ts29229_avps/dict_ts29229_avps.c
new file mode 100644
index 0000000..d8beb19
--- /dev/null
+++ b/extensions/dict_ts29229_avps/dict_ts29229_avps.c
@@ -0,0 +1,1206 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29229_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697168.8
+
+const char *ts29229_avps_proto_ver = PROTO_VER;
+const double ts29229_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29229_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Visited-Network-Identifier */
+ {
+ struct dict_avp_data data = {
+ 600, /* Code */
+ 10415, /* Vendor */
+ "Visited-Network-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Public-Identity */
+ {
+ struct dict_avp_data data = {
+ 601, /* Code */
+ 10415, /* Vendor */
+ "Public-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Server-Name */
+ {
+ struct dict_avp_data data = {
+ 602, /* Code */
+ 10415, /* Vendor */
+ "Server-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Mandatory-Capability */
+ {
+ struct dict_avp_data data = {
+ 604, /* Code */
+ 10415, /* Vendor */
+ "Mandatory-Capability", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Optional-Capability */
+ {
+ struct dict_avp_data data = {
+ 605, /* Code */
+ 10415, /* Vendor */
+ "Optional-Capability", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Data */
+ {
+ struct dict_avp_data data = {
+ 606, /* Code */
+ 10415, /* Vendor */
+ "User-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SIP-Number-Auth-Items */
+ {
+ struct dict_avp_data data = {
+ 607, /* Code */
+ 10415, /* Vendor */
+ "SIP-Number-Auth-Items", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SIP-Authentication-Scheme */
+ {
+ struct dict_avp_data data = {
+ 608, /* Code */
+ 10415, /* Vendor */
+ "SIP-Authentication-Scheme", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* SIP-Authenticate */
+ {
+ struct dict_avp_data data = {
+ 609, /* Code */
+ 10415, /* Vendor */
+ "SIP-Authenticate", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SIP-Authorization */
+ {
+ struct dict_avp_data data = {
+ 610, /* Code */
+ 10415, /* Vendor */
+ "SIP-Authorization", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SIP-Authentication-Context */
+ {
+ struct dict_avp_data data = {
+ 611, /* Code */
+ 10415, /* Vendor */
+ "SIP-Authentication-Context", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SIP-Item-Number */
+ {
+ struct dict_avp_data data = {
+ 613, /* Code */
+ 10415, /* Vendor */
+ "SIP-Item-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Server-Assignment-Type */
+ {
+ struct dict_avp_data data = {
+ 614, /* Code */
+ 10415, /* Vendor */
+ "Server-Assignment-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Server-Assignment-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NO_ASSIGNMENT", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "REGISTRATION", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "AUTHENTICATION_TIMEOUT", { .i32=10 }};
+ struct dict_enumval_data t_4 = { "DEREGISTRATION_TOO_MUCH_DATA", { .i32=11 }};
+ struct dict_enumval_data t_5 = { "AAA_USER_DATA_REQUEST", { .i32=12 }};
+ struct dict_enumval_data t_6 = { "PGW_UPDATE", { .i32=13 }};
+ struct dict_enumval_data t_7 = { "RESTORATION", { .i32=14 }};
+ struct dict_enumval_data t_8 = { "RE_REGISTRATION", { .i32=2 }};
+ struct dict_enumval_data t_9 = { "UNREGISTERED_USER", { .i32=3 }};
+ struct dict_enumval_data t_10 = { "TIMEOUT_DEREGISTRATION", { .i32=4 }};
+ struct dict_enumval_data t_11 = { "USER_DEREGISTRATION", { .i32=5 }};
+ struct dict_enumval_data t_12 = { "TIMEOUT_DEREGISTRATION_STORE_SERVER_NAME", { .i32=6 }};
+ struct dict_enumval_data t_13 = { "USER_DEREGISTRATION_STORE_SERVER_NAME", { .i32=7 }};
+ struct dict_enumval_data t_14 = { "ADMINISTRATIVE_DEREGISTRATION", { .i32=8 }};
+ struct dict_enumval_data t_15 = { "AUTHENTICATION_FAILURE", { .i32=9 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Reason-Code */
+ {
+ struct dict_avp_data data = {
+ 616, /* Code */
+ 10415, /* Vendor */
+ "Reason-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Reason-Code)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PERMANENT_TERMINATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NEW_SERVER_ASSIGNED", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "SERVER_CHANGE", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "REMOVE_S_CSCF", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Reason-Info */
+ {
+ struct dict_avp_data data = {
+ 617, /* Code */
+ 10415, /* Vendor */
+ "Reason-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Primary-Event-Charging-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 619, /* Code */
+ 10415, /* Vendor */
+ "Primary-Event-Charging-Function-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterURI_type, NULL);
+ };
+ /* Secondary-Event-Charging-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 620, /* Code */
+ 10415, /* Vendor */
+ "Secondary-Event-Charging-Function-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterURI_type, NULL);
+ };
+ /* Primary-Charging-Collection-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 621, /* Code */
+ 10415, /* Vendor */
+ "Primary-Charging-Collection-Function-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterURI_type, NULL);
+ };
+ /* Secondary-Charging-Collection-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 622, /* Code */
+ 10415, /* Vendor */
+ "Secondary-Charging-Collection-Function-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterURI_type, NULL);
+ };
+ /* User-Authorization-Type */
+ {
+ struct dict_avp_data data = {
+ 623, /* Code */
+ 10415, /* Vendor */
+ "User-Authorization-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(User-Authorization-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "REGISTRATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "DE_REGISTRATION", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "REGISTRATION_AND_CAPABILITIES", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* User-Data-Already-Available */
+ {
+ struct dict_avp_data data = {
+ 624, /* Code */
+ 10415, /* Vendor */
+ "User-Data-Already-Available", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(User-Data-Already-Available)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "USER_DATA_NOT_AVAILABLE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "USER_DATA_ALREADY_AVAILABLE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Confidentiality-Key */
+ {
+ struct dict_avp_data data = {
+ 625, /* Code */
+ 10415, /* Vendor */
+ "Confidentiality-Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Integrity-Key */
+ {
+ struct dict_avp_data data = {
+ 626, /* Code */
+ 10415, /* Vendor */
+ "Integrity-Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Feature-List-ID */
+ {
+ struct dict_avp_data data = {
+ 629, /* Code */
+ 10415, /* Vendor */
+ "Feature-List-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Feature-List */
+ {
+ struct dict_avp_data data = {
+ 630, /* Code */
+ 10415, /* Vendor */
+ "Feature-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Originating-Request */
+ {
+ struct dict_avp_data data = {
+ 633, /* Code */
+ 10415, /* Vendor */
+ "Originating-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Originating-Request)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ORIGINATING", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Wildcarded-Public-Identity */
+ {
+ struct dict_avp_data data = {
+ 634, /* Code */
+ 10415, /* Vendor */
+ "Wildcarded-Public-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* UAR-Flags */
+ {
+ struct dict_avp_data data = {
+ 637, /* Code */
+ 10415, /* Vendor */
+ "UAR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Loose-Route-Indication */
+ {
+ struct dict_avp_data data = {
+ 638, /* Code */
+ 10415, /* Vendor */
+ "Loose-Route-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Loose-Route-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "LOOSE_ROUTE_NOT_REQUIRED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "LOOSE_ROUTE_REQUIRED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Path */
+ {
+ struct dict_avp_data data = {
+ 640, /* Code */
+ 10415, /* Vendor */
+ "Path", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Contact */
+ {
+ struct dict_avp_data data = {
+ 641, /* Code */
+ 10415, /* Vendor */
+ "Contact", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Call-ID-SIP-Header */
+ {
+ struct dict_avp_data data = {
+ 643, /* Code */
+ 10415, /* Vendor */
+ "Call-ID-SIP-Header", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* From-SIP-Header */
+ {
+ struct dict_avp_data data = {
+ 644, /* Code */
+ 10415, /* Vendor */
+ "From-SIP-Header", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* To-SIP-Header */
+ {
+ struct dict_avp_data data = {
+ 645, /* Code */
+ 10415, /* Vendor */
+ "To-SIP-Header", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Record-Route */
+ {
+ struct dict_avp_data data = {
+ 646, /* Code */
+ 10415, /* Vendor */
+ "Record-Route", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Multiple-Registration-Indication */
+ {
+ struct dict_avp_data data = {
+ 648, /* Code */
+ 10415, /* Vendor */
+ "Multiple-Registration-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Multiple-Registration-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NOT_MULTIPLE_REGISTRATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MULTIPLE_REGISTRATION", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Session-Priority */
+ {
+ struct dict_avp_data data = {
+ 650, /* Code */
+ 10415, /* Vendor */
+ "Session-Priority", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Priority)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PRIORITY_0", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PRIORITY_1", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "PRIORITY_2", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "PRIORITY_3", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "PRIORITY_4", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Priviledged-Sender-Indication */
+ {
+ struct dict_avp_data data = {
+ 652, /* Code */
+ 10415, /* Vendor */
+ "Priviledged-Sender-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Priviledged-Sender-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PRIVILEDGED_SENDER", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* LIA-Flags */
+ {
+ struct dict_avp_data data = {
+ 653, /* Code */
+ 10415, /* Vendor */
+ "LIA-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Initial-CSeq-Sequence-Number */
+ {
+ struct dict_avp_data data = {
+ 654, /* Code */
+ 10415, /* Vendor */
+ "Initial-CSeq-Sequence-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SAR-Flags */
+ {
+ struct dict_avp_data data = {
+ 655, /* Code */
+ 10415, /* Vendor */
+ "SAR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* WebRTC-Authentication-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 657, /* Code */
+ 10415, /* Vendor */
+ "WebRTC-Authentication-Function-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* WebRTC-Web-Server-Function-Name */
+ {
+ struct dict_avp_data data = {
+ 658, /* Code */
+ 10415, /* Vendor */
+ "WebRTC-Web-Server-Function-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Wildcarded-IMPU */
+ {
+ struct dict_avp_data data = {
+ 636, /* Code */
+ 10415, /* Vendor */
+ "Wildcarded-IMPU", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Subscription-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 642, /* Code */
+ 10415, /* Vendor */
+ "Subscription-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Server-Capabilities */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 603, /* Code */
+ 10415, /* Vendor */
+ "Server-Capabilities", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Associated-Registered-Identities */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 647, /* Code */
+ 10415, /* Vendor */
+ "Associated-Registered-Identities", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SIP-Digest-Authenticate */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 635, /* Code */
+ 10415, /* Vendor */
+ "SIP-Digest-Authenticate", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Supported-Features */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 628, /* Code */
+ 10415, /* Vendor */
+ "Supported-Features", /* Name */
+ AVP_FLAG_VENDOR, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Allowed-WAF-WWSF-Identities */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 656, /* Code */
+ 10415, /* Vendor */
+ "Allowed-WAF-WWSF-Identities", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Identity-with-Emergency-Registration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 651, /* Code */
+ 10415, /* Vendor */
+ "Identity-with-Emergency-Registration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Associated-Identities */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 632, /* Code */
+ 10415, /* Vendor */
+ "Associated-Identities", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Deregistration-Reason */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 615, /* Code */
+ 10415, /* Vendor */
+ "Deregistration-Reason", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Charging-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 618, /* Code */
+ 10415, /* Vendor */
+ "Charging-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SIP-Auth-Data-Item */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 612, /* Code */
+ 10415, /* Vendor */
+ "SIP-Auth-Data-Item", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Restoration-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 649, /* Code */
+ 10415, /* Vendor */
+ "Restoration-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Supported-Applications */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 631, /* Code */
+ 10415, /* Vendor */
+ "Supported-Applications", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SCSCF-Restoration-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 639, /* Code */
+ 10415, /* Vendor */
+ "SCSCF-Restoration-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29229_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Subscription-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Subscription-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Call-ID-SIP-Header"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "From-SIP-Header"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "To-SIP-Header"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Record-Route"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Contact"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Server-Capabilities */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Server-Capabilities"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Mandatory-Capability"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Optional-Capability"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Name"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Associated-Registered-Identities */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Associated-Registered-Identities"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SIP-Digest-Authenticate */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SIP-Digest-Authenticate"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Digest-Realm"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Digest-Algorithm"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Digest-QoP"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Digest-HA1"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Supported-Features */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Supported-Features"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Vendor-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Feature-List-ID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Feature-List"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Allowed-WAF-WWSF-Identities */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Allowed-WAF-WWSF-Identities"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "WebRTC-Authentication-Function-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "WebRTC-Web-Server-Function-Name"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Identity-with-Emergency-Registration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Identity-with-Emergency-Registration"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Public-Identity"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Associated-Identities */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Associated-Identities"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Deregistration-Reason */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Deregistration-Reason"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Reason-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reason-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Charging-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Charging-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Primary-Event-Charging-Function-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Secondary-Event-Charging-Function-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Primary-Charging-Collection-Function-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Secondary-Charging-Collection-Function-Name"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SIP-Auth-Data-Item */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SIP-Auth-Data-Item"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SIP-Item-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Authentication-Scheme"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Authenticate"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Authorization"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Authentication-Context"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Confidentiality-Key"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Integrity-Key"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Digest-Authenticate"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-IPv6-Prefix"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Framed-Interface-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Line-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Restoration-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Restoration-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Path"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Contact"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Initial-CSeq-Sequence-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Call-ID-SIP-Header"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subscription-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Supported-Applications */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Supported-Applications"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Auth-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Acct-Application-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Vendor-Specific-Application-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SCSCF-Restoration-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SCSCF-Restoration-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Restoration-Info"}, RULE_REQUIRED, 1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIP-Authentication-Scheme"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29229_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29229_avps_load_defs(conffile);
+ return dict_ts29229_avps_load_rules(conffile);
+}
+
+const char* dict_ts29229_avps_proto_ver(char * conffile) {
+ return ts29229_avps_proto_ver;
+}
+
+const double dict_ts29229_avps_gen_ts(char * conffile) {
+ return ts29229_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29229_avps", dict_ts29229_avps_load_defs, dict_ts29229_avps_load_rules, "dict_rfc7683_avps", "dict_rfc4590_avps", "dict_draftload_avps", "dict_rfc7155_avps", "dict_etsi283034_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29229_avps/ts29229_avps.did b/extensions/dict_ts29229_avps/ts29229_avps.did
new file mode 100644
index 0000000..6a2c8ee
--- /dev/null
+++ b/extensions/dict_ts29229_avps/ts29229_avps.did
@@ -0,0 +1,8 @@
+dict_draftload_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
diff --git a/extensions/dict_ts29272_avps/CMakeLists.txt b/extensions/dict_ts29272_avps/CMakeLists.txt
new file mode 100644
index 0000000..85b98a2
--- /dev/null
+++ b/extensions/dict_ts29272_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29272_avps extension
+PROJECT("dict_ts29272_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29272_avps dict_ts29272_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29272_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29272_AVPS)
+
+
+
diff --git a/extensions/dict_ts29272_avps/dict_ts29272_avps.c b/extensions/dict_ts29272_avps/dict_ts29272_avps.c
new file mode 100644
index 0000000..5d74805
--- /dev/null
+++ b/extensions/dict_ts29272_avps/dict_ts29272_avps.c
@@ -0,0 +1,3599 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29272_avps (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697187.84
+
+const char *ts29272_avps_proto_ver = PROTO_VER;
+const double ts29272_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29272_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* IMEI */
+ {
+ struct dict_avp_data data = {
+ 1402, /* Code */
+ 10415, /* Vendor */
+ "IMEI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Software-Version */
+ {
+ struct dict_avp_data data = {
+ 1403, /* Code */
+ 10415, /* Vendor */
+ "Software-Version", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* QoS-Subscribed */
+ {
+ struct dict_avp_data data = {
+ 1404, /* Code */
+ 10415, /* Vendor */
+ "QoS-Subscribed", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ULR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1405, /* Code */
+ 10415, /* Vendor */
+ "ULR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ULA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1406, /* Code */
+ 10415, /* Vendor */
+ "ULA-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Visited-PLMN-Id */
+ {
+ struct dict_avp_data data = {
+ 1407, /* Code */
+ 10415, /* Vendor */
+ "Visited-PLMN-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Number-Of-Requested-Vectors */
+ {
+ struct dict_avp_data data = {
+ 1410, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Requested-Vectors", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Re-Synchronization-Info */
+ {
+ struct dict_avp_data data = {
+ 1411, /* Code */
+ 10415, /* Vendor */
+ "Re-Synchronization-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Immediate-Response-Preferred */
+ {
+ struct dict_avp_data data = {
+ 1412, /* Code */
+ 10415, /* Vendor */
+ "Immediate-Response-Preferred", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Network-Access-Mode */
+ {
+ struct dict_avp_data data = {
+ 1417, /* Code */
+ 10415, /* Vendor */
+ "Network-Access-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Network-Access-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PACKET_AND_CIRCUIT", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Reserved", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "ONLY_PACKET", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* HPLMN-ODB */
+ {
+ struct dict_avp_data data = {
+ 1418, /* Code */
+ 10415, /* Vendor */
+ "HPLMN-ODB", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Item-Number */
+ {
+ struct dict_avp_data data = {
+ 1419, /* Code */
+ 10415, /* Vendor */
+ "Item-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Cancellation-Type */
+ {
+ struct dict_avp_data data = {
+ 1420, /* Code */
+ 10415, /* Vendor */
+ "Cancellation-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Cancellation-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MME_UPDATE_PROCEDURE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SGSN_UPDATE_PROCEDURE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "SUBSCRIPTION_WITHDRAWAL", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "UPDATE_PROCEDURE_IWF", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "INITIAL_ATTACH_PROCEDURE", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* DSR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1421, /* Code */
+ 10415, /* Vendor */
+ "DSR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* DSA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1422, /* Code */
+ 10415, /* Vendor */
+ "DSA-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Context-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1423, /* Code */
+ 10415, /* Vendor */
+ "Context-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Subscriber-Status */
+ {
+ struct dict_avp_data data = {
+ 1424, /* Code */
+ 10415, /* Vendor */
+ "Subscriber-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Subscriber-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SERVICE_GRANTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "OPERATOR_DETERMINED_BARRING", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Operator-Determined-Barring */
+ {
+ struct dict_avp_data data = {
+ 1425, /* Code */
+ 10415, /* Vendor */
+ "Operator-Determined-Barring", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Access-Restriction-Data */
+ {
+ struct dict_avp_data data = {
+ 1426, /* Code */
+ 10415, /* Vendor */
+ "Access-Restriction-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* APN-OI-Replacement */
+ {
+ struct dict_avp_data data = {
+ 1427, /* Code */
+ 10415, /* Vendor */
+ "APN-OI-Replacement", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* All-APN-Configurations-Included-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1428, /* Code */
+ 10415, /* Vendor */
+ "All-APN-Configurations-Included-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(All-APN-Configurations-Included-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "All_APN_CONFIGURATIONS_INCLUDED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MODIFIED_ADDED_APN_CONFIGURATIONS_INCLUDED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* VPLMN-Dynamic-Address-Allowed */
+ {
+ struct dict_avp_data data = {
+ 1432, /* Code */
+ 10415, /* Vendor */
+ "VPLMN-Dynamic-Address-Allowed", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(VPLMN-Dynamic-Address-Allowed)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NOTALLOWED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ALLOWED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* STN-SR */
+ {
+ struct dict_avp_data data = {
+ 1433, /* Code */
+ 10415, /* Vendor */
+ "STN-SR", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Alert-Reason */
+ {
+ struct dict_avp_data data = {
+ 1434, /* Code */
+ 10415, /* Vendor */
+ "Alert-Reason", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Alert-Reason)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UE_PRESENT", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "UE_MEMORY_AVAILABLE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CSG-Id */
+ {
+ struct dict_avp_data data = {
+ 1437, /* Code */
+ 10415, /* Vendor */
+ "CSG-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PDN-GW-Allocation-Type */
+ {
+ struct dict_avp_data data = {
+ 1438, /* Code */
+ 10415, /* Vendor */
+ "PDN-GW-Allocation-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PDN-GW-Allocation-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "STATIC", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "DYNAMIC", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Expiration-Date */
+ {
+ struct dict_avp_data data = {
+ 1439, /* Code */
+ 10415, /* Vendor */
+ "Expiration-Date", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* RAT-Frequency-Selection-Priority-ID */
+ {
+ struct dict_avp_data data = {
+ 1440, /* Code */
+ 10415, /* Vendor */
+ "RAT-Frequency-Selection-Priority-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* IDA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1441, /* Code */
+ 10415, /* Vendor */
+ "IDA-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PUA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1442, /* Code */
+ 10415, /* Vendor */
+ "PUA-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* NOR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1443, /* Code */
+ 10415, /* Vendor */
+ "NOR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Id */
+ {
+ struct dict_avp_data data = {
+ 1444, /* Code */
+ 10415, /* Vendor */
+ "User-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Equipment-Status */
+ {
+ struct dict_avp_data data = {
+ 1445, /* Code */
+ 10415, /* Vendor */
+ "Equipment-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Equipment-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "WHITELISTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "BLACKLISTED", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "GREYLISTED", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Regional-Subscription-Zone-Code */
+ {
+ struct dict_avp_data data = {
+ 1446, /* Code */
+ 10415, /* Vendor */
+ "Regional-Subscription-Zone-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RAND */
+ {
+ struct dict_avp_data data = {
+ 1447, /* Code */
+ 10415, /* Vendor */
+ "RAND", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* XRES */
+ {
+ struct dict_avp_data data = {
+ 1448, /* Code */
+ 10415, /* Vendor */
+ "XRES", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* AUTN */
+ {
+ struct dict_avp_data data = {
+ 1449, /* Code */
+ 10415, /* Vendor */
+ "AUTN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* KASME */
+ {
+ struct dict_avp_data data = {
+ 1450, /* Code */
+ 10415, /* Vendor */
+ "KASME", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Trace-Collection-Entity */
+ {
+ struct dict_avp_data data = {
+ 1452, /* Code */
+ 10415, /* Vendor */
+ "Trace-Collection-Entity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Kc */
+ {
+ struct dict_avp_data data = {
+ 1453, /* Code */
+ 10415, /* Vendor */
+ "Kc", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SRES */
+ {
+ struct dict_avp_data data = {
+ 1454, /* Code */
+ 10415, /* Vendor */
+ "SRES", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PDN-Type */
+ {
+ struct dict_avp_data data = {
+ 1456, /* Code */
+ 10415, /* Vendor */
+ "PDN-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PDN-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "IPv4", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "IPv6", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "IPv4v6", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "IPv4_OR_IPv6", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Roaming-Restricted-Due-To-Unsupported-Feature */
+ {
+ struct dict_avp_data data = {
+ 1457, /* Code */
+ 10415, /* Vendor */
+ "Roaming-Restricted-Due-To-Unsupported-Feature", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Roaming-Restricted-Due-To-Unsupported-Feature)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Roaming_Restricted_Due_To_Unsupported_Feature", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Trace-Reference */
+ {
+ struct dict_avp_data data = {
+ 1459, /* Code */
+ 10415, /* Vendor */
+ "Trace-Reference", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Trace-Depth */
+ {
+ struct dict_avp_data data = {
+ 1462, /* Code */
+ 10415, /* Vendor */
+ "Trace-Depth", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Trace-Depth)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "GPRS_Subscription_Data", { .i32=72 }};
+ struct dict_enumval_data t_2 = { "Complete_Data_List_Included_Indicator", { .i32=73 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Trace-NE-Type-List */
+ {
+ struct dict_avp_data data = {
+ 1463, /* Code */
+ 10415, /* Vendor */
+ "Trace-NE-Type-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Trace-Interface-List */
+ {
+ struct dict_avp_data data = {
+ 1464, /* Code */
+ 10415, /* Vendor */
+ "Trace-Interface-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Trace-Event-List */
+ {
+ struct dict_avp_data data = {
+ 1465, /* Code */
+ 10415, /* Vendor */
+ "Trace-Event-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* OMC-Id */
+ {
+ struct dict_avp_data data = {
+ 1466, /* Code */
+ 10415, /* Vendor */
+ "OMC-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Complete-Data-List-Included-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1468, /* Code */
+ 10415, /* Vendor */
+ "Complete-Data-List-Included-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Complete-Data-List-Included-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "All_PDP_CONTEXTS_INCLUDED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CONTEXTS_INCLUDED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PDP-Type */
+ {
+ struct dict_avp_data data = {
+ 1470, /* Code */
+ 10415, /* Vendor */
+ "PDP-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* 3GPP2-MEID */
+ {
+ struct dict_avp_data data = {
+ 1471, /* Code */
+ 10415, /* Vendor */
+ "3GPP2-MEID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* GMLC-Number */
+ {
+ struct dict_avp_data data = {
+ 1474, /* Code */
+ 10415, /* Vendor */
+ "GMLC-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SS-Code */
+ {
+ struct dict_avp_data data = {
+ 1476, /* Code */
+ 10415, /* Vendor */
+ "SS-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SS-Status */
+ {
+ struct dict_avp_data data = {
+ 1477, /* Code */
+ 10415, /* Vendor */
+ "SS-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Notification-To-UE-User */
+ {
+ struct dict_avp_data data = {
+ 1478, /* Code */
+ 10415, /* Vendor */
+ "Notification-To-UE-User", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Notification-To-UE-User)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NOTIFY_LOCATION_ALLOWED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NOTIFYANDVERIFY_LOCATION_ALLOWED_IF_NO_RESPONSE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "NOTIFYANDVERIFY_LOCATION_NOT_ALLOWED_IF_NO_RESPONSE", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "LOCATION_NOT_ALLOWED", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Client-Identity */
+ {
+ struct dict_avp_data data = {
+ 1480, /* Code */
+ 10415, /* Vendor */
+ "Client-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* GMLC-Restriction */
+ {
+ struct dict_avp_data data = {
+ 1481, /* Code */
+ 10415, /* Vendor */
+ "GMLC-Restriction", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(GMLC-Restriction)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "GMLC_LIST", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "HOME_COUNTRY", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PLMN-Client */
+ {
+ struct dict_avp_data data = {
+ 1482, /* Code */
+ 10415, /* Vendor */
+ "PLMN-Client", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PLMN-Client)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "BROADCAST_SERVICE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "O_AND_M_HPLMN", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "O_AND_M_VPLMN", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "ANONYMOUS_LOCATION", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "TARGET_UE_SUBSCRIBED_SERVICE", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ServiceTypeIdentity */
+ {
+ struct dict_avp_data data = {
+ 1484, /* Code */
+ 10415, /* Vendor */
+ "ServiceTypeIdentity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TS-Code */
+ {
+ struct dict_avp_data data = {
+ 1487, /* Code */
+ 10415, /* Vendor */
+ "TS-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SGSN-Number */
+ {
+ struct dict_avp_data data = {
+ 1489, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* IDR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1490, /* Code */
+ 10415, /* Vendor */
+ "IDR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ICS-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1491, /* Code */
+ 10415, /* Vendor */
+ "ICS-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(ICS-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "FALSE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "TRUE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* IMS-Voice-Over-PS-Sessions-Supported */
+ {
+ struct dict_avp_data data = {
+ 1492, /* Code */
+ 10415, /* Vendor */
+ "IMS-Voice-Over-PS-Sessions-Supported", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IMS-Voice-Over-PS-Sessions-Supported)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NOT_SUPPORTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions */
+ {
+ struct dict_avp_data data = {
+ 1493, /* Code */
+ 10415, /* Vendor */
+ "Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Homogeneous-Support-of-IMS-Voice-Over-PS-Sessions)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NOT_SUPPORTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Last-UE-Activity-Time */
+ {
+ struct dict_avp_data data = {
+ 1494, /* Code */
+ 10415, /* Vendor */
+ "Last-UE-Activity-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* User-State */
+ {
+ struct dict_avp_data data = {
+ 1499, /* Code */
+ 10415, /* Vendor */
+ "User-State", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(User-State)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DETACHED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ATTACHED_NOT_REACHABLE_FOR_PAGING", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "ATTACHED_REACHABLE_FOR_PAGING", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "CONNECTED_NOT_REACHABLE_FOR_PAGING", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "CONNECTED_REACHABLE_FOR_PAGING", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "RESERVED", { .i32=5 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* E-UTRAN-Cell-Global-Identity */
+ {
+ struct dict_avp_data data = {
+ 1602, /* Code */
+ 10415, /* Vendor */
+ "E-UTRAN-Cell-Global-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Tracking-Area-Identity */
+ {
+ struct dict_avp_data data = {
+ 1603, /* Code */
+ 10415, /* Vendor */
+ "Tracking-Area-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Cell-Global-Identity */
+ {
+ struct dict_avp_data data = {
+ 1604, /* Code */
+ 10415, /* Vendor */
+ "Cell-Global-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Routing-Area-Identity */
+ {
+ struct dict_avp_data data = {
+ 1605, /* Code */
+ 10415, /* Vendor */
+ "Routing-Area-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Location-Area-Identity */
+ {
+ struct dict_avp_data data = {
+ 1606, /* Code */
+ 10415, /* Vendor */
+ "Location-Area-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-Area-Identity */
+ {
+ struct dict_avp_data data = {
+ 1607, /* Code */
+ 10415, /* Vendor */
+ "Service-Area-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Geographical-Information */
+ {
+ struct dict_avp_data data = {
+ 1608, /* Code */
+ 10415, /* Vendor */
+ "Geographical-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Geodetic-Information */
+ {
+ struct dict_avp_data data = {
+ 1609, /* Code */
+ 10415, /* Vendor */
+ "Geodetic-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Current-Location-Retrieved */
+ {
+ struct dict_avp_data data = {
+ 1610, /* Code */
+ 10415, /* Vendor */
+ "Current-Location-Retrieved", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Current-Location-Retrieved)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ACTIVE_LOCATION_RETRIEVAL", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Age-Of-Location-Information */
+ {
+ struct dict_avp_data data = {
+ 1611, /* Code */
+ 10415, /* Vendor */
+ "Age-Of-Location-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Error-Diagnostic */
+ {
+ struct dict_avp_data data = {
+ 1614, /* Code */
+ 10415, /* Vendor */
+ "Error-Diagnostic", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Error-Diagnostic)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "GPRS_DATA_SUBSCRIBED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NO_GPRS_DATA_SUBSCRIBED", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "ODB_ALL_APN", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "ODB_HPLMN_APN", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "ODB_VPLMN_APN", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Ext-PDP-Address */
+ {
+ struct dict_avp_data data = {
+ 1621, /* Code */
+ 10415, /* Vendor */
+ "Ext-PDP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* UE-SRVCC-Capability */
+ {
+ struct dict_avp_data data = {
+ 1615, /* Code */
+ 10415, /* Vendor */
+ "UE-SRVCC-Capability", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(UE-SRVCC-Capability)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UE_SRVCC_NOT_SUPPORTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "UE_SRVCC_SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MPS-Priority */
+ {
+ struct dict_avp_data data = {
+ 1616, /* Code */
+ 10415, /* Vendor */
+ "MPS-Priority", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* VPLMN-LIPA-Allowed */
+ {
+ struct dict_avp_data data = {
+ 1617, /* Code */
+ 10415, /* Vendor */
+ "VPLMN-LIPA-Allowed", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(VPLMN-LIPA-Allowed)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "LIPA_NOTALLOWED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "LIPA_ALLOWED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* LIPA-Permission */
+ {
+ struct dict_avp_data data = {
+ 1618, /* Code */
+ 10415, /* Vendor */
+ "LIPA-Permission", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(LIPA-Permission)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "LIPA_PROHIBITED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "LIPA_ONLY", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "LIPA_CONDITIONAL", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Subscribed-Periodic-RAU-TAU-Timer */
+ {
+ struct dict_avp_data data = {
+ 1619, /* Code */
+ 10415, /* Vendor */
+ "Subscribed-Periodic-RAU-TAU-Timer", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Ext-PDP-Type */
+ {
+ struct dict_avp_data data = {
+ 1620, /* Code */
+ 10415, /* Vendor */
+ "Ext-PDP-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SIPTO-Permission */
+ {
+ struct dict_avp_data data = {
+ 1613, /* Code */
+ 10415, /* Vendor */
+ "SIPTO-Permission", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SIPTO-Permission)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ALLOWED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NOTALLOWED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Job-Type */
+ {
+ struct dict_avp_data data = {
+ 1623, /* Code */
+ 10415, /* Vendor */
+ "Job-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Job-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Area_Scope", { .i32=138 }};
+ struct dict_enumval_data t_2 = { "List_Of_Measurements", { .i32=139 }};
+ struct dict_enumval_data t_3 = { "Reporting_Trigger", { .i32=140 }};
+ struct dict_enumval_data t_4 = { "Report_Interval", { .i32=141 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* List-Of-Measurements */
+ {
+ struct dict_avp_data data = {
+ 1625, /* Code */
+ 10415, /* Vendor */
+ "List-Of-Measurements", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Reporting-Trigger */
+ {
+ struct dict_avp_data data = {
+ 1626, /* Code */
+ 10415, /* Vendor */
+ "Reporting-Trigger", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Report-Interval */
+ {
+ struct dict_avp_data data = {
+ 1627, /* Code */
+ 10415, /* Vendor */
+ "Report-Interval", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Report-Interval)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Report_Amount", { .i32=142 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Report-Amount */
+ {
+ struct dict_avp_data data = {
+ 1628, /* Code */
+ 10415, /* Vendor */
+ "Report-Amount", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Report-Amount)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Event_Threshold_RSRP", { .i32=143 }};
+ struct dict_enumval_data t_2 = { "Event_Threshold_RSRQ", { .i32=144 }};
+ struct dict_enumval_data t_3 = { "Logging_Interval", { .i32=145 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Event-Threshold-RSRP */
+ {
+ struct dict_avp_data data = {
+ 1629, /* Code */
+ 10415, /* Vendor */
+ "Event-Threshold-RSRP", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Event-Threshold-RSRQ */
+ {
+ struct dict_avp_data data = {
+ 1630, /* Code */
+ 10415, /* Vendor */
+ "Event-Threshold-RSRQ", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Logging-Interval */
+ {
+ struct dict_avp_data data = {
+ 1631, /* Code */
+ 10415, /* Vendor */
+ "Logging-Interval", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Logging-Interval)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Logging_Duration", { .i32=146 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Logging-Duration */
+ {
+ struct dict_avp_data data = {
+ 1632, /* Code */
+ 10415, /* Vendor */
+ "Logging-Duration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Logging-Duration)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Relay_Node_Indicator", { .i32=147 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Relay-Node-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1633, /* Code */
+ 10415, /* Vendor */
+ "Relay-Node-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Relay-Node-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NOT_RELAY_NODE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "RELAY_NODE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MDT-User-Consent */
+ {
+ struct dict_avp_data data = {
+ 1634, /* Code */
+ 10415, /* Vendor */
+ "MDT-User-Consent", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MDT-User-Consent)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CONSENT_NOT_GIVEN", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CONSENT_GIVEN", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PUR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1635, /* Code */
+ 10415, /* Vendor */
+ "PUR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Subscribed-VSRVCC */
+ {
+ struct dict_avp_data data = {
+ 1636, /* Code */
+ 10415, /* Vendor */
+ "Subscribed-VSRVCC", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Subscribed-VSRVCC)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "VSRVCC_SUBSCRIBED", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CLR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1638, /* Code */
+ 10415, /* Vendor */
+ "CLR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UVR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1639, /* Code */
+ 10415, /* Vendor */
+ "UVR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UVA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1640, /* Code */
+ 10415, /* Vendor */
+ "UVA-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Time-Zone */
+ {
+ struct dict_avp_data data = {
+ 1642, /* Code */
+ 10415, /* Vendor */
+ "Time-Zone", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* A-MSISDN */
+ {
+ struct dict_avp_data data = {
+ 1643, /* Code */
+ 10415, /* Vendor */
+ "A-MSISDN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MME-Number-for-MT-SMS */
+ {
+ struct dict_avp_data data = {
+ 1645, /* Code */
+ 10415, /* Vendor */
+ "MME-Number-for-MT-SMS", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SMS-Register-Request */
+ {
+ struct dict_avp_data data = {
+ 1648, /* Code */
+ 10415, /* Vendor */
+ "SMS-Register-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SMS-Register-Request)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SMS_REGISTRATION_REQUIRED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SMS_REGISTRATION_NOT_PREFERRED", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "NO_PREFERENCE", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Daylight-Saving-Time */
+ {
+ struct dict_avp_data data = {
+ 1650, /* Code */
+ 10415, /* Vendor */
+ "Daylight-Saving-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Daylight-Saving-Time)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NO_ADJUSTMENT", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PLUS_ONE_HOUR_ADJUSTMENT", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "PLUS_TWO_HOURS_ADJUSTMENT", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Subscription-Data-Flags */
+ {
+ struct dict_avp_data data = {
+ 1654, /* Code */
+ 10415, /* Vendor */
+ "Subscription-Data-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Measurement-Period-LTE */
+ {
+ struct dict_avp_data data = {
+ 1655, /* Code */
+ 10415, /* Vendor */
+ "Measurement-Period-LTE", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Measurement-Period-LTE)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Measurement_Period_UMTS", { .i32=167 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Measurement-Period-UMTS */
+ {
+ struct dict_avp_data data = {
+ 1656, /* Code */
+ 10415, /* Vendor */
+ "Measurement-Period-UMTS", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Measurement-Period-UMTS)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Collection_Period_RRM_LTE", { .i32=168 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Collection-Period-RRM-LTE */
+ {
+ struct dict_avp_data data = {
+ 1657, /* Code */
+ 10415, /* Vendor */
+ "Collection-Period-RRM-LTE", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Collection-Period-RRM-LTE)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Collection_Period_RRM_UMTS", { .i32=169 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Collection-Period-RRM-UMTS */
+ {
+ struct dict_avp_data data = {
+ 1658, /* Code */
+ 10415, /* Vendor */
+ "Collection-Period-RRM-UMTS", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Collection-Period-RRM-UMTS)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Positioning_Method", { .i32=170 }};
+ struct dict_enumval_data t_2 = { "Measurement_Quantity", { .i32=171 }};
+ struct dict_enumval_data t_3 = { "Event_Threshold_Event_1F", { .i32=172 }};
+ struct dict_enumval_data t_4 = { "Event_Threshold_Event_1I", { .i32=173 }};
+ struct dict_enumval_data t_5 = { "Restoration_Priority", { .i32=174 }};
+ struct dict_enumval_data t_6 = { "SGs_MME_Identity", { .i32=175 }};
+ struct dict_enumval_data t_7 = { "SIPTO_Local_Network_Permission", { .i32=176 }};
+ struct dict_enumval_data t_8 = { "Coupled_Node_Diameter_ID", { .i32=177 }};
+ struct dict_enumval_data t_9 = { "OC_Supported_Features", { .i32=178 }};
+ struct dict_enumval_data t_10 = { "OC_OLR", { .i32=179 }};
+ struct dict_enumval_data t_11 = { "ProSe_Subscription_Data", { .i32=180 }};
+ struct dict_enumval_data t_12 = { "WLAN_offloadability", { .i32=181 }};
+ struct dict_enumval_data t_13 = { "WLAN_offloadability_EUTRAN", { .i32=182 }};
+ struct dict_enumval_data t_14 = { "WLAN_offloadability_UTRAN", { .i32=183 }};
+ struct dict_enumval_data t_15 = { "Reset_ID", { .i32=184 }};
+ struct dict_enumval_data t_16 = { "MDT_Allowed_PLMN_Id", { .i32=185 }};
+ struct dict_enumval_data t_17 = { "Adjacent_PLMNs", { .i32=186 }};
+ struct dict_enumval_data t_18 = { "Adjacent_Access_Restriction_Data", { .i32=187 }};
+ struct dict_enumval_data t_19 = { "DL_Buffering_Suggested_Packet_Count", { .i32=188 }};
+ struct dict_enumval_data t_20 = { "IMSI_Group_Id", { .i32=189 }};
+ struct dict_enumval_data t_21 = { "Group_Service_Id", { .i32=190 }};
+ struct dict_enumval_data t_22 = { "Group_PLMN_Id", { .i32=191 }};
+ struct dict_enumval_data t_23 = { "Local_Group_Id", { .i32=192 }};
+ struct dict_enumval_data t_24 = { "AESE_Communication_Pattern", { .i32=193 }};
+ struct dict_enumval_data t_25 = { "Communication_Pattern_Set", { .i32=194 }};
+ struct dict_enumval_data t_26 = { "Monitoring_Event_Configuration", { .i32=195 }};
+ struct dict_enumval_data t_27 = { "Monitoring_Event_Report", { .i32=196 }};
+ struct dict_enumval_data t_28 = { "UE_Reachability_Configuration", { .i32=197 }};
+ struct dict_enumval_data t_29 = { "eNodeB_Id", { .i32=198 }};
+ struct dict_enumval_data t_30 = { "Supported_Services", { .i32=199 }};
+ struct dict_enumval_data t_31 = { "Supported_Monitoring_Events", { .i32=200 }};
+ struct dict_enumval_data t_32 = { "AIR_Flags", { .i32=201 }};
+ struct dict_enumval_data t_33 = { "UE_Usage_Type", { .i32=202 }};
+ struct dict_enumval_data t_34 = { "DRMP", { .i32=203 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_26, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_27, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_28, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_29, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_30, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_31, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_32, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_33, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_34, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Positioning-Method */
+ {
+ struct dict_avp_data data = {
+ 1659, /* Code */
+ 10415, /* Vendor */
+ "Positioning-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Measurement-Quantity */
+ {
+ struct dict_avp_data data = {
+ 1660, /* Code */
+ 10415, /* Vendor */
+ "Measurement-Quantity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Event-Threshold-Event-1F */
+ {
+ struct dict_avp_data data = {
+ 1661, /* Code */
+ 10415, /* Vendor */
+ "Event-Threshold-Event-1F", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Event-Threshold-Event-1I */
+ {
+ struct dict_avp_data data = {
+ 1662, /* Code */
+ 10415, /* Vendor */
+ "Event-Threshold-Event-1I", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Restoration-Priority */
+ {
+ struct dict_avp_data data = {
+ 1663, /* Code */
+ 10415, /* Vendor */
+ "Restoration-Priority", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SGs-MME-Identity */
+ {
+ struct dict_avp_data data = {
+ 1664, /* Code */
+ 10415, /* Vendor */
+ "SGs-MME-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* SIPTO-Local-Network-Permission */
+ {
+ struct dict_avp_data data = {
+ 1665, /* Code */
+ 10415, /* Vendor */
+ "SIPTO-Local-Network-Permission", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Coupled-Node-Diameter-ID */
+ {
+ struct dict_avp_data data = {
+ 1666, /* Code */
+ 10415, /* Vendor */
+ "Coupled-Node-Diameter-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* WLAN-offloadability-EUTRAN */
+ {
+ struct dict_avp_data data = {
+ 1668, /* Code */
+ 10415, /* Vendor */
+ "WLAN-offloadability-EUTRAN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* WLAN-offloadability-UTRAN */
+ {
+ struct dict_avp_data data = {
+ 1669, /* Code */
+ 10415, /* Vendor */
+ "WLAN-offloadability-UTRAN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Reset-ID */
+ {
+ struct dict_avp_data data = {
+ 1670, /* Code */
+ 10415, /* Vendor */
+ "Reset-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MDT-Allowed-PLMN-Id */
+ {
+ struct dict_avp_data data = {
+ 1671, /* Code */
+ 10415, /* Vendor */
+ "MDT-Allowed-PLMN-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* DL-Buffering-Suggested-Packet-Count */
+ {
+ struct dict_avp_data data = {
+ 1674, /* Code */
+ 10415, /* Vendor */
+ "DL-Buffering-Suggested-Packet-Count", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Group-Service-Id */
+ {
+ struct dict_avp_data data = {
+ 1676, /* Code */
+ 10415, /* Vendor */
+ "Group-Service-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Group-PLMN-Id */
+ {
+ struct dict_avp_data data = {
+ 1677, /* Code */
+ 10415, /* Vendor */
+ "Group-PLMN-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Local-Group-Id */
+ {
+ struct dict_avp_data data = {
+ 1678, /* Code */
+ 10415, /* Vendor */
+ "Local-Group-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* AIR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1679, /* Code */
+ 10415, /* Vendor */
+ "AIR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UE-Usage-Type */
+ {
+ struct dict_avp_data data = {
+ 1680, /* Code */
+ 10415, /* Vendor */
+ "UE-Usage-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Non-IP-PDN-Type-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1681, /* Code */
+ 10415, /* Vendor */
+ "Non-IP-PDN-Type-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Non-IP-PDN-Type-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MAINTAIN_PDN_CONNECTION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "DISCONNECT_PDN_CONNECTION_WITH_REACTIVATION_REQUEST", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "DISCONNECT_PDN_CONNECTION_WITHOUT_REACTIVATION_REQUEST", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Non-IP-Data-Delivery-Mechanism */
+ {
+ struct dict_avp_data data = {
+ 1682, /* Code */
+ 10415, /* Vendor */
+ "Non-IP-Data-Delivery-Mechanism", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Additional-Context-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1683, /* Code */
+ 10415, /* Vendor */
+ "Additional-Context-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SCEF-Realm */
+ {
+ struct dict_avp_data data = {
+ 1684, /* Code */
+ 10415, /* Vendor */
+ "SCEF-Realm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* Preferred-Data-Mode */
+ {
+ struct dict_avp_data data = {
+ 1686, /* Code */
+ 10415, /* Vendor */
+ "Preferred-Data-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* V2X-Permission */
+ {
+ struct dict_avp_data data = {
+ 1689, /* Code */
+ 10415, /* Vendor */
+ "V2X-Permission", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PDN-Connection-Continuity */
+ {
+ struct dict_avp_data data = {
+ 1690, /* Code */
+ 10415, /* Vendor */
+ "PDN-Connection-Continuity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* eDRX-Cycle-Length-Value */
+ {
+ struct dict_avp_data data = {
+ 1692, /* Code */
+ 10415, /* Vendor */
+ "eDRX-Cycle-Length-Value", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UE-PC5-AMBR */
+ {
+ struct dict_avp_data data = {
+ 1693, /* Code */
+ 10415, /* Vendor */
+ "UE-PC5-AMBR", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* V2X-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1688, /* Code */
+ 10415, /* Vendor */
+ "V2X-Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* E-UTRAN-Vector */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1414, /* Code */
+ 10415, /* Vendor */
+ "E-UTRAN-Vector", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* AMBR */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1435, /* Code */
+ 10415, /* Vendor */
+ "AMBR", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Adjacent-Access-Restriction-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1673, /* Code */
+ 10415, /* Vendor */
+ "Adjacent-Access-Restriction-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* GERAN-Vector */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1416, /* Code */
+ 10415, /* Vendor */
+ "GERAN-Vector", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* eDRX-Cycle-Length */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1691, /* Code */
+ 10415, /* Vendor */
+ "eDRX-Cycle-Length", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Area-Scope */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1624, /* Code */
+ 10415, /* Vendor */
+ "Area-Scope", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Call-Barring-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1488, /* Code */
+ 10415, /* Vendor */
+ "Call-Barring-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* CSG-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1436, /* Code */
+ 10415, /* Vendor */
+ "CSG-Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* VPLMN-CSG-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1641, /* Code */
+ 10415, /* Vendor */
+ "VPLMN-CSG-Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MO-LR */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1485, /* Code */
+ 10415, /* Vendor */
+ "MO-LR", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* WLAN-offloadability */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1667, /* Code */
+ 10415, /* Vendor */
+ "WLAN-offloadability", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Equivalent-PLMN-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1637, /* Code */
+ 10415, /* Vendor */
+ "Equivalent-PLMN-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* UTRAN-Vector */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1415, /* Code */
+ 10415, /* Vendor */
+ "UTRAN-Vector", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Local-Time-Zone */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1649, /* Code */
+ 10415, /* Vendor */
+ "Local-Time-Zone", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* IMSI-Group-Id */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1675, /* Code */
+ 10415, /* Vendor */
+ "IMSI-Group-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Terminal-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1401, /* Code */
+ 10415, /* Vendor */
+ "Terminal-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Teleservice-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1486, /* Code */
+ 10415, /* Vendor */
+ "Teleservice-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Service-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1483, /* Code */
+ 10415, /* Vendor */
+ "Service-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Requested-UTRAN-GERAN-Authentication-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1409, /* Code */
+ 10415, /* Vendor */
+ "Requested-UTRAN-GERAN-Authentication-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Subscription-Data-Deletion */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1685, /* Code */
+ 10415, /* Vendor */
+ "Subscription-Data-Deletion", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MME-User-State */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1497, /* Code */
+ 10415, /* Vendor */
+ "MME-User-State", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Requested-EUTRAN-Authentication-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1408, /* Code */
+ 10415, /* Vendor */
+ "Requested-EUTRAN-Authentication-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Adjacent-PLMNs */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1672, /* Code */
+ 10415, /* Vendor */
+ "Adjacent-PLMNs", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SGSN-User-State */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1498, /* Code */
+ 10415, /* Vendor */
+ "SGSN-User-State", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* External-Client */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1479, /* Code */
+ 10415, /* Vendor */
+ "External-Client", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* EPS-User-State */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1495, /* Code */
+ 10415, /* Vendor */
+ "EPS-User-State", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SGSN-Location-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1601, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Location-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* LCS-PrivacyException */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1475, /* Code */
+ 10415, /* Vendor */
+ "LCS-PrivacyException", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* EPS-Subscribed-QoS-Profile */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1431, /* Code */
+ 10415, /* Vendor */
+ "EPS-Subscribed-QoS-Profile", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Authentication-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1413, /* Code */
+ 10415, /* Vendor */
+ "Authentication-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Specific-APN-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1472, /* Code */
+ 10415, /* Vendor */
+ "Specific-APN-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MDT-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1622, /* Code */
+ 10415, /* Vendor */
+ "MDT-Configuration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MME-Location-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1600, /* Code */
+ 10415, /* Vendor */
+ "MME-Location-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* PDP-Context */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1469, /* Code */
+ 10415, /* Vendor */
+ "PDP-Context", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Emergency-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1687, /* Code */
+ 10415, /* Vendor */
+ "Emergency-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* GPRS-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1467, /* Code */
+ 10415, /* Vendor */
+ "GPRS-Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* APN-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1430, /* Code */
+ 10415, /* Vendor */
+ "APN-Configuration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* EPS-Location-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1496, /* Code */
+ 10415, /* Vendor */
+ "EPS-Location-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Trace-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1458, /* Code */
+ 10415, /* Vendor */
+ "Trace-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Active-APN */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1612, /* Code */
+ 10415, /* Vendor */
+ "Active-APN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* LCS-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1473, /* Code */
+ 10415, /* Vendor */
+ "LCS-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* APN-Configuration-Profile */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1429, /* Code */
+ 10415, /* Vendor */
+ "APN-Configuration-Profile", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1400, /* Code */
+ 10415, /* Vendor */
+ "Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29272_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* V2X-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "V2X-Subscription-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "V2X-Permission"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-PC5-AMBR"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* E-UTRAN-Vector */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "E-UTRAN-Vector"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Item-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAND"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "XRES"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AUTN"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "KASME"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* AMBR */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "AMBR"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-UL"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Max-Requested-Bandwidth-DL"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Adjacent-Access-Restriction-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Adjacent-Access-Restriction-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Restriction-Data"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* GERAN-Vector */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "GERAN-Vector"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Item-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAND"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SRES"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Kc"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* eDRX-Cycle-Length */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "eDRX-Cycle-Length"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "eDRX-Cycle-Length-Value"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Area-Scope */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Area-Scope"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Cell-Global-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "E-UTRAN-Cell-Global-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Area-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Location-Area-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Tracking-Area-Identity"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Call-Barring-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Call-Barring-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SS-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SS-Status"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* CSG-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "CSG-Subscription-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "CSG-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Expiration-Date"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Selection"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* VPLMN-CSG-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "VPLMN-CSG-Subscription-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "CSG-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Expiration-Date"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MO-LR */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MO-LR"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SS-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SS-Status"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* WLAN-offloadability */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "WLAN-offloadability"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "WLAN-offloadability-EUTRAN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "WLAN-offloadability-UTRAN"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Equivalent-PLMN-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Equivalent-PLMN-List"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_REQUIRED, 1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* UTRAN-Vector */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "UTRAN-Vector"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Item-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAND"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "XRES"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AUTN"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Confidentiality-Key"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Integrity-Key"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Local-Time-Zone */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Local-Time-Zone"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Time-Zone"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Daylight-Saving-Time"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* IMSI-Group-Id */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "IMSI-Group-Id"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Group-Service-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Group-PLMN-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Local-Group-Id"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Terminal-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Terminal-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "IMEI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP2-MEID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Software-Version"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Teleservice-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Teleservice-List"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TS-Code"}, RULE_REQUIRED, 1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Service-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Service-Type"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "ServiceTypeIdentity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GMLC-Restriction"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Notification-To-UE-User"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Requested-UTRAN-GERAN-Authentication-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Requested-UTRAN-GERAN-Authentication-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Number-Of-Requested-Vectors"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Immediate-Response-Preferred"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Re-Synchronization-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Subscription-Data-Deletion */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Subscription-Data-Deletion"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "DSR-Flags"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Context-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Reference"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TS-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SS-Code"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MME-User-State */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MME-User-State"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "User-State"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Requested-EUTRAN-Authentication-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Requested-EUTRAN-Authentication-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Number-Of-Requested-Vectors"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Immediate-Response-Preferred"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Re-Synchronization-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Adjacent-PLMNs */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Adjacent-PLMNs"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_REQUIRED, 1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SGSN-User-State */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SGSN-User-State"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "User-State"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* External-Client */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "External-Client"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Client-Identity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GMLC-Restriction"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Notification-To-UE-User"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* EPS-User-State */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "EPS-User-State"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MME-User-State"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-User-State"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SGSN-Location-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SGSN-Location-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Cell-Global-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Location-Area-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Area-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Routing-Area-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Geographical-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Geodetic-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Current-Location-Retrieved"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Age-Of-Location-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* LCS-PrivacyException */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "LCS-PrivacyException"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SS-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SS-Status"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Notification-To-UE-User"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "External-Client"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PLMN-Client"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* EPS-Subscribed-QoS-Profile */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "EPS-Subscribed-QoS-Profile"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Class-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Allocation-Retention-Priority"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Authentication-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Authentication-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "E-UTRAN-Vector"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UTRAN-Vector"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GERAN-Vector"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Specific-APN-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Specific-APN-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Service-Selection"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MIP6-Agent-Info"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-Network-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MDT-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MDT-Configuration"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Job-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Area-Scope"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "List-Of-Measurements"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reporting-Trigger"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Report-Interval"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Report-Amount"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Threshold-RSRP"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Threshold-RSRQ"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Logging-Interval"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Logging-Duration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Measurement-Period-LTE"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Measurement-Period-UMTS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Collection-Period-RRM-LTE"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Collection-Period-RRM-UMTS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Positioning-Method"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Measurement-Quantity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Threshold-Event-1F"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Threshold-Event-1I"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MDT-Allowed-PLMN-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MME-Location-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MME-Location-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "E-UTRAN-Cell-Global-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Tracking-Area-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Geographical-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Geodetic-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Current-Location-Retrieved"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Age-Of-Location-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "eNodeB-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Extended-eNodeB-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* PDP-Context */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "PDP-Context"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Context-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDP-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Subscribed"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "VPLMN-Dynamic-Address-Allowed"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Selection"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Ext-PDP-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Ext-PDP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AMBR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-OI-Replacement"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIPTO-Permission"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LIPA-Permission"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Restoration-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIPTO-Local-Network-Permission"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Non-IP-Data-Delivery-Mechanism"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Emergency-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Emergency-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MIP6-Agent-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* GPRS-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "GPRS-Subscription-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Complete-Data-List-Included-Indicator"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDP-Context"}, RULE_REQUIRED, 1, 50 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* APN-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "APN-Configuration"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Context-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Served-Party-IP-Address"}, RULE_OPTIONAL, -1, 2 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Selection"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "EPS-Subscribed-QoS-Profile"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "VPLMN-Dynamic-Address-Allowed"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MIP6-Agent-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-Network-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-GW-Allocation-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AMBR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Specific-APN-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-OI-Replacement"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIPTO-Permission"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LIPA-Permission"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Restoration-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SIPTO-Local-Network-Permission"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "WLAN-offloadability"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Non-IP-PDN-Type-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Non-IP-Data-Delivery-Mechanism"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Realm"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Preferred-Data-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Connection-Continuity"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* EPS-Location-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "EPS-Location-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MME-Location-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Location-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Trace-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Trace-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Trace-Reference"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Depth"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-NE-Type-List"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Interface-List"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Event-List"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "OMC-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Collection-Entity"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MDT-Configuration"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Active-APN */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Active-APN"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Context-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Selection"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MIP6-Agent-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-Network-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Specific-APN-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* LCS-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "LCS-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "GMLC-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-PrivacyException"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MO-LR"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* APN-Configuration-Profile */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "APN-Configuration-Profile"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Context-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Additional-Context-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "All-APN-Configurations-Included-Indicator"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Configuration"}, RULE_REQUIRED, 1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Subscription-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Subscriber-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "A-MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "STN-SR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ICS-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Network-Access-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Operator-Determined-Barring"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "HPLMN-ODB"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Regional-Subscription-Zone-Code"}, RULE_OPTIONAL, -1, 10 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Restriction-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-OI-Replacement"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Teleservice-List"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Call-Barring-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AMBR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Configuration-Profile"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Frequency-Selection-Priority-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GPRS-Subscription-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CSG-Subscription-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Roaming-Restricted-Due-To-Unsupported-Feature"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subscribed-Periodic-RAU-TAU-Timer"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MPS-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "VPLMN-LIPA-Allowed"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Relay-Node-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MDT-User-Consent"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subscribed-VSRVCC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Subscription-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Subscription-Data-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Adjacent-Access-Restriction-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DL-Buffering-Suggested-Packet-Count"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMSI-Group-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Usage-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AESE-Communication-Pattern"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Configuration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Emergency-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "V2X-Subscription-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "eDRX-Cycle-Length"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29272_avps (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29272_avps_load_defs(conffile);
+ return dict_ts29272_avps_load_rules(conffile);
+}
+
+const char* dict_ts29272_avps_proto_ver(char * conffile) {
+ return ts29272_avps_proto_ver;
+}
+
+const double dict_ts29272_avps_gen_ts(char * conffile) {
+ return ts29272_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29272_avps", dict_ts29272_avps_load_defs, dict_ts29272_avps_load_rules, "dict_ts32299_avps", "dict_ts29336_avps", "dict_ts29273_avps", "dict_ts29212_avps", "dict_ts29214_avps", "dict_ts29344_avps", "dict_ts29338_avps", "dict_ts29217_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_ts29173_avps", "dict_rfc5778_avps", "dict_ts29061_avps", "dict_rfc5447_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc4004_avps", "dict_rfc5777_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29272_avps/ts29272_avps.did b/extensions/dict_ts29272_avps/ts29272_avps.did
new file mode 100644
index 0000000..f7022e2
--- /dev/null
+++ b/extensions/dict_ts29272_avps/ts29272_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29337_avps
+dict_3gpp2_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_ts29338_avps
+dict_ts29173_avps
+dict_ts29336_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_draftload_avps
+dict_etsi283034_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_rfc7155_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc4004_avps
+dict_rfc5447_avps
+dict_ts29272_avps
diff --git a/extensions/dict_ts29273_avps/CMakeLists.txt b/extensions/dict_ts29273_avps/CMakeLists.txt
new file mode 100644
index 0000000..3e60d42
--- /dev/null
+++ b/extensions/dict_ts29273_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29273_avps extension
+PROJECT("dict_ts29273_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29273_avps dict_ts29273_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29273_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29273_AVPS)
+
+
+
diff --git a/extensions/dict_ts29273_avps/dict_ts29273_avps.c b/extensions/dict_ts29273_avps/dict_ts29273_avps.c
new file mode 100644
index 0000000..9906d3a
--- /dev/null
+++ b/extensions/dict_ts29273_avps/dict_ts29273_avps.c
@@ -0,0 +1,836 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29273_avps (e20).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e20"
+#define GEN_DATE 1506697133.32
+
+const char *ts29273_avps_proto_ver = PROTO_VER;
+const double ts29273_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29273_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* ANID */
+ {
+ struct dict_avp_data data = {
+ 1504, /* Code */
+ 10415, /* Vendor */
+ "ANID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* AN-Trusted */
+ {
+ struct dict_avp_data data = {
+ 1503, /* Code */
+ 10415, /* Vendor */
+ "AN-Trusted", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AN-Trusted)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TRUSTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "UNTRUSTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MIP-FA-RK */
+ {
+ struct dict_avp_data data = {
+ 1506, /* Code */
+ 10415, /* Vendor */
+ "MIP-FA-RK", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP-FA-RK-SPI */
+ {
+ struct dict_avp_data data = {
+ 1507, /* Code */
+ 10415, /* Vendor */
+ "MIP-FA-RK-SPI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Full-Network-Name */
+ {
+ struct dict_avp_data data = {
+ 1516, /* Code */
+ 10415, /* Vendor */
+ "Full-Network-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Short-Network-Name */
+ {
+ struct dict_avp_data data = {
+ 1517, /* Code */
+ 10415, /* Vendor */
+ "Short-Network-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Mobile-Node-Identifier */
+ {
+ struct dict_avp_data data = {
+ 506, /* Code */
+ 10415, /* Vendor */
+ "Mobile-Node-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* AAA-Failure-Indication */
+ {
+ struct dict_avp_data data = {
+ 1518, /* Code */
+ 10415, /* Vendor */
+ "AAA-Failure-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Transport-Access-Type */
+ {
+ struct dict_avp_data data = {
+ 1519, /* Code */
+ 10415, /* Vendor */
+ "Transport-Access-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Transport-Access-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "BBF", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Visited-Network-Identifier */
+ {
+ struct dict_avp_data data = {
+ 600, /* Code */
+ 10415, /* Vendor */
+ "Visited-Network-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* DER-Flags */
+ {
+ struct dict_avp_data data = {
+ 1520, /* Code */
+ 10415, /* Vendor */
+ "DER-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* DEA-Flags */
+ {
+ struct dict_avp_data data = {
+ 1521, /* Code */
+ 10415, /* Vendor */
+ "DEA-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SSID */
+ {
+ struct dict_avp_data data = {
+ 1524, /* Code */
+ 10415, /* Vendor */
+ "SSID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* HESSID */
+ {
+ struct dict_avp_data data = {
+ 1525, /* Code */
+ 10415, /* Vendor */
+ "HESSID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* TWAN-Connection-Mode */
+ {
+ struct dict_avp_data data = {
+ 1527, /* Code */
+ 10415, /* Vendor */
+ "TWAN-Connection-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Connectivity-Flags */
+ {
+ struct dict_avp_data data = {
+ 1529, /* Code */
+ 10415, /* Vendor */
+ "Connectivity-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TWAN-PCO */
+ {
+ struct dict_avp_data data = {
+ 1530, /* Code */
+ 10415, /* Vendor */
+ "TWAN-PCO", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TWAG-CP-Address */
+ {
+ struct dict_avp_data data = {
+ 1531, /* Code */
+ 10415, /* Vendor */
+ "TWAG-CP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* TWAG-UP-Address */
+ {
+ struct dict_avp_data data = {
+ 1532, /* Code */
+ 10415, /* Vendor */
+ "TWAG-UP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* TWAN-S2a-Failure-Cause */
+ {
+ struct dict_avp_data data = {
+ 1533, /* Code */
+ 10415, /* Vendor */
+ "TWAN-S2a-Failure-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Back-Off-Timer */
+ {
+ struct dict_avp_data data = {
+ 1534, /* Code */
+ 10415, /* Vendor */
+ "SM-Back-Off-Timer", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* WLCP-Key */
+ {
+ struct dict_avp_data data = {
+ 1535, /* Code */
+ 10415, /* Vendor */
+ "WLCP-Key", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Emergency-Services */
+ {
+ struct dict_avp_data data = {
+ 1538, /* Code */
+ 10415, /* Vendor */
+ "Emergency-Services", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* IMEI-Check-In-VPLMN-Result */
+ {
+ struct dict_avp_data data = {
+ 1540, /* Code */
+ 10415, /* Vendor */
+ "IMEI-Check-In-VPLMN-Result", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Non-3GPP-IP-Access */
+ {
+ struct dict_avp_data data = {
+ 1501, /* Code */
+ 10415, /* Vendor */
+ "Non-3GPP-IP-Access", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Non-3GPP-IP-Access)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NON_3GPP_SUBSCRIPTION_ALLOWED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NON_3GPP_SUBSCRIPTION_BARRED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Non-3GPP-IP-Access-APN */
+ {
+ struct dict_avp_data data = {
+ 1502, /* Code */
+ 10415, /* Vendor */
+ "Non-3GPP-IP-Access-APN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Non-3GPP-IP-Access-APN)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Non_3GPP_APNS_ENABLE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Non_3GPP_APNS_DISABLE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PPR-Flags */
+ {
+ struct dict_avp_data data = {
+ 1508, /* Code */
+ 10415, /* Vendor */
+ "PPR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TWAN-Default-APN-Context-Id */
+ {
+ struct dict_avp_data data = {
+ 1512, /* Code */
+ 10415, /* Vendor */
+ "TWAN-Default-APN-Context-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Access-Authorization-Flags */
+ {
+ struct dict_avp_data data = {
+ 1511, /* Code */
+ 10415, /* Vendor */
+ "Access-Authorization-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-Selection */
+ {
+ struct dict_avp_data data = {
+ 493, /* Code */
+ 10415, /* Vendor */
+ "Service-Selection", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* 3GPP-AAA-Server-Name */
+ {
+ struct dict_avp_data data = {
+ 318, /* Code */
+ 10415, /* Vendor */
+ "3GPP-AAA-Server-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* ERP-Authorization */
+ {
+ struct dict_avp_data data = {
+ 1541, /* Code */
+ 10415, /* Vendor */
+ "ERP-Authorization", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIP6-Feature-Vector */
+ {
+ struct dict_avp_data data = {
+ 124, /* Code */
+ 10415, /* Vendor */
+ "MIP6-Feature-Vector", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Origination-Time-Stamp */
+ {
+ struct dict_avp_data data = {
+ 1536, /* Code */
+ 10415, /* Vendor */
+ "Origination-Time-Stamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Maximum-Wait-Time */
+ {
+ struct dict_avp_data data = {
+ 1537, /* Code */
+ 10415, /* Vendor */
+ "Maximum-Wait-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Access-Network-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1526, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MIP6-Agent-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 486, /* Code */
+ 10415, /* Vendor */
+ "MIP6-Agent-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* WLAN-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1509, /* Code */
+ 10415, /* Vendor */
+ "WLAN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TWAN-Connectivity-Parameters */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1528, /* Code */
+ 10415, /* Vendor */
+ "TWAN-Connectivity-Parameters", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TWAN-Access-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1510, /* Code */
+ 10415, /* Vendor */
+ "TWAN-Access-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Trace-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1505, /* Code */
+ 10415, /* Vendor */
+ "Trace-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Non-3GPP-User-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1500, /* Code */
+ 10415, /* Vendor */
+ "Non-3GPP-User-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29273_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Access-Network-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Access-Network-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "BSSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Location-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Location-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Operator-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Logical-Access-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MIP6-Agent-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MIP6-Agent-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "MIP-Home-Agent-Address"}, RULE_OPTIONAL, -1, 2 },
+ { { .avp_vendor = 0, .avp_name = "MIP-Home-Agent-Host"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "MIP6-Home-Link-Prefix"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* WLAN-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "WLAN-Identifier"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "HESSID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TWAN-Connectivity-Parameters */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TWAN-Connectivity-Parameters"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Connectivity-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Selection"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Served-Party-IP-Address"}, RULE_OPTIONAL, -1, 2 },
+ { { .avp_vendor = 10415, .avp_name = "TWAN-PCO"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAG-UP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAN-S2a-Failure-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Back-Off-Timer"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TWAN-Access-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TWAN-Access-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Access-Authorization-Flags"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "WLAN-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Trace-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Trace-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Trace-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Reference"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Non-3GPP-User-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Non-3GPP-User-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Non-3GPP-IP-Access"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Non-3GPP-IP-Access-APN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Session-Timeout"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MIP6-Feature-Vector"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AMBR"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Context-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-OI-Replacement"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Configuration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trace-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAN-Default-APN-Context-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAN-Access-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Emergency-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ERP-Authorization"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29273_avps (e20)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29273_avps_load_defs(conffile);
+ return dict_ts29273_avps_load_rules(conffile);
+}
+
+const char* dict_ts29273_avps_proto_ver(char * conffile) {
+ return ts29273_avps_proto_ver;
+}
+
+const double dict_ts29273_avps_gen_ts(char * conffile) {
+ return ts29273_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29273_avps", dict_ts29273_avps_load_defs, dict_ts29273_avps_load_rules, "dict_ts32299_avps", "dict_ts29272_avps", "dict_ts29212_avps", "dict_ts29229_avps", "dict_rfc5778_avps", "dict_ts29061_avps", "dict_rfc4006bis_avps", "dict_rfc6942_avps", "dict_rfc7155_avps", "dict_rfc4072_avps", "dict_rfc5447_avps", "dict_rfc7683_avps", "dict_rfc6734_avps", "dict_rfc4004_avps", "dict_rfc5580_avps", "dict_rfc5777_avps", "dict_draftload_avps", "dict_etsi283034_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29273_avps/ts29273_avps.did b/extensions/dict_ts29273_avps/ts29273_avps.did
new file mode 100644
index 0000000..923b7dc
--- /dev/null
+++ b/extensions/dict_ts29273_avps/ts29273_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc5778_avps
+dict_ts29338_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_rfc7155_avps
+dict_rfc4072_avps
+dict_rfc4004_avps
+dict_rfc5447_avps
+dict_ts29273_avps
diff --git a/extensions/dict_ts29329_avps/CMakeLists.txt b/extensions/dict_ts29329_avps/CMakeLists.txt
new file mode 100644
index 0000000..0af05e9
--- /dev/null
+++ b/extensions/dict_ts29329_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29329_avps extension
+PROJECT("dict_ts29329_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29329_avps dict_ts29329_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29329_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29329_AVPS)
+
+
+
diff --git a/extensions/dict_ts29329_avps/dict_ts29329_avps.c b/extensions/dict_ts29329_avps/dict_ts29329_avps.c
new file mode 100644
index 0000000..a3577ea
--- /dev/null
+++ b/extensions/dict_ts29329_avps/dict_ts29329_avps.c
@@ -0,0 +1,643 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29329_avps (e20).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e20"
+#define GEN_DATE 1506697146.88
+
+const char *ts29329_avps_proto_ver = PROTO_VER;
+const double ts29329_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29329_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* MSISDN */
+ {
+ struct dict_avp_data data = {
+ 701, /* Code */
+ 10415, /* Vendor */
+ "MSISDN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Data */
+ {
+ struct dict_avp_data data = {
+ 702, /* Code */
+ 10415, /* Vendor */
+ "User-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Data-Reference */
+ {
+ struct dict_avp_data data = {
+ 703, /* Code */
+ 10415, /* Vendor */
+ "Data-Reference", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Data-Reference)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "RepositoryData", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "IMSPublicIdentity", { .i32=10 }};
+ struct dict_enumval_data t_3 = { "IMSUserState", { .i32=11 }};
+ struct dict_enumval_data t_4 = { "S_CSCFName", { .i32=12 }};
+ struct dict_enumval_data t_5 = { "InitialFilterCriteria", { .i32=13 }};
+ struct dict_enumval_data t_6 = { "LocationInformation", { .i32=14 }};
+ struct dict_enumval_data t_7 = { "UserState", { .i32=15 }};
+ struct dict_enumval_data t_8 = { "ChargingInformation", { .i32=16 }};
+ struct dict_enumval_data t_9 = { "MSISDN", { .i32=17 }};
+ struct dict_enumval_data t_10 = { "PSIActivation", { .i32=18 }};
+ struct dict_enumval_data t_11 = { "DSAI", { .i32=19 }};
+ struct dict_enumval_data t_12 = { "ServiceLevelTraceInfo", { .i32=21 }};
+ struct dict_enumval_data t_13 = { "IPAddressSecureBindingInformation", { .i32=22 }};
+ struct dict_enumval_data t_14 = { "ServicePriorityLevel", { .i32=23 }};
+ struct dict_enumval_data t_15 = { "SMSRegistrationInfo", { .i32=24 }};
+ struct dict_enumval_data t_16 = { "UEReachabilityForIP", { .i32=25 }};
+ struct dict_enumval_data t_17 = { "TADSinformation", { .i32=26 }};
+ struct dict_enumval_data t_18 = { "STN_SR", { .i32=27 }};
+ struct dict_enumval_data t_19 = { "UE_SRVCC_Capability", { .i32=28 }};
+ struct dict_enumval_data t_20 = { "ExtendedPriority", { .i32=29 }};
+ struct dict_enumval_data t_21 = { "CSRN", { .i32=30 }};
+ struct dict_enumval_data t_22 = { "ReferenceLocationInformation", { .i32=31 }};
+ struct dict_enumval_data t_23 = { "IMSI", { .i32=32 }};
+ struct dict_enumval_data t_24 = { "IMSPrivateUserIdentity", { .i32=33 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Service-Indication */
+ {
+ struct dict_avp_data data = {
+ 704, /* Code */
+ 10415, /* Vendor */
+ "Service-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Subs-Req-Type */
+ {
+ struct dict_avp_data data = {
+ 705, /* Code */
+ 10415, /* Vendor */
+ "Subs-Req-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Subs-Req-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Subscribe", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Unsubscribe", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Requested-Domain */
+ {
+ struct dict_avp_data data = {
+ 706, /* Code */
+ 10415, /* Vendor */
+ "Requested-Domain", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Requested-Domain)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CS_Domain", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PS_Domain", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Current-Location */
+ {
+ struct dict_avp_data data = {
+ 707, /* Code */
+ 10415, /* Vendor */
+ "Current-Location", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Current-Location)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DoNotNeedInitiateActiveLocationRetrieval", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "InitiateActiveLocationRetrieval", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Identity-Set */
+ {
+ struct dict_avp_data data = {
+ 708, /* Code */
+ 10415, /* Vendor */
+ "Identity-Set", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Identity-Set)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ALL_IDENTITIES", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "REGISTERED_IDENTITIES", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "IMPLICIT_IDENTITIES", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "ALIAS_IDENTITIES", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Expiry-Time */
+ {
+ struct dict_avp_data data = {
+ 709, /* Code */
+ 10415, /* Vendor */
+ "Expiry-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Send-Data-Indication */
+ {
+ struct dict_avp_data data = {
+ 710, /* Code */
+ 10415, /* Vendor */
+ "Send-Data-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Send-Data-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "USER_DATA_NOT_REQUESTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "USER_DATA_REQUESTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* DSAI-Tag */
+ {
+ struct dict_avp_data data = {
+ 711, /* Code */
+ 10415, /* Vendor */
+ "DSAI-Tag", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Wildcarded-Public-Identity */
+ {
+ struct dict_avp_data data = {
+ 634, /* Code */
+ 10415, /* Vendor */
+ "Wildcarded-Public-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Wildcarded-IMPU */
+ {
+ struct dict_avp_data data = {
+ 636, /* Code */
+ 10415, /* Vendor */
+ "Wildcarded-IMPU", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* One-Time-Notification */
+ {
+ struct dict_avp_data data = {
+ 712, /* Code */
+ 10415, /* Vendor */
+ "One-Time-Notification", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(One-Time-Notification)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ONE_TIME_NOTIFICATION_REQUESTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "IP", { .i32=25 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Requested-Nodes */
+ {
+ struct dict_avp_data data = {
+ 713, /* Code */
+ 10415, /* Vendor */
+ "Requested-Nodes", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Serving-Node-Indication */
+ {
+ struct dict_avp_data data = {
+ 714, /* Code */
+ 10415, /* Vendor */
+ "Serving-Node-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Serving-Node-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ONLY_SERVING_NODES_REQUIRED", { .i32=0 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Sequence-Number */
+ {
+ struct dict_avp_data data = {
+ 716, /* Code */
+ 10415, /* Vendor */
+ "Sequence-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Pre-paging-Supported */
+ {
+ struct dict_avp_data data = {
+ 717, /* Code */
+ 10415, /* Vendor */
+ "Pre-paging-Supported", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Pre-paging-Supported)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PREPAGING_NOT_SUPPORTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PREPAGING_SUPPORTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Local-Time-Zone-Indication */
+ {
+ struct dict_avp_data data = {
+ 718, /* Code */
+ 10415, /* Vendor */
+ "Local-Time-Zone-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Local-Time-Zone-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ONLY_LOCAL_TIME_ZONE_REQUESTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "LOCAL_TIME_ZONE_WITH_LOCATION_INFO_REQUESTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* UDR-Flags */
+ {
+ struct dict_avp_data data = {
+ 719, /* Code */
+ 10415, /* Vendor */
+ "UDR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Call-Reference-Number */
+ {
+ struct dict_avp_data data = {
+ 721, /* Code */
+ 10415, /* Vendor */
+ "Call-Reference-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* AS-Number */
+ {
+ struct dict_avp_data data = {
+ 722, /* Code */
+ 10415, /* Vendor */
+ "AS-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Identity */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 700, /* Code */
+ 10415, /* Vendor */
+ "User-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Call-Reference-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 720, /* Code */
+ 10415, /* Vendor */
+ "Call-Reference-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Repository-Data-ID */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 715, /* Code */
+ 10415, /* Vendor */
+ "Repository-Data-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29329_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* User-Identity */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "User-Identity"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Public-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Call-Reference-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Call-Reference-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Call-Reference-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AS-Number"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Repository-Data-ID */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Repository-Data-ID"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Service-Indication"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sequence-Number"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29329_avps (e20)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29329_avps_load_defs(conffile);
+ return dict_ts29329_avps_load_rules(conffile);
+}
+
+const char* dict_ts29329_avps_proto_ver(char * conffile) {
+ return ts29329_avps_proto_ver;
+}
+
+const double dict_ts29329_avps_gen_ts(char * conffile) {
+ return ts29329_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29329_avps", dict_ts29329_avps_load_defs, dict_ts29329_avps_load_rules, "dict_ts29229_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29329_avps/ts29329_avps.did b/extensions/dict_ts29329_avps/ts29329_avps.did
new file mode 100644
index 0000000..8596274
--- /dev/null
+++ b/extensions/dict_ts29329_avps/ts29329_avps.did
@@ -0,0 +1,9 @@
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
diff --git a/extensions/dict_ts29336_avps/CMakeLists.txt b/extensions/dict_ts29336_avps/CMakeLists.txt
new file mode 100644
index 0000000..e466aa2
--- /dev/null
+++ b/extensions/dict_ts29336_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29336_avps extension
+PROJECT("dict_ts29336_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29336_avps dict_ts29336_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29336_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29336_AVPS)
+
+
+
diff --git a/extensions/dict_ts29336_avps/dict_ts29336_avps.c b/extensions/dict_ts29336_avps/dict_ts29336_avps.c
new file mode 100644
index 0000000..2295896
--- /dev/null
+++ b/extensions/dict_ts29336_avps/dict_ts29336_avps.c
@@ -0,0 +1,1454 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29336_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1508010198.59
+
+const char *ts29336_avps_proto_ver = PROTO_VER;
+const double ts29336_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29336_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* IP-SM-GW-Number */
+ {
+ struct dict_avp_data data = {
+ 3100, /* Code */
+ 10415, /* Vendor */
+ "IP-SM-GW-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* IP-SM-GW-Name */
+ {
+ struct dict_avp_data data = {
+ 3101, /* Code */
+ 10415, /* Vendor */
+ "IP-SM-GW-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* Service-ID */
+ {
+ struct dict_avp_data data = {
+ 3103, /* Code */
+ 10415, /* Vendor */
+ "Service-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Service-ID)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DEVICE_TRIGGER", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SMS_MO", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SCS-Identity */
+ {
+ struct dict_avp_data data = {
+ 3104, /* Code */
+ 10415, /* Vendor */
+ "SCS-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* HSS-Cause */
+ {
+ struct dict_avp_data data = {
+ 3109, /* Code */
+ 10415, /* Vendor */
+ "HSS-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SIR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3110, /* Code */
+ 10415, /* Vendor */
+ "SIR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* External-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3111, /* Code */
+ 10415, /* Vendor */
+ "External-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* IP-SM-GW-Realm */
+ {
+ struct dict_avp_data data = {
+ 3112, /* Code */
+ 10415, /* Vendor */
+ "IP-SM-GW-Realm", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* Periodic-Communication-Indicator */
+ {
+ struct dict_avp_data data = {
+ 3115, /* Code */
+ 10415, /* Vendor */
+ "Periodic-Communication-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Communication-Duration-Time */
+ {
+ struct dict_avp_data data = {
+ 3116, /* Code */
+ 10415, /* Vendor */
+ "Communication-Duration-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Periodic-Time */
+ {
+ struct dict_avp_data data = {
+ 3117, /* Code */
+ 10415, /* Vendor */
+ "Periodic-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Stationary-Indication */
+ {
+ struct dict_avp_data data = {
+ 3119, /* Code */
+ 10415, /* Vendor */
+ "Stationary-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SCEF-Reference-ID */
+ {
+ struct dict_avp_data data = {
+ 3124, /* Code */
+ 10415, /* Vendor */
+ "SCEF-Reference-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SCEF-ID */
+ {
+ struct dict_avp_data data = {
+ 3125, /* Code */
+ 10415, /* Vendor */
+ "SCEF-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* SCEF-Reference-ID-for-Deletion */
+ {
+ struct dict_avp_data data = {
+ 3126, /* Code */
+ 10415, /* Vendor */
+ "SCEF-Reference-ID-for-Deletion", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Monitoring-Type */
+ {
+ struct dict_avp_data data = {
+ 3127, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Maximum-Number-of-Reports */
+ {
+ struct dict_avp_data data = {
+ 3128, /* Code */
+ 10415, /* Vendor */
+ "Maximum-Number-of-Reports", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Monitoring-Duration */
+ {
+ struct dict_avp_data data = {
+ 3130, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Duration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Maximum-Detection-Time */
+ {
+ struct dict_avp_data data = {
+ 3131, /* Code */
+ 10415, /* Vendor */
+ "Maximum-Detection-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Reachability-Type */
+ {
+ struct dict_avp_data data = {
+ 3132, /* Code */
+ 10415, /* Vendor */
+ "Reachability-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Maximum-Latency */
+ {
+ struct dict_avp_data data = {
+ 3133, /* Code */
+ 10415, /* Vendor */
+ "Maximum-Latency", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Maximum-Response-Time */
+ {
+ struct dict_avp_data data = {
+ 3134, /* Code */
+ 10415, /* Vendor */
+ "Maximum-Response-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MONTE-Location-Type */
+ {
+ struct dict_avp_data data = {
+ 3136, /* Code */
+ 10415, /* Vendor */
+ "MONTE-Location-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Accuracy */
+ {
+ struct dict_avp_data data = {
+ 3137, /* Code */
+ 10415, /* Vendor */
+ "Accuracy", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Association-Type */
+ {
+ struct dict_avp_data data = {
+ 3138, /* Code */
+ 10415, /* Vendor */
+ "Association-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Roaming-Information */
+ {
+ struct dict_avp_data data = {
+ 3139, /* Code */
+ 10415, /* Vendor */
+ "Roaming-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Reachability-Information */
+ {
+ struct dict_avp_data data = {
+ 3140, /* Code */
+ 10415, /* Vendor */
+ "Reachability-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* IMEI-Change */
+ {
+ struct dict_avp_data data = {
+ 3141, /* Code */
+ 10415, /* Vendor */
+ "IMEI-Change", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Supported-Monitoring-Events */
+ {
+ struct dict_avp_data data = {
+ 3144, /* Code */
+ 10415, /* Vendor */
+ "Supported-Monitoring-Events", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED64 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CIR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3145, /* Code */
+ 10415, /* Vendor */
+ "CIR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-Result-Code */
+ {
+ struct dict_avp_data data = {
+ 3147, /* Code */
+ 10415, /* Vendor */
+ "Service-Result-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Reference-ID-Validity-Time */
+ {
+ struct dict_avp_data data = {
+ 3148, /* Code */
+ 10415, /* Vendor */
+ "Reference-ID-Validity-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Event-Handling */
+ {
+ struct dict_avp_data data = {
+ 3149, /* Code */
+ 10415, /* Vendor */
+ "Event-Handling", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Node-Type */
+ {
+ struct dict_avp_data data = {
+ 3153, /* Code */
+ 10415, /* Vendor */
+ "Node-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* S6t-HSS-Cause */
+ {
+ struct dict_avp_data data = {
+ 3154, /* Code */
+ 10415, /* Vendor */
+ "S6t-HSS-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Requested-Validity-Time */
+ {
+ struct dict_avp_data data = {
+ 3159, /* Code */
+ 10415, /* Vendor */
+ "Requested-Validity-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Granted-Validity-Time */
+ {
+ struct dict_avp_data data = {
+ 3160, /* Code */
+ 10415, /* Vendor */
+ "Granted-Validity-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Loss-Of-Connectivity-Reason */
+ {
+ struct dict_avp_data data = {
+ 3162, /* Code */
+ 10415, /* Vendor */
+ "Loss-Of-Connectivity-Reason", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Group-Reporting-Guard-Timer */
+ {
+ struct dict_avp_data data = {
+ 3163, /* Code */
+ 10415, /* Vendor */
+ "Group-Reporting-Guard-Timer", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CIA-Flags */
+ {
+ struct dict_avp_data data = {
+ 3164, /* Code */
+ 10415, /* Vendor */
+ "CIA-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RIR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3167, /* Code */
+ 10415, /* Vendor */
+ "RIR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Type-Of-External-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3168, /* Code */
+ 10415, /* Vendor */
+ "Type-Of-External-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* T4-Parameters */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3106, /* Code */
+ 10415, /* Vendor */
+ "T4-Parameters", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Restricted-PLMN-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3157, /* Code */
+ 10415, /* Vendor */
+ "Restricted-PLMN-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* NIDD-Authorization-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3151, /* Code */
+ 10415, /* Vendor */
+ "NIDD-Authorization-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* User-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3102, /* Code */
+ 10415, /* Vendor */
+ "User-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Scheduled-Communication-Time */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3118, /* Code */
+ 10415, /* Vendor */
+ "Scheduled-Communication-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Allowed-PLMN-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3158, /* Code */
+ 10415, /* Vendor */
+ "Allowed-PLMN-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* NIDD-Authorization-Update */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3161, /* Code */
+ 10415, /* Vendor */
+ "NIDD-Authorization-Update", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Location-Information-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3135, /* Code */
+ 10415, /* Vendor */
+ "Location-Information-Configuration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* NIDD-Authorization-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3150, /* Code */
+ 10415, /* Vendor */
+ "NIDD-Authorization-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Supported-Services */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3143, /* Code */
+ 10415, /* Vendor */
+ "Supported-Services", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* UE-Reachability-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3129, /* Code */
+ 10415, /* Vendor */
+ "UE-Reachability-Configuration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Service-Result */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3146, /* Code */
+ 10415, /* Vendor */
+ "Service-Result", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Service-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3152, /* Code */
+ 10415, /* Vendor */
+ "Service-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Enhanced-Coverage-Restriction */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3155, /* Code */
+ 10415, /* Vendor */
+ "Enhanced-Coverage-Restriction", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Communication-Pattern-Set */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3114, /* Code */
+ 10415, /* Vendor */
+ "Communication-Pattern-Set", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* T4-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3108, /* Code */
+ 10415, /* Vendor */
+ "T4-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Service-Parameters */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3105, /* Code */
+ 10415, /* Vendor */
+ "Service-Parameters", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Monitoring-Event-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3122, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Event-Configuration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* AESE-Error-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3121, /* Code */
+ 10415, /* Vendor */
+ "AESE-Error-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Monitoring-Event-Config-Status */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3142, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Event-Config-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* AESE-Communication-Pattern */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3113, /* Code */
+ 10415, /* Vendor */
+ "AESE-Communication-Pattern", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* AESE-Communication-Pattern-Config-Status */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3120, /* Code */
+ 10415, /* Vendor */
+ "AESE-Communication-Pattern-Config-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Service-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3107, /* Code */
+ 10415, /* Vendor */
+ "Service-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Enhanced-Coverage-Restriction-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3156, /* Code */
+ 10415, /* Vendor */
+ "Enhanced-Coverage-Restriction-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Monitoring-Event-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3123, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Event-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Group-Monitoring-Event-Report-Item */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3166, /* Code */
+ 10415, /* Vendor */
+ "Group-Monitoring-Event-Report-Item", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Group-Monitoring-Event-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3165, /* Code */
+ 10415, /* Vendor */
+ "Group-Monitoring-Event-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29336_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* T4-Parameters */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "T4-Parameters"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Priority-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-RP-SMEA"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Restricted-PLMN-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Restricted-PLMN-List"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* NIDD-Authorization-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "NIDD-Authorization-Response"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "External-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Granted-Validity-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* User-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "User-Identifier"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "External-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Type-Of-External-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Scheduled-Communication-Time */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Scheduled-Communication-Time"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Day-Of-Week-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Time-Of-Day-Start"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Time-Of-Day-End"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Allowed-PLMN-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Allowed-PLMN-List"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* NIDD-Authorization-Update */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "NIDD-Authorization-Update"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "External-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Granted-Validity-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Location-Information-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Location-Information-Configuration"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MONTE-Location-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Accuracy"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* NIDD-Authorization-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "NIDD-Authorization-Request"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Service-Selection"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requested-Validity-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Supported-Services */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Supported-Services"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Supported-Monitoring-Events"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Node-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* UE-Reachability-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "UE-Reachability-Configuration"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Reachability-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-Latency"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-Response-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Service-Result */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Service-Result"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Vendor-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Result-Code"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Service-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Service-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Service-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Node-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Enhanced-Coverage-Restriction */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Enhanced-Coverage-Restriction"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Restricted-PLMN-List"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Allowed-PLMN-List"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Communication-Pattern-Set */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Communication-Pattern-Set"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Periodic-Communication-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Communication-Duration-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Periodic-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Scheduled-Communication-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Stationary-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reference-ID-Validity-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* T4-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "T4-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "HSS-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Additional-Serving-Node"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Service-Parameters */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Service-Parameters"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "T4-Parameters"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Port-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Monitoring-Event-Configuration */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Configuration"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID-for-Deletion"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-Number-of-Reports"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Duration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charged-Party"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-Detection-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Reachability-Configuration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Location-Information-Configuration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Association-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DL-Buffering-Suggested-Packet-Count"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* AESE-Error-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "AESE-Error-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Service-Result"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Monitoring-Event-Config-Status */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Config-Status"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Service-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* AESE-Communication-Pattern */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "AESE-Communication-Pattern"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID-for-Deletion"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Communication-Pattern-Set"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* AESE-Communication-Pattern-Config-Status */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "AESE-Communication-Pattern-Config-Status"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AESE-Error-Report"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Service-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Service-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "T4-Data"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Enhanced-Coverage-Restriction-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Enhanced-Coverage-Restriction-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Enhanced-Coverage-Restriction"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Monitoring-Event-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Roaming-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMEI-Change"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reachability-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-UE-Availability-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "EPS-Location-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event-Handling"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Loss-Of-Connectivity-Reason"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Group-Monitoring-Event-Report-Item */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Group-Monitoring-Event-Report-Item"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "User-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Roaming-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reachability-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-UE-Availability-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "EPS-Location-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Report"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "S6t-HSS-Cause"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Group-Monitoring-Event-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Group-Monitoring-Event-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Group-Monitoring-Event-Report-Item"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29336_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29336_avps_load_defs(conffile);
+ return dict_ts29336_avps_load_rules(conffile);
+}
+
+const char* dict_proto_ver(char * conffile) {
+ return ts29336_avps_proto_ver;
+}
+
+const double dict_gen_ts(char * conffile) {
+ return ts29336_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29336_avps", dict_ts29336_avps_load_defs, dict_ts29336_avps_load_rules, "dict_ts32299_avps", "dict_ts29272_avps", "dict_ts29338_avps", "dict_ts29329_avps", "dict_ts29368_avps", "dict_ts29229_avps", "dict_ts29217_avps", "dict_ts29173_avps", "dict_rfc5778_avps", "dict_draftload_avps", "dict_rfc5777_avps", "dict_rfc7683_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29336_avps/ts29336_avps.did b/extensions/dict_ts29336_avps/ts29336_avps.did
new file mode 100644
index 0000000..24bab4c
--- /dev/null
+++ b/extensions/dict_ts29336_avps/ts29336_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
diff --git a/extensions/dict_ts29337_avps/CMakeLists.txt b/extensions/dict_ts29337_avps/CMakeLists.txt
new file mode 100644
index 0000000..4c2b69b
--- /dev/null
+++ b/extensions/dict_ts29337_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29337_avps extension
+PROJECT("dict_ts29337_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29337_avps dict_ts29337_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29337_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29337_AVPS)
+
+
+
diff --git a/extensions/dict_ts29337_avps/dict_ts29337_avps.c b/extensions/dict_ts29337_avps/dict_ts29337_avps.c
new file mode 100644
index 0000000..ae60b55
--- /dev/null
+++ b/extensions/dict_ts29337_avps/dict_ts29337_avps.c
@@ -0,0 +1,248 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29337_avps (e00).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e00"
+#define GEN_DATE 1506697153.25
+
+const char *ts29337_avps_proto_ver = PROTO_VER;
+const double ts29337_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29337_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* SM-Delivery-Outcome-T4 */
+ {
+ struct dict_avp_data data = {
+ 3200, /* Code */
+ 10415, /* Vendor */
+ "SM-Delivery-Outcome-T4", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-Delivery-Outcome-T4)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ABSENT_SUBSCRIBER", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "UE_MEMORY_CAPACITY_EXCEEDED", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "SUCCESSFUL_TRANSFER", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "VALIDITY_TIME_EXPIRED", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Absent-Subscriber-Diagnostic-T4 */
+ {
+ struct dict_avp_data data = {
+ 3201, /* Code */
+ 10415, /* Vendor */
+ "Absent-Subscriber-Diagnostic-T4", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Absent-Subscriber-Diagnostic-T4)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ORIGINAL_MESSAGE_NOT_DELETED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NEW_MESSAGE_NOT_STORED", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "REPLACE", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "UE_PURGED", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "ROAMING_RESTRICTION", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "UNIDENTIFIED_SUBSCRIBER", { .i32=5 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Trigger-Action */
+ {
+ struct dict_avp_data data = {
+ 3202, /* Code */
+ 10415, /* Vendor */
+ "Trigger-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MTC-Error-Diagnostic */
+ {
+ struct dict_avp_data data = {
+ 3203, /* Code */
+ 10415, /* Vendor */
+ "MTC-Error-Diagnostic", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29337_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29337_avps (e00)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29337_avps_load_defs(conffile);
+ return dict_ts29337_avps_load_rules(conffile);
+}
+
+const char* dict_ts29337_avps_proto_ver(char * conffile) {
+ return ts29337_avps_proto_ver;
+}
+
+const double dict_ts29337_avps_gen_ts(char * conffile) {
+ return ts29337_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29337_avps", dict_ts29337_avps_load_defs, dict_ts29337_avps_load_rules, "dict_ts29336_avps", "dict_ts29338_avps", "dict_ts29272_avps", "dict_ts29368_avps", "dict_ts29229_avps", "dict_ts29173_avps", "dict_rfc4006bis_avps", "dict_rfc7155_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29337_avps/ts29337_avps.did b/extensions/dict_ts29337_avps/ts29337_avps.did
new file mode 100644
index 0000000..065f753
--- /dev/null
+++ b/extensions/dict_ts29337_avps/ts29337_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29173_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc5447_avps
+dict_rfc5778_avps
+dict_rfc5777_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29337_avps
diff --git a/extensions/dict_ts29338_avps/CMakeLists.txt b/extensions/dict_ts29338_avps/CMakeLists.txt
new file mode 100644
index 0000000..c58b332
--- /dev/null
+++ b/extensions/dict_ts29338_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29338_avps extension
+PROJECT("dict_ts29338_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29338_avps dict_ts29338_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29338_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29338_AVPS)
+
+
+
diff --git a/extensions/dict_ts29338_avps/dict_ts29338_avps.c b/extensions/dict_ts29338_avps/dict_ts29338_avps.c
new file mode 100644
index 0000000..a29863f
--- /dev/null
+++ b/extensions/dict_ts29338_avps/dict_ts29338_avps.c
@@ -0,0 +1,732 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29338_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697156.63
+
+const char *ts29338_avps_proto_ver = PROTO_VER;
+const double ts29338_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29338_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* SM-RP-MTI */
+ {
+ struct dict_avp_data data = {
+ 3308, /* Code */
+ 10415, /* Vendor */
+ "SM-RP-MTI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-RP-MTI)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SM_DELIVER", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SM_STATUS_REPORT", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SM-RP-SMEA */
+ {
+ struct dict_avp_data data = {
+ 3309, /* Code */
+ 10415, /* Vendor */
+ "SM-RP-SMEA", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SRR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3310, /* Code */
+ 10415, /* Vendor */
+ "SRR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Delivery-Not-Intended */
+ {
+ struct dict_avp_data data = {
+ 3311, /* Code */
+ 10415, /* Vendor */
+ "SM-Delivery-Not-Intended", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-Delivery-Not-Intended)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ONLY_IMSI_REQUESTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ONLY_MCC_MNC_REQUESTED", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MWD-Status */
+ {
+ struct dict_avp_data data = {
+ 3312, /* Code */
+ 10415, /* Vendor */
+ "MWD-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MME-Absent-User-Diagnostic-SM */
+ {
+ struct dict_avp_data data = {
+ 3313, /* Code */
+ 10415, /* Vendor */
+ "MME-Absent-User-Diagnostic-SM", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MSC-Absent-User-Diagnostic-SM */
+ {
+ struct dict_avp_data data = {
+ 3314, /* Code */
+ 10415, /* Vendor */
+ "MSC-Absent-User-Diagnostic-SM", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SGSN-Absent-User-Diagnostic-SM */
+ {
+ struct dict_avp_data data = {
+ 3315, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Absent-User-Diagnostic-SM", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Delivery-Cause */
+ {
+ struct dict_avp_data data = {
+ 3321, /* Code */
+ 10415, /* Vendor */
+ "SM-Delivery-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-Delivery-Cause)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MEMORY_CAPACITY_EXCEEDED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ABSENT_USER", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "SUCCESSFUL_TRANSFER", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Absent-User-Diagnostic-SM */
+ {
+ struct dict_avp_data data = {
+ 3322, /* Code */
+ 10415, /* Vendor */
+ "Absent-User-Diagnostic-SM", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* RDR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3323, /* Code */
+ 10415, /* Vendor */
+ "RDR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Maximum-UE-Availability-Time */
+ {
+ struct dict_avp_data data = {
+ 3329, /* Code */
+ 10415, /* Vendor */
+ "Maximum-UE-Availability-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* SMS-GMSC-Alert-Event */
+ {
+ struct dict_avp_data data = {
+ 3333, /* Code */
+ 10415, /* Vendor */
+ "SMS-GMSC-Alert-Event", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SC-Address */
+ {
+ struct dict_avp_data data = {
+ 3300, /* Code */
+ 10415, /* Vendor */
+ "SC-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-RP-UI */
+ {
+ struct dict_avp_data data = {
+ 3301, /* Code */
+ 10415, /* Vendor */
+ "SM-RP-UI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TFR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3302, /* Code */
+ 10415, /* Vendor */
+ "TFR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Enumerated-Delivery-Failure-Cause */
+ {
+ struct dict_avp_data data = {
+ 3304, /* Code */
+ 10415, /* Vendor */
+ "SM-Enumerated-Delivery-Failure-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-Enumerated-Delivery-Failure-Cause)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MEMORY_CAPACITY_EXCEEDED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "EQUIPMENT_PROTOCOL_ERROR", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "EQUIPMENT_NOT_SM_EQUIPPED", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "UNKNOWN_SERVICE_CENTRE", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "SC_CONGESTION", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "INVALID_SME_ADDRESS", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "USER_NOT_SC_USER", { .i32=6 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SM-Diagnostic-Info */
+ {
+ struct dict_avp_data data = {
+ 3305, /* Code */
+ 10415, /* Vendor */
+ "SM-Diagnostic-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Delivery-Timer */
+ {
+ struct dict_avp_data data = {
+ 3306, /* Code */
+ 10415, /* Vendor */
+ "SM-Delivery-Timer", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Delivery-Start-Time */
+ {
+ struct dict_avp_data data = {
+ 3307, /* Code */
+ 10415, /* Vendor */
+ "SM-Delivery-Start-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* HSS-ID */
+ {
+ struct dict_avp_data data = {
+ 3325, /* Code */
+ 10415, /* Vendor */
+ "HSS-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Originating-SIP-URI */
+ {
+ struct dict_avp_data data = {
+ 3326, /* Code */
+ 10415, /* Vendor */
+ "Originating-SIP-URI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Destination-SIP-URI */
+ {
+ struct dict_avp_data data = {
+ 3327, /* Code */
+ 10415, /* Vendor */
+ "Destination-SIP-URI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* OFR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3328, /* Code */
+ 10415, /* Vendor */
+ "OFR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Maximum-Retransmission-Time */
+ {
+ struct dict_avp_data data = {
+ 3330, /* Code */
+ 10415, /* Vendor */
+ "Maximum-Retransmission-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Requested-Retransmission-Time */
+ {
+ struct dict_avp_data data = {
+ 3331, /* Code */
+ 10415, /* Vendor */
+ "Requested-Retransmission-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* SMS-GMSC-Address */
+ {
+ struct dict_avp_data data = {
+ 3332, /* Code */
+ 10415, /* Vendor */
+ "SMS-GMSC-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SGSN-SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3319, /* Code */
+ 10415, /* Vendor */
+ "SGSN-SM-Delivery-Outcome", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SM-Delivery-Failure-Cause */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3303, /* Code */
+ 10415, /* Vendor */
+ "SM-Delivery-Failure-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SMSMI-Correlation-ID */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3324, /* Code */
+ 10415, /* Vendor */
+ "SMSMI-Correlation-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* IP-SM-GW-SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3320, /* Code */
+ 10415, /* Vendor */
+ "IP-SM-GW-SM-Delivery-Outcome", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MSC-SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3318, /* Code */
+ 10415, /* Vendor */
+ "MSC-SM-Delivery-Outcome", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MME-SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3317, /* Code */
+ 10415, /* Vendor */
+ "MME-SM-Delivery-Outcome", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3316, /* Code */
+ 10415, /* Vendor */
+ "SM-Delivery-Outcome", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29338_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* SGSN-SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SGSN-SM-Delivery-Outcome"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Absent-User-Diagnostic-SM"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SM-Delivery-Failure-Cause */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SM-Delivery-Failure-Cause"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SM-Enumerated-Delivery-Failure-Cause"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Diagnostic-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SMSMI-Correlation-ID */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SMSMI-Correlation-ID"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "HSS-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Originating-SIP-URI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Destination-SIP-URI"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* IP-SM-GW-SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "IP-SM-GW-SM-Delivery-Outcome"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Absent-User-Diagnostic-SM"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MSC-SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MSC-SM-Delivery-Outcome"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Absent-User-Diagnostic-SM"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MME-SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MME-SM-Delivery-Outcome"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SM-Delivery-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Absent-User-Diagnostic-SM"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SM-Delivery-Outcome */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SM-Delivery-Outcome"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MME-SM-Delivery-Outcome"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSC-SM-Delivery-Outcome"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-SM-Delivery-Outcome"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-SM-GW-SM-Delivery-Outcome"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29338_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29338_avps_load_defs(conffile);
+ return dict_ts29338_avps_load_rules(conffile);
+}
+
+const char* dict_ts29338_avps_proto_ver(char * conffile) {
+ return ts29338_avps_proto_ver;
+}
+
+const double dict_ts29338_avps_gen_ts(char * conffile) {
+ return ts29338_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29338_avps", dict_ts29338_avps_load_defs, dict_ts29338_avps_load_rules, "dict_ts29272_avps", "dict_ts29336_avps", "dict_ts29173_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29338_avps/ts29338_avps.did b/extensions/dict_ts29338_avps/ts29338_avps.did
new file mode 100644
index 0000000..7319bee
--- /dev/null
+++ b/extensions/dict_ts29338_avps/ts29338_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29338_avps
diff --git a/extensions/dict_ts29343_avps/CMakeLists.txt b/extensions/dict_ts29343_avps/CMakeLists.txt
new file mode 100644
index 0000000..320d3cf
--- /dev/null
+++ b/extensions/dict_ts29343_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29343_avps extension
+PROJECT("dict_ts29343_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29343_avps dict_ts29343_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29343_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29343_AVPS)
+
+
+
diff --git a/extensions/dict_ts29343_avps/dict_ts29343_avps.c b/extensions/dict_ts29343_avps/dict_ts29343_avps.c
new file mode 100644
index 0000000..c128ba5
--- /dev/null
+++ b/extensions/dict_ts29343_avps/dict_ts29343_avps.c
@@ -0,0 +1,375 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29343_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697159.87
+
+const char *ts29343_avps_proto_ver = PROTO_VER;
+const double ts29343_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29343_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Origin-App-Layer-User-Id */
+ {
+ struct dict_avp_data data = {
+ 3600, /* Code */
+ 10415, /* Vendor */
+ "Origin-App-Layer-User-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Target-App-Layer-User-Id */
+ {
+ struct dict_avp_data data = {
+ 3601, /* Code */
+ 10415, /* Vendor */
+ "Target-App-Layer-User-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* ProSe-Function-ID */
+ {
+ struct dict_avp_data data = {
+ 3602, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Function-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Request-Type */
+ {
+ struct dict_avp_data data = {
+ 3603, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Request-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PDUID */
+ {
+ struct dict_avp_data data = {
+ 3604, /* Code */
+ 10415, /* Vendor */
+ "PDUID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Application-Data */
+ {
+ struct dict_avp_data data = {
+ 3605, /* Code */
+ 10415, /* Vendor */
+ "Application-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Allowed-Suffixes-Number */
+ {
+ struct dict_avp_data data = {
+ 3606, /* Code */
+ 10415, /* Vendor */
+ "Allowed-Suffixes-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Suffix-Code */
+ {
+ struct dict_avp_data data = {
+ 3609, /* Code */
+ 10415, /* Vendor */
+ "Suffix-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Suffix-Mask */
+ {
+ struct dict_avp_data data = {
+ 3610, /* Code */
+ 10415, /* Vendor */
+ "Suffix-Mask", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Metadata-Indicator */
+ {
+ struct dict_avp_data data = {
+ 3612, /* Code */
+ 10415, /* Vendor */
+ "Metadata-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Code-Suffix-Mask */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3608, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Code-Suffix-Mask", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Banned-User-Target */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3611, /* Code */
+ 10415, /* Vendor */
+ "Banned-User-Target", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Monitor-Target */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3607, /* Code */
+ 10415, /* Vendor */
+ "Monitor-Target", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29343_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* ProSe-Code-Suffix-Mask */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ProSe-Code-Suffix-Mask"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Suffix-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Suffix-Mask"}, RULE_REQUIRED, 1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Banned-User-Target */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Banned-User-Target"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Target-RPAUID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Target-PDUID"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Monitor-Target */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Monitor-Target"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Target-RPAUID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDUID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Metadata-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Code-Suffix-Mask"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29343_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29343_avps_load_defs(conffile);
+ return dict_ts29343_avps_load_rules(conffile);
+}
+
+const char* dict_ts29343_avps_proto_ver(char * conffile) {
+ return ts29343_avps_proto_ver;
+}
+
+const double dict_ts29343_avps_gen_ts(char * conffile) {
+ return ts29343_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29343_avps", dict_ts29343_avps_load_defs, dict_ts29343_avps_load_rules, "dict_ts29345_avps", "dict_draftload_avps");
+
+
+
diff --git a/extensions/dict_ts29343_avps/ts29343_avps.did b/extensions/dict_ts29343_avps/ts29343_avps.did
new file mode 100644
index 0000000..0a43883
--- /dev/null
+++ b/extensions/dict_ts29343_avps/ts29343_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29128_avps
+dict_ts29337_avps
+dict_3gpp2_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_ts29338_avps
+dict_ts29336_avps
+dict_ts29368_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_ts29273_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29173_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_ts29344_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc4072_avps
+dict_ts29345_avps
+dict_ts29343_avps
diff --git a/extensions/dict_ts29344_avps/CMakeLists.txt b/extensions/dict_ts29344_avps/CMakeLists.txt
new file mode 100644
index 0000000..657962e
--- /dev/null
+++ b/extensions/dict_ts29344_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29344_avps extension
+PROJECT("dict_ts29344_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29344_avps dict_ts29344_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29344_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29344_AVPS)
+
+
+
diff --git a/extensions/dict_ts29344_avps/dict_ts29344_avps.c b/extensions/dict_ts29344_avps/dict_ts29344_avps.c
new file mode 100644
index 0000000..e0a0aa6
--- /dev/null
+++ b/extensions/dict_ts29344_avps/dict_ts29344_avps.c
@@ -0,0 +1,317 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29344_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697162.59
+
+const char *ts29344_avps_proto_ver = PROTO_VER;
+const double ts29344_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29344_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* ProSe-Permission */
+ {
+ struct dict_avp_data data = {
+ 3702, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Permission", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Direct-Allowed */
+ {
+ struct dict_avp_data data = {
+ 3704, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Direct-Allowed", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UPR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3705, /* Code */
+ 10415, /* Vendor */
+ "UPR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PNR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3706, /* Code */
+ 10415, /* Vendor */
+ "PNR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Authorized-Discovery-Range */
+ {
+ struct dict_avp_data data = {
+ 3708, /* Code */
+ 10415, /* Vendor */
+ "Authorized-Discovery-Range", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Initial-Location-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3707, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Initial-Location-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ProSe-Allowed-PLMN */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3703, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Allowed-PLMN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ProSe-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3701, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Subscription-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29344_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* ProSe-Initial-Location-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ProSe-Initial-Location-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MME-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "E-UTRAN-Cell-Global-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Tracking-Area-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Age-Of-Location-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ProSe-Allowed-PLMN */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ProSe-Allowed-PLMN"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Authorized-Discovery-Range"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Direct-Allowed"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ProSe-Subscription-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ProSe-Subscription-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Permission"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Allowed-PLMN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29344_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29344_avps_load_defs(conffile);
+ return dict_ts29344_avps_load_rules(conffile);
+}
+
+const char* dict_ts29344_avps_proto_ver(char * conffile) {
+ return ts29344_avps_proto_ver;
+}
+
+const double dict_ts29344_avps_gen_ts(char * conffile) {
+ return ts29344_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29344_avps", dict_ts29344_avps_load_defs, dict_ts29344_avps_load_rules, "dict_ts29272_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_ts29173_avps", "dict_ts29061_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29344_avps/ts29344_avps.did b/extensions/dict_ts29344_avps/ts29344_avps.did
new file mode 100644
index 0000000..b548b53
--- /dev/null
+++ b/extensions/dict_ts29344_avps/ts29344_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29345_avps
+dict_ts29337_avps
+dict_3gpp2_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_ts29338_avps
+dict_ts29336_avps
+dict_ts29368_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29173_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_ts29344_avps
diff --git a/extensions/dict_ts29345_avps/CMakeLists.txt b/extensions/dict_ts29345_avps/CMakeLists.txt
new file mode 100644
index 0000000..52410c9
--- /dev/null
+++ b/extensions/dict_ts29345_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29345_avps extension
+PROJECT("dict_ts29345_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29345_avps dict_ts29345_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29345_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29345_AVPS)
+
+
+
diff --git a/extensions/dict_ts29345_avps/dict_ts29345_avps.c b/extensions/dict_ts29345_avps/dict_ts29345_avps.c
new file mode 100644
index 0000000..f3991d4
--- /dev/null
+++ b/extensions/dict_ts29345_avps/dict_ts29345_avps.c
@@ -0,0 +1,1300 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29345_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697165.68
+
+const char *ts29345_avps_proto_ver = PROTO_VER;
+const double ts29345_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29345_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* App-Layer-User-Id */
+ {
+ struct dict_avp_data data = {
+ 3801, /* Code */
+ 10415, /* Vendor */
+ "App-Layer-User-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Assistance-Info-Validity-Timer */
+ {
+ struct dict_avp_data data = {
+ 3803, /* Code */
+ 10415, /* Vendor */
+ "Assistance-Info-Validity-Timer", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Discovery-Type */
+ {
+ struct dict_avp_data data = {
+ 3804, /* Code */
+ 10415, /* Vendor */
+ "Discovery-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Filter-Id */
+ {
+ struct dict_avp_data data = {
+ 3805, /* Code */
+ 10415, /* Vendor */
+ "Filter-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MAC-Address */
+ {
+ struct dict_avp_data data = {
+ 3806, /* Code */
+ 10415, /* Vendor */
+ "MAC-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Operating-Channel */
+ {
+ struct dict_avp_data data = {
+ 3808, /* Code */
+ 10415, /* Vendor */
+ "Operating-Channel", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* P2P-Features */
+ {
+ struct dict_avp_data data = {
+ 3809, /* Code */
+ 10415, /* Vendor */
+ "P2P-Features", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-App-Code */
+ {
+ struct dict_avp_data data = {
+ 3810, /* Code */
+ 10415, /* Vendor */
+ "ProSe-App-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-App-Id */
+ {
+ struct dict_avp_data data = {
+ 3811, /* Code */
+ 10415, /* Vendor */
+ "ProSe-App-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* ProSe-App-Mask */
+ {
+ struct dict_avp_data data = {
+ 3812, /* Code */
+ 10415, /* Vendor */
+ "ProSe-App-Mask", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PRR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3814, /* Code */
+ 10415, /* Vendor */
+ "PRR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Validity-Timer */
+ {
+ struct dict_avp_data data = {
+ 3815, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Validity-Timer", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Requesting-EPUID */
+ {
+ struct dict_avp_data data = {
+ 3816, /* Code */
+ 10415, /* Vendor */
+ "Requesting-EPUID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Targeted-EPUID */
+ {
+ struct dict_avp_data data = {
+ 3817, /* Code */
+ 10415, /* Vendor */
+ "Targeted-EPUID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Time-Window */
+ {
+ struct dict_avp_data data = {
+ 3818, /* Code */
+ 10415, /* Vendor */
+ "Time-Window", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* WLAN-Link-Layer-Id */
+ {
+ struct dict_avp_data data = {
+ 3821, /* Code */
+ 10415, /* Vendor */
+ "WLAN-Link-Layer-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Location-Update-Event-Type */
+ {
+ struct dict_avp_data data = {
+ 3824, /* Code */
+ 10415, /* Vendor */
+ "Location-Update-Event-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Location-Update-Event-Trigger */
+ {
+ struct dict_avp_data data = {
+ 3826, /* Code */
+ 10415, /* Vendor */
+ "Location-Update-Event-Trigger", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Report-Cardinality */
+ {
+ struct dict_avp_data data = {
+ 3827, /* Code */
+ 10415, /* Vendor */
+ "Report-Cardinality", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Report-Cardinality)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SINGLE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MULTIPLE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Minimum-Interval-Time */
+ {
+ struct dict_avp_data data = {
+ 3828, /* Code */
+ 10415, /* Vendor */
+ "Minimum-Interval-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Location-Report-Interval-Time */
+ {
+ struct dict_avp_data data = {
+ 3830, /* Code */
+ 10415, /* Vendor */
+ "Location-Report-Interval-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Total-Number-Of-Reports */
+ {
+ struct dict_avp_data data = {
+ 3831, /* Code */
+ 10415, /* Vendor */
+ "Total-Number-Of-Reports", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Validity-Time-Announce */
+ {
+ struct dict_avp_data data = {
+ 3832, /* Code */
+ 10415, /* Vendor */
+ "Validity-Time-Announce", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Validity-Time-Monitor */
+ {
+ struct dict_avp_data data = {
+ 3833, /* Code */
+ 10415, /* Vendor */
+ "Validity-Time-Monitor", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Validity-Time-Communication */
+ {
+ struct dict_avp_data data = {
+ 3834, /* Code */
+ 10415, /* Vendor */
+ "Validity-Time-Communication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIC */
+ {
+ struct dict_avp_data data = {
+ 3836, /* Code */
+ 10415, /* Vendor */
+ "MIC", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UTC-based-Counter */
+ {
+ struct dict_avp_data data = {
+ 3837, /* Code */
+ 10415, /* Vendor */
+ "UTC-based-Counter", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Match-Refresh-Timer */
+ {
+ struct dict_avp_data data = {
+ 3838, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Match-Refresh-Timer", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Metadata-Index-Mask */
+ {
+ struct dict_avp_data data = {
+ 3839, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Metadata-Index-Mask", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* OS-ID */
+ {
+ struct dict_avp_data data = {
+ 3841, /* Code */
+ 10415, /* Vendor */
+ "OS-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* OS-App-ID */
+ {
+ struct dict_avp_data data = {
+ 3842, /* Code */
+ 10415, /* Vendor */
+ "OS-App-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Requesting-RPAUID */
+ {
+ struct dict_avp_data data = {
+ 3843, /* Code */
+ 10415, /* Vendor */
+ "Requesting-RPAUID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Target-RPAUID */
+ {
+ struct dict_avp_data data = {
+ 3844, /* Code */
+ 10415, /* Vendor */
+ "Target-RPAUID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Target-PDUID */
+ {
+ struct dict_avp_data data = {
+ 3845, /* Code */
+ 10415, /* Vendor */
+ "Target-PDUID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Restricted-Code */
+ {
+ struct dict_avp_data data = {
+ 3846, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Restricted-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Restricted-Code-Suffix-Range */
+ {
+ struct dict_avp_data data = {
+ 3847, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Restricted-Code-Suffix-Range", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Beginning-Suffix */
+ {
+ struct dict_avp_data data = {
+ 3848, /* Code */
+ 10415, /* Vendor */
+ "Beginning-Suffix", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Ending-Suffix */
+ {
+ struct dict_avp_data data = {
+ 3849, /* Code */
+ 10415, /* Vendor */
+ "Ending-Suffix", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Discovery-Entry-ID */
+ {
+ struct dict_avp_data data = {
+ 3850, /* Code */
+ 10415, /* Vendor */
+ "Discovery-Entry-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Match-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 3851, /* Code */
+ 10415, /* Vendor */
+ "Match-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* PMR-Flags */
+ {
+ struct dict_avp_data data = {
+ 3852, /* Code */
+ 10415, /* Vendor */
+ "PMR-Flags", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Application-Metadata */
+ {
+ struct dict_avp_data data = {
+ 3853, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Application-Metadata", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Banned-RPAUID */
+ {
+ struct dict_avp_data data = {
+ 3858, /* Code */
+ 10415, /* Vendor */
+ "Banned-RPAUID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Banned-PDUID */
+ {
+ struct dict_avp_data data = {
+ 3859, /* Code */
+ 10415, /* Vendor */
+ "Banned-PDUID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* DUSK */
+ {
+ struct dict_avp_data data = {
+ 3862, /* Code */
+ 10415, /* Vendor */
+ "DUSK", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* DUIK */
+ {
+ struct dict_avp_data data = {
+ 3863, /* Code */
+ 10415, /* Vendor */
+ "DUIK", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* DUCK */
+ {
+ struct dict_avp_data data = {
+ 3864, /* Code */
+ 10415, /* Vendor */
+ "DUCK", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MIC-Check-Indicator */
+ {
+ struct dict_avp_data data = {
+ 3865, /* Code */
+ 10415, /* Vendor */
+ "MIC-Check-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Encrypted-Bitmask */
+ {
+ struct dict_avp_data data = {
+ 3866, /* Code */
+ 10415, /* Vendor */
+ "Encrypted-Bitmask", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-App-Code-Suffix-Range */
+ {
+ struct dict_avp_data data = {
+ 3867, /* Code */
+ 10415, /* Vendor */
+ "ProSe-App-Code-Suffix-Range", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Query-Code */
+ {
+ struct dict_avp_data data = {
+ 9900, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Query-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ProSe-Response-Code */
+ {
+ struct dict_avp_data data = {
+ 9901, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Response-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Periodic-Location-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3829, /* Code */
+ 10415, /* Vendor */
+ "Periodic-Location-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Code-Receiving-Security-Material */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3860, /* Code */
+ 10415, /* Vendor */
+ "Code-Receiving-Security-Material", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Code-Sending-Security-Material */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3861, /* Code */
+ 10415, /* Vendor */
+ "Code-Sending-Security-Material", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Change-Of-Area-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3825, /* Code */
+ 10415, /* Vendor */
+ "Change-Of-Area-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* WLAN-Link-Layer-Id-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3822, /* Code */
+ 10415, /* Vendor */
+ "WLAN-Link-Layer-Id-List", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Match-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3856, /* Code */
+ 10415, /* Vendor */
+ "Match-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ProSe-App-Code-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3835, /* Code */
+ 10415, /* Vendor */
+ "ProSe-App-Code-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* App-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3840, /* Code */
+ 10415, /* Vendor */
+ "App-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Match-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3807, /* Code */
+ 10415, /* Vendor */
+ "Match-Report", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ProSe-Discovery-Filter */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3813, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Discovery-Filter", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Discovery-Auth-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3854, /* Code */
+ 10415, /* Vendor */
+ "Discovery-Auth-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Match-Report-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3857, /* Code */
+ 10415, /* Vendor */
+ "Match-Report-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Location-Update-Trigger */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3823, /* Code */
+ 10415, /* Vendor */
+ "Location-Update-Trigger", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* WiFi-P2P-Assistance-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3819, /* Code */
+ 10415, /* Vendor */
+ "WiFi-P2P-Assistance-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Discovery-Auth-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3855, /* Code */
+ 10415, /* Vendor */
+ "Discovery-Auth-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* WLAN-Assistance-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3820, /* Code */
+ 10415, /* Vendor */
+ "WLAN-Assistance-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Assistance-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3802, /* Code */
+ 10415, /* Vendor */
+ "Assistance-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29345_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Periodic-Location-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Periodic-Location-Type"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Location-Report-Interval-Time"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Total-Number-Of-Reports"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Code-Receiving-Security-Material */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Code-Receiving-Security-Material"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "DUSK"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DUIK"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MIC-Check-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DUCK"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Encrypted-Bitmask"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Code-Sending-Security-Material */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Code-Sending-Security-Material"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "DUSK"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DUIK"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DUCK"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Encrypted-Bitmask"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Change-Of-Area-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Change-Of-Area-Type"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Location-Update-Event-Trigger"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Report-Cardinality"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Minimum-Interval-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* WLAN-Link-Layer-Id-List */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "WLAN-Link-Layer-Id-List"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "WLAN-Link-Layer-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Match-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Match-Request"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Discovery-Type"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ProSe-App-Code-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ProSe-App-Code-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MIC"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UTC-based-Counter"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* App-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "App-Identifier"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "OS-ID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "OS-App-ID"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Match-Report */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Match-Report"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Discovery-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Metadata-Index-Mask"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Validity-Timer"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Match-Refresh-Timer"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Application-Metadata"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ProSe-Discovery-Filter */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ProSe-Discovery-Filter"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Filter-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Validity-Timer"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Code"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Mask"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Discovery-Auth-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Discovery-Auth-Request"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Discovery-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Code-Suffix-Range"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Validity-Timer"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "App-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requesting-RPAUID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Target-RPAUID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Target-PDUID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Restricted-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Query-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Response-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Restricted-Code-Suffix-Range"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Banned-RPAUID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Banned-PDUID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Result"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Match-Report-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Match-Report-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Discovery-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Location-Update-Trigger */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Location-Update-Trigger"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Location-Update-Event-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Of-Area-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Periodic-Location-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* WiFi-P2P-Assistance-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "WiFi-P2P-Assistance-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "EAP-Master-Session-Key"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "P2P-Features"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "WLAN-Link-Layer-Id-List"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "WLAN-Link-Layer-Id-List"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Operating-Channel"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Assistance-Info-Validity-Timer"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Discovery-Auth-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Discovery-Auth-Response"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Discovery-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Discovery-Filter"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Restricted-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Query-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Response-Code"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* WLAN-Assistance-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "WLAN-Assistance-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "WiFi-P2P-Assistance-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Assistance-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Assistance-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "WLAN-Assistance-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29345_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29345_avps_load_defs(conffile);
+ return dict_ts29345_avps_load_rules(conffile);
+}
+
+const char* dict_ts29345_avps_proto_ver(char * conffile) {
+ return ts29345_avps_proto_ver;
+}
+
+const double dict_ts29345_avps_gen_ts(char * conffile) {
+ return ts29345_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29345_avps", dict_ts29345_avps_load_defs, dict_ts29345_avps_load_rules, "dict_ts32299_avps", "dict_ts29272_avps", "dict_ts29273_avps", "dict_ts29336_avps", "dict_ts29344_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_draftload_avps", "dict_rfc7683_avps", "dict_rfc4072_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29345_avps/ts29345_avps.did b/extensions/dict_ts29345_avps/ts29345_avps.did
new file mode 100644
index 0000000..3108b3a
--- /dev/null
+++ b/extensions/dict_ts29345_avps/ts29345_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29337_avps
+dict_3gpp2_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_ts29338_avps
+dict_ts29336_avps
+dict_ts29368_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_ts29273_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29173_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_ts29344_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_rfc4072_avps
+dict_ts29345_avps
diff --git a/extensions/dict_ts29368_avps/CMakeLists.txt b/extensions/dict_ts29368_avps/CMakeLists.txt
new file mode 100644
index 0000000..47f7169
--- /dev/null
+++ b/extensions/dict_ts29368_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29368_avps extension
+PROJECT("dict_ts29368_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29368_avps dict_ts29368_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29368_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29368_AVPS)
+
+
+
diff --git a/extensions/dict_ts29368_avps/dict_ts29368_avps.c b/extensions/dict_ts29368_avps/dict_ts29368_avps.c
new file mode 100644
index 0000000..4ced331
--- /dev/null
+++ b/extensions/dict_ts29368_avps/dict_ts29368_avps.c
@@ -0,0 +1,446 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29368_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697146.83
+
+const char *ts29368_avps_proto_ver = PROTO_VER;
+const double ts29368_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29368_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* Payload */
+ {
+ struct dict_avp_data data = {
+ 3004, /* Code */
+ 10415, /* Vendor */
+ "Payload", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Action-Type */
+ {
+ struct dict_avp_data data = {
+ 3005, /* Code */
+ 10415, /* Vendor */
+ "Action-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Action-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Non_Priority", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Priority", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Report", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Recall", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "Replace", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "Delivery", { .i32=5 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Priority-Indication */
+ {
+ struct dict_avp_data data = {
+ 3006, /* Code */
+ 10415, /* Vendor */
+ "Priority-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Priority-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Non-Priority", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Priority", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Reference-Number */
+ {
+ struct dict_avp_data data = {
+ 3007, /* Code */
+ 10415, /* Vendor */
+ "Reference-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Request-Status */
+ {
+ struct dict_avp_data data = {
+ 3008, /* Code */
+ 10415, /* Vendor */
+ "Request-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Request-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SUCCESS", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "INVPAYLOAD", { .i32=101 }};
+ struct dict_enumval_data t_3 = { "INVEXTID", { .i32=102 }};
+ struct dict_enumval_data t_4 = { "INVSCSID", { .i32=103 }};
+ struct dict_enumval_data t_5 = { "INVPERIOD", { .i32=104 }};
+ struct dict_enumval_data t_6 = { "NOTAUTHORIZED", { .i32=105 }};
+ struct dict_enumval_data t_7 = { "SERVICEUNAVAILABLE", { .i32=106 }};
+ struct dict_enumval_data t_8 = { "PERMANENTERROR", { .i32=107 }};
+ struct dict_enumval_data t_9 = { "QUOTAEXCEEDED", { .i32=108 }};
+ struct dict_enumval_data t_10 = { "RATEEXCEEDED", { .i32=109 }};
+ struct dict_enumval_data t_11 = { "REPLACEFAIL", { .i32=110 }};
+ struct dict_enumval_data t_12 = { "RECALLFAIL", { .i32=111 }};
+ struct dict_enumval_data t_13 = { "ORIGINALMESSAGESENT", { .i32=112 }};
+ struct dict_enumval_data t_14 = { "TEMPORARYERROR", { .i32=201 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Delivery-Outcome */
+ {
+ struct dict_avp_data data = {
+ 3009, /* Code */
+ 10415, /* Vendor */
+ "Delivery-Outcome", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Delivery-Outcome)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SUCCESS", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "EXPIRED", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "TEMPORARYERROR", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "UNDELIVERABLE", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "UNCONFIRMED", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Application-Port-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3010, /* Code */
+ 10415, /* Vendor */
+ "Application-Port-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Old-Reference-Number */
+ {
+ struct dict_avp_data data = {
+ 3011, /* Code */
+ 10415, /* Vendor */
+ "Old-Reference-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Feature-Supported-In-Final-Target */
+ {
+ struct dict_avp_data data = {
+ 3012, /* Code */
+ 10415, /* Vendor */
+ "Feature-Supported-In-Final-Target", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Trigger-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3003, /* Code */
+ 10415, /* Vendor */
+ "Trigger-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Device-Notification */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3002, /* Code */
+ 10415, /* Vendor */
+ "Device-Notification", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Device-Action */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3001, /* Code */
+ 10415, /* Vendor */
+ "Device-Action", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29368_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Trigger-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Trigger-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Payload"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Priority-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Port-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Device-Notification */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Device-Notification"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "External-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCS-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reference-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Action-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Request-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MTC-Error-Diagnostic"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Delivery-Outcome"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-RP-UI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Port-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Device-Action */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Device-Action"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "External-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCS-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reference-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Old-Reference-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Action-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trigger-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Validity-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29368_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29368_avps_load_defs(conffile);
+ return dict_ts29368_avps_load_rules(conffile);
+}
+
+const char* dict_ts29368_avps_proto_ver(char * conffile) {
+ return ts29368_avps_proto_ver;
+}
+
+const double dict_ts29368_avps_gen_ts(char * conffile) {
+ return ts29368_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29368_avps", dict_ts29368_avps_load_defs, dict_ts29368_avps_load_rules, "dict_ts29337_avps", "dict_ts29336_avps", "dict_ts29338_avps", "dict_ts29329_avps", "dict_ts29229_avps", "dict_draftload_avps", "dict_rfc4006bis_avps");
+
+
+
diff --git a/extensions/dict_ts29368_avps/ts29368_avps.did b/extensions/dict_ts29368_avps/ts29368_avps.did
new file mode 100644
index 0000000..6f87787
--- /dev/null
+++ b/extensions/dict_ts29368_avps/ts29368_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29468_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29337_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts29173_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc5447_avps
+dict_rfc5778_avps
+dict_rfc5777_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
diff --git a/extensions/dict_ts29468_avps/CMakeLists.txt b/extensions/dict_ts29468_avps/CMakeLists.txt
new file mode 100644
index 0000000..0c54916
--- /dev/null
+++ b/extensions/dict_ts29468_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts29468_avps extension
+PROJECT("dict_ts29468_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts29468_avps dict_ts29468_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts29468_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS29468_AVPS)
+
+
+
diff --git a/extensions/dict_ts29468_avps/dict_ts29468_avps.c b/extensions/dict_ts29468_avps/dict_ts29468_avps.c
new file mode 100644
index 0000000..15fd2bb
--- /dev/null
+++ b/extensions/dict_ts29468_avps/dict_ts29468_avps.c
@@ -0,0 +1,639 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts29468_avps (e10).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e10"
+#define GEN_DATE 1506697168.73
+
+const char *ts29468_avps_proto_ver = PROTO_VER;
+const double ts29468_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts29468_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* BMSC-Address */
+ {
+ struct dict_avp_data data = {
+ 3500, /* Code */
+ 10415, /* Vendor */
+ "BMSC-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* BMSC-Port */
+ {
+ struct dict_avp_data data = {
+ 3501, /* Code */
+ 10415, /* Vendor */
+ "BMSC-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Common-Tunnel-Endpoint-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3524, /* Code */
+ 10415, /* Vendor */
+ "Common-Tunnel-Endpoint-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MB2U-Security */
+ {
+ struct dict_avp_data data = {
+ 3517, /* Code */
+ 10415, /* Vendor */
+ "MB2U-Security", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Bearer-Event */
+ {
+ struct dict_avp_data data = {
+ 3502, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Bearer-Event", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-Bearer-Result */
+ {
+ struct dict_avp_data data = {
+ 3506, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Bearer-Result", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MBMS-eNB-IP-Multicast-Address */
+ {
+ struct dict_avp_data data = {
+ 3520, /* Code */
+ 10415, /* Vendor */
+ "MBMS-eNB-IP-Multicast-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* MBMS-eNB-IPv6-Multicast-Address */
+ {
+ struct dict_avp_data data = {
+ 3521, /* Code */
+ 10415, /* Vendor */
+ "MBMS-eNB-IPv6-Multicast-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* MBMS-GW-SSM-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 3522, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GW-SSM-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* MBMS-GW-SSM-IPv6-Address */
+ {
+ struct dict_avp_data data = {
+ 3523, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GW-SSM-IPv6-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* MBMS-Start-Time */
+ {
+ struct dict_avp_data data = {
+ 3507, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Start-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Radio-Frequency */
+ {
+ struct dict_avp_data data = {
+ 3508, /* Code */
+ 10415, /* Vendor */
+ "Radio-Frequency", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TMGI-Allocation-Result */
+ {
+ struct dict_avp_data data = {
+ 3511, /* Code */
+ 10415, /* Vendor */
+ "TMGI-Allocation-Result", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TMGI-Deallocation-Result */
+ {
+ struct dict_avp_data data = {
+ 3514, /* Code */
+ 10415, /* Vendor */
+ "TMGI-Deallocation-Result", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TMGI-Number */
+ {
+ struct dict_avp_data data = {
+ 3516, /* Code */
+ 10415, /* Vendor */
+ "TMGI-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* TMGI-Expiry */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3515, /* Code */
+ 10415, /* Vendor */
+ "TMGI-Expiry", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Local-MB2-U-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3519, /* Code */
+ 10415, /* Vendor */
+ "Local-MB2-U-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MBMS-Bearer-Event-Notification */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3503, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Bearer-Event-Notification", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MBMS-Bearer-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3505, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Bearer-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TMGI-Deallocation-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3513, /* Code */
+ 10415, /* Vendor */
+ "TMGI-Deallocation-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TMGI-Allocation-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3509, /* Code */
+ 10415, /* Vendor */
+ "TMGI-Allocation-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TMGI-Deallocation-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3512, /* Code */
+ 10415, /* Vendor */
+ "TMGI-Deallocation-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Local-M1-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3518, /* Code */
+ 10415, /* Vendor */
+ "Local-M1-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TMGI-Allocation-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3510, /* Code */
+ 10415, /* Vendor */
+ "TMGI-Allocation-Response", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MBMS-Bearer-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3504, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Bearer-Request", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts29468_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* TMGI-Expiry */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TMGI-Expiry"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TMGI"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Local-MB2-U-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Local-MB2-U-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "BMSC-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "BMSC-Port"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MBMS-Bearer-Event-Notification */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MBMS-Bearer-Event-Notification"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TMGI"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Flow-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Bearer-Event"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MBMS-Bearer-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MBMS-Bearer-Response"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TMGI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Flow-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Session-Duration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Bearer-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "BMSC-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "BMSC-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MB2U-Security"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Radio-Frequency"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TMGI-Deallocation-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TMGI-Deallocation-Response"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TMGI"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TMGI-Deallocation-Result"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TMGI-Allocation-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TMGI-Allocation-Request"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TMGI-Number"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TMGI"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TMGI-Deallocation-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TMGI-Deallocation-Request"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TMGI"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Local-M1-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Local-M1-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MBMS-eNB-IP-Multicast-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-eNB-IPv6-Multicast-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-GW-SSM-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-GW-SSM-IPv6-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Common-Tunnel-Endpoint-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TMGI-Allocation-Response */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TMGI-Allocation-Response"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TMGI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Session-Duration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TMGI-Allocation-Result"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MBMS-Bearer-Request */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MBMS-Bearer-Request"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MBMS-StartStop-Indication"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TMGI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Flow-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Service-Area"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Start-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MB2U-Security"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Cell-List"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Local-M1-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Local-MB2-U-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts29468_avps (e10)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts29468_avps_load_defs(conffile);
+ return dict_ts29468_avps_load_rules(conffile);
+}
+
+const char* dict_ts29468_avps_proto_ver(char * conffile) {
+ return ts29468_avps_proto_ver;
+}
+
+const double dict_ts29468_avps_gen_ts(char * conffile) {
+ return ts29468_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts29468_avps", dict_ts29468_avps_load_defs, dict_ts29468_avps_load_rules, "dict_ts29212_avps", "dict_ts29229_avps", "dict_ts29061_avps", "dict_draftload_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts29468_avps/ts29468_avps.did b/extensions/dict_ts29468_avps/ts29468_avps.did
new file mode 100644
index 0000000..3b6a01f
--- /dev/null
+++ b/extensions/dict_ts29468_avps/ts29468_avps.did
@@ -0,0 +1,37 @@
+dict_rfc6942_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_ts29215_avps
+dict_ts29217_avps
+dict_3gpp2_avps
+dict_ts29343_avps
+dict_ts29338_avps
+dict_ts29128_avps
+dict_ts29344_avps
+dict_ts29345_avps
+dict_ts32299_avps
+dict_rfc6734_avps
+dict_rfc5778_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_ts29173_avps
+dict_ts29337_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_ts29229_avps
+dict_draftload_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts29336_avps
+dict_ts29061_avps
+dict_rfc5447_avps
+dict_ts29272_avps
+dict_rfc7683_avps
+dict_rfc7944_avps
+dict_rfc5777_avps
+dict_rfc4006bis_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29212_avps
+dict_ts29468_avps
diff --git a/extensions/dict_ts32299_avps/CMakeLists.txt b/extensions/dict_ts32299_avps/CMakeLists.txt
new file mode 100644
index 0000000..3ee6973
--- /dev/null
+++ b/extensions/dict_ts32299_avps/CMakeLists.txt
@@ -0,0 +1,16 @@
+# The dict_ts32299_avps extension
+PROJECT("dict_ts32299_avps library generated by FdGen " C)
+
+# Compile as a module
+FD_ADD_EXTENSION(dict_ts32299_avps dict_ts32299_avps.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS dict_ts32299_avps
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+COMPONENT freeDiameter-dictionary-TS32299_AVPS)
+
+
+
diff --git a/extensions/dict_ts32299_avps/dict_ts32299_avps.c b/extensions/dict_ts32299_avps/dict_ts32299_avps.c
new file mode 100644
index 0000000..d81140a
--- /dev/null
+++ b/extensions/dict_ts32299_avps/dict_ts32299_avps.c
@@ -0,0 +1,7604 @@
+/*
+* Copyright (c) 2017 Sprint
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/****************
+ Generated By: fdtool enhancements to diafuzzer
+ License: same as freeDiameter
+****************/
+
+
+/*
+ * Dictionary definitions of objects specified in ts32299_avps (e30).
+ */
+#include <freeDiameter/extension.h>
+
+#define PROTO_VER "e30"
+#define GEN_DATE 1506697143.39
+
+const char *ts32299_avps_proto_ver = PROTO_VER;
+const double ts32299_avps_gen_date = GEN_DATE;
+
+/* The content of this file follows the same structure as dict_base_proto.c */
+
+#define CHECK_dict_new( _type, _data, _parent, _ref ) \
+{ \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref) ); \
+ if ( _ret != 0 && _ret != EEXIST ) \
+ return _ret; \
+}
+
+#define CHECK_dict_search( _type, _criteria, _what, _result ) \
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
+
+struct local_rules_definition {
+ struct dict_avp_request avp_vendor_plus_name;
+ enum rule_position position;
+ int min;
+ int max;
+};
+
+#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
+
+/* Attention! This version of the macro uses AVP_BY_NAME_AND_VENDOR, in contrast to most other copies! */
+#define PARSE_loc_rules( _rulearray, _parent) { \
+ int __ar; \
+ for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
+ struct dict_rule_data __data = { NULL, \
+ (_rulearray)[__ar].position, \
+ 0, \
+ (_rulearray)[__ar].min, \
+ (_rulearray)[__ar].max}; \
+ __data.rule_order = RULE_ORDER(__data.rule_position); \
+ CHECK_FCT( fd_dict_search( \
+ fd_g_config->cnf_dict, \
+ DICT_AVP, \
+ AVP_BY_NAME_AND_VENDOR, \
+ &(_rulearray)[__ar].avp_vendor_plus_name, \
+ &__data.rule_avp, 0 ) ); \
+ if ( !__data.rule_avp ) { \
+ TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return ENOENT; \
+ } \
+ { \
+ int _ret = fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &(__data), (_parent), NULL ); \
+ if ( _ret != 0 && _ret != EEXIST ) { \
+ TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
+ (_rulearray)[__ar].avp_vendor_plus_name.avp_name); \
+ return EINVAL; \
+ } \
+ } \
+ } \
+}
+
+#define CHECK_vendor_new( _data ) { \
+ struct dict_object * vendor_found; \
+ if (fd_dict_search(fd_g_config->cnf_dict,DICT_VENDOR,VENDOR_BY_ID,&_data.vendor_id,&vendor_found,ENOENT) == ENOENT) { \
+ CHECK_FCT(fd_dict_new(fd_g_config->cnf_dict, DICT_VENDOR, &_data, NULL, NULL)); \
+ } \
+}
+
+#define enumval_def_u32( _val_, _str_ ) \
+ { _str_, { .u32 = _val_ }}
+
+#define enumval_def_os( _len_, _val_, _str_ ) \
+ { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
+
+
+static int dict_ts32299_avps_load_defs(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ /* Application Section */
+ {
+ /* Create the vendors */ {
+ struct dict_vendor_data vendor_data = { 10415, "3GPP" };
+ CHECK_dict_new(DICT_VENDOR, &vendor_data, NULL, NULL)
+ }
+ }
+
+
+ /* AVP section */
+ {
+ struct dict_object * Address_type;
+ struct dict_object * UTF8String_type;
+ struct dict_object * DiameterIdentity_type;
+ struct dict_object * DiameterURI_type;
+ struct dict_object * Time_type;
+ struct dict_object * IPFilterRule_type;
+
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "UTF8String", &UTF8String_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterIdentity", &DiameterIdentity_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "DiameterURI", &DiameterURI_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Time", &Time_type);
+ CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "IPFilterRule", &IPFilterRule_type);
+ /* 3GPP-PS-Data-Off-Status */
+ {
+ struct dict_avp_data data = {
+ 4406, /* Code */
+ 10415, /* Vendor */
+ "3GPP-PS-Data-Off-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(3GPP-PS-Data-Off-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Active", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Inactive", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Access-Network-Information */
+ {
+ struct dict_avp_data data = {
+ 1263, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Access-Transfer-Type */
+ {
+ struct dict_avp_data data = {
+ 2710, /* Code */
+ 10415, /* Vendor */
+ "Access-Transfer-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Access-Transfer-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "PS_to_CS_Transfer", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CS_to_PS_Transfer", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "PS_to_PS_Transfer", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "CS_to_CS_Transfer", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Account-Expiration */
+ {
+ struct dict_avp_data data = {
+ 2309, /* Code */
+ 10415, /* Vendor */
+ "Account-Expiration", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Adaptations */
+ {
+ struct dict_avp_data data = {
+ 1217, /* Code */
+ 10415, /* Vendor */
+ "Adaptations", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Adaptations)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Yes", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "No", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Additional-Exception-Reports */
+ {
+ struct dict_avp_data data = {
+ 3936, /* Code */
+ 10415, /* Vendor */
+ "Additional-Exception-Reports", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Additional-Exception-Reports)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Not_allowed", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Allowed", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Additional-Type-Information */
+ {
+ struct dict_avp_data data = {
+ 1205, /* Code */
+ 10415, /* Vendor */
+ "Additional-Type-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Address-Data */
+ {
+ struct dict_avp_data data = {
+ 897, /* Code */
+ 10415, /* Vendor */
+ "Address-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Addressee-Type */
+ {
+ struct dict_avp_data data = {
+ 1208, /* Code */
+ 10415, /* Vendor */
+ "Addressee-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Addressee-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "TO", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CC", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "BCC", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Address-Type */
+ {
+ struct dict_avp_data data = {
+ 899, /* Code */
+ 10415, /* Vendor */
+ "Address-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Address-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "e_mail_address", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MSISDN", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "IPv4_Address", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "IPv6_Address", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "Numeric_Shortcode", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "Alphanumeric_Shortcode", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "Other", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "IMSI", { .i32=7 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Alternate-Charged-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 1280, /* Code */
+ 10415, /* Vendor */
+ "Alternate-Charged-Party-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Announcement-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3905, /* Code */
+ 10415, /* Vendor */
+ "Announcement-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Announcement-Order */
+ {
+ struct dict_avp_data data = {
+ 3906, /* Code */
+ 10415, /* Vendor */
+ "Announcement-Order", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Announcing-UE-HPLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3426, /* Code */
+ 10415, /* Vendor */
+ "Announcing-UE-HPLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Announcing-UE-VPLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3427, /* Code */
+ 10415, /* Vendor */
+ "Announcing-UE-VPLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* AoC-Format */
+ {
+ struct dict_avp_data data = {
+ 2310, /* Code */
+ 10415, /* Vendor */
+ "AoC-Format", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AoC-Format)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "MONETARY", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NON_MONETARY", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "CAI", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* AoC-Request-Type */
+ {
+ struct dict_avp_data data = {
+ 2055, /* Code */
+ 10415, /* Vendor */
+ "AoC-Request-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AoC-Request-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "AoC_NOT_REQUESTED", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "AoC_FULL", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "AoC_COST_ONLY", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "AoC_TARIFF_ONLY", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* AoC-Service-Obligatory-Type */
+ {
+ struct dict_avp_data data = {
+ 2312, /* Code */
+ 10415, /* Vendor */
+ "AoC-Service-Obligatory-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AoC-Service-Obligatory-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NON_BINDING", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "BINDING", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* AoC-Service-Type */
+ {
+ struct dict_avp_data data = {
+ 2313, /* Code */
+ 10415, /* Vendor */
+ "AoC-Service-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(AoC-Service-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NONE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "AOC-S", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "AOC-D", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "AOC-E", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Applic-ID */
+ {
+ struct dict_avp_data data = {
+ 1218, /* Code */
+ 10415, /* Vendor */
+ "Applic-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Application-Provided-Called-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 837, /* Code */
+ 10415, /* Vendor */
+ "Application-Provided-Called-Party-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Application-Server */
+ {
+ struct dict_avp_data data = {
+ 836, /* Code */
+ 10415, /* Vendor */
+ "Application-Server", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Application-Specific-Data */
+ {
+ struct dict_avp_data data = {
+ 3458, /* Code */
+ 10415, /* Vendor */
+ "Application-Specific-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Associated-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 2035, /* Code */
+ 10415, /* Vendor */
+ "Associated-Party-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Associated-URI */
+ {
+ struct dict_avp_data data = {
+ 856, /* Code */
+ 10415, /* Vendor */
+ "Associated-URI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Authorised-QoS */
+ {
+ struct dict_avp_data data = {
+ 849, /* Code */
+ 10415, /* Vendor */
+ "Authorised-QoS", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Aux-Applic-Info */
+ {
+ struct dict_avp_data data = {
+ 1219, /* Code */
+ 10415, /* Vendor */
+ "Aux-Applic-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Base-Time-Interval */
+ {
+ struct dict_avp_data data = {
+ 1265, /* Code */
+ 10415, /* Vendor */
+ "Base-Time-Interval", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Bearer-Capability */
+ {
+ struct dict_avp_data data = {
+ 3412, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Capability", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Bearer-Service */
+ {
+ struct dict_avp_data data = {
+ 854, /* Code */
+ 10415, /* Vendor */
+ "Bearer-Service", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* BSSID */
+ {
+ struct dict_avp_data data = {
+ 2716, /* Code */
+ 10415, /* Vendor */
+ "BSSID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Called-Asserted-Identity */
+ {
+ struct dict_avp_data data = {
+ 1250, /* Code */
+ 10415, /* Vendor */
+ "Called-Asserted-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Called-Identity */
+ {
+ struct dict_avp_data data = {
+ 3916, /* Code */
+ 10415, /* Vendor */
+ "Called-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Called-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 832, /* Code */
+ 10415, /* Vendor */
+ "Called-Party-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Calling-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 831, /* Code */
+ 10415, /* Vendor */
+ "Calling-Party-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Carrier-Select-Routing-Information */
+ {
+ struct dict_avp_data data = {
+ 2023, /* Code */
+ 10415, /* Vendor */
+ "Carrier-Select-Routing-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Cause-Code */
+ {
+ struct dict_avp_data data = {
+ 861, /* Code */
+ 10415, /* Vendor */
+ "Cause-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Cellular-Network-Information */
+ {
+ struct dict_avp_data data = {
+ 3924, /* Code */
+ 10415, /* Vendor */
+ "Cellular-Network-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* CG-Address */
+ {
+ struct dict_avp_data data = {
+ 846, /* Code */
+ 10415, /* Vendor */
+ "CG-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Change-Condition */
+ {
+ struct dict_avp_data data = {
+ 2037, /* Code */
+ 10415, /* Vendor */
+ "Change-Condition", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Change-Time */
+ {
+ struct dict_avp_data data = {
+ 2038, /* Code */
+ 10415, /* Vendor */
+ "Change-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Charge-Reason-Code */
+ {
+ struct dict_avp_data data = {
+ 2118, /* Code */
+ 10415, /* Vendor */
+ "Charge-Reason-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Charge-Reason-Code)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UNKNOWN", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "USAGE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "COMMUNICATION_ATTEMPT_CHARGE", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "SETUP_CHARGE", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "ADD_ON_CHARGE", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Charged-Party */
+ {
+ struct dict_avp_data data = {
+ 857, /* Code */
+ 10415, /* Vendor */
+ "Charged-Party", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Charging-Characteristics-Selection-Mode */
+ {
+ struct dict_avp_data data = {
+ 2066, /* Code */
+ 10415, /* Vendor */
+ "Charging-Characteristics-Selection-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Charging-Characteristics-Selection-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Serving_Node_Supplied", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Subscription_specific", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "APN_specific", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Home_Default", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "Roaming_Default", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "Visiting_Default", { .i32=5 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Charging-Per-IP-CAN-Session-Indicator */
+ {
+ struct dict_avp_data data = {
+ 4400, /* Code */
+ 10415, /* Vendor */
+ "Charging-Per-IP-CAN-Session-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Charging-Per-IP-CAN-Session-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Inactive", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Active", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Class-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1214, /* Code */
+ 10415, /* Vendor */
+ "Class-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Class-Identifier)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Personal", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Advertisement", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Informational", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Auto", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Client-Address */
+ {
+ struct dict_avp_data data = {
+ 2018, /* Code */
+ 10415, /* Vendor */
+ "Client-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* CN-Operator-Selection-Entity */
+ {
+ struct dict_avp_data data = {
+ 3421, /* Code */
+ 10415, /* Vendor */
+ "CN-Operator-Selection-Entity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CN-Operator-Selection-Entity)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "The_Serving_Network_has_been_selected_by_the_UE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "The_Serving_Network_has_been_selected_by_the_network", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Content-Class */
+ {
+ struct dict_avp_data data = {
+ 1220, /* Code */
+ 10415, /* Vendor */
+ "Content-Class", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Content-Class)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "text", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "image_basic", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "image_rich", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "video_basic", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "video_rich", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "megapixel", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "content_basic", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "content_rich", { .i32=7 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Content-Disposition */
+ {
+ struct dict_avp_data data = {
+ 828, /* Code */
+ 10415, /* Vendor */
+ "Content-Disposition", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Content-Length */
+ {
+ struct dict_avp_data data = {
+ 827, /* Code */
+ 10415, /* Vendor */
+ "Content-Length", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Content-Size */
+ {
+ struct dict_avp_data data = {
+ 1206, /* Code */
+ 10415, /* Vendor */
+ "Content-Size", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Content-Type */
+ {
+ struct dict_avp_data data = {
+ 826, /* Code */
+ 10415, /* Vendor */
+ "Content-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Coverage-Status */
+ {
+ struct dict_avp_data data = {
+ 3428, /* Code */
+ 10415, /* Vendor */
+ "Coverage-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Coverage-Status)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Out_of_coverage", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "In_coverage", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CP-CIoT-EPS-Optimisation-Indicator */
+ {
+ struct dict_avp_data data = {
+ 3930, /* Code */
+ 10415, /* Vendor */
+ "CP-CIoT-EPS-Optimisation-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CP-CIoT-EPS-Optimisation-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Not_Apply", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Apply", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CSG-Access-Mode */
+ {
+ struct dict_avp_data data = {
+ 2317, /* Code */
+ 10415, /* Vendor */
+ "CSG-Access-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CSG-Access-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Closed_mode", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Hybrid_Mode", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CSG-Membership-Indication */
+ {
+ struct dict_avp_data data = {
+ 2318, /* Code */
+ 10415, /* Vendor */
+ "CSG-Membership-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(CSG-Membership-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Not_CSG_member", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CSG_Member", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* CUG-Information */
+ {
+ struct dict_avp_data data = {
+ 2304, /* Code */
+ 10415, /* Vendor */
+ "CUG-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Data-Coding-Scheme */
+ {
+ struct dict_avp_data data = {
+ 2001, /* Code */
+ 10415, /* Vendor */
+ "Data-Coding-Scheme", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Deferred-Location-Event-Type */
+ {
+ struct dict_avp_data data = {
+ 1230, /* Code */
+ 10415, /* Vendor */
+ "Deferred-Location-Event-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Delivery-Report-Requested */
+ {
+ struct dict_avp_data data = {
+ 1216, /* Code */
+ 10415, /* Vendor */
+ "Delivery-Report-Requested", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Delivery-Report-Requested)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "No", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Yes", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Diagnostics */
+ {
+ struct dict_avp_data data = {
+ 2039, /* Code */
+ 10415, /* Vendor */
+ "Diagnostics", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Discoveree-UE-HPLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 4402, /* Code */
+ 10415, /* Vendor */
+ "Discoveree-UE-HPLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Discoveree-UE-VPLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 4403, /* Code */
+ 10415, /* Vendor */
+ "Discoveree-UE-VPLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Discoverer-UE-HPLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 4404, /* Code */
+ 10415, /* Vendor */
+ "Discoverer-UE-HPLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Discoverer-UE-VPLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 4405, /* Code */
+ 10415, /* Vendor */
+ "Discoverer-UE-VPLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Domain-Name */
+ {
+ struct dict_avp_data data = {
+ 1200, /* Code */
+ 10415, /* Vendor */
+ "Domain-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* DRM-Content */
+ {
+ struct dict_avp_data data = {
+ 1221, /* Code */
+ 10415, /* Vendor */
+ "DRM-Content", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(DRM-Content)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "No", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Yes", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Dynamic-Address-Flag */
+ {
+ struct dict_avp_data data = {
+ 2051, /* Code */
+ 10415, /* Vendor */
+ "Dynamic-Address-Flag", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Dynamic-Address-Flag)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Static", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Dynamic", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Dynamic-Address-Flag-Extension */
+ {
+ struct dict_avp_data data = {
+ 2068, /* Code */
+ 10415, /* Vendor */
+ "Dynamic-Address-Flag-Extension", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Dynamic-Address-Flag-Extension)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Static", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Dynamic", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Envelope-End-Time */
+ {
+ struct dict_avp_data data = {
+ 1267, /* Code */
+ 10415, /* Vendor */
+ "Envelope-End-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Envelope-Reporting */
+ {
+ struct dict_avp_data data = {
+ 1268, /* Code */
+ 10415, /* Vendor */
+ "Envelope-Reporting", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Envelope-Reporting)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DO_NOT_REPORT_ENVELOPES", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "REPORT_ENVELOPES", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "REPORT_ENVELOPES_WITH_VOLUME", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "REPORT_ENVELOPES_WITH_EVENTS", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "REPORT_ENVELOPES_WITH_VOLUME_AND_EVENTS", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Envelope-Start-Time */
+ {
+ struct dict_avp_data data = {
+ 1269, /* Code */
+ 10415, /* Vendor */
+ "Envelope-Start-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* EPDG-Address */
+ {
+ struct dict_avp_data data = {
+ 3425, /* Code */
+ 10415, /* Vendor */
+ "EPDG-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Event */
+ {
+ struct dict_avp_data data = {
+ 825, /* Code */
+ 10415, /* Vendor */
+ "Event", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Event-Charging-TimeStamp */
+ {
+ struct dict_avp_data data = {
+ 1258, /* Code */
+ 10415, /* Vendor */
+ "Event-Charging-TimeStamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Expires */
+ {
+ struct dict_avp_data data = {
+ 888, /* Code */
+ 10415, /* Vendor */
+ "Expires", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* File-Repair-Supported */
+ {
+ struct dict_avp_data data = {
+ 1224, /* Code */
+ 10415, /* Vendor */
+ "File-Repair-Supported", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(File-Repair-Supported)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SUPPORTED", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "NOT_SUPPORTED", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Forwarding-Pending */
+ {
+ struct dict_avp_data data = {
+ 3415, /* Code */
+ 10415, /* Vendor */
+ "Forwarding-Pending", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Forwarding-Pending)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Forwarding_not_pending", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Forwarding_pending", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* From-Address */
+ {
+ struct dict_avp_data data = {
+ 2708, /* Code */
+ 10415, /* Vendor */
+ "From-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* GGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 847, /* Code */
+ 10415, /* Vendor */
+ "GGSN-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* IMS-Application-Reference-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2601, /* Code */
+ 10415, /* Vendor */
+ "IMS-Application-Reference-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* IMS-Charging-Identifier */
+ {
+ struct dict_avp_data data = {
+ 841, /* Code */
+ 10415, /* Vendor */
+ "IMS-Charging-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* IMS-Communication-Service-Identifier */
+ {
+ struct dict_avp_data data = {
+ 1281, /* Code */
+ 10415, /* Vendor */
+ "IMS-Communication-Service-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* IMS-Emergency-Indicator */
+ {
+ struct dict_avp_data data = {
+ 2322, /* Code */
+ 10415, /* Vendor */
+ "IMS-Emergency-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IMS-Emergency-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Non_Emergency", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Emergency", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* IMS-Visited-Network-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2713, /* Code */
+ 10415, /* Vendor */
+ "IMS-Visited-Network-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* IMSI-Unauthenticated-Flag */
+ {
+ struct dict_avp_data data = {
+ 2308, /* Code */
+ 10415, /* Vendor */
+ "IMSI-Unauthenticated-Flag", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IMSI-Unauthenticated-Flag)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Authenticated", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Unauthenticated", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Incoming-Trunk-Group-Id */
+ {
+ struct dict_avp_data data = {
+ 852, /* Code */
+ 10415, /* Vendor */
+ "Incoming-Trunk-Group-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Initial-IMS-Charging-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2321, /* Code */
+ 10415, /* Vendor */
+ "Initial-IMS-Charging-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Instance-Id */
+ {
+ struct dict_avp_data data = {
+ 3402, /* Code */
+ 10415, /* Vendor */
+ "Instance-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Interface-Id */
+ {
+ struct dict_avp_data data = {
+ 2003, /* Code */
+ 10415, /* Vendor */
+ "Interface-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Interface-Port */
+ {
+ struct dict_avp_data data = {
+ 2004, /* Code */
+ 10415, /* Vendor */
+ "Interface-Port", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Interface-Text */
+ {
+ struct dict_avp_data data = {
+ 2005, /* Code */
+ 10415, /* Vendor */
+ "Interface-Text", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Interface-Type */
+ {
+ struct dict_avp_data data = {
+ 2006, /* Code */
+ 10415, /* Vendor */
+ "Interface-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Interface-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Unknown", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "MOBILE_ORIGINATING", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "MOBILE_TERMINATING", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "APPLICATION_ORIGINATING", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "APPLICATION_TERMINATION", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Inter-UE-Transfer */
+ {
+ struct dict_avp_data data = {
+ 3902, /* Code */
+ 10415, /* Vendor */
+ "Inter-UE-Transfer", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Inter-UE-Transfer)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Intra_UE_transfer", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Inter_UE_transfer", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* IP-Realm-Default-Indication */
+ {
+ struct dict_avp_data data = {
+ 2603, /* Code */
+ 10415, /* Vendor */
+ "IP-Realm-Default-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(IP-Realm-Default-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Default_IP_Realm_Not_used", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Default_IP_realm_used", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ISUP-Cause-Diagnostics */
+ {
+ struct dict_avp_data data = {
+ 3422, /* Code */
+ 10415, /* Vendor */
+ "ISUP-Cause-Diagnostics", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ISUP-Cause-Location */
+ {
+ struct dict_avp_data data = {
+ 3423, /* Code */
+ 10415, /* Vendor */
+ "ISUP-Cause-Location", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ISUP-Cause-Value */
+ {
+ struct dict_avp_data data = {
+ 3424, /* Code */
+ 10415, /* Vendor */
+ "ISUP-Cause-Value", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* ISUP-Location-Number */
+ {
+ struct dict_avp_data data = {
+ 3414, /* Code */
+ 10415, /* Vendor */
+ "ISUP-Location-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Language */
+ {
+ struct dict_avp_data data = {
+ 3914, /* Code */
+ 10415, /* Vendor */
+ "Language", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Layer-2-Group-ID */
+ {
+ struct dict_avp_data data = {
+ 3429, /* Code */
+ 10415, /* Vendor */
+ "Layer-2-Group-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* LCS-APN */
+ {
+ struct dict_avp_data data = {
+ 1231, /* Code */
+ 10415, /* Vendor */
+ "LCS-APN", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* LCS-Client-Dialed-By-MS */
+ {
+ struct dict_avp_data data = {
+ 1233, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-Dialed-By-MS", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* LCS-Client-External-ID */
+ {
+ struct dict_avp_data data = {
+ 1234, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-External-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* LCS-Client-Type */
+ {
+ struct dict_avp_data data = {
+ 1241, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(LCS-Client-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "EMERGENCY_SERVICES", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "VALUE_ADDED_SERVICES", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "PLMN_OPERATOR_SERVICES", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "LAWFUL_INTERCEPT_SERVICES", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* LCS-Data-Coding-Scheme */
+ {
+ struct dict_avp_data data = {
+ 1236, /* Code */
+ 10415, /* Vendor */
+ "LCS-Data-Coding-Scheme", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* LCS-Format-Indicator */
+ {
+ struct dict_avp_data data = {
+ 1237, /* Code */
+ 10415, /* Vendor */
+ "LCS-Format-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(LCS-Format-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "LOGICAL_NAME", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "EMAIL_ADDRESS", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "MSISDN", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "URL", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "SIP_URL", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* LCS-Name-String */
+ {
+ struct dict_avp_data data = {
+ 1238, /* Code */
+ 10415, /* Vendor */
+ "LCS-Name-String", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* LCS-Requestor-ID-String */
+ {
+ struct dict_avp_data data = {
+ 1240, /* Code */
+ 10415, /* Vendor */
+ "LCS-Requestor-ID-String", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Local-GW-Inserted-Indication */
+ {
+ struct dict_avp_data data = {
+ 2604, /* Code */
+ 10415, /* Vendor */
+ "Local-GW-Inserted-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Local-GW-Inserted-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Local_GW_Not_Inserted", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Local_GW_Inserted", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Local-Sequence-Number */
+ {
+ struct dict_avp_data data = {
+ 2063, /* Code */
+ 10415, /* Vendor */
+ "Local-Sequence-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Location-Estimate */
+ {
+ struct dict_avp_data data = {
+ 1242, /* Code */
+ 10415, /* Vendor */
+ "Location-Estimate", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Location-Estimate-Type */
+ {
+ struct dict_avp_data data = {
+ 1243, /* Code */
+ 10415, /* Vendor */
+ "Location-Estimate-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Location-Estimate-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CURRENT_LOCATION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CURRENT_LAST_KNOWN_LOCATION", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "INITIAL_LOCATION", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "ACTIVATE_DEFERRED_LOCATION", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "CANCEL_DEFERRED_LOCATION", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Low-Balance-Indication */
+ {
+ struct dict_avp_data data = {
+ 2020, /* Code */
+ 10415, /* Vendor */
+ "Low-Balance-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Low-Balance-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NOT_APPLICABLE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "YES", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Low-Priority-Indicator */
+ {
+ struct dict_avp_data data = {
+ 2602, /* Code */
+ 10415, /* Vendor */
+ "Low-Priority-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Low-Priority-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NO", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "YES", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-Charged-Party */
+ {
+ struct dict_avp_data data = {
+ 2323, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Charged-Party", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-Charged-Party)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Content_Provider", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Subscriber", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MBMS-GW-Address */
+ {
+ struct dict_avp_data data = {
+ 2307, /* Code */
+ 10415, /* Vendor */
+ "MBMS-GW-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* MBMS-User-Service-Type */
+ {
+ struct dict_avp_data data = {
+ 1225, /* Code */
+ 10415, /* Vendor */
+ "MBMS-User-Service-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MBMS-User-Service-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DOWNLOAD", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "STREAMING", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Media-Initiator-Flag */
+ {
+ struct dict_avp_data data = {
+ 882, /* Code */
+ 10415, /* Vendor */
+ "Media-Initiator-Flag", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Media-Initiator-Flag)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "called_party", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "calling_party", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "unknown", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Media-Initiator-Party */
+ {
+ struct dict_avp_data data = {
+ 1288, /* Code */
+ 10415, /* Vendor */
+ "Media-Initiator-Party", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Message-ID */
+ {
+ struct dict_avp_data data = {
+ 1210, /* Code */
+ 10415, /* Vendor */
+ "Message-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Message-Size */
+ {
+ struct dict_avp_data data = {
+ 1212, /* Code */
+ 10415, /* Vendor */
+ "Message-Size", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Message-Type */
+ {
+ struct dict_avp_data data = {
+ 1211, /* Code */
+ 10415, /* Vendor */
+ "Message-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Message-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "m_send_req", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "m_forward_req", { .i32=10 }};
+ struct dict_enumval_data t_3 = { "m_forward_conf", { .i32=11 }};
+ struct dict_enumval_data t_4 = { "m_mbox_store_conf", { .i32=12 }};
+ struct dict_enumval_data t_5 = { "m_mbox_view_conf", { .i32=13 }};
+ struct dict_enumval_data t_6 = { "m_mbox_upload_conf", { .i32=14 }};
+ struct dict_enumval_data t_7 = { "m_mbox_delete_conf", { .i32=15 }};
+ struct dict_enumval_data t_8 = { "m_send_conf", { .i32=2 }};
+ struct dict_enumval_data t_9 = { "m_notification_ind", { .i32=3 }};
+ struct dict_enumval_data t_10 = { "m_notifyresp_ind", { .i32=4 }};
+ struct dict_enumval_data t_11 = { "m_retrieve_conf", { .i32=5 }};
+ struct dict_enumval_data t_12 = { "m_acknowledge_ind", { .i32=6 }};
+ struct dict_enumval_data t_13 = { "m_delivery_ind", { .i32=7 }};
+ struct dict_enumval_data t_14 = { "m_read_rec_ind", { .i32=8 }};
+ struct dict_enumval_data t_15 = { "m_read_orig_ind", { .i32=9 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MMBox-Storage-Requested */
+ {
+ struct dict_avp_data data = {
+ 1248, /* Code */
+ 10415, /* Vendor */
+ "MMBox-Storage-Requested", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(MMBox-Storage-Requested)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "No", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Yes", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* MMTel-SService-Type */
+ {
+ struct dict_avp_data data = {
+ 2031, /* Code */
+ 10415, /* Vendor */
+ "MMTel-SService-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Monitored-PLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3430, /* Code */
+ 10415, /* Vendor */
+ "Monitored-PLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Monitoring-Event-Configuration-Activity */
+ {
+ struct dict_avp_data data = {
+ 3919, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Event-Configuration-Activity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Monitoring-Event-Functionality */
+ {
+ struct dict_avp_data data = {
+ 3922, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Event-Functionality", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Monitoring-Event-Report-Number */
+ {
+ struct dict_avp_data data = {
+ 3923, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Event-Report-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Monitoring-UE-HPLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3431, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-UE-HPLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Monitoring-UE-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3432, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-UE-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Monitoring-UE-VPLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3433, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-UE-VPLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* MSC-Address */
+ {
+ struct dict_avp_data data = {
+ 3417, /* Code */
+ 10415, /* Vendor */
+ "MSC-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* MTC-IWF-Address */
+ {
+ struct dict_avp_data data = {
+ 3406, /* Code */
+ 10415, /* Vendor */
+ "MTC-IWF-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Neighbour-Node-Address */
+ {
+ struct dict_avp_data data = {
+ 2705, /* Code */
+ 10415, /* Vendor */
+ "Neighbour-Node-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Network-Call-Reference-Number */
+ {
+ struct dict_avp_data data = {
+ 3418, /* Code */
+ 10415, /* Vendor */
+ "Network-Call-Reference-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* NNI-Type */
+ {
+ struct dict_avp_data data = {
+ 2704, /* Code */
+ 10415, /* Vendor */
+ "NNI-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(NNI-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "non_roaming", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "roaming_without_loopback", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "roaming_with_loopback", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Node-Functionality */
+ {
+ struct dict_avp_data data = {
+ 862, /* Code */
+ 10415, /* Vendor */
+ "Node-Functionality", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Node-Functionality)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "S-CSCF", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "P-CSCF", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "I-CSCF", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "MRFC", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "MGCF", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "BGCF", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "AS", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "IBCF", { .i32=7 }};
+ struct dict_enumval_data t_9 = { "S-GW", { .i32=8 }};
+ struct dict_enumval_data t_10 = { "P-GW", { .i32=9 }};
+ struct dict_enumval_data t_11 = { "HSGW", { .i32=10 }};
+ struct dict_enumval_data t_12 = { "E-CSCF", { .i32=11 }};
+ struct dict_enumval_data t_13 = { "MME", { .i32=12 }};
+ struct dict_enumval_data t_14 = { "TRF", { .i32=13 }};
+ struct dict_enumval_data t_15 = { "TF", { .i32=14 }};
+ struct dict_enumval_data t_16 = { "ATCF", { .i32=15 }};
+ struct dict_enumval_data t_17 = { "Proxy-function", { .i32=16 }};
+ struct dict_enumval_data t_18 = { "ePDG", { .i32=17 }};
+ struct dict_enumval_data t_19 = { "TDF", { .i32=18 }};
+ struct dict_enumval_data t_20 = { "TWAG", { .i32=19 }};
+ struct dict_enumval_data t_21 = { "SCEF", { .i32=20 }};
+ struct dict_enumval_data t_22 = { "IWK-SCEF", { .i32=21 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Node-Id */
+ {
+ struct dict_avp_data data = {
+ 2064, /* Code */
+ 10415, /* Vendor */
+ "Node-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Number-Of-Diversions */
+ {
+ struct dict_avp_data data = {
+ 2034, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Diversions", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Number-Of-Messages-Sent */
+ {
+ struct dict_avp_data data = {
+ 2019, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Messages-Sent", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Number-Of-Participants */
+ {
+ struct dict_avp_data data = {
+ 885, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Participants", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Number-Of-Received-Talk-Bursts */
+ {
+ struct dict_avp_data data = {
+ 1282, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Received-Talk-Bursts", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Number-Of-Talk-Bursts */
+ {
+ struct dict_avp_data data = {
+ 1283, /* Code */
+ 10415, /* Vendor */
+ "Number-Of-Talk-Bursts", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Number-Portability-Routing-Information */
+ {
+ struct dict_avp_data data = {
+ 2024, /* Code */
+ 10415, /* Vendor */
+ "Number-Portability-Routing-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Online-Charging-Flag */
+ {
+ struct dict_avp_data data = {
+ 2303, /* Code */
+ 10415, /* Vendor */
+ "Online-Charging-Flag", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Online-Charging-Flag)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ECF_address_not_provided", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ECF_address_provided", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Originating-IOI */
+ {
+ struct dict_avp_data data = {
+ 839, /* Code */
+ 10415, /* Vendor */
+ "Originating-IOI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Originator */
+ {
+ struct dict_avp_data data = {
+ 864, /* Code */
+ 10415, /* Vendor */
+ "Originator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Originator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Calling_Party", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Called_Party", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Originator-SCCP-Address */
+ {
+ struct dict_avp_data data = {
+ 2008, /* Code */
+ 10415, /* Vendor */
+ "Originator-SCCP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Outgoing-Session-Id */
+ {
+ struct dict_avp_data data = {
+ 2320, /* Code */
+ 10415, /* Vendor */
+ "Outgoing-Session-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Outgoing-Trunk-Group-Id */
+ {
+ struct dict_avp_data data = {
+ 853, /* Code */
+ 10415, /* Vendor */
+ "Outgoing-Trunk-Group-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Participant-Access-Priority */
+ {
+ struct dict_avp_data data = {
+ 1259, /* Code */
+ 10415, /* Vendor */
+ "Participant-Access-Priority", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Participant-Access-Priority)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Pre_emptive_priority", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "High_priority", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "Normal_priority", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "Low_priority", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Participant-Action-Type */
+ {
+ struct dict_avp_data data = {
+ 2049, /* Code */
+ 10415, /* Vendor */
+ "Participant-Action-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Participant-Action-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CREATE_CONF", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "JOIN_CONF", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "INVITE_INTO_CONF", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "QUIT_CONF", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Participants-Involved */
+ {
+ struct dict_avp_data data = {
+ 887, /* Code */
+ 10415, /* Vendor */
+ "Participants-Involved", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* PC3-Control-Protocol-Cause */
+ {
+ struct dict_avp_data data = {
+ 3434, /* Code */
+ 10415, /* Vendor */
+ "PC3-Control-Protocol-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PC3-EPC-Control-Protocol-Cause */
+ {
+ struct dict_avp_data data = {
+ 3435, /* Code */
+ 10415, /* Vendor */
+ "PC3-EPC-Control-Protocol-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PDN-Connection-Charging-ID */
+ {
+ struct dict_avp_data data = {
+ 2050, /* Code */
+ 10415, /* Vendor */
+ "PDN-Connection-Charging-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PDP-Address */
+ {
+ struct dict_avp_data data = {
+ 1227, /* Code */
+ 10415, /* Vendor */
+ "PDP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* PDP-Address-Prefix-Length */
+ {
+ struct dict_avp_data data = {
+ 2606, /* Code */
+ 10415, /* Vendor */
+ "PDP-Address-Prefix-Length", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* PDP-Context-Type */
+ {
+ struct dict_avp_data data = {
+ 1247, /* Code */
+ 10415, /* Vendor */
+ "PDP-Context-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PDP-Context-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Primary", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Secondary", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Play-Alternative */
+ {
+ struct dict_avp_data data = {
+ 3913, /* Code */
+ 10415, /* Vendor */
+ "Play-Alternative", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Play-Alternative)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "served_party", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "remote_party", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PoC-Change-Condition */
+ {
+ struct dict_avp_data data = {
+ 1261, /* Code */
+ 10415, /* Vendor */
+ "PoC-Change-Condition", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Change-Condition)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ServiceChange", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "VolumeLimit", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "TimeLimit", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "NumberofTalkBurstLimit", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "NumberofActiveParticipants", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "TariffTime", { .i32=5 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PoC-Change-Time */
+ {
+ struct dict_avp_data data = {
+ 1262, /* Code */
+ 10415, /* Vendor */
+ "PoC-Change-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* PoC-Controlling-Address */
+ {
+ struct dict_avp_data data = {
+ 858, /* Code */
+ 10415, /* Vendor */
+ "PoC-Controlling-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* PoC-Event-Type */
+ {
+ struct dict_avp_data data = {
+ 2025, /* Code */
+ 10415, /* Vendor */
+ "PoC-Event-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Event-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Normal", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Instant_Personal_Alert", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "PoC_Group_Advertisement", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Early_Session_Setting_Up", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "PoC_Talk_Burst", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PoC-Group-Name */
+ {
+ struct dict_avp_data data = {
+ 859, /* Code */
+ 10415, /* Vendor */
+ "PoC-Group-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* PoC-Server-Role */
+ {
+ struct dict_avp_data data = {
+ 883, /* Code */
+ 10415, /* Vendor */
+ "PoC-Server-Role", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Server-Role)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Participating_PoC_Server", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Controlling_PoC_Server", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PoC-Session-Id */
+ {
+ struct dict_avp_data data = {
+ 1229, /* Code */
+ 10415, /* Vendor */
+ "PoC-Session-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* PoC-Session-Initiation-Type */
+ {
+ struct dict_avp_data data = {
+ 1277, /* Code */
+ 10415, /* Vendor */
+ "PoC-Session-Initiation-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Session-Initiation-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Pre_established", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "On_demand", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PoC-Session-Type */
+ {
+ struct dict_avp_data data = {
+ 884, /* Code */
+ 10415, /* Vendor */
+ "PoC-Session-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-Session-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "1_to_1_PoC", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Chat_PoC_Group", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Pre_arranged_PoC_Group", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Ad_hoc_PoC_Gropu", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PoC-User-Role-IDs */
+ {
+ struct dict_avp_data data = {
+ 1253, /* Code */
+ 10415, /* Vendor */
+ "PoC-User-Role-IDs", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* PoC-User-Role-Info-Units */
+ {
+ struct dict_avp_data data = {
+ 1254, /* Code */
+ 10415, /* Vendor */
+ "PoC-User-Role-Info-Units", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PoC-User-Role-Info-Units)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Moderator", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "Dispatcher", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "Session_Owner", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "Session_Participant", { .i32=4 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Positioning-Data */
+ {
+ struct dict_avp_data data = {
+ 1245, /* Code */
+ 10415, /* Vendor */
+ "Positioning-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Preferred-AoC-Currency */
+ {
+ struct dict_avp_data data = {
+ 2315, /* Code */
+ 10415, /* Vendor */
+ "Preferred-AoC-Currency", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Priority */
+ {
+ struct dict_avp_data data = {
+ 1209, /* Code */
+ 10415, /* Vendor */
+ "Priority", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Priority)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Low", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Normal", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "High", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Privacy-Indicator */
+ {
+ struct dict_avp_data data = {
+ 3915, /* Code */
+ 10415, /* Vendor */
+ "Privacy-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Privacy-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "NOT_PRIVATE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PRIVATE", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ProSe-3rd-Party-Application-ID */
+ {
+ struct dict_avp_data data = {
+ 3440, /* Code */
+ 10415, /* Vendor */
+ "ProSe-3rd-Party-Application-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* ProSe-Direct-Discovery-Model */
+ {
+ struct dict_avp_data data = {
+ 3442, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Direct-Discovery-Model", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(ProSe-Direct-Discovery-Model)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Model_A", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Model_B", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ProSe-Event-Type */
+ {
+ struct dict_avp_data data = {
+ 3443, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Event-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(ProSe-Event-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Annoucing", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Monitoring", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Match_Report", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ProSe-Function-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 3444, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Function-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* ProSe-Function-PLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3457, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Function-PLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* ProSe-Functionality */
+ {
+ struct dict_avp_data data = {
+ 3445, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Functionality", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(ProSe-Functionality)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Direct_discovery", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "EPC_level_discovery", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Direct_communication", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ProSe-Group-IP-Multicast-Address */
+ {
+ struct dict_avp_data data = {
+ 3446, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Group-IP-Multicast-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* ProSe-Range-Class */
+ {
+ struct dict_avp_data data = {
+ 3448, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Range-Class", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(ProSe-Range-Class)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Reserved", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "50_m", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "100_m", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Unused", { .i32=255 }};
+ struct dict_enumval_data t_5 = { "200_m", { .i32=3 }};
+ struct dict_enumval_data t_6 = { "500_m", { .i32=4 }};
+ struct dict_enumval_data t_7 = { "1000_m", { .i32=5 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ProSe-Reason-For-Cancellation */
+ {
+ struct dict_avp_data data = {
+ 3449, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Reason-For-Cancellation", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(ProSe-Reason-For-Cancellation)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Proximity_Alert_sent", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Time_expired_with_no_renewal", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Requestor_cancellation", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ProSe-Request-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 3450, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Request-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* ProSe-Role-Of-UE */
+ {
+ struct dict_avp_data data = {
+ 3451, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Role-Of-UE", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(ProSe-Role-Of-UE)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Announcing_UE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Monitoring_UE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Requestor_UE", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "Requested_UE", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* ProSe-Source-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 3452, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Source-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* ProSe-UE-ID */
+ {
+ struct dict_avp_data data = {
+ 3453, /* Code */
+ 10415, /* Vendor */
+ "ProSe-UE-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Proximity-Alert-Indication */
+ {
+ struct dict_avp_data data = {
+ 3454, /* Code */
+ 10415, /* Vendor */
+ "Proximity-Alert-Indication", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Proximity-Alert-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Alert", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "No_Alert", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Proximity-Alert-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 3455, /* Code */
+ 10415, /* Vendor */
+ "Proximity-Alert-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Proximity-Cancellation-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 3456, /* Code */
+ 10415, /* Vendor */
+ "Proximity-Cancellation-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* PS-Append-Free-Format-Data */
+ {
+ struct dict_avp_data data = {
+ 867, /* Code */
+ 10415, /* Vendor */
+ "PS-Append-Free-Format-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(PS-Append-Free-Format-Data)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Append", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Overwrite", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* PS-Free-Format-Data */
+ {
+ struct dict_avp_data data = {
+ 866, /* Code */
+ 10415, /* Vendor */
+ "PS-Free-Format-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Quota-Consumption-Time */
+ {
+ struct dict_avp_data data = {
+ 881, /* Code */
+ 10415, /* Vendor */
+ "Quota-Consumption-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Quota-Holding-Time */
+ {
+ struct dict_avp_data data = {
+ 871, /* Code */
+ 10415, /* Vendor */
+ "Quota-Holding-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Quota-Indicator */
+ {
+ struct dict_avp_data data = {
+ 3912, /* Code */
+ 10415, /* Vendor */
+ "Quota-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Quota-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "QUOTA_IS_NOT_USED_DURING_PLAYBACK", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "QUOTA_IS_USED_DURING_PLAYBACK", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Radio-Frequency */
+ {
+ struct dict_avp_data data = {
+ 3462, /* Code */
+ 10415, /* Vendor */
+ "Radio-Frequency", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Radio-Parameter-Set-Values */
+ {
+ struct dict_avp_data data = {
+ 3464, /* Code */
+ 10415, /* Vendor */
+ "Radio-Parameter-Set-Values", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Radio-Resources-Indicator */
+ {
+ struct dict_avp_data data = {
+ 3465, /* Code */
+ 10415, /* Vendor */
+ "Radio-Resources-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Rate-Control-Max-Message-Size */
+ {
+ struct dict_avp_data data = {
+ 3937, /* Code */
+ 10415, /* Vendor */
+ "Rate-Control-Max-Message-Size", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Rate-Control-Max-Rate */
+ {
+ struct dict_avp_data data = {
+ 3938, /* Code */
+ 10415, /* Vendor */
+ "Rate-Control-Max-Rate", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Rate-Control-Time-Unit */
+ {
+ struct dict_avp_data data = {
+ 3939, /* Code */
+ 10415, /* Vendor */
+ "Rate-Control-Time-Unit", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Read-Reply-Report-Requested */
+ {
+ struct dict_avp_data data = {
+ 1222, /* Code */
+ 10415, /* Vendor */
+ "Read-Reply-Report-Requested", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Read-Reply-Report-Requested)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "No", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Yes", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Reason-Header */
+ {
+ struct dict_avp_data data = {
+ 3401, /* Code */
+ 10415, /* Vendor */
+ "Reason-Header", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Received-Talk-Burst-Time */
+ {
+ struct dict_avp_data data = {
+ 1284, /* Code */
+ 10415, /* Vendor */
+ "Received-Talk-Burst-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Received-Talk-Burst-Volume */
+ {
+ struct dict_avp_data data = {
+ 1285, /* Code */
+ 10415, /* Vendor */
+ "Received-Talk-Burst-Volume", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Recipient-SCCP-Address */
+ {
+ struct dict_avp_data data = {
+ 2010, /* Code */
+ 10415, /* Vendor */
+ "Recipient-SCCP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Refund-Information */
+ {
+ struct dict_avp_data data = {
+ 2022, /* Code */
+ 10415, /* Vendor */
+ "Refund-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Related-IMS-Charging-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2711, /* Code */
+ 10415, /* Vendor */
+ "Related-IMS-Charging-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Related-IMS-Charging-Identifier-Node */
+ {
+ struct dict_avp_data data = {
+ 2712, /* Code */
+ 10415, /* Vendor */
+ "Related-IMS-Charging-Identifier-Node", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Relationship-Mode */
+ {
+ struct dict_avp_data data = {
+ 2706, /* Code */
+ 10415, /* Vendor */
+ "Relationship-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Relationship-Mode)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "trusted", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "non_trusted", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Reply-Applic-ID */
+ {
+ struct dict_avp_data data = {
+ 1223, /* Code */
+ 10415, /* Vendor */
+ "Reply-Applic-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Reply-Path-Requested */
+ {
+ struct dict_avp_data data = {
+ 2011, /* Code */
+ 10415, /* Vendor */
+ "Reply-Path-Requested", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Reply-Path-Requested)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "No_Reply_Path_Set", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Reply_path_Set", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Reporting-Reason */
+ {
+ struct dict_avp_data data = {
+ 872, /* Code */
+ 10415, /* Vendor */
+ "Reporting-Reason", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Reporting-Reason)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "THRESHOLD", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "QHT", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "FINAL", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "QUOTA_EXHAUSTED", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "VALIDITY_TIME", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "OTHER_QUOTA_TYPE", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "RATING_CONDITION_CHANGE", { .i32=6 }};
+ struct dict_enumval_data t_8 = { "FORCED_REAUTHORISATION", { .i32=7 }};
+ struct dict_enumval_data t_9 = { "POOL_EXHAUSTED", { .i32=8 }};
+ struct dict_enumval_data t_10 = { "UNUSED_QUOTA_TIMER", { .i32=9 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Requested-Party-Address */
+ {
+ struct dict_avp_data data = {
+ 1251, /* Code */
+ 10415, /* Vendor */
+ "Requested-Party-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Requested-PLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3436, /* Code */
+ 10415, /* Vendor */
+ "Requested-PLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Requestor-PLMN-Identifier */
+ {
+ struct dict_avp_data data = {
+ 3437, /* Code */
+ 10415, /* Vendor */
+ "Requestor-PLMN-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Role-Of-Node */
+ {
+ struct dict_avp_data data = {
+ 829, /* Code */
+ 10415, /* Vendor */
+ "Role-Of-Node", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Role-Of-Node)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ORIGINATING_ROLE", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "TERMINATING_ROLE", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "FORWARDING_ROLE", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Role-Of-ProSe-Function */
+ {
+ struct dict_avp_data data = {
+ 3438, /* Code */
+ 10415, /* Vendor */
+ "Role-Of-ProSe-Function", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Role-Of-ProSe-Function)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "HPLMN", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "VPLMN", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Local_PLMN", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Route-Header-Received */
+ {
+ struct dict_avp_data data = {
+ 3403, /* Code */
+ 10415, /* Vendor */
+ "Route-Header-Received", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Route-Header-Transmitted */
+ {
+ struct dict_avp_data data = {
+ 3404, /* Code */
+ 10415, /* Vendor */
+ "Route-Header-Transmitted", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* SCS-Address */
+ {
+ struct dict_avp_data data = {
+ 3941, /* Code */
+ 10415, /* Vendor */
+ "SCS-Address", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* SCS-Realm */
+ {
+ struct dict_avp_data data = {
+ 3942, /* Code */
+ 10415, /* Vendor */
+ "SCS-Realm", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* SDP-Answer-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 1275, /* Code */
+ 10415, /* Vendor */
+ "SDP-Answer-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* SDP-Media-Description */
+ {
+ struct dict_avp_data data = {
+ 845, /* Code */
+ 10415, /* Vendor */
+ "SDP-Media-Description", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* SDP-Media-Name */
+ {
+ struct dict_avp_data data = {
+ 844, /* Code */
+ 10415, /* Vendor */
+ "SDP-Media-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* SDP-Offer-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 1274, /* Code */
+ 10415, /* Vendor */
+ "SDP-Offer-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* SDP-Session-Description */
+ {
+ struct dict_avp_data data = {
+ 842, /* Code */
+ 10415, /* Vendor */
+ "SDP-Session-Description", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* SDP-Type */
+ {
+ struct dict_avp_data data = {
+ 2036, /* Code */
+ 10415, /* Vendor */
+ "SDP-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SDP-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SDP_Offer", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "SDP_Answer", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Serving-Node-Identity */
+ {
+ struct dict_avp_data data = {
+ 3929, /* Code */
+ 10415, /* Vendor */
+ "Serving-Node-Identity", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, DiameterIdentity_type, NULL);
+ };
+ /* Served-Party-IP-Address */
+ {
+ struct dict_avp_data data = {
+ 848, /* Code */
+ 10415, /* Vendor */
+ "Served-Party-IP-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Service-Id */
+ {
+ struct dict_avp_data data = {
+ 855, /* Code */
+ 10415, /* Vendor */
+ "Service-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Service-Mode */
+ {
+ struct dict_avp_data data = {
+ 2032, /* Code */
+ 10415, /* Vendor */
+ "Service-Mode", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Service-Specific-Data */
+ {
+ struct dict_avp_data data = {
+ 863, /* Code */
+ 10415, /* Vendor */
+ "Service-Specific-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Service-Specific-Type */
+ {
+ struct dict_avp_data data = {
+ 1257, /* Code */
+ 10415, /* Vendor */
+ "Service-Specific-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Serving-Node-Type */
+ {
+ struct dict_avp_data data = {
+ 2047, /* Code */
+ 10415, /* Vendor */
+ "Serving-Node-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Serving-Node-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SGSN", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PMIPSGW", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "GTPSGW", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "ePDG", { .i32=3 }};
+ struct dict_enumval_data t_5 = { "hSGW", { .i32=4 }};
+ struct dict_enumval_data t_6 = { "MME", { .i32=5 }};
+ struct dict_enumval_data t_7 = { "TWAN", { .i32=6 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Session-Direction */
+ {
+ struct dict_avp_data data = {
+ 2707, /* Code */
+ 10415, /* Vendor */
+ "Session-Direction", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Session-Direction)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "inbound", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "outbound", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SGi-PtP-Tunnelling-Method */
+ {
+ struct dict_avp_data data = {
+ 3931, /* Code */
+ 10415, /* Vendor */
+ "SGi-PtP-Tunnelling-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SGi-PtP-Tunnelling-Method)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UDP_IP_based", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Others", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SGSN-Address */
+ {
+ struct dict_avp_data data = {
+ 1228, /* Code */
+ 10415, /* Vendor */
+ "SGSN-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* SGW-Address */
+ {
+ struct dict_avp_data data = {
+ 2067, /* Code */
+ 10415, /* Vendor */
+ "SGW-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* SGW-Change */
+ {
+ struct dict_avp_data data = {
+ 2065, /* Code */
+ 10415, /* Vendor */
+ "SGW-Change", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SGW-Change)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "ACR_Start_NOT_due_to_SGW_Change", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "ACR_Start_due_to_SGW_Change", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SIP-Method */
+ {
+ struct dict_avp_data data = {
+ 824, /* Code */
+ 10415, /* Vendor */
+ "SIP-Method", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* SIP-Request-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 834, /* Code */
+ 10415, /* Vendor */
+ "SIP-Request-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* SIP-Request-Timestamp-Fraction */
+ {
+ struct dict_avp_data data = {
+ 2301, /* Code */
+ 10415, /* Vendor */
+ "SIP-Request-Timestamp-Fraction", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SIP-Response-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 835, /* Code */
+ 10415, /* Vendor */
+ "SIP-Response-Timestamp", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* SIP-Response-Timestamp-Fraction */
+ {
+ struct dict_avp_data data = {
+ 2302, /* Code */
+ 10415, /* Vendor */
+ "SIP-Response-Timestamp-Fraction", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Device-Trigger-Indicator */
+ {
+ struct dict_avp_data data = {
+ 3407, /* Code */
+ 10415, /* Vendor */
+ "SM-Device-Trigger-Indicator", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-Device-Trigger-Indicator)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Not_DeviceTrigger", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Device_Trigger", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SM-Discharge-Time */
+ {
+ struct dict_avp_data data = {
+ 2012, /* Code */
+ 10415, /* Vendor */
+ "SM-Discharge-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* SM-Message-Type */
+ {
+ struct dict_avp_data data = {
+ 2007, /* Code */
+ 10415, /* Vendor */
+ "SM-Message-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-Message-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SUBMISSION", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "DELIVERY_REPORT", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "SM_Service_Request", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SM-Protocol-ID */
+ {
+ struct dict_avp_data data = {
+ 2013, /* Code */
+ 10415, /* Vendor */
+ "SM-Protocol-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Sequence-Number */
+ {
+ struct dict_avp_data data = {
+ 3408, /* Code */
+ 10415, /* Vendor */
+ "SM-Sequence-Number", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-Service-Type */
+ {
+ struct dict_avp_data data = {
+ 2029, /* Code */
+ 10415, /* Vendor */
+ "SM-Service-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SM-Service-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "VAS4SMS_Short_Message_content_processing", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "VAS4SMS_Short_Message_forwarding", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "VAS4SMS_Short_Message_Deferred_Delivery", { .i32=10 }};
+ struct dict_enumval_data t_4 = { "VAS4SMS_Short_Message_Forwarding_multiple_subscriptions", { .i32=2 }};
+ struct dict_enumval_data t_5 = { "VAS4SMS_Short_Message_filtering", { .i32=3 }};
+ struct dict_enumval_data t_6 = { "VAS4SMS_Short_Message_receipt", { .i32=4 }};
+ struct dict_enumval_data t_7 = { "VAS4SMS_Short_Message_Network_Storage", { .i32=5 }};
+ struct dict_enumval_data t_8 = { "VAS4SMS_Short_Message_to_multiple_destinations", { .i32=6 }};
+ struct dict_enumval_data t_9 = { "VAS4SMS_Short_Message_Auto_Reply", { .i32=8 }};
+ struct dict_enumval_data t_10 = { "VAS4SMS_Short_Message_Personal_Signature", { .i32=9 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SM-Status */
+ {
+ struct dict_avp_data data = {
+ 2014, /* Code */
+ 10415, /* Vendor */
+ "SM-Status", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SM-User-Data-Header */
+ {
+ struct dict_avp_data data = {
+ 2015, /* Code */
+ 10415, /* Vendor */
+ "SM-User-Data-Header", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SMS-Node */
+ {
+ struct dict_avp_data data = {
+ 2016, /* Code */
+ 10415, /* Vendor */
+ "SMS-Node", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(SMS-Node)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "SMS_Router", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "IP_SM_GW", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "SMS_Router_and_IP_SM_GW", { .i32=2 }};
+ struct dict_enumval_data t_4 = { "SMS_SC", { .i32=3 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* SMS-Result */
+ {
+ struct dict_avp_data data = {
+ 3409, /* Code */
+ 10415, /* Vendor */
+ "SMS-Result", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* SMSC-Address */
+ {
+ struct dict_avp_data data = {
+ 2017, /* Code */
+ 10415, /* Vendor */
+ "SMSC-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Start-of-Charging */
+ {
+ struct dict_avp_data data = {
+ 3419, /* Code */
+ 10415, /* Vendor */
+ "Start-of-Charging", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Start-Time */
+ {
+ struct dict_avp_data data = {
+ 2041, /* Code */
+ 10415, /* Vendor */
+ "Start-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Status-AS-Code */
+ {
+ struct dict_avp_data data = {
+ 2702, /* Code */
+ 10415, /* Vendor */
+ "Status-AS-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Status-AS-Code)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "4xx", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "5xx", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "Timeout", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Stop-Time */
+ {
+ struct dict_avp_data data = {
+ 2042, /* Code */
+ 10415, /* Vendor */
+ "Stop-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Submission-Time */
+ {
+ struct dict_avp_data data = {
+ 1202, /* Code */
+ 10415, /* Vendor */
+ "Submission-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Subscriber-Role */
+ {
+ struct dict_avp_data data = {
+ 2033, /* Code */
+ 10415, /* Vendor */
+ "Subscriber-Role", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Subscriber-Role)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Originating", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Terminating", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* TAD-Identifier */
+ {
+ struct dict_avp_data data = {
+ 2717, /* Code */
+ 10415, /* Vendor */
+ "TAD-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(TAD-Identifier)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CS", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "PS", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Talk-Burst-Time */
+ {
+ struct dict_avp_data data = {
+ 1286, /* Code */
+ 10415, /* Vendor */
+ "Talk-Burst-Time", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Talk-Burst-Volume */
+ {
+ struct dict_avp_data data = {
+ 1287, /* Code */
+ 10415, /* Vendor */
+ "Talk-Burst-Volume", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Tariff-XML */
+ {
+ struct dict_avp_data data = {
+ 2306, /* Code */
+ 10415, /* Vendor */
+ "Tariff-XML", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Teleservice */
+ {
+ struct dict_avp_data data = {
+ 3413, /* Code */
+ 10415, /* Vendor */
+ "Teleservice", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Terminating-IOI */
+ {
+ struct dict_avp_data data = {
+ 840, /* Code */
+ 10415, /* Vendor */
+ "Terminating-IOI", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Time-First-Reception */
+ {
+ struct dict_avp_data data = {
+ 3466, /* Code */
+ 10415, /* Vendor */
+ "Time-First-Reception", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Time-First-Transmission */
+ {
+ struct dict_avp_data data = {
+ 3467, /* Code */
+ 10415, /* Vendor */
+ "Time-First-Transmission", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Time-First-Usage */
+ {
+ struct dict_avp_data data = {
+ 2043, /* Code */
+ 10415, /* Vendor */
+ "Time-First-Usage", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Time-Indicator */
+ {
+ struct dict_avp_data data = {
+ 3911, /* Code */
+ 10415, /* Vendor */
+ "Time-Indicator", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Time-Last-Usage */
+ {
+ struct dict_avp_data data = {
+ 2044, /* Code */
+ 10415, /* Vendor */
+ "Time-Last-Usage", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Time-Quota-Threshold */
+ {
+ struct dict_avp_data data = {
+ 868, /* Code */
+ 10415, /* Vendor */
+ "Time-Quota-Threshold", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Time-Quota-Type */
+ {
+ struct dict_avp_data data = {
+ 1271, /* Code */
+ 10415, /* Vendor */
+ "Time-Quota-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Time-Quota-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "DISCRETE_TIME_PERIOD", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "CONTINUOUS_TIME_PERIOD", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Time-Usage */
+ {
+ struct dict_avp_data data = {
+ 2045, /* Code */
+ 10415, /* Vendor */
+ "Time-Usage", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Token-Text */
+ {
+ struct dict_avp_data data = {
+ 1215, /* Code */
+ 10415, /* Vendor */
+ "Token-Text", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Transcoder-Inserted-Indication */
+ {
+ struct dict_avp_data data = {
+ 2605, /* Code */
+ 10415, /* Vendor */
+ "Transcoder-Inserted-Indication", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Transcoder-Inserted-Indication)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Transcoder_Not_Inserted", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "Transcoder_Inserted", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Transit-IOI-List */
+ {
+ struct dict_avp_data data = {
+ 2701, /* Code */
+ 10415, /* Vendor */
+ "Transit-IOI-List", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Trigger-Type */
+ {
+ struct dict_avp_data data = {
+ 870, /* Code */
+ 10415, /* Vendor */
+ "Trigger-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(Trigger-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "CHANGE_IN_SGSN_IP_ADDRESS", { .i32=1 }};
+ struct dict_enumval_data t_2 = { "CHANGE_IN_QOS", { .i32=2 }};
+ struct dict_enumval_data t_3 = { "CHANGE_IN_LOCATION", { .i32=3 }};
+ struct dict_enumval_data t_4 = { "CHANGE_IN_RAT", { .i32=4 }};
+ struct dict_enumval_data t_5 = { "CHANGE_IN_UE_TIMEZONE", { .i32=5 }};
+ struct dict_enumval_data t_6 = { "CHANGEINQOS_TRAFFIC_CLASS", { .i32=10 }};
+ struct dict_enumval_data t_7 = { "CHANGEINQOS_RELIABILITY_CLASS", { .i32=11 }};
+ struct dict_enumval_data t_8 = { "CHANGEINQOS_DELAY_CLASS", { .i32=12 }};
+ struct dict_enumval_data t_9 = { "CHANGEINQOS_PEAK_THROUGHPUT", { .i32=13 }};
+ struct dict_enumval_data t_10 = { "CHANGEINQOS_PRECEDENCE_CLASS", { .i32=14 }};
+ struct dict_enumval_data t_11 = { "CHANGEINQOS_MEAN_THROUGHPUT", { .i32=15 }};
+ struct dict_enumval_data t_12 = { "CHANGEINQOS_MAXIMUM_BIT_RATE_FOR_UPLINK", { .i32=16 }};
+ struct dict_enumval_data t_13 = { "CHANGEINQOS_MAXIMUM_BIT_RATE_FOR_DOWNLINK", { .i32=17 }};
+ struct dict_enumval_data t_14 = { "CHANGEINQOS_RESIDUAL_BER", { .i32=18 }};
+ struct dict_enumval_data t_15 = { "CHANGEINQOS_SDU_ERROR_RATIO", { .i32=19 }};
+ struct dict_enumval_data t_16 = { "CHANGEINQOS_TRANSFER_DELAY", { .i32=20 }};
+ struct dict_enumval_data t_17 = { "CHANGEINQOS_TRAFFIC_HANDLING_PRIORITY", { .i32=21 }};
+ struct dict_enumval_data t_18 = { "CHANGEINQOS_GUARANTEED_BIT_RATE_FOR_UPLINK", { .i32=22 }};
+ struct dict_enumval_data t_19 = { "CHANGEINQOS_GUARANTEED_BIT_RATE_FOR_DOWNLINK", { .i32=23 }};
+ struct dict_enumval_data t_20 = { "CHANGEINQOS_APN_AGGREGATE_MAXIMUM_BIT_RATE", { .i32=24 }};
+ struct dict_enumval_data t_21 = { "CHANGEINLOCATION_MCC", { .i32=30 }};
+ struct dict_enumval_data t_22 = { "CHANGEINLOCATION_MNC", { .i32=31 }};
+ struct dict_enumval_data t_23 = { "CHANGEINLOCATION_RAC", { .i32=32 }};
+ struct dict_enumval_data t_24 = { "CHANGEINLOCATION_LAC", { .i32=33 }};
+ struct dict_enumval_data t_25 = { "CHANGEINLOCATION_CellId", { .i32=34 }};
+ struct dict_enumval_data t_26 = { "CHANGEINLOCATION_TAC", { .i32=35 }};
+ struct dict_enumval_data t_27 = { "CHANGEINLOCATION_ECGI", { .i32=36 }};
+ struct dict_enumval_data t_28 = { "CHANGE_IN_MEDIA_COMPOSITION", { .i32=40 }};
+ struct dict_enumval_data t_29 = { "CHANGE_IN_PARTICIPANTS_NMB", { .i32=50 }};
+ struct dict_enumval_data t_30 = { "CHANGE_IN_THRSHLD_OF_PARTICIPANTS_NMB", { .i32=51 }};
+ struct dict_enumval_data t_31 = { "CHANGE_IN_USER_PARTICIPATING_TYPE", { .i32=52 }};
+ struct dict_enumval_data t_32 = { "CHANGE_IN_SERVICE_CONDITION", { .i32=60 }};
+ struct dict_enumval_data t_33 = { "CHANGE_IN_SERVING_NODE", { .i32=61 }};
+ struct dict_enumval_data t_34 = { "CHANGE_IN_ACCESS_FOR_A_SERVICE_DATA_FLOW", { .i32=62 }};
+ struct dict_enumval_data t_35 = { "CHANGE_IN_USER_CSG_INFORMATION", { .i32=70 }};
+ struct dict_enumval_data t_36 = { "CHANGE_IN_HYBRID_SUBSCRIBED_USER_CSG_INFORMATION", { .i32=71 }};
+ struct dict_enumval_data t_37 = { "CHANGE_IN_HYBRID_UNSUBSCRIBED_USER_CSG_INFORMATION", { .i32=72 }};
+ struct dict_enumval_data t_38 = { "CHANGE_OF_UE_PRESENCE_IN_PRESENCE_REPORTING_AREA", { .i32=73 }};
+ struct dict_enumval_data t_39 = { "CHANGE_IN_APN_RATE_CONTROL", { .i32=75 }};
+ struct dict_enumval_data t_40 = { "CHANGE_IN_3GPP_PS_DATA_OFF", { .i32=76 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_4, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_5, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_6, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_7, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_8, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_9, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_10, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_11, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_12, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_13, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_14, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_15, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_16, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_17, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_18, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_19, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_20, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_21, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_22, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_23, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_24, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_25, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_26, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_27, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_28, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_29, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_30, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_31, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_32, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_33, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_34, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_35, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_36, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_37, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_38, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_39, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_40, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* TWAG-Address */
+ {
+ struct dict_avp_data data = {
+ 3903, /* Code */
+ 10415, /* Vendor */
+ "TWAG-Address", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Address_type, NULL);
+ };
+ /* Type-Number */
+ {
+ struct dict_avp_data data = {
+ 1204, /* Code */
+ 10415, /* Vendor */
+ "Type-Number", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* UNI-PDU-CP-Only-Flag */
+ {
+ struct dict_avp_data data = {
+ 3932, /* Code */
+ 10415, /* Vendor */
+ "UNI-PDU-CP-Only-Flag", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(UNI-PDU-CP-Only-Flag)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "UNI_PDU_both_UP_CP", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "UNI_PDU_CP_Only", { .i32=1 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* Unit-Quota-Threshold */
+ {
+ struct dict_avp_data data = {
+ 1226, /* Code */
+ 10415, /* Vendor */
+ "Unit-Quota-Threshold", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Usage-Information-Report-Sequence-Number */
+ {
+ struct dict_avp_data data = {
+ 3439, /* Code */
+ 10415, /* Vendor */
+ "Usage-Information-Report-Sequence-Number", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* User-Participating-Type */
+ {
+ struct dict_avp_data data = {
+ 1279, /* Code */
+ 10415, /* Vendor */
+ "User-Participating-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_INTEGER32 /* base type of data */
+ };
+ struct dict_object *type;
+ struct dict_type_data tdata = { AVP_TYPE_INTEGER32, "3GPP/Enumerated(User-Participating-Type)", NULL, NULL, NULL };
+ struct dict_enumval_data t_1 = { "Normal", { .i32=0 }};
+ struct dict_enumval_data t_2 = { "NW_PoC_Box", { .i32=1 }};
+ struct dict_enumval_data t_3 = { "UE_PoC_Box", { .i32=2 }};
+ /* Create the Enumerated type, and then the AVP */
+ CHECK_dict_new( DICT_TYPE, &tdata, NULL, &type);
+ CHECK_dict_new( DICT_ENUMVAL, &t_1, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_2, type, NULL);
+ CHECK_dict_new( DICT_ENUMVAL, &t_3, type, NULL);
+ CHECK_dict_new( DICT_AVP, &data, type, NULL);
+ };
+ /* User-Session-Id */
+ {
+ struct dict_avp_data data = {
+ 830, /* Code */
+ 10415, /* Vendor */
+ "User-Session-Id", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* Variable-Part-Order */
+ {
+ struct dict_avp_data data = {
+ 3908, /* Code */
+ 10415, /* Vendor */
+ "Variable-Part-Order", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Variable-Part-Type */
+ {
+ struct dict_avp_data data = {
+ 3909, /* Code */
+ 10415, /* Vendor */
+ "Variable-Part-Type", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Variable-Part-Value */
+ {
+ struct dict_avp_data data = {
+ 3910, /* Code */
+ 10415, /* Vendor */
+ "Variable-Part-Value", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, UTF8String_type, NULL);
+ };
+ /* VLR-Number */
+ {
+ struct dict_avp_data data = {
+ 3420, /* Code */
+ 10415, /* Vendor */
+ "VLR-Number", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Volume-Quota-Threshold */
+ {
+ struct dict_avp_data data = {
+ 869, /* Code */
+ 10415, /* Vendor */
+ "Volume-Quota-Threshold", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_UNSIGNED32 /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, NULL, NULL);
+ };
+ /* Submission-Timestamp */
+ {
+ struct dict_avp_data data = {
+ 9911, /* Code */
+ 10415, /* Vendor */
+ "Submission-Timestamp", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_OCTETSTRING /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data, Time_type, NULL);
+ };
+ /* Scale-Factor */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2059, /* Code */
+ 10415, /* Vendor */
+ "Scale-Factor", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SDP-Media-Component */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 843, /* Code */
+ 10415, /* Vendor */
+ "SDP-Media-Component", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* UWAN-User-Location-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3918, /* Code */
+ 10415, /* Vendor */
+ "UWAN-User-Location-Info", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Address-Domain */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 898, /* Code */
+ 10415, /* Vendor */
+ "Address-Domain", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Location-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3460, /* Code */
+ 10415, /* Vendor */
+ "Location-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MBMS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 880, /* Code */
+ 10415, /* Vendor */
+ "MBMS-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* AoC-Service */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2311, /* Code */
+ 10415, /* Vendor */
+ "AoC-Service", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ProSe-Direct-Communication-Transmission-Data-Container */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3441, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Direct-Communication-Transmission-Data-Container", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* APN-Rate-Control-Downlink */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3934, /* Code */
+ 10415, /* Vendor */
+ "APN-Rate-Control-Downlink", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* PoC-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 879, /* Code */
+ 10415, /* Vendor */
+ "PoC-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Supplementary-Service */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2048, /* Code */
+ 10415, /* Vendor */
+ "Supplementary-Service", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Transmitter-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3468, /* Code */
+ 10415, /* Vendor */
+ "Transmitter-Info", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Unit-Cost */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2061, /* Code */
+ 10415, /* Vendor */
+ "Unit-Cost", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Time-Stamps */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 833, /* Code */
+ 10415, /* Vendor */
+ "Time-Stamps", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* NNI-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2703, /* Code */
+ 10415, /* Vendor */
+ "NNI-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Trigger */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1264, /* Code */
+ 10415, /* Vendor */
+ "Trigger", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Related-Trigger */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3926, /* Code */
+ 10415, /* Vendor */
+ "Related-Trigger", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Talk-Burst-Exchange */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1255, /* Code */
+ 10415, /* Vendor */
+ "Talk-Burst-Exchange", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Time-Quota-Mechanism */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1270, /* Code */
+ 10415, /* Vendor */
+ "Time-Quota-Mechanism", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Variable-Part */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3907, /* Code */
+ 10415, /* Vendor */
+ "Variable-Part", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Additional-Content-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1207, /* Code */
+ 10415, /* Vendor */
+ "Additional-Content-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* APN-Rate-Control-Uplink */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3935, /* Code */
+ 10415, /* Vendor */
+ "APN-Rate-Control-Uplink", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Basic-Service-Code */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3411, /* Code */
+ 10415, /* Vendor */
+ "Basic-Service-Code", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Event-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 823, /* Code */
+ 10415, /* Vendor */
+ "Event-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ProSe-Direct-Communication-Reception-Data-Container */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3461, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Direct-Communication-Reception-Data-Container", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Originator-Interface */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2009, /* Code */
+ 10415, /* Vendor */
+ "Originator-Interface", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Destination-Interface */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2002, /* Code */
+ 10415, /* Vendor */
+ "Destination-Interface", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ISUP-Cause */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3416, /* Code */
+ 10415, /* Vendor */
+ "ISUP-Cause", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* LCS-Requestor-ID */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1239, /* Code */
+ 10415, /* Vendor */
+ "LCS-Requestor-ID", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* PS-Furnish-Charging-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 865, /* Code */
+ 10415, /* Vendor */
+ "PS-Furnish-Charging-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* User-CSG-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2319, /* Code */
+ 10415, /* Vendor */
+ "User-CSG-Information", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Called-Identity-Change */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3917, /* Code */
+ 10415, /* Vendor */
+ "Called-Identity-Change", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Service-Specific-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1249, /* Code */
+ 10415, /* Vendor */
+ "Service-Specific-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Accumulated-Cost */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2052, /* Code */
+ 10415, /* Vendor */
+ "Accumulated-Cost", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SCS-AS-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3940, /* Code */
+ 10415, /* Vendor */
+ "SCS-AS-Address", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Message-Class */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1213, /* Code */
+ 10415, /* Vendor */
+ "Message-Class", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Location-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1244, /* Code */
+ 10415, /* Vendor */
+ "Location-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Rate-Element */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2058, /* Code */
+ 10415, /* Vendor */
+ "Rate-Element", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Participant-Group */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1260, /* Code */
+ 10415, /* Vendor */
+ "Participant-Group", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Enhanced-Diagnostics */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3901, /* Code */
+ 10415, /* Vendor */
+ "Enhanced-Diagnostics", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Access-Network-Info-Change */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 4401, /* Code */
+ 10415, /* Vendor */
+ "Access-Network-Info-Change", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* PoC-User-Role */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1252, /* Code */
+ 10415, /* Vendor */
+ "PoC-User-Role", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* LCS-Client-Name */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1235, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-Name", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Message-Body */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 889, /* Code */
+ 10415, /* Vendor */
+ "Message-Body", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Radio-Parameter-Set-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3463, /* Code */
+ 10415, /* Vendor */
+ "Radio-Parameter-Set-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SM-Device-Trigger-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3405, /* Code */
+ 10415, /* Vendor */
+ "SM-Device-Trigger-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* TWAN-User-Location-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2714, /* Code */
+ 10415, /* Vendor */
+ "TWAN-User-Location-Info", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* VCS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3410, /* Code */
+ 10415, /* Vendor */
+ "VCS-Information", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Trunk-Group-ID */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 851, /* Code */
+ 10415, /* Vendor */
+ "Trunk-Group-ID", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Incremental-Cost */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2062, /* Code */
+ 10415, /* Vendor */
+ "Incremental-Cost", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SDP-TimeStamps */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1273, /* Code */
+ 10415, /* Vendor */
+ "SDP-TimeStamps", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Inter-Operator-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 838, /* Code */
+ 10415, /* Vendor */
+ "Inter-Operator-Identifier", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* NIDD-Submission */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3928, /* Code */
+ 10415, /* Vendor */
+ "NIDD-Submission", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Application-Server-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 850, /* Code */
+ 10415, /* Vendor */
+ "Application-Server-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* CPDT-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3927, /* Code */
+ 10415, /* Vendor */
+ "CPDT-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Envelope */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1266, /* Code */
+ 10415, /* Vendor */
+ "Envelope", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Related-Change-Condition-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3925, /* Code */
+ 10415, /* Vendor */
+ "Related-Change-Condition-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* LCS-Client-Id */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1232, /* Code */
+ 10415, /* Vendor */
+ "LCS-Client-Id", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Early-Media-Description */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1272, /* Code */
+ 10415, /* Vendor */
+ "Early-Media-Description", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* AoC-Subscription-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2314, /* Code */
+ 10415, /* Vendor */
+ "AoC-Subscription-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Current-Tariff */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2056, /* Code */
+ 10415, /* Vendor */
+ "Current-Tariff", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* APN-Rate-Control */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3933, /* Code */
+ 10415, /* Vendor */
+ "APN-Rate-Control", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Access-Transfer-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2709, /* Code */
+ 10415, /* Vendor */
+ "Access-Transfer-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Recipient-Received-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2028, /* Code */
+ 10415, /* Vendor */
+ "Recipient-Received-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* AoC-Cost-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2053, /* Code */
+ 10415, /* Vendor */
+ "AoC-Cost-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Originator-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 886, /* Code */
+ 10415, /* Vendor */
+ "Originator-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Originator-Received-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2027, /* Code */
+ 10415, /* Vendor */
+ "Originator-Received-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Remaining-Balance */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2021, /* Code */
+ 10415, /* Vendor */
+ "Remaining-Balance", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* AF-Correlation-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1276, /* Code */
+ 10415, /* Vendor */
+ "AF-Correlation-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Recipient-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1201, /* Code */
+ 10415, /* Vendor */
+ "Recipient-Address", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Next-Tariff */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2057, /* Code */
+ 10415, /* Vendor */
+ "Next-Tariff", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Coverage-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3459, /* Code */
+ 10415, /* Vendor */
+ "Coverage-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Announcement-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3904, /* Code */
+ 10415, /* Vendor */
+ "Announcement-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MM-Content-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1203, /* Code */
+ 10415, /* Vendor */
+ "MM-Content-Type", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MMTel-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2030, /* Code */
+ 10415, /* Vendor */
+ "MMTel-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Service-Data-Container */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2040, /* Code */
+ 10415, /* Vendor */
+ "Service-Data-Container", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* MMS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 877, /* Code */
+ 10415, /* Vendor */
+ "MMS-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Recipient-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2026, /* Code */
+ 10415, /* Vendor */
+ "Recipient-Info", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Traffic-Data-Volumes */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2046, /* Code */
+ 10415, /* Vendor */
+ "Traffic-Data-Volumes", /* Name */
+ 0, /* Fixed flags */
+ 0, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* LCS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 878, /* Code */
+ 10415, /* Vendor */
+ "LCS-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Tariff-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2060, /* Code */
+ 10415, /* Vendor */
+ "Tariff-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* ProSe-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3447, /* Code */
+ 10415, /* Vendor */
+ "ProSe-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* SMS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2000, /* Code */
+ 10415, /* Vendor */
+ "SMS-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Real-Time-Tariff-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2305, /* Code */
+ 10415, /* Vendor */
+ "Real-Time-Tariff-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* AoC-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 2054, /* Code */
+ 10415, /* Vendor */
+ "AoC-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Monitoring-Event-Report-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3920, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Event-Report-Data", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Offline-Charging */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 1278, /* Code */
+ 10415, /* Vendor */
+ "Offline-Charging", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* IMS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 876, /* Code */
+ 10415, /* Vendor */
+ "IMS-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Monitoring-Event-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 3921, /* Code */
+ 10415, /* Vendor */
+ "Monitoring-Event-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* PS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 874, /* Code */
+ 10415, /* Vendor */
+ "PS-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+ /* Service-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_data data = {
+ 873, /* Code */
+ 10415, /* Vendor */
+ "Service-Information", /* Name */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
+ AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flag values */
+ AVP_TYPE_GROUPED /* base type of data */
+ };
+ CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
+ }
+
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ return 0;
+}
+
+static int dict_ts32299_avps_load_rules(char * conffile)
+{
+ /* Grouped AVP section */
+ {
+ /* Scale-Factor */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Scale-Factor"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Value-Digits"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Exponent"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SDP-Media-Component */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SDP-Media-Component"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SDP-Media-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Media-Description"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Local-GW-Inserted-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IP-Realm-Default-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Transcoder-Inserted-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Media-Initiator-Flag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Media-Initiator-Party"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Charging-Identifier-Value"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* UWAN-User-Location-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "UWAN-User-Location-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "UE-Local-IP-Address"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UDP-Source-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "BSSID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Address-Domain */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Address-Domain"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Domain-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-IMSI-MCC-MNC"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Location-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Location-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MBMS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MBMS-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "TMGI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-User-Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "File-Repair-Supported"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Required-MBMS-Bearer-Capabilities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-2G-3G-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RAI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Service-Area"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Session-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CN-IP-Multicast-Distribution"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-GW-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Charged-Party"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Data-Transfer-Start"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Data-Transfer-Stop"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* AoC-Service */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "AoC-Service"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "AoC-Service-Obligatory-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AoC-Service-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ProSe-Direct-Communication-Transmission-Data-Container */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ProSe-Direct-Communication-Transmission-Data-Container"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Local-Sequence-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Coverage-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Output-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Condition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Information-Report-Sequence-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Radio-Resources-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Radio-Frequency"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* APN-Rate-Control-Downlink */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "APN-Rate-Control-Downlink"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Rate-Control-Time-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rate-Control-Max-Rate"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rate-Control-Max-Message-Size"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* PoC-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "PoC-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "PoC-Server-Role"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Supplementary-Service */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Supplementary-Service"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MMTel-SService-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Mode"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Transmitter-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Transmitter-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Source-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-UE-ID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Unit-Cost */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Unit-Cost"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Value-Digits"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Exponent"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Time-Stamps */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Time-Stamps"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SIP-Request-Timestamp"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* NNI-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "NNI-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Session-Direction"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NNI-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Relationship-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Neighbour-Node-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Trigger */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Trigger"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Trigger-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Related-Trigger */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Related-Trigger"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Trigger-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Talk-Burst-Exchange */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Talk-Burst-Exchange"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "PoC-Change-Time"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Time-Quota-Mechanism */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Time-Quota-Mechanism"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Time-Quota-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Base-Time-Interval"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Variable-Part */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Variable-Part"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Variable-Part-Order"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Variable-Part-Type"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Variable-Part-Value"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Additional-Content-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Additional-Content-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Type-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Additional-Type-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-Size"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* APN-Rate-Control-Uplink */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "APN-Rate-Control-Uplink"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Additional-Exception-Reports"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rate-Control-Time-Unit"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rate-Control-Max-Rate"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Basic-Service-Code */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Basic-Service-Code"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Service"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Teleservice"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Event-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Event-Type"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SIP-Method"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Event"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Expires"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ProSe-Direct-Communication-Reception-Data-Container */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ProSe-Direct-Communication-Reception-Data-Container"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Local-Sequence-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Coverage-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Input-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Condition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Visited-PLMN-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Usage-Information-Report-Sequence-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Radio-Resources-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Radio-Frequency"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Originator-Interface */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Originator-Interface"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Interface-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Text"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Destination-Interface */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Destination-Interface"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Interface-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Text"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Port"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Interface-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ISUP-Cause */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ISUP-Cause"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "ISUP-Cause-Location"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* LCS-Requestor-ID */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "LCS-Requestor-ID"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "LCS-Data-Coding-Scheme"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Requestor-ID-String"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* PS-Furnish-Charging-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "PS-Furnish-Charging-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-Free-Format-Data"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-Append-Free-Format-Data"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* User-CSG-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "User-CSG-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "CSG-Id"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CSG-Access-Mode"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CSG-Membership-Indication"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Called-Identity-Change */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Called-Identity-Change"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Called-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Service-Specific-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Service-Specific-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Service-Specific-Data"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Accumulated-Cost */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Accumulated-Cost"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Value-Digits"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Exponent"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SCS-AS-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SCS-AS-Address"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SCS-Realm"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCS-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Message-Class */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Message-Class"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Class-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Token-Text"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Location-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Location-Type"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Location-Estimate-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Deferred-Location-Event-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Rate-Element */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Rate-Element"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "CC-Unit-Type"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Participant-Group */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Participant-Group"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Called-Party-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Participant-Access-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Participating-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Enhanced-Diagnostics */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Enhanced-Diagnostics"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "RAN-NAS-Release-Cause"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Access-Network-Info-Change */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Access-Network-Info-Change"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Cellular-Network-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* PoC-User-Role */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "PoC-User-Role"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "PoC-User-Role-IDs"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* LCS-Client-Name */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "LCS-Client-Name"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "LCS-Data-Coding-Scheme"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Name-String"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Format-Indicator"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Message-Body */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Message-Body"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Content-Type"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Radio-Parameter-Set-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Radio-Parameter-Set-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Radio-Parameter-Set-Values"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SM-Device-Trigger-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SM-Device-Trigger-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "MTC-IWF-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reference-Number"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* TWAN-User-Location-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "TWAN-User-Location-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SSID"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "BSSID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* VCS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "VCS-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Capability"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Network-Call-Reference-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSC-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Trunk-Group-ID */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Trunk-Group-ID"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Incoming-Trunk-Group-Id"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Incremental-Cost */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Incremental-Cost"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Value-Digits"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Exponent"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SDP-TimeStamps */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SDP-TimeStamps"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SDP-Offer-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Answer-Timestamp"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Inter-Operator-Identifier */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Inter-Operator-Identifier"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Originating-IOI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Terminating-IOI"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* NIDD-Submission */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "NIDD-Submission"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Submission-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Input-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Output-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Condition"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Application-Server-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Application-Server-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Application-Server"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* CPDT-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "CPDT-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "External-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Envelope */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Envelope"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Envelope-Start-Time"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Envelope-End-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Total-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Input-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Output-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "CC-Service-Specific-Units"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Related-Change-Condition-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Related-Change-Condition-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Condition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 5535, .avp_name = "3GPP2-BSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UWAN-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-RAT-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* LCS-Client-Id */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "LCS-Client-Id"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "LCS-Client-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Client-External-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Client-Dialed-By-MS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Client-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-APN"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Requestor-ID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Early-Media-Description */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Early-Media-Description"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SDP-TimeStamps"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Media-Component"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Session-Description"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* AoC-Subscription-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "AoC-Subscription-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "AoC-Service"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AoC-Format"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Preferred-AoC-Currency"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Current-Tariff */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Current-Tariff"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Currency-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Scale-Factor"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rate-Element"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* APN-Rate-Control */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "APN-Rate-Control"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "APN-Rate-Control-Uplink"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Rate-Control-Downlink"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Access-Transfer-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Access-Transfer-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Access-Transfer-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Cellular-Network-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Inter-UE-Transfer"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Instance-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Related-IMS-Charging-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Related-IMS-Charging-Identifier-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Recipient-Received-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Recipient-Received-Address"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Address-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Domain"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* AoC-Cost-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "AoC-Cost-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Accumulated-Cost"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Incremental-Cost"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Currency-Code"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Originator-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Originator-Address"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Address-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Domain"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Originator-Received-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Originator-Received-Address"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Address-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Domain"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Remaining-Balance */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Remaining-Balance"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Unit-Value"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Currency-Code"}, RULE_REQUIRED, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* AF-Correlation-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "AF-Correlation-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "AF-Charging-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Flows"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Recipient-Address */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Recipient-Address"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Address-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Address-Domain"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Addressee-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Next-Tariff */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Next-Tariff"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Currency-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Scale-Factor"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Rate-Element"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Coverage-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Coverage-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Coverage-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Location-Info"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Announcement-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Announcement-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Announcement-Identifier"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Variable-Part"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Quota-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Announcement-Order"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Play-Alternative"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Privacy-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Language"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MM-Content-Type */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MM-Content-Type"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Type-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Additional-Type-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-Size"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Additional-Content-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MMTel-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MMTel-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Supplementary-Service"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Service-Data-Container */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Service-Data-Container"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "AF-Correlation-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Input-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Output-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Local-Sequence-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Rating-Group"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Service-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Specific-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-First-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Last-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Usage"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Condition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 5535, .avp_name = "3GPP2-BSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UWAN-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Sponsor-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Service-Provider-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Related-Change-Condition-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-PLMN-Rate-Control"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Rate-Control"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-PS-Data-Off-Status"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* MMS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "MMS-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Originator-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Submission-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MM-Content-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-Size"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Delivery-Report-Requested"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Read-Reply-Report-Requested"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MMBox-Storage-Requested"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Applic-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reply-Applic-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Aux-Applic-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Content-Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "DRM-Content"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Adaptations"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Recipient-Info */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Recipient-Info"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Destination-Interface"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-Received-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-SCCP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Protocol-ID"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Traffic-Data-Volumes */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Traffic-Data-Volumes"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Input-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Accounting-Output-Octets"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Condition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UWAN-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-RAT-Type"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* LCS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "LCS-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "LCS-Client-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Location-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Location-Estimate"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Positioning-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-IMSI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MSISDN"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Tariff-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Tariff-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Current-Tariff"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Tariff-Time-Change"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Next-Tariff"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* ProSe-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "ProSe-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Announcing-UE-HPLMN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Announcing-UE-VPLMN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-UE-HPLMN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-UE-VPLMN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Role-Of-ProSe-Function"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-App-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-3rd-Party-Application-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Specific-Data"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Event-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Direct-Discovery-Model"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Function-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Function-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Validity-Timer"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Role-Of-UE"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Request-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PC3-Control-Protocol-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-UE-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requestor-PLMN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Origin-App-Layer-User-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "WLAN-Link-Layer-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requesting-EPUID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Target-App-Layer-User-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requested-PLMN-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Window"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Range-Class"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Proximity-Alert-Indication"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Proximity-Alert-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Proximity-Cancellation-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Reason-For-Cancellation"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PC3-EPC-Control-Protocol-Cause"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-UE-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Source-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Layer-2-Group-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Group-IP-Multicast-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Coverage-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Radio-Parameter-Set-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Transmitter-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-First-Transmission"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-First-Reception"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Direct-Communication-Transmission-Data-Container"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Direct-Communication-Reception-Data-Container"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* SMS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "SMS-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "SMS-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Client-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Originator-SCCP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMSC-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Data-Coding-Scheme"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Discharge-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Message-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Originator-Interface"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Protocol-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reply-Path-Requested"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-User-Data-Header"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Number-Of-Messages-Sent"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Sequence-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Recipient-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Originator-Received-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Service-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMS-Result"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Device-Trigger-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SM-Device-Trigger-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Real-Time-Tariff-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Real-Time-Tariff-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Tariff-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Tariff-XML"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* AoC-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "AoC-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "AoC-Cost-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Tariff-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AoC-Subscription-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Monitoring-Event-Report-Data */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Report-Data"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Report-Number"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charged-Party"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reachability-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "EPS-Location-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Communication-Failure-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Number-Of-UE-Per-Location-Report"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Offline-Charging */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Offline-Charging"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Quota-Consumption-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Quota-Mechanism"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Envelope-Reporting"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Multiple-Services-Credit-Control"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* IMS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "IMS-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Event-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Role-Of-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Node-Functionality"}, RULE_REQUIRED, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Outgoing-Session-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Session-Priority"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Calling-Party-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Called-Party-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Called-Asserted-Identity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Called-Identity-Change"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Number-Portability-Routing-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Carrier-Select-Routing-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Alternate-Charged-Party-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Requested-Party-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Associated-URI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Time-Stamps"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Application-Server-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Inter-Operator-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Transit-IOI-List"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Charging-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Session-Description"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SDP-Media-Component"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Served-Party-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Server-Capabilities"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Trunk-Group-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Bearer-Service"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Specific-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Message-Body"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Cause-Code"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Reason-Header"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Cellular-Network-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Early-Media-Description"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Communication-Service-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Application-Reference-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Online-Charging-Flag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Real-Time-Tariff-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Account-Expiration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Initial-IMS-Charging-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NNI-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "From-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Emergency-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Visited-Network-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Network-Info-Change"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Access-Transfer-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Related-IMS-Charging-Identifier"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Related-IMS-Charging-Identifier-Node"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Route-Header-Received"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Route-Header-Transmitted"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Instance-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TAD-Identifier"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Monitoring-Event-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Functionality"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Event-Timestamp"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Configuration-Activity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-Reference-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCEF-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-Number-of-Reports"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Duration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charged-Party"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Maximum-Detection-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UE-Reachability-Configuration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MONTE-Location-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Accuracy"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Number-Of-UE-Per-Location-Configuration"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Monitoring-Event-Report"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* PS-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "PS-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDN-Connection-Charging-ID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Node-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-PDP-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDP-Address-Prefix-Length"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Dynamic-Address-Flag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Dynamic-Address-Flag-Extension"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "QoS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "GGSN-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TDF-IP-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGW-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "EPDG-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAG-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CG-Address"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-Node-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGW-Change"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-IMSI-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMSI-Unauthenticated-Flag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-GGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-NSAPI"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "Called-Station-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Selection-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-Charging-Characteristics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Characteristics-Selection-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-SGSN-MCC-MNC"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-MS-TimeZone"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ADC-Rule-Base-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-Location-Info-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "User-CSG-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Presence-Reporting-Area-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 5535, .avp_name = "3GPP2-BSID"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "TWAN-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UWAN-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-RAT-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-Furnish-Charging-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PDP-Context-Type"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Offline-Charging"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Traffic-Data-Volumes"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Service-Data-Container"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 0, .avp_name = "User-Equipment-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Terminal-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Start-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Stop-Time"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Change-Condition"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Diagnostics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Low-Priority-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Mode"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "NBIFOM-Support"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Number-for-MT-SMS"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Name"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MME-Realm"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Logical-Access-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 13019, .avp_name = "Physical-Access-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Fixed-User-Location-Info"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CN-Operator-Selection-Entity"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Enhanced-Diagnostics"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SGi-PtP-Tunnelling-Method"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CP-CIoT-EPS-Optimisation-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "UNI-PDU-CP-Only-Flag"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Serving-PLMN-Rate-Control"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "APN-Rate-Control"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "Charging-Per-IP-CAN-Session-Indicator"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "RRC-Cause-Counter"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "3GPP-PS-Data-Off-Status"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SCS-AS-Address"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+ /* Service-Information */
+ {
+ /* Grouped */
+ struct dict_object * avp;
+ struct dict_avp_request avp_vendor_plus_name = { .avp_vendor = 10415, .avp_name = "Service-Information"};
+ CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &avp_vendor_plus_name, &avp)
+ struct local_rules_definition rules[] =
+ {
+ { { .avp_vendor = 0, .avp_name = "Subscription-Id"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "AoC-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "IMS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MMS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "LCS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "PoC-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MBMS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "SMS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "VCS-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "MMTel-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "ProSe-Information"}, RULE_OPTIONAL, -1, -1 },
+ { { .avp_vendor = 10415, .avp_name = "CPDT-Information"}, RULE_OPTIONAL, -1, -1 }
+ };
+ PARSE_loc_rules( rules, avp );
+ }
+
+ }
+
+ /* Commands section */
+ {
+
+ }
+
+ LOG_D( "Extension 'Dictionary definitions for ts32299_avps (e30)' initialized");
+ return 0;
+}
+
+int dict_entry(char * conffile)
+{
+ dict_ts32299_avps_load_defs(conffile);
+ return dict_ts32299_avps_load_rules(conffile);
+}
+
+const char* dict_ts32299_avps_proto_ver(char * conffile) {
+ return ts32299_avps_proto_ver;
+}
+
+const double dict_ts32299_avps_gen_ts(char * conffile) {
+ return ts32299_avps_gen_date;
+}
+
+EXTENSION_ENTRY2("dict_ts32299_avps", dict_ts32299_avps_load_defs, dict_ts32299_avps_load_rules, "dict_ts29272_avps", "dict_ts29273_avps", "dict_ts29212_avps", "dict_ts29336_avps", "dict_ts29128_avps", "dict_ts29214_avps", "dict_ts29345_avps", "dict_ts29337_avps", "dict_ts29344_avps", "dict_ts29368_avps", "dict_ts29217_avps", "dict_ts29229_avps", "dict_ts29338_avps", "dict_ts29468_avps", "dict_ts29329_avps", "dict_ts29061_avps", "dict_rfc5778_avps", "dict_ts29173_avps", "dict_rfc4006bis_avps", "dict_ts29343_avps", "dict_rfc7155_avps", "dict_rfc5447_avps", "dict_rfc7683_avps", "dict_rfc4590_avps", "dict_draftload_avps", "dict_rfc4004_avps", "dict_rfc5777_avps", "dict_etsi283034_avps", "dict_3gpp2_avps", "dict_rfc7944_avps");
+
+
+
diff --git a/extensions/dict_ts32299_avps/ts32299_avps.did b/extensions/dict_ts32299_avps/ts32299_avps.did
new file mode 100644
index 0000000..9bb29ee
--- /dev/null
+++ b/extensions/dict_ts32299_avps/ts32299_avps.did
@@ -0,0 +1,37 @@
+dict_ts29343_avps
+dict_ts29128_avps
+dict_ts29345_avps
+dict_ts29337_avps
+dict_ts29217_avps
+dict_ts29344_avps
+dict_ts29173_avps
+dict_ts29338_avps
+dict_ts29468_avps
+dict_3gpp2_avps
+dict_ts29215_avps
+dict_ts29154_avps
+dict_ts29214_avps
+dict_rfc6942_avps
+dict_rfc6734_avps
+dict_rfc5580_avps
+dict_rfc4072_avps
+dict_ts29273_avps
+dict_rfc4006bis_avps
+dict_ts29212_avps
+dict_ts29061_avps
+dict_ts29272_avps
+dict_rfc5447_avps
+dict_rfc5778_avps
+dict_rfc5777_avps
+dict_ts29336_avps
+dict_etsi283034_avps
+dict_rfc4590_avps
+dict_rfc4004_avps
+dict_rfc7155_avps
+dict_ts29229_avps
+dict_rfc7683_avps
+dict_draftload_avps
+dict_rfc7944_avps
+dict_ts29329_avps
+dict_ts29368_avps
+dict_ts32299_avps
diff --git a/extensions/fdbuild_conf.sh b/extensions/fdbuild_conf.sh
new file mode 100644
index 0000000..6d09727
--- /dev/null
+++ b/extensions/fdbuild_conf.sh
@@ -0,0 +1,42 @@
+#Copyright (c) 2017 Sprint
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#!/bin/sh
+
+usage ()
+{
+ echo "Scans the current directory and adds, as required, the "
+ echo "extensions to the specified config file intially disabled."
+ echo "Usage: $0 <config file>"
+}
+
+if [ "$#" -ne 1 ]; then
+ usage
+ exit 0
+fi
+
+if [ -e $1 ]; then
+ echo "Updating $1"
+ for D in *; do
+ if [ -d "${D}" ]; then
+ INDIR=`grep -c "${D}.fdx" $1`
+ if [ "$INDIR" -eq 0 ]; then
+ echo "Adding ${D} to file"
+ sed -i '$ i#LoadExtension = \"/usr/local/lib/freeDiameter/'"${D}"'.fdx\";' $1
+ fi
+ fi
+ done
+else
+ echo "File $1 does not exist. Please provide valid config file\n"
+fi
diff --git a/extensions/fdbuild_make.sh b/extensions/fdbuild_make.sh
new file mode 100644
index 0000000..8a13dfd
--- /dev/null
+++ b/extensions/fdbuild_make.sh
@@ -0,0 +1,43 @@
+#Copyright (c) 2017 Sprint
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#!/bin/sh
+
+usage ()
+{
+ echo "Scans the current directory and adds, as required, the "
+ echo "subdirectories to the specified cmake file with their build ON (enabled)."
+ echo "Usage: $0 <make file>"
+}
+
+
+if [ "$#" -ne 1 ]; then
+ usage
+ exit 0
+fi
+
+if [ -e $1 ]; then
+ echo "Updating $1"
+ for D in *; do
+ if [ -d "${D}" ]; then
+ INDIR=`grep -c FD_EXTENSION_SUBDIR\(${D} $1`
+ if [ "$INDIR" -eq 0 ]; then
+ echo "Adding ${D} to file"
+ echo "FD_EXTENSION_SUBDIR(${D} \"${D} extension library\" ON)" >> $1
+ fi
+ fi
+ done
+else
+ echo "File $1 doesn't exist.Please provide valid make file\n"
+fi
diff --git a/extensions/fddict_conf.sh b/extensions/fddict_conf.sh
new file mode 100644
index 0000000..a5096e4
--- /dev/null
+++ b/extensions/fddict_conf.sh
@@ -0,0 +1,55 @@
+#Copyright (c) 2017 Sprint
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#!/bin/sh
+
+usage ()
+{
+ echo "Usage: $0 <dictionary name> <ON|OFF> <config file>"
+}
+
+if [ "$#" -ne 3 ]; then
+ usage
+ exit 0
+fi
+
+if [ "$2" != "ON" ] && [ "$2" != "OFF" ]; then
+ usage
+ exit
+fi
+
+DCTDIR=$1
+STATE=$2
+CFGFILE=$3
+
+if [ -e $3 ]; then
+ if [ -d "${DCTDIR}" ]; then
+ INDIR=`grep -c "${DCTDIR}.fdx" $3`
+ if [ "$INDIR" -eq 0 ]; then
+ echo "Adding ${DCTDIR} to file"
+ sed -i '$i#LoadExtension = "/usr/local/lib/freeDiameter/'"${DCTDIR}"'.fdx";' ${CFGFILE}
+ elif [ "${STATE}" = "ON" ]; then
+ echo "Turning On"
+ sed -i 's/\#LoadExtension = "\/usr\/local\/lib\/freeDiameter\/'"${DCTDIR}"'.fdx";/LoadExtension = "\/usr\/local\/lib\/freeDiameter\/'"${DCTDIR}"'.fdx";/g' ${CFGFILE}
+ else
+ echo "Turning Off"
+ sed -i.bak -e 's/LoadExtension = "\/usr\/local\/lib\/freeDiameter\/'"${DCTDIR}"'.fdx";/#LoadExtension = "\/usr\/local\/lib\/freeDiameter\/'"${DCTDIR}"'.fdx";/g' ${CFGFILE}
+ fi
+ else
+ echo "Directory $1 doesn't exist\n"
+ fi
+else
+ echo "File $3 doesn't exist. Please provide valid conf file\n"
+fi
+
diff --git a/extensions/fddict_confall.sh b/extensions/fddict_confall.sh
new file mode 100644
index 0000000..e6bc48c
--- /dev/null
+++ b/extensions/fddict_confall.sh
@@ -0,0 +1,51 @@
+#Copyright (c) 2017 Sprint
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#!/bin/sh
+
+usage ()
+{
+ echo "Usage: $0 <dictionary name> <ON|OFF> <config file>"
+}
+
+if [ "$#" -ne 3 ]; then
+ usage
+ exit 0
+fi
+
+if [ "$2" != "ON" ] && [ "$2" != "OFF" ]; then
+ usage
+ exit
+fi
+
+DCTDIR=$1
+STATE=$2
+CFGFILE=$3
+
+if [ -e $3 ]; then
+ if [ -d "dict_${DCTDIR}" ]; then
+ if [ -e "dict_${DCTDIR}/${DCTDIR}.did" ]; then
+ while read p; do
+ echo "Turning $p $2"
+ ./fddict_conf.sh $p $2 $3
+ done <dict_${DCTDIR}/${DCTDIR}.did
+ else
+ echo "dict_${DCTDIR}.did was not present - skipping"
+ fi
+ else
+ echo "Directory dict_${DCTDIR} doesn't exist\n"
+ fi
+else
+ echo "File $3 doesn't exist. Please provide valid config file\n"
+fi
diff --git a/extensions/fddict_make.sh b/extensions/fddict_make.sh
new file mode 100644
index 0000000..607eef8
--- /dev/null
+++ b/extensions/fddict_make.sh
@@ -0,0 +1,55 @@
+#Copyright (c) 2017 Sprint
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#!/bin/sh
+
+usage ()
+{
+ echo "Used to configure cmake files to turn on/off building a specific dictionary "
+ echo "Usage: $0 <dictionary name> <ON|OFF> <make file>"
+}
+
+if [ "$#" -ne 3 ]; then
+ usage
+ exit 0
+fi
+
+if [ "$2" != "ON" ] && [ "$2" != "OFF" ]; then
+ usage
+ exit
+fi
+
+DCTDIR=$1
+STATE=$2
+CFGFILE=$3
+
+if [ -e $3 ]; then
+ if [ -d "${DCTDIR}" ]; then
+ INDIR=`grep -c FD_EXTENSION_SUBDIR\(${DCTDIR} $3`
+ if [ "$INDIR" -eq 0 ]; then
+ echo "Adding ${DCTDIR} to file"
+ echo "FD_EXTENSION_SUBDIR(${DCTDIR} \"${DCTDIR} extension library\" $2)" >> ${CFGFILE}
+ elif [ "${STATE}" = "ON" ]; then
+ echo "Turning On"
+ sed -i.bak -e "s/FD_EXTENSION_SUBDIR(${DCTDIR}\\(.*\\)\"\\(.*\\)\"\\(.*\\)*OFF)/FD_EXTENSION_SUBDIR(${DCTDIR}\\1\"\\2\"\\3ON)/" ${CFGFILE}
+ else
+ echo "Turning Off"
+ sed -i.bak -e "s/FD_EXTENSION_SUBDIR(${DCTDIR}\\(.*\\)\"\\(.*\\)\"\\(.*\\)*ON)/FD_EXTENSION_SUBDIR(${DCTDIR}\\1\"\\2\"\\3OFF)/" ${CFGFILE}
+ fi
+ else
+ echo "Directory ${DCTDIR} doesn't exist\n"
+ fi
+else
+ echo "File $3 doesn't exist. Please provide valid make file\n"
+fi
diff --git a/extensions/fddict_makeall.sh b/extensions/fddict_makeall.sh
new file mode 100644
index 0000000..00274ca
--- /dev/null
+++ b/extensions/fddict_makeall.sh
@@ -0,0 +1,54 @@
+#Copyright (c) 2017 Sprint
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#!/bin/sh
+
+usage ()
+{
+ echo "Turns on/off dictionary build in cmake for the specified"
+ echo "specific (no 'dict_' in front) and all items it depends upon"
+ echo "as defined in its associated .did file."
+ echo "Usage: $0 <dictionary name> <ON|OFF> <make file>"
+}
+
+if [ "$#" -ne 3 ]; then
+ usage
+ exit 0
+fi
+
+if [ "$2" != "ON" ] && [ "$2" != "OFF" ]; then
+ usage
+ exit
+fi
+
+DCTDIR=$1
+STATE=$2
+CFGFILE=$3
+
+if [ -e $3 ]; then
+ if [ -d "dict_${DCTDIR}" ]; then
+ if [ -e "dict_${DCTDIR}/${DCTDIR}.did" ]; then
+ while read p; do
+ echo "Turning $p $2"
+ ./fddict_make.sh $p $2 $3
+ done <dict_${DCTDIR}/${DCTDIR}.did
+ else
+ echo "dict_${DCTDIR}.did was not present - skipping"
+ fi
+ else
+ echo "Directory dict_${DCTDIR} doesn't exist\n"
+ fi
+else
+ echo "File $3 doesn't exist. Please provide valid make file\n"
+fi
diff --git a/extensions/rt_busypeers/CMakeLists.txt b/extensions/rt_busypeers/CMakeLists.txt
new file mode 100644
index 0000000..af24d81
--- /dev/null
+++ b/extensions/rt_busypeers/CMakeLists.txt
@@ -0,0 +1,30 @@
+# The rt_busypeer extension
+PROJECT("Handling of TOO_BUSY messages and relay timeout capability routing extension" C)
+
+# Parser files
+BISON_FILE(rtbusy_conf.y)
+FLEX_FILE(rtbusy_conf.l)
+SET_SOURCE_FILES_PROPERTIES(lex.rtbusy_conf.c rtbusy_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( RTBUSY_SRC
+ rtbusy.c
+ rtbusy.h
+ lex.rtbusy_conf.c
+ rtbusy_conf.tab.c
+ rtbusy_conf.tab.h
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(rt_busypeers ${RTBUSY_SRC})
+
+
+####
+## INSTALL section ##
+
+# We install with the daemon component because it is a base feature.
+INSTALL(TARGETS rt_busypeers
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-daemon)
diff --git a/extensions/rt_busypeers/rtbusy.c b/extensions/rt_busypeers/rtbusy.c
new file mode 100644
index 0000000..e554a44
--- /dev/null
+++ b/extensions/rt_busypeers/rtbusy.c
@@ -0,0 +1,281 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2015, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* See doc/rt_busypeers.conf.sample for more details about the features of this extension */
+#include "rtbusy.h"
+
+/* The configuration structure */
+struct rtbusy_conf rtbusy_conf;
+
+static struct fd_rt_fwd_hdl * rt_busy_hdl = NULL;
+
+static void rtbusy_expirecb(void * data, DiamId_t sentto, size_t senttolen, struct msg ** req);
+
+/* The function that does the actual work */
+int rt_busy_process_busy(struct msg ** pmsg, int is_req, DiamId_t sentto, size_t senttolen, union avp_value *oh)
+{
+ struct msg * qry = NULL;
+ struct rt_data * rtd = NULL;
+ struct fd_list * candidates = NULL;
+ int sendingattempts;
+ int resend = 1;
+
+
+ TRACE_ENTRY("%p(%p) %d %p %p", pmsg, pmsg?*pmsg:NULL, is_req, sentto, oh);
+
+ if (is_req) {
+ qry = *pmsg;
+ } else {
+ CHECK_FCT( fd_msg_answ_getq( *pmsg, &qry ) );
+ }
+
+ CHECK_FCT( fd_msg_rt_get ( qry, &rtd ) );
+ ASSERT(rtd);
+
+ /* rtd is the routing data associated with the query that was sent */
+
+ /* Store the error in this routing data, this avoids sending the message to the same peer again */
+ CHECK_FCT( fd_rtd_error_add(rtd,
+ sentto, senttolen,
+ (uint8_t *)(oh ? (DiamId_t)oh->os.data : fd_g_config->cnf_diamid), oh ? oh->os.len : fd_g_config->cnf_diamid_len ,
+ ER_DIAMETER_TOO_BUSY,
+ &candidates,
+ &sendingattempts) );
+
+ /* Now we need to decide if we re-send this query to a different peer or return an error to upstream */
+
+ /* First, are we exceeding the allowed attempts? */
+ if (rtbusy_conf.RetryMaxPeers != 0) {
+ if (sendingattempts >= rtbusy_conf.RetryMaxPeers) {
+ TRACE_DEBUG(FULL, "Maximum number of sending attempts reached for message %p, returning an error upstream", qry);
+ resend = 0;
+ }
+ }
+
+ if (resend) {
+ /* Check if we have any valid candidate left for sending the message. This may not be 100% accurate but there should not be
+ any situation where this is actually an issue. */
+ if (FD_IS_LIST_EMPTY(candidates)) {
+ resend = 0;
+ } else {
+ struct rtd_candidate * first = candidates->next->o;
+ if (first->score < 0) /* No more candidate available */
+ resend = 0;
+ }
+ }
+
+ /* Ok, now act on the message, we know what to do */
+ if (resend) {
+ if (!is_req) {
+ /* We must free the answer we received, and send the query again */
+ CHECK_FCT( fd_msg_answ_detach(*pmsg) );
+ CHECK_FCT( fd_msg_free(*pmsg) );
+ *pmsg = qry;
+ }
+ /* Send the query again. We need to re-associate the expirecb which was cleaned, if it is used */
+ if (rtbusy_conf.RelayTimeout) {
+ char *buf = NULL;
+ size_t len;
+ struct timespec expire;
+ CHECK_SYS( clock_gettime(CLOCK_REALTIME, &expire) );
+ expire.tv_sec += rtbusy_conf.RelayTimeout/1000 + ((expire.tv_nsec + (1000000LL * (rtbusy_conf.RelayTimeout % 1000))) / 1000000000LL);
+ expire.tv_nsec = (expire.tv_nsec + (1000000LL * (rtbusy_conf.RelayTimeout % 1000))) % 1000000000LL;
+ CHECK_MALLOC_DO( fd_msg_dump_full(&buf, &len, NULL, *pmsg, fd_g_config->cnf_dict, 0, 1), /* nothing */);
+ TRACE_ERROR( "No answer received for message from peer '%.*s' before timeout (%dms), re-sending: %s", (int)senttolen, sentto,
+ rtbusy_conf.RelayTimeout, buf);
+ free(buf);
+ CHECK_FCT( fd_msg_send_timeout( pmsg, NULL, NULL, rtbusy_expirecb, &expire ) );
+ } else {
+ CHECK_FCT( fd_msg_send(pmsg, NULL, NULL) );
+ }
+
+ } else {
+ if (is_req) {
+ char *buf = NULL;
+ size_t len;
+
+ CHECK_MALLOC_DO( fd_msg_dump_full(&buf, &len, NULL, *pmsg, fd_g_config->cnf_dict, 0, 1), /* nothing */);
+ TRACE_ERROR( "No answer received for message from peer '%.*s' before timeout (%dms), giving up and sending error reply: %s", (int)senttolen, sentto,
+ rtbusy_conf.RelayTimeout, buf);
+ free(buf);
+ /* We must create an answer */
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, pmsg, MSGFL_ANSW_ERROR ) );
+
+ CHECK_FCT( fd_msg_rescode_set(*pmsg, "DIAMETER_TOO_BUSY", "[rt_busypeers] Timeout reached while waiting for an answer", NULL, 1 ) );
+
+ CHECK_FCT( fd_msg_send(pmsg, NULL, NULL) );
+ }
+ /* Otherwise, we have nothing to do at all, the answer will be forwarded upstream as part of the normal processing */
+
+ }
+
+ return 0;
+}
+
+/* Callback called on expiry of the timeout timer */
+static void rtbusy_expirecb(void * data, DiamId_t sentto, size_t senttolen, struct msg ** preq)
+{
+ CHECK_FCT_DO( rt_busy_process_busy(preq, 1, sentto, senttolen, NULL), /* continue */ );
+}
+
+/* the routing callback that handles all the tasks of this extension */
+static int rtbusy_fwd_cb(void * cbdata, struct msg ** pmsg)
+{
+ struct msg_hdr * hdr;
+ struct avp * avp;
+ union avp_value *a_rc = NULL, *a_oh = NULL;
+ DiamId_t sentto = NULL;
+ size_t senttolen;
+
+ /* Get the header of the message */
+ CHECK_FCT( fd_msg_hdr(*pmsg, &hdr) );
+
+ /* If the message is a request, we only associate the timeout */
+ if (hdr->msg_flags & CMD_FLAG_REQUEST) {
+ struct timespec expire;
+ CHECK_SYS( clock_gettime(CLOCK_REALTIME, &expire) );
+ expire.tv_sec += rtbusy_conf.RelayTimeout/1000 + ((expire.tv_nsec + (1000000LL * (rtbusy_conf.RelayTimeout % 1000))) / 1000000000LL);
+ expire.tv_nsec = (expire.tv_nsec + (1000000LL * (rtbusy_conf.RelayTimeout % 1000))) % 1000000000LL;
+ CHECK_FCT( fd_msg_anscb_associate( *pmsg, NULL, NULL, rtbusy_expirecb, &expire ) );
+ return 0;
+ }
+
+ /* From this point, the message is an answer; we need to check if the E flag is set and if the Result-Code is DIAMETER_TOO_BUSY */
+
+ if (!(hdr->msg_flags & CMD_FLAG_ERROR)) {
+ /* This answer does not have the E flag, no need to process further */
+ return 0;
+ }
+
+ CHECK_FCT( fd_msg_source_get( *pmsg, &sentto, &senttolen ) );
+
+ /* Now get the AVPs we are interested in */
+ CHECK_FCT( fd_msg_browse(*pmsg, MSG_BRW_FIRST_CHILD, &avp, NULL) );
+ while (avp) {
+ struct avp_hdr * ahdr;
+
+ CHECK_FCT( fd_msg_avp_hdr( avp, &ahdr ) );
+ if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) {
+ switch (ahdr->avp_code) {
+ case AC_ORIGIN_HOST:
+ /* Parse this AVP */
+ CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
+ ASSERT( ahdr->avp_value );
+ a_oh = ahdr->avp_value;
+ break;
+
+ case AC_RESULT_CODE:
+ /* Parse this AVP */
+ CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
+ ASSERT( ahdr->avp_value );
+ a_rc = ahdr->avp_value;
+
+ if (a_rc->u32 != ER_DIAMETER_TOO_BUSY) {
+ /* It is not a TOO_BUSY error, we don't do anything */
+ goto out;
+ }
+ break;
+ }
+
+ if (a_rc && a_oh)
+ break;
+ }
+
+ /* Go to next AVP */
+ CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) );
+ }
+
+ /* Check we have received the necessary information */
+ if (!a_rc) {
+ TRACE_ERROR( "Invalid Diameter answer without a Result-Code AVP, rt_busypeer module gave up processing");
+ goto out;
+ }
+
+ if (!a_oh) {
+ TRACE_ERROR( "Invalid Diameter answer without an Origin-Host AVP, rt_busypeer module gave up processing");
+ goto out;
+ }
+
+ /* Pass this error to the function that processes BUSY status */
+ CHECK_FCT( rt_busy_process_busy(pmsg, 0, sentto, senttolen, a_oh) );
+
+out:
+ return 0;
+}
+
+
+/* entry point */
+static int rtbusy_entry(char * conffile)
+{
+ enum fd_rt_fwd_dir dir = RT_FWD_ANS;
+ TRACE_ENTRY("%p", conffile);
+
+ /* Initialize the configuration */
+ memset(&rtbusy_conf, 0, sizeof(rtbusy_conf));
+
+ /* Parse the configuration file */
+ CHECK_FCT( rtbusy_conf_handle(conffile) );
+
+ if (rtbusy_conf.SkipTooBusyErrors && !rtbusy_conf.RelayTimeout) {
+ TRACE_NOTICE("[rt_busypeers] Configuration file does not specify any behavior (no effect)!");
+ return 0;
+ }
+
+ if (rtbusy_conf.SkipTooBusyErrors)
+ dir = RT_FWD_REQ; /* in this case, RelayTimeout is not 0 */
+ else if (rtbusy_conf.RelayTimeout)
+ dir = RT_FWD_ALL;
+
+ /* Register the callback */
+ CHECK_FCT( fd_rt_fwd_register ( rtbusy_fwd_cb, NULL, dir, &rt_busy_hdl ) );
+
+ /* We're done */
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+
+ /* Unregister the cb */
+ if (rt_busy_hdl)
+ CHECK_FCT_DO( fd_rt_fwd_unregister ( rt_busy_hdl, NULL), /* continue */);
+
+ /* Done */
+ return ;
+}
+
+EXTENSION_ENTRY("rt_busypeers", rtbusy_entry);
diff --git a/extensions/rt_busypeers/rtbusy.h b/extensions/rt_busypeers/rtbusy.h
new file mode 100644
index 0000000..c6ce91c
--- /dev/null
+++ b/extensions/rt_busypeers/rtbusy.h
@@ -0,0 +1,54 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * See the rt_busypeers.conf.sample file for the format of the configuration file.
+ */
+
+/* FreeDiameter's common include file */
+#include <freeDiameter/extension.h>
+
+
+/* Parse the configuration file */
+int rtbusy_conf_handle(char * conffile);
+
+/* The configuration structure */
+extern struct rtbusy_conf {
+ int SkipTooBusyErrors;
+ int RetryDistantPeers;
+ int RetryMaxPeers;
+ int RelayTimeout;
+} rtbusy_conf;
+
diff --git a/extensions/rt_busypeers/rtbusy_conf.l b/extensions/rt_busypeers/rtbusy_conf.l
new file mode 100644
index 0000000..fe819bf
--- /dev/null
+++ b/extensions/rt_busypeers/rtbusy_conf.l
@@ -0,0 +1,107 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Tokenizer
+ *
+ */
+
+%{
+#include "rtbusy.h"
+#include "rtbusy_conf.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+qstring \"[^\"\n]*\"
+
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+ /* Recognize any integer */
+[-]?[[:digit:]]+ {
+ /* Convert this to an integer value */
+ int ret=0;
+ ret = sscanf(yytext, "%i", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ TRACE_ERROR("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+
+
+ /* The key words */
+(?i:"SkipTooBusyErrors") { return SKIPTOOBUSYERRORS; }
+(?i:"RetryDistantPeers") { return RETRYDISTANTPEERS; }
+(?i:"RetryMaxPeers") { return RETRYMAXPEERS; }
+(?i:"RelayTimeout") { return RELAYTIMEOUT; }
+
+ /* Valid single characters for yyparse */
+[=;] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]=;\n]+ {
+ TRACE_ERROR("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/rt_busypeers/rtbusy_conf.y b/extensions/rt_busypeers/rtbusy_conf.y
new file mode 100644
index 0000000..96a5303
--- /dev/null
+++ b/extensions/rt_busypeers/rtbusy_conf.y
@@ -0,0 +1,168 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "rtbusy.h"
+#include "rtbusy_conf.tab.h"
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+/* Parse the configuration file */
+int rtbusy_conf_handle(char * conffile)
+{
+ extern FILE * rtbusy_confin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ rtbusy_confin = fopen(conffile, "r");
+ if (rtbusy_confin == NULL) {
+ ret = errno;
+ TRACE_ERROR("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(rtbusy_confin);
+
+ if (ret != 0) {
+ TRACE_ERROR( "Unable to parse the configuration file.");
+ return EINVAL;
+ } else {
+ TRACE_DEBUG(FULL, "[rt_busypeers] Configuration: %d-%d-%d-%d.", rtbusy_conf.SkipTooBusyErrors, rtbusy_conf.RetryDistantPeers, rtbusy_conf.RetryMaxPeers, rtbusy_conf.RelayTimeout);
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int rtbusy_conflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ fd_log_error("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_error("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_error("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ int integer;
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */
+%token <integer> INTEGER
+
+/* Tokens */
+%token SKIPTOOBUSYERRORS
+%token RETRYDISTANTPEERS
+%token RETRYMAXPEERS
+%token RELAYTIMEOUT
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty is OK */
+ | conffile toobusy
+ | conffile distant
+ | conffile maxretry
+ | conffile timeout
+ | conffile errors
+ {
+ yyerror(&yylloc, conffile, "An error occurred while parsing the configuration file");
+ return EINVAL;
+ }
+ ;
+
+ /* Lexical or syntax error */
+errors: LEX_ERROR
+ | error
+ ;
+
+toobusy: SKIPTOOBUSYERRORS ';'
+ {
+ rtbusy_conf.SkipTooBusyErrors=1;
+ }
+ ;
+
+distant: RETRYDISTANTPEERS ';'
+ {
+ rtbusy_conf.RetryDistantPeers=1;
+ }
+ ;
+
+maxretry: RETRYMAXPEERS '=' INTEGER ';'
+ {
+ rtbusy_conf.RetryMaxPeers=$3;
+ }
+ ;
+
+timeout: RELAYTIMEOUT '=' INTEGER ';'
+ {
+ rtbusy_conf.RelayTimeout=$3;
+ }
+ ;
+
diff --git a/extensions/rt_default/CMakeLists.txt b/extensions/rt_default/CMakeLists.txt
new file mode 100644
index 0000000..bdaa42c
--- /dev/null
+++ b/extensions/rt_default/CMakeLists.txt
@@ -0,0 +1,43 @@
+# The rt_default extension
+PROJECT("Configurable routing extension" C)
+
+# Check if REG_STARTEND is provided on the host
+SET(CHECK_REG_STARTEND_SOURCE_CODE "
+ #include <unistd.h>
+ #include <regex.h>
+ int main() {
+ return regexec(NULL, NULL, 0, NULL, REG_STARTEND);
+ }
+ ")
+CHECK_C_SOURCE_COMPILES("${CHECK_REG_STARTEND_SOURCE_CODE}" HAVE_REG_STARTEND)
+# Generate the host.h file
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/rt_default-host.h.in ${CMAKE_CURRENT_BINARY_DIR}/rt_default-host.h)
+
+# Parser files
+BISON_FILE(rtd_conf.y)
+FLEX_FILE(rtd_conf.l)
+SET_SOURCE_FILES_PROPERTIES(lex.rtd_conf.c rtd_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( RT_DEFAULT_SRC
+ rt_default.c
+ rt_default.h
+ lex.rtd_conf.c
+ rtd_conf.tab.c
+ rtd_conf.tab.h
+ rtd_rules.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(rt_default ${RT_DEFAULT_SRC})
+
+
+####
+## INSTALL section ##
+
+# We install with the daemon component because it is a base feature.
+INSTALL(TARGETS rt_default
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-daemon)
diff --git a/extensions/rt_default/rt_default-host.h.in b/extensions/rt_default/rt_default-host.h.in
new file mode 100644
index 0000000..34e05a5
--- /dev/null
+++ b/extensions/rt_default/rt_default-host.h.in
@@ -0,0 +1,42 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Configuration from compile-time */
+#ifndef RTD_IS_CONFIG
+#define RTD_IS_CONFIG
+
+#cmakedefine HAVE_REG_STARTEND
+
+#endif /* RTD_IS_CONFIG */
diff --git a/extensions/rt_default/rt_default.c b/extensions/rt_default/rt_default.c
new file mode 100644
index 0000000..dd4057a
--- /dev/null
+++ b/extensions/rt_default/rt_default.c
@@ -0,0 +1,99 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * Configurable routing of messages for freeDiameter.
+ */
+
+#include "rt_default.h"
+
+/* The callback called on new messages */
+static int rtd_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
+{
+ struct msg * msg = *pmsg;
+ TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
+
+ CHECK_PARAMS(msg && candidates);
+
+ /* Simply pass it to the appropriate function */
+ if (FD_IS_LIST_EMPTY(candidates)) {
+ return 0;
+ } else {
+ return rtd_process( msg, candidates );
+ }
+}
+
+/* handler */
+static struct fd_rt_out_hdl * rtd_hdl = NULL;
+
+/* entry point */
+static int rtd_entry(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* Initialize the repo */
+ CHECK_FCT( rtd_init() );
+
+ /* Parse the configuration file */
+ CHECK_FCT( rtd_conf_handle(conffile) );
+
+#if 0
+ /* Dump the rules */
+ rtd_dump();
+#endif /* 0 */
+
+ /* Register the callback */
+ CHECK_FCT( fd_rt_out_register( rtd_out, NULL, 5, &rtd_hdl ) );
+
+ /* We're done */
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+
+ /* Unregister the cb */
+ CHECK_FCT_DO( fd_rt_out_unregister ( rtd_hdl, NULL ), /* continue */ );
+
+ /* Destroy the data */
+ rtd_fini();
+
+ /* Done */
+ return ;
+}
+
+EXTENSION_ENTRY("rt_default", rtd_entry);
diff --git a/extensions/rt_default/rt_default.h b/extensions/rt_default/rt_default.h
new file mode 100644
index 0000000..8ecaa5e
--- /dev/null
+++ b/extensions/rt_default/rt_default.h
@@ -0,0 +1,86 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Header file for the rt_default extension.
+ *
+ * See the rt_default.conf.sample file for the format of the configuration file.
+ */
+
+/* FreeDiameter's common include file */
+#include <freeDiameter/extension.h>
+
+/* Host configuration for this specific extension */
+#include <rt_default-host.h>
+
+/* Parse the configuration file */
+int rtd_conf_handle(char * conffile);
+
+/* Initialize the rules repository */
+int rtd_init(void);
+
+/* Destroy the rules repository */
+void rtd_fini(void);
+
+/* Some constants definitions */
+enum rtd_crit_type {
+ RTD_CRI_ALL = 0,
+ RTD_CRI_OH,
+ RTD_CRI_OR,
+ RTD_CRI_DH,
+ RTD_CRI_DR,
+ RTD_CRI_UN,
+ RTD_CRI_SI,
+
+ RTD_CRI_MAX
+};
+
+enum rtd_targ_type {
+ RTD_TAR_ID = 0,
+ RTD_TAR_REALM,
+
+ RTD_TAR_MAX
+};
+
+#define RTD_CRIT_REG 0x1
+#define RTD_TARG_REG 0x2
+
+/* Add a rule */
+int rtd_add(enum rtd_crit_type ct, char * criteria, enum rtd_targ_type tt, char * target, int score, int flags);
+
+/* Process a message & peer list through the rules repository, updating the scores */
+int rtd_process( struct msg * msg, struct fd_list * candidates );
+
+/* For debug: dump the rule repository */
+void rtd_dump(void);
diff --git a/extensions/rt_default/rtd_conf.l b/extensions/rt_default/rtd_conf.l
new file mode 100644
index 0000000..b256aa8
--- /dev/null
+++ b/extensions/rt_default/rtd_conf.l
@@ -0,0 +1,146 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Tokenizer
+ *
+ */
+
+%{
+#include "rt_default.h"
+/* Include yacc tokens definitions */
+#include "rtd_conf.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+qstring \"[^\"\n]*\"
+
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+ /* Recognize any integer */
+[-]?[[:digit:]]+ {
+ /* Convert this to an integer value */
+ int ret=0;
+ ret = sscanf(yytext, "%i", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+ /* In addition, recognize some constant names as integers also */
+(?i:"NO_DELIVERY") { yylval->integer = FD_SCORE_NO_DELIVERY; return INTEGER; }
+(?i:"DEFAULT") { yylval->integer = FD_SCORE_DEFAULT; return INTEGER; }
+(?i:"DEFAULT_REALM") { yylval->integer = FD_SCORE_DEFAULT_REALM; return INTEGER; }
+(?i:"REALM") { yylval->integer = FD_SCORE_REALM; return INTEGER; }
+(?i:"REDIR_HOST") { yylval->integer = FD_SCORE_REDIR_HOST; return INTEGER; }
+(?i:"REDIR_APP") { yylval->integer = FD_SCORE_REDIR_APP; return INTEGER; }
+(?i:"REDIR_REALM") { yylval->integer = FD_SCORE_REDIR_REALM; return INTEGER; }
+(?i:"REDIR_REALM_APP") { yylval->integer = FD_SCORE_REDIR_REALM_APP; return INTEGER; }
+(?i:"REDIR_USER") { yylval->integer = FD_SCORE_REDIR_USER; return INTEGER; }
+(?i:"REDIR_SESSION") { yylval->integer = FD_SCORE_REDIR_SESSION; return INTEGER; }
+(?i:"FINALDEST") { yylval->integer = FD_SCORE_FINALDEST; return INTEGER; }
+
+ /* Recognize bracketed quoted strings */
+[[]{qstring}[]] {
+ /* Match a quoted string containing a regex */
+ CHECK_MALLOC_DO( yylval->string = strdup(yytext+2),
+ {
+ TRACE_DEBUG(INFO, "Unable to copy the string '%s': %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ } );
+ yylval->string[strlen(yytext) - 4] = '\0';
+ return BQSTRING;
+ }
+
+ /* Recognize quoted strings */
+{qstring} {
+ /* Match a quoted string. */
+ CHECK_MALLOC_DO( yylval->string = strdup(yytext+1),
+ {
+ TRACE_DEBUG(INFO, "Unable to copy the string '%s': %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ } );
+ yylval->string[strlen(yytext) - 2] = '\0';
+ return QSTRING;
+ }
+
+ /* The key words */
+(?i:"oh") { return OH; }
+(?i:"or") { return OR; }
+(?i:"dh") { return DH; }
+(?i:"dr") { return DR; }
+(?i:"un") { return UN; }
+(?i:"si") { return SI; }
+(?i:"rlm") { return REALM; }
+
+ /* Valid single characters for yyparse */
+[*:=+-;] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]\"*:=+;\n]+ {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/rt_default/rtd_conf.y b/extensions/rt_default/rtd_conf.y
new file mode 100644
index 0000000..d6ed329
--- /dev/null
+++ b/extensions/rt_default/rtd_conf.y
@@ -0,0 +1,273 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ * See doc/rt_default.conf.sample for configuration file format
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "rt_default.h"
+#include "rtd_conf.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+static int rules_added = 0;
+
+/* Parse the configuration file */
+int rtd_conf_handle(char * conffile)
+{
+ extern FILE * rtd_confin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ rtd_confin = fopen(conffile, "r");
+ if (rtd_confin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(rtd_confin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ } else {
+ TRACE_DEBUG(FULL, "Added %d RULES routing entries successfully.", rules_added);
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int rtd_conflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ int integer; /* Store integer values */
+ char *string; /* The string is allocated by strdup in lex.*/
+ struct {
+ char * str;
+ int regex;
+ } tstring; /* typed string */
+ struct {
+ char * str;
+ int regex;
+ enum rtd_crit_type type;
+ } criteria;
+ struct {
+ char * str;
+ int regex;
+ enum rtd_targ_type type;
+ } target;
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */
+%token <string> QSTRING
+/* A (de)bracket-quoted string (malloc'd in lex parser; it must be freed after use): ["blahblah"] */
+%token <string> BQSTRING
+
+/* An integer value */
+%token <integer> INTEGER
+
+/* The types for this gramar */
+%type <tstring> TSTRING
+%type <criteria> CRITERIA
+%type <target> TARGET
+%type <integer> EXPR_INT
+
+/* Tokens */
+%token OH
+%token OR
+%token DH
+%token DR
+%token UN
+%token SI
+
+%token REALM
+
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK */
+ | conffile rule
+ ;
+
+ /* a RULE entry */
+rule: CRITERIA ':' TARGET '+' '=' EXPR_INT ';'
+ {
+ int flag = 0;
+ if ($1.regex)
+ flag |= RTD_CRIT_REG;
+ if ($3.regex)
+ flag |= RTD_TARG_REG;
+
+ /* Add this rule to the repository */
+ CHECK_FCT_DO( rtd_add($1.type, $1.str, $3.type, $3.str, $6, flag),
+ {
+ yyerror (&yylloc, conffile, "An error occurred while adding a rule, aborting...");
+ YYERROR;
+ } );
+
+ rules_added++;
+ }
+ ;
+
+ /* QSTRING and BQSTRING are equivalent in the grammar */
+TSTRING: QSTRING
+ {
+ $$.str = $1;
+ $$.regex = 0;
+ }
+ | BQSTRING
+ {
+ $$.str = $1;
+ $$.regex = 1;
+ }
+ ;
+
+ /* Details of the CRITERIA type */
+CRITERIA: '*'
+ {
+ $$.str = NULL;
+ $$.regex = 0;
+ $$.type = RTD_CRI_ALL;
+ }
+ | OH '=' TSTRING
+ {
+ $$.str = $3.str;
+ $$.regex =$3.regex;
+ $$.type = RTD_CRI_OH;
+ }
+ | OR '=' TSTRING
+ {
+ $$.str = $3.str;
+ $$.regex =$3.regex;
+ $$.type = RTD_CRI_OR;
+ }
+ | DH '=' TSTRING
+ {
+ $$.str = $3.str;
+ $$.regex =$3.regex;
+ $$.type = RTD_CRI_DH;
+ }
+ | DR '=' TSTRING
+ {
+ $$.str = $3.str;
+ $$.regex =$3.regex;
+ $$.type = RTD_CRI_DR;
+ }
+ | UN '=' TSTRING
+ {
+ $$.str = $3.str;
+ $$.regex =$3.regex;
+ $$.type = RTD_CRI_UN;
+ }
+ | SI '=' TSTRING
+ {
+ $$.str = $3.str;
+ $$.regex =$3.regex;
+ $$.type = RTD_CRI_SI;
+ }
+ ;
+
+ /* Details of the TARGET type */
+TARGET: TSTRING
+ {
+ $$.str = $1.str;
+ $$.regex =$1.regex;
+ $$.type = RTD_TAR_ID;
+ }
+ | REALM '=' TSTRING
+ {
+ $$.str = $3.str;
+ $$.regex =$3.regex;
+ $$.type = RTD_TAR_REALM;
+ }
+ ;
+
+ /* An expression that has an integer value; we allow + and - operators cause it is convenient */
+EXPR_INT: INTEGER
+ {
+ $$ = $1;
+ }
+ | EXPR_INT '+' INTEGER
+ {
+ $$ = $1 + $3;
+ }
+ | EXPR_INT '-' INTEGER
+ {
+ $$ = $1 - $3;
+ }
+ ;
diff --git a/extensions/rt_default/rtd_rules.c b/extensions/rt_default/rtd_rules.c
new file mode 100644
index 0000000..8d3a53c
--- /dev/null
+++ b/extensions/rt_default/rtd_rules.c
@@ -0,0 +1,608 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "rt_default.h"
+
+/* The regular expressions header */
+#include <regex.h>
+
+/* We will search for each candidate peer all the rules that are defined, and check which one applies to the message
+ * Therefore our repository is organized hierarchicaly.
+ * At the top level, we have two lists of TARGETS (one for IDENTITY, one for REALM), ordered as follow:
+ * - first, the TARGETS defined with a regular expression. We will try matching all regexp to all candidates in the list.
+ * - then, the TARGETS defined by a plain text. We don't have to compare the whole list to each candidate since the list is ordered.
+ *
+ * Under each TARGET element, we have the list of RULES that are defined for this target, ordered by CRITERIA type, then is_regex, then string value.
+ *
+ * Note: Except during configuration parsing and module termination, the lists are only ever accessed read-only, so we do not need a lock.
+ */
+
+/* Structure to hold the data that is used for matching. */
+struct match_data {
+ int is_regex; /* determines how the string is matched */
+ char *plain; /* match this value with strcasecmp if is_regex is false. The string is allocated by the lex tokenizer, must be freed at the end. */
+ regex_t preg; /* match with regexec if is_regex is true. regfree must be called at the end. A copy of the original string is anyway saved in plain. */
+};
+
+/* The sentinels for the TARGET lists */
+static struct fd_list TARGETS[RTD_TAR_MAX];
+
+/* Structure of a TARGET element */
+struct target {
+ struct fd_list chain; /* link in the top-level list */
+ struct match_data md; /* the data to determine if the current candidate matches this element */
+ struct fd_list rules[RTD_CRI_MAX]; /* Sentinels for the lists of rules applying to this target. One list per rtd_crit_type */
+ /* note : we do not need the rtd_targ_type here, it is implied by the root of the list this target element is attached to */
+};
+
+/* Structure of a RULE element */
+struct rule {
+ struct fd_list chain; /* link in the parent target list */
+ struct match_data md; /* the data that the criteria must match, -- ignored for RTD_CRI_ALL */
+ int score; /* The score added to the candidate, if the message matches this criteria */
+ /* The type of rule depends on the sentinel */
+};
+
+/*********************************************************************/
+
+/* Compile a regular expression pattern */
+static int compile_regex( regex_t * preg, char * str )
+{
+ int err;
+
+ /* Compile the regular expression */
+ err = regcomp(preg, str, REG_EXTENDED | REG_NOSUB);
+ if (err != 0) {
+ char * buf;
+ size_t bl;
+
+ /* Error while compiling the regex */
+ TRACE_DEBUG(INFO, "Error while compiling the regular expression '%s':", str);
+
+ /* Get the error message size */
+ bl = regerror(err, preg, NULL, 0);
+
+ /* Alloc the buffer for error message */
+ CHECK_MALLOC( buf = malloc(bl) );
+
+ /* Get the error message content */
+ regerror(err, preg, buf, bl);
+ TRACE_DEBUG(INFO, "\t%s", buf);
+
+ /* Free the buffer, return the error */
+ free(buf);
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+/* Create a target item and initialize its content */
+static struct target * new_target(char * str, int regex)
+{
+ int i;
+ struct target *new = NULL;
+ CHECK_MALLOC_DO( new = malloc(sizeof(struct target)), return NULL );
+ memset(new, 0, sizeof(struct target));
+
+ fd_list_init(&new->chain, new);
+ new->md.plain = str;
+ new->md.is_regex = regex;
+ if (regex) {
+ CHECK_FCT_DO( compile_regex(&new->md.preg, str),
+ {
+ free(new);
+ return NULL;
+ } );
+ }
+ for (i = 0; i < RTD_CRI_MAX; i++) {
+ fd_list_init(&new->rules[i], new);
+ }
+ return new;
+}
+
+/* Create a rule item and initialize its content; return NULL in case of error */
+static struct rule * new_rule(char * str, int regex, int score)
+{
+ struct rule *new = NULL;
+ CHECK_MALLOC_DO( new = malloc(sizeof(struct rule)), return NULL );
+ memset(new, 0, sizeof(struct rule));
+
+ fd_list_init(&new->chain, new);
+ new->md.plain = str;
+ new->md.is_regex = regex;
+ if (regex) {
+ CHECK_FCT_DO( compile_regex(&new->md.preg, str),
+ {
+ free(new);
+ return NULL;
+ } );
+ }
+ new->score = score;
+ return new;
+}
+
+/* Debug functions */
+static void dump_rule(int indent, struct rule * rule)
+{
+ fd_log_debug("%*s%s%s%s += %d",
+ indent, "",
+ rule->md.is_regex ? "[" : "'",
+ rule->md.plain,
+ rule->md.is_regex ? "]" : "'",
+ rule->score);
+}
+static void dump_target(int indent, struct target * target)
+{
+ int i;
+ fd_log_debug("%*s%s%s%s :",
+ indent, "",
+ target->md.is_regex ? "[" : "'",
+ target->md.plain ?: "(empty)",
+ target->md.is_regex ? "]" : "'");
+ for (i = 0; i < RTD_CRI_MAX; i++) {
+ if (! FD_IS_LIST_EMPTY(&target->rules[i])) {
+ struct fd_list * li;
+ fd_log_debug("%*s rules[%d]:",
+ indent, "", i);
+ for (li = target->rules[i].next; li != &target->rules[i]; li = li->next) {
+ dump_rule(indent + 3, (struct rule *)li);
+ }
+ }
+ }
+}
+
+static void clear_md(struct match_data * md)
+{
+ /* delete the string */
+ if (md->plain) {
+ free(md->plain);
+ md->plain = NULL;
+ }
+
+ /* delete the preg if needed */
+ if (md->is_regex) {
+ regfree(&md->preg);
+ md->is_regex = 0;
+ }
+}
+
+/* Destroy a rule item */
+static void del_rule(struct rule * del)
+{
+ /* Unlink this rule */
+ fd_list_unlink(&del->chain);
+
+ /* Delete the match data */
+ clear_md(&del->md);
+
+ free(del);
+}
+
+/* Destroy a target item, and all its rules */
+static void del_target(struct target * del)
+{
+ int i;
+
+ /* Unlink this target */
+ fd_list_unlink(&del->chain);
+
+ /* Delete the match data */
+ clear_md(&del->md);
+
+ /* Delete the children rules */
+ for (i = 0; i < RTD_CRI_MAX; i++) {
+ while (! FD_IS_LIST_EMPTY(&del->rules[i]) ) {
+ del_rule((struct rule *)(del->rules[i].next));
+ }
+ }
+
+ free(del);
+}
+
+
+/* Compare a string with a match_data value. *res contains the result of the comparison (always >0 for regex non-match situations) */
+static int compare_match(char * str, size_t len, struct match_data * md, int * res)
+{
+ int err;
+
+ CHECK_PARAMS( str && md && res );
+
+ /* Plain strings: we compare with strncasecmp */
+ if (md->is_regex == 0) {
+ *res = strncasecmp(str, md->plain, len);
+ return 0;
+ }
+
+ /* Regexp */
+ *res = 1;
+
+#ifdef HAVE_REG_STARTEND
+ {
+ regmatch_t pmatch[1];
+ memset(pmatch, 0, sizeof(pmatch));
+ pmatch[0].rm_so = 0;
+ pmatch[0].rm_eo = len;
+ err = regexec(&md->preg, str, 0, pmatch, REG_STARTEND);
+ }
+#else /* HAVE_REG_STARTEND */
+ {
+ /* We have to create a copy of the string in this case */
+ char *mystrcpy;
+ CHECK_MALLOC( mystrcpy = os0dup(str, len) );
+ err = regexec(&md->preg, mystrcpy, 0, NULL, 0);
+ free(mystrcpy);
+ }
+#endif /* HAVE_REG_STARTEND */
+
+ /* Now check the result */
+ if (err == 0) {
+ /* We have a match */
+ *res = 0;
+ return 0;
+ }
+
+ if (err == REG_NOMATCH) {
+ *res = 1;
+ return 0;
+ }
+
+ /* In other cases, we have an error */
+ {
+ char * buf;
+ size_t bl;
+
+ /* Error while compiling the regex */
+ TRACE_DEBUG(INFO, "Error while executing the regular expression '%s':", md->plain);
+
+ /* Get the error message size */
+ bl = regerror(err, &md->preg, NULL, 0);
+
+ /* Alloc the buffer for error message */
+ CHECK_MALLOC( buf = malloc(bl) );
+
+ /* Get the error message content */
+ regerror(err, &md->preg, buf, bl);
+ TRACE_DEBUG(INFO, "\t%s", buf);
+
+ /* Free the buffer, return the error */
+ free(buf);
+ }
+
+ return (err == REG_ESPACE) ? ENOMEM : EINVAL;
+}
+
+/* Search in list (targets or rules) the next matching item for octet string str(len). Returned in next_match, or *next_match == NULL if no more match. Re-enter with same next_match for the next one. */
+static int get_next_match(struct fd_list * list, char * str, size_t len, struct fd_list ** next_match)
+{
+ struct fd_list * li;
+
+ TRACE_ENTRY("%p %p %zd %p", list, str, len, next_match);
+ CHECK_PARAMS(list && str && len && next_match);
+
+ if (*next_match)
+ li = (*next_match)->next;
+ else
+ li = list->next;
+
+ /* Initialize the return value */
+ *next_match = NULL;
+
+ for ( ; li != list; li = li->next) {
+ int cmp;
+ struct {
+ struct fd_list chain;
+ struct match_data md;
+ } * next_item = (void *)li;
+
+ /* Check if the string matches this next item */
+ CHECK_FCT( compare_match(str, len, &next_item->md, &cmp) );
+
+ if (cmp == 0) {
+ /* matched! */
+ *next_match = li;
+ return 0;
+ }
+
+ if (cmp < 0) /* we can stop searching */
+ break;
+ }
+
+ /* We're done with the list */
+ return 0;
+}
+
+static struct dict_object * AVP_MODELS[RTD_CRI_MAX];
+
+/*********************************************************************/
+
+/* Prepare the module */
+int rtd_init(void)
+{
+ int i;
+
+ TRACE_ENTRY();
+
+ for (i = 0; i < RTD_TAR_MAX; i++) {
+ fd_list_init(&TARGETS[i], NULL);
+ }
+
+ for (i = 1; i < RTD_CRI_MAX; i++) {
+ switch (i) {
+ case RTD_CRI_OH:
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &AVP_MODELS[i], ENOENT ));
+ break;
+ case RTD_CRI_OR:
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &AVP_MODELS[i], ENOENT ));
+ break;
+ case RTD_CRI_DH:
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &AVP_MODELS[i], ENOENT ));
+ break;
+ case RTD_CRI_DR:
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &AVP_MODELS[i], ENOENT ));
+ break;
+ case RTD_CRI_UN:
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &AVP_MODELS[i], ENOENT ));
+ break;
+ case RTD_CRI_SI:
+ CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &AVP_MODELS[i], ENOENT ));
+ break;
+ default:
+ TRACE_DEBUG(INFO, "Missing definition in extension initializer");
+ ASSERT( 0 );
+ return EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+/* Destroy the module's data */
+void rtd_fini(void)
+{
+ int i;
+
+ TRACE_ENTRY();
+
+ for (i = 0; i < RTD_TAR_MAX; i++) {
+ while (!FD_IS_LIST_EMPTY(&TARGETS[i])) {
+ del_target((struct target *) TARGETS[i].next);
+ }
+ }
+
+}
+
+/* Add a new rule in the repository. this is called when the configuration file is being parsed */
+int rtd_add(enum rtd_crit_type ct, char * criteria, enum rtd_targ_type tt, char * target, int score, int flags)
+{
+ struct fd_list * target_suiv = NULL;
+ struct fd_list * rule_suiv = NULL;
+ struct target * trg = NULL;
+ struct rule * rul = NULL;
+
+ TRACE_ENTRY("%d %p %d %p %d %x", ct, criteria, tt, target, score, flags);
+ CHECK_PARAMS((ct < RTD_CRI_MAX) && ((ct == RTD_CRI_ALL) || criteria) && (tt < RTD_TAR_MAX) && target);
+
+ /* First, search in the TARGET list if we already have this target */
+ for (target_suiv = TARGETS[tt].next; target_suiv != &TARGETS[tt]; target_suiv = target_suiv->next) {
+ int cmp;
+ struct target * cur = (struct target *)target_suiv;
+
+ if (flags & RTD_TARG_REG) {
+ /* We are adding a regexp, it is saved in the list before the plain expressions */
+ if (cur->md.is_regex == 0)
+ break;
+ } else {
+ /* We are adding a plain expression, save it after all regexps */
+ if (cur->md.is_regex != 0)
+ continue;
+ }
+
+ /* At this point, the type is the same, so compare the plain string value */
+ cmp = strcmp(cur->md.plain, target);
+ if (cmp < 0)
+ continue;
+
+ if (cmp == 0) /* We already have a target with the same string */
+ trg = cur;
+
+ break;
+ }
+
+ if (trg) {
+ /* Ok, we can free the target string, we will use the previously allocated one */
+ free(target);
+ } else {
+ CHECK_MALLOC( trg = new_target(target, flags & RTD_TARG_REG) );
+ fd_list_insert_before( target_suiv, &trg->chain );
+ }
+
+ /* Now, search for the rule position in this target's list */
+ if (ct == RTD_CRI_ALL) {
+ /* Special case: we don't have a criteria -- always create a rule element */
+ CHECK_MALLOC( rul = new_rule(NULL, 0, score) );
+ fd_list_insert_before( &trg->rules[RTD_CRI_ALL], &rul->chain );
+ } else {
+ for (rule_suiv = trg->rules[ct].next; rule_suiv != &trg->rules[ct]; rule_suiv = rule_suiv->next) {
+ int cmp;
+ struct rule * cur = (struct rule *)rule_suiv;
+
+ if (flags & RTD_CRIT_REG) {
+ /* We are adding a regexp, it is saved in the list before the plain expressions */
+ if (cur->md.is_regex == 0)
+ break;
+ } else {
+ /* We are adding a plain expression, save it after all regexps */
+ if (cur->md.is_regex != 0)
+ continue;
+ }
+
+ /* At this point, the type is the same, so compare the plain string value */
+ cmp = strcmp(cur->md.plain, criteria);
+ if (cmp < 0)
+ continue;
+
+ if (cmp == 0) /* We already have a target with the same string */
+ rul = cur;
+
+ break;
+ }
+
+ if (rul) {
+ /* Ok, we can free the target string, we will use the previously allocated one */
+ free(criteria);
+ TRACE_DEBUG(INFO, "Warning: duplicate rule (%s : %s) found, merging score...", rul->md.plain, trg->md.plain);
+ rul->score += score;
+ } else {
+ CHECK_MALLOC( rul = new_rule(criteria, flags & RTD_CRIT_REG, score) );
+ fd_list_insert_before( rule_suiv, &rul->chain );
+ }
+ }
+
+ return 0;
+}
+
+/* Check if a message and list of eligible candidate match any of our rules, and update its score according to it. */
+int rtd_process( struct msg * msg, struct fd_list * candidates )
+{
+ struct fd_list * li;
+ struct {
+ enum { NOT_RESOLVED_YET = 0, NOT_FOUND, FOUND } status;
+ union avp_value * avp;
+ } parsed_msg_avp[RTD_CRI_MAX];
+
+ TRACE_ENTRY("%p %p", msg, candidates);
+ CHECK_PARAMS(msg && candidates);
+
+ /* We delay looking for the AVPs in the message until we really need them. Another approach would be to parse the message once and save all needed AVPs. */
+ memset(parsed_msg_avp, 0, sizeof(parsed_msg_avp));
+
+ /* For each candidate in the list */
+ for (li = candidates->next; li != candidates; li = li->next) {
+ struct rtd_candidate * cand = (struct rtd_candidate *)li;
+ int i;
+ struct {
+ char * str;
+ size_t len;
+ } cand_data[RTD_TAR_MAX] = {
+ { cand->diamid, strlen(cand->diamid) },
+ { cand->realm, strlen(cand->realm) }
+ };
+
+ for (i = 0; i < RTD_TAR_MAX; i++) {
+ /* Search the next rule matching this candidate in the i-th target list */
+ struct target * target = NULL;
+
+ do {
+ int j;
+ struct fd_list * l;
+ struct rule * r;
+
+ CHECK_FCT ( get_next_match( &TARGETS[i], cand_data[i].str, cand_data[i].len, (void *)&target) );
+ if (!target)
+ break;
+
+ /* First, apply all rules of criteria RTD_CRI_ALL */
+ for ( l = target->rules[RTD_CRI_ALL].next; l != &target->rules[RTD_CRI_ALL]; l = l->next ) {
+ r = (struct rule *)l;
+ cand->score += r->score;
+ TRACE_DEBUG(ANNOYING, "Applied rule {'*' : '%s' += %d} to candidate '%s'", target->md.plain, r->score, cand->diamid);
+ }
+
+ /* The target is matching this candidate, check if there are additional rules criteria matching this message. */
+ for ( j = 1; j < RTD_CRI_MAX; j++ ) {
+ if ( ! FD_IS_LIST_EMPTY(&target->rules[j]) ) {
+ /* if needed, find the required data in the message */
+ if (parsed_msg_avp[j].status == NOT_RESOLVED_YET) {
+ struct avp * avp = NULL;
+ /* Search for the AVP in the message */
+ CHECK_FCT( fd_msg_search_avp ( msg, AVP_MODELS[j], &avp ) );
+ if (avp == NULL) {
+ parsed_msg_avp[j].status = NOT_FOUND;
+ } else {
+ struct avp_hdr * ahdr = NULL;
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+ if (ahdr->avp_value == NULL) {
+ /* This should not happen, but anyway let's just ignore it */
+ parsed_msg_avp[j].status = NOT_FOUND;
+ } else {
+ /* OK, we got the AVP */
+ parsed_msg_avp[j].status = FOUND;
+ parsed_msg_avp[j].avp = ahdr->avp_value;
+ }
+ }
+ }
+
+ /* If we did not find the data for these rules in the message, just skip the series */
+ if (parsed_msg_avp[j].status == NOT_FOUND) {
+ TRACE_DEBUG(ANNOYING, "Skipping series of rules %d of target '%s', criteria absent from the message", j, target->md.plain);
+ continue;
+ }
+
+ /* OK, we can now check if one of our rule's criteria match the message content */
+ r = NULL;
+ do {
+ CHECK_FCT ( get_next_match( &target->rules[j], (char *) /* is this cast safe? */ parsed_msg_avp[j].avp->os.data, parsed_msg_avp[j].avp->os.len, (void *)&r) );
+ if (!r)
+ break;
+
+ cand->score += r->score;
+ TRACE_DEBUG(ANNOYING, "Applied rule {'%s' : '%s' += %d} to candidate '%s'", r->md.plain, target->md.plain, r->score, cand->diamid);
+ } while (1);
+ }
+ }
+ } while (1);
+ }
+ }
+
+ return 0;
+}
+
+void rtd_dump(void)
+{
+ int i;
+ fd_log_debug("[rt_default] Dumping rules repository...");
+ for (i = 0; i < RTD_TAR_MAX; i++) {
+ if (!FD_IS_LIST_EMPTY( &TARGETS[i] )) {
+ struct fd_list * li;
+ fd_log_debug(" Targets list %d:", i);
+ for (li = TARGETS[i].next; li != &TARGETS[i]; li = li->next) {
+ dump_target(4, (struct target *)li);
+ }
+ }
+ }
+
+ fd_log_debug("[rt_default] End of dump");
+}
diff --git a/extensions/rt_ereg/CMakeLists.txt b/extensions/rt_ereg/CMakeLists.txt
new file mode 100644
index 0000000..2b6ec2e
--- /dev/null
+++ b/extensions/rt_ereg/CMakeLists.txt
@@ -0,0 +1,44 @@
+# The rt_ereg extension
+PROJECT("Regular expression matching based routing extension" C)
+
+# Check if REG_STARTEND is provided on the host
+SET(CHECK_REG_STARTEND_SOURCE_CODE "
+ #include <unistd.h>
+ #include <regex.h>
+ int main() {
+ return regexec(NULL, NULL, 0, NULL, REG_STARTEND);
+ }
+ ")
+CHECK_C_SOURCE_COMPILES("${CHECK_REG_STARTEND_SOURCE_CODE}" HAVE_REG_STARTEND)
+IF (HAVE_REG_STARTEND)
+ ADD_DEFINITIONS(-DHAVE_REG_STARTEND)
+ENDIF (HAVE_REG_STARTEND)
+
+
+# Parser files
+BISON_FILE(rtereg_conf.y)
+FLEX_FILE(rtereg_conf.l)
+SET_SOURCE_FILES_PROPERTIES(lex.rtereg_conf.c rtereg_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( RTEREG_SRC
+ rtereg.c
+ rtereg.h
+ lex.rtereg_conf.c
+ rtereg_conf.tab.c
+ rtereg_conf.tab.h
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(rt_ereg ${RTEREG_SRC})
+
+
+####
+## INSTALL section ##
+
+# We install with the daemon component because it is a base feature.
+INSTALL(TARGETS rt_ereg
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-daemon)
diff --git a/extensions/rt_ereg/rtereg.c b/extensions/rt_ereg/rtereg.c
new file mode 100644
index 0000000..be4db16
--- /dev/null
+++ b/extensions/rt_ereg/rtereg.c
@@ -0,0 +1,225 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * This extension allows to perform some pattern-matching on an AVP
+ * and send the message to a server accordingly.
+ * See rt_ereg.conf.sample file for the format of the configuration file.
+ */
+
+#include "rtereg.h"
+
+/* The configuration structure */
+struct rtereg_conf rtereg_conf;
+
+#ifndef HAVE_REG_STARTEND
+static char * buf = NULL;
+static size_t bufsz;
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+#endif /* HAVE_REG_STARTEND */
+
+static int proceed(char * value, size_t len, struct fd_list * candidates)
+{
+ int i;
+
+ for (i = 0; i < rtereg_conf.rules_nb; i++) {
+ /* Does this pattern match the value? */
+ struct rtereg_rule * r = &rtereg_conf.rules[i];
+ int err = 0;
+ struct fd_list * c;
+
+ TRACE_DEBUG(ANNOYING, "Attempt pattern matching of '%.*s' with rule '%s'", (int)len, value, r->pattern);
+
+ #ifdef HAVE_REG_STARTEND
+ {
+ regmatch_t pmatch[1];
+ memset(pmatch, 0, sizeof(pmatch));
+ pmatch[0].rm_so = 0;
+ pmatch[0].rm_eo = len;
+ err = regexec(&r->preg, value, 0, pmatch, REG_STARTEND);
+ }
+ #else /* HAVE_REG_STARTEND */
+ {
+ /* We have a 0-terminated string */
+ err = regexec(&r->preg, value, 0, NULL, 0);
+ }
+ #endif /* HAVE_REG_STARTEND */
+
+ if (err == REG_NOMATCH)
+ continue;
+
+ if (err != 0) {
+ char * errstr;
+ size_t bl;
+
+ /* Error while compiling the regex */
+ TRACE_DEBUG(INFO, "Error while executing the regular expression '%s':", r->pattern);
+
+ /* Get the error message size */
+ bl = regerror(err, &r->preg, NULL, 0);
+
+ /* Alloc the buffer for error message */
+ CHECK_MALLOC( errstr = malloc(bl) );
+
+ /* Get the error message content */
+ regerror(err, &r->preg, errstr, bl);
+ TRACE_DEBUG(INFO, "\t%s", errstr);
+
+ /* Free the buffer, return the error */
+ free(errstr);
+
+ return (err == REG_ESPACE) ? ENOMEM : EINVAL;
+ }
+
+ /* From this point, the expression matched the AVP value */
+ TRACE_DEBUG(FULL, "[rt_ereg] Match: '%s' to value '%.*s' => '%s' += %d",
+ r->pattern,
+ (int)len,
+ value,
+ r->server,
+ r->score);
+
+ for (c = candidates->next; c != candidates; c = c->next) {
+ struct rtd_candidate * cand = (struct rtd_candidate *)c;
+
+ if (strcmp(r->server, cand->diamid) == 0) {
+ cand->score += r->score;
+ break;
+ }
+ }
+ };
+
+ return 0;
+}
+
+/* The callback called on new messages */
+static int rtereg_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
+{
+ struct msg * msg = *pmsg;
+ struct avp * avp = NULL;
+
+ TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
+
+ CHECK_PARAMS(msg && candidates);
+
+ /* Check if it is worth processing the message */
+ if (FD_IS_LIST_EMPTY(candidates)) {
+ return 0;
+ }
+
+ /* Now search the AVP in the message */
+ CHECK_FCT( fd_msg_search_avp ( msg, rtereg_conf.avp, &avp ) );
+ if (avp != NULL) {
+ struct avp_hdr * ahdr = NULL;
+ CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
+ if (ahdr->avp_value != NULL) {
+#ifndef HAVE_REG_STARTEND
+ int ret;
+
+ /* Lock the buffer */
+ CHECK_POSIX( pthread_mutex_lock(&mtx) );
+
+ /* Augment the buffer if needed */
+ if (ahdr->avp_value->os.len >= bufsz) {
+ CHECK_MALLOC_DO( buf = realloc(buf, ahdr->avp_value->os.len + 1),
+ { pthread_mutex_unlock(&mtx); return ENOMEM; } );
+ }
+
+ /* Copy the AVP value */
+ memcpy(buf, ahdr->avp_value->os.data, ahdr->avp_value->os.len);
+ buf[ahdr->avp_value->os.len] = '\0';
+
+ /* Now apply the rules */
+ ret = proceed(buf, ahdr->avp_value->os.len, candidates);
+
+ CHECK_POSIX(pthread_mutex_unlock(&mtx));
+
+ CHECK_FCT(ret);
+#else /* HAVE_REG_STARTEND */
+ CHECK_FCT( proceed((char *) ahdr->avp_value->os.data, ahdr->avp_value->os.len, candidates) );
+#endif /* HAVE_REG_STARTEND */
+ }
+ }
+
+ return 0;
+}
+
+/* handler */
+static struct fd_rt_out_hdl * rtereg_hdl = NULL;
+
+/* entry point */
+static int rtereg_entry(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* Initialize the configuration */
+ memset(&rtereg_conf, 0, sizeof(rtereg_conf));
+
+ /* Parse the configuration file */
+ CHECK_FCT( rtereg_conf_handle(conffile) );
+
+ /* Register the callback */
+ CHECK_FCT( fd_rt_out_register( rtereg_out, NULL, 1, &rtereg_hdl ) );
+
+ /* We're done */
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ int i;
+ TRACE_ENTRY();
+
+ /* Unregister the cb */
+ CHECK_FCT_DO( fd_rt_out_unregister ( rtereg_hdl, NULL ), /* continue */ );
+
+ /* Destroy the data */
+ if (rtereg_conf.rules)
+ for (i = 0; i < rtereg_conf.rules_nb; i++) {
+ free(rtereg_conf.rules[i].pattern);
+ free(rtereg_conf.rules[i].server);
+ regfree(&rtereg_conf.rules[i].preg);
+ }
+ free(rtereg_conf.rules);
+#ifndef HAVE_REG_STARTEND
+ free(buf);
+#endif /* HAVE_REG_STARTEND */
+
+ /* Done */
+ return ;
+}
+
+EXTENSION_ENTRY("rt_ereg", rtereg_entry);
diff --git a/extensions/rt_ereg/rtereg.h b/extensions/rt_ereg/rtereg.h
new file mode 100644
index 0000000..495c82f
--- /dev/null
+++ b/extensions/rt_ereg/rtereg.h
@@ -0,0 +1,64 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * See the rt_ereg.conf.sample file for the format of the configuration file.
+ */
+
+/* FreeDiameter's common include file */
+#include <freeDiameter/extension.h>
+#include <regex.h>
+
+
+/* Parse the configuration file */
+int rtereg_conf_handle(char * conffile);
+
+struct rtereg_rule {
+ char * pattern; /* The pattern we try to match the AVP value to */
+ regex_t preg; /* compiled regex */
+ char * server; /* The peer that gets its score raised in case of match */
+ int score; /* The relative value that is added to the peer's score */
+};
+
+
+/* The configuration structure */
+extern struct rtereg_conf {
+ int rules_nb; /* Number of rules in the configuration */
+ struct rtereg_rule *rules; /* The array of rules */
+
+ struct dict_object * avp; /* cache the dictionary object that we are searching */
+
+} rtereg_conf;
+
diff --git a/extensions/rt_ereg/rtereg_conf.l b/extensions/rt_ereg/rtereg_conf.l
new file mode 100644
index 0000000..8a281a5
--- /dev/null
+++ b/extensions/rt_ereg/rtereg_conf.l
@@ -0,0 +1,119 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Tokenizer
+ *
+ */
+
+%{
+#include "rtereg.h"
+/* Include yacc tokens definitions */
+#include "rtereg_conf.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+qstring \"[^\"\n]*\"
+
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+
+ /* Recognize quoted strings */
+{qstring} {
+ /* Match a quoted string. */
+ CHECK_MALLOC_DO( yylval->string = strdup(yytext+1),
+ {
+ TRACE_DEBUG(INFO, "Unable to copy the string '%s': %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ } );
+ yylval->string[strlen(yytext) - 2] = '\0';
+ return QSTRING;
+ }
+
+
+ /* Recognize any integer */
+[-]?[[:digit:]]+ {
+ /* Convert this to an integer value */
+ int ret=0;
+ ret = sscanf(yytext, "%i", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+
+
+ /* The key words */
+(?i:"AVP") { return AVP; }
+
+ /* Valid single characters for yyparse */
+[=:;+-] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]\":=+;\n]+ {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/rt_ereg/rtereg_conf.y b/extensions/rt_ereg/rtereg_conf.y
new file mode 100644
index 0000000..a213323
--- /dev/null
+++ b/extensions/rt_ereg/rtereg_conf.y
@@ -0,0 +1,209 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "rtereg.h"
+#include "rtereg_conf.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+/* Parse the configuration file */
+int rtereg_conf_handle(char * conffile)
+{
+ extern FILE * rtereg_confin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ rtereg_confin = fopen(conffile, "r");
+ if (rtereg_confin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(rtereg_confin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ } else {
+ TRACE_DEBUG(FULL, "[rt-ereg] Added %d rules successfully.", rtereg_conf.rules_nb);
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int rtereg_conflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ char *string; /* The string is allocated by strdup in lex.*/
+ int integer;
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */
+%token <string> QSTRING
+%token <integer> INTEGER
+
+/* Tokens */
+%token AVP
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: rules avp rules
+ ;
+
+ /* a server entry */
+avp: AVP '=' QSTRING ';'
+ {
+ if (rtereg_conf.avp != NULL) {
+ yyerror(&yylloc, conffile, "Only one AVP can be specified");
+ YYERROR;
+ }
+
+ CHECK_FCT_DO( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, $3, &rtereg_conf.avp, ENOENT ),
+ {
+ TRACE_DEBUG(INFO, "Unable to find '%s' AVP in the loaded dictionaries.", $3);
+ yyerror (&yylloc, conffile, "Invalid AVP value.");
+ YYERROR;
+ } );
+
+ /* Now check the type */
+ {
+ struct dict_avp_data data;
+ CHECK_FCT( fd_dict_getval( rtereg_conf.avp, &data) );
+ CHECK_PARAMS_DO (data.avp_basetype == AVP_TYPE_OCTETSTRING,
+ {
+ TRACE_DEBUG(INFO, "'%s' AVP in not an OCTETSTRING AVP (%d).", $3, data.avp_basetype);
+ yyerror (&yylloc, conffile, "AVP in not an OCTETSTRING type.");
+ YYERROR;
+ } );
+ }
+ }
+ ;
+
+rules: /* empty OK */
+ | rules rule
+ ;
+
+rule: QSTRING ':' QSTRING '+' '=' INTEGER ';'
+ {
+ struct rtereg_rule * new;
+ int err;
+
+ /* Add new rule in the array */
+ rtereg_conf.rules_nb += 1;
+ CHECK_MALLOC_DO(rtereg_conf.rules = realloc(rtereg_conf.rules, rtereg_conf.rules_nb * sizeof(struct rtereg_rule)),
+ {
+ yyerror (&yylloc, conffile, "Not enough memory to store the configuration...");
+ YYERROR;
+ } );
+
+ new = &rtereg_conf.rules[rtereg_conf.rules_nb - 1];
+
+ new->pattern = $1;
+ new->server = $3;
+ new->score = $6;
+
+ /* Attempt to compile the regex */
+ CHECK_FCT_DO( err=regcomp(&new->preg, new->pattern, REG_EXTENDED | REG_NOSUB),
+ {
+ char * buf;
+ size_t bl;
+
+ /* Error while compiling the regex */
+ TRACE_DEBUG(INFO, "Error while compiling the regular expression '%s':", new->pattern);
+
+ /* Get the error message size */
+ bl = regerror(err, &new->preg, NULL, 0);
+
+ /* Alloc the buffer for error message */
+ CHECK_MALLOC( buf = malloc(bl) );
+
+ /* Get the error message content */
+ regerror(err, &new->preg, buf, bl);
+ TRACE_DEBUG(INFO, "\t%s", buf);
+
+ /* Free the buffer, return the error */
+ free(buf);
+
+ yyerror (&yylloc, conffile, "Invalid regular expression.");
+ YYERROR;
+ } );
+ }
+ ;
diff --git a/extensions/rt_ignore_dh/CMakeLists.txt b/extensions/rt_ignore_dh/CMakeLists.txt
new file mode 100644
index 0000000..f0717b9
--- /dev/null
+++ b/extensions/rt_ignore_dh/CMakeLists.txt
@@ -0,0 +1,20 @@
+# The rt_ignore_dh extension
+PROJECT("Routing extension that removes Destination-Host from messages and restores from Proxy-Info for answers" C)
+
+# List of source files
+SET(RT_IGNORE_DH_SRC
+ rt_ignore_dh.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(rt_ignore_dh ${RT_IGNORE_DH_SRC})
+
+####
+## INSTALL section ##
+
+# We install with the daemon component because it is a base feature.
+INSTALL(TARGETS rt_ignore_dh
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-daemon)
diff --git a/extensions/rt_ignore_dh/rt_ignore_dh.c b/extensions/rt_ignore_dh/rt_ignore_dh.c
new file mode 100644
index 0000000..7385fef
--- /dev/null
+++ b/extensions/rt_ignore_dh/rt_ignore_dh.c
@@ -0,0 +1,217 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Thomas Klausner <tk@giga.or.at> *
+* *
+* Copyright (c) 2013, Thomas Klausner *
+* All rights reserved. *
+* *
+* Written under contract by nfotex IT GmbH, http://nfotex.com/ *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* 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 <freeDiameter/extension.h>
+
+/*
+ * Remove Destination-Hosts, putting it into Proxy-Info, and restore it to
+ * Origin-Host for answers.
+ */
+
+struct dict_object * dh_avp_do; /* cache the Destination-Host dictionary object */
+struct dict_object * oh_avp_do; /* cache the Origin-Host dictionary object */
+struct dict_object * ph_avp_do; /* cache the Proxy-Host dictionary object */
+struct dict_object * pi_avp_do; /* cache the Proxy-Info dictionary object */
+struct dict_object * ps_avp_do; /* cache the Proxy-State dictionary object */
+
+static int restore_origin_host(struct msg **msg) {
+ struct avp *avp, *child;
+ struct avp *oh_avp = NULL;
+ struct avp *pi_avp = NULL;
+ void *ps, *new_oh;
+ size_t ps_len, new_oh_len = 0;
+ union avp_value val;
+
+ ps = new_oh = NULL;
+
+ CHECK_FCT(fd_msg_browse(*msg, MSG_BRW_FIRST_CHILD, &avp, NULL));
+ /* look for Origin-Host and Proxy-Info matching this host */
+ while (avp && (!oh_avp || !pi_avp)) {
+ struct avp_hdr * ahdr;
+ int match = 0;
+
+ CHECK_FCT(fd_msg_avp_hdr(avp, &ahdr));
+ if (!(ahdr->avp_flags & AVP_FLAG_VENDOR)) {
+ switch (ahdr->avp_code) {
+ case AC_ORIGIN_HOST:
+ oh_avp = avp;
+ CHECK_FCT(fd_msg_parse_dict(oh_avp, fd_g_config->cnf_dict, NULL));
+ break;
+ case AC_PROXY_INFO:
+ ps = NULL;
+ ps_len = 0;
+ CHECK_FCT(fd_msg_parse_dict(avp, fd_g_config->cnf_dict, NULL));
+ CHECK_FCT(fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &child, NULL));
+ while (child && (!match || !ps)) {
+ struct avp_hdr *chdr;
+ CHECK_FCT(fd_msg_avp_hdr(child, &chdr));
+ if (!(chdr->avp_flags & AVP_FLAG_VENDOR)) {
+ switch (chdr->avp_code) {
+ case AC_PROXY_HOST:
+ if (fd_os_cmp(chdr->avp_value->os.data, chdr->avp_value->os.len,
+ fd_g_config->cnf_diamid, fd_g_config->cnf_diamid_len) == 0) {
+ match = 1;
+ }
+ break;
+ case AC_PROXY_STATE:
+ ps = chdr->avp_value->os.data;
+ ps_len = chdr->avp_value->os.len;
+ break;
+ default:
+ break;
+ }
+ }
+ CHECK_FCT(fd_msg_browse(child, MSG_BRW_NEXT, &child, NULL));
+ }
+ if (match && ps) {
+ new_oh = ps;
+ new_oh_len = ps_len;
+ pi_avp = avp;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ CHECK_FCT(fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL));
+ }
+ if (!pi_avp)
+ return 0;
+
+ memset(&val, 0, sizeof(val));
+ val.os.data = new_oh;
+ val.os.len = new_oh_len;
+ if (!oh_avp) {
+ TRACE_ERROR("Message contained no Origin-Host");
+ } else {
+ CHECK_FCT(fd_msg_avp_setvalue(oh_avp, &val));
+ }
+ fd_msg_free((msg_or_avp*)pi_avp);
+
+ fd_log_debug("Restored Origin-Host '%.*s' from Proxy-Info", (int)new_oh_len, (char *)new_oh);
+ return 0;
+}
+
+static int stow_destination_host(struct msg **msg) {
+ struct avp * avp = NULL;
+ struct avp * ph_avp = NULL;
+ struct avp * pi_avp = NULL;
+ struct avp * ps_avp = NULL;
+
+ /* Look for the Destination-Host AVP in the message */
+ CHECK_FCT(fd_msg_search_avp(*msg, dh_avp_do, &avp));
+ if (avp != NULL) {
+ struct avp_hdr * ahdr = NULL;
+ union avp_value val;
+
+ CHECK_FCT(fd_msg_avp_hdr(avp, &ahdr));
+ if (ahdr->avp_value != NULL) {
+ /* add Proxy-Info->{Proxy-Host, Proxy-State} using Destination-Host information */
+ CHECK_FCT(fd_msg_avp_new(ph_avp_do, 0, &ph_avp));
+ memset(&val, 0, sizeof(val));
+ val.os.data = (uint8_t *)(fd_g_config->cnf_diamid);
+ val.os.len = fd_g_config->cnf_diamid_len;
+ CHECK_FCT(fd_msg_avp_setvalue(ph_avp, &val));
+
+ CHECK_FCT(fd_msg_avp_new(ps_avp_do, 0, &ps_avp));
+ memset(&val, 0, sizeof(val));
+ val.os.data = ahdr->avp_value->os.data;
+ val.os.len = ahdr->avp_value->os.len;
+ CHECK_FCT(fd_msg_avp_setvalue(ps_avp, &val));
+
+ CHECK_FCT(fd_msg_avp_new(pi_avp_do, 0, &pi_avp));
+ CHECK_FCT(fd_msg_avp_add(pi_avp, MSG_BRW_LAST_CHILD, ph_avp));
+ CHECK_FCT(fd_msg_avp_add(pi_avp, MSG_BRW_LAST_CHILD, ps_avp));
+
+ /* remove Destination-Host from message */
+ fd_msg_free((msg_or_avp*)avp);
+ /* add Proxy-Info */
+ CHECK_FCT(fd_msg_avp_add(*msg, MSG_BRW_LAST_CHILD, pi_avp));
+ fd_log_debug("Stowed Destination-Host '%.*s' into Proxy-Info", (int)val.os.len, (const char *)val.os.data);
+ }
+ }
+
+ return 0;
+}
+
+/* The callback for putting Destination-Host into Proxy-Info and restoring it on the way back */
+static int rt_ignore_destination_host(void * cbdata, struct msg **msg) {
+ struct msg_hdr * hdr;
+ int ret;
+
+ TRACE_ENTRY("%p %p", cbdata, msg);
+
+ CHECK_PARAMS(msg && *msg);
+
+ /* Read the message header */
+ CHECK_FCT(fd_msg_hdr(*msg, &hdr));
+ if (hdr->msg_flags & CMD_FLAG_REQUEST) {
+ ret = stow_destination_host(msg);
+ } else {
+ ret = restore_origin_host(msg);
+ }
+
+ return ret;
+}
+
+/* handler */
+static struct fd_rt_fwd_hdl * rt_ignore_destination_host_hdl = NULL;
+
+/* entry point */
+static int rt_ignore_destination_host_entry(char * conffile)
+{
+ CHECK_FCT_DO(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &dh_avp_do, ENOENT),
+ { TRACE_ERROR("Unable to find 'Destination-Host' AVP in the loaded dictionaries."); });
+ CHECK_FCT_DO(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &oh_avp_do, ENOENT),
+ { TRACE_ERROR("Unable to find 'Origin-Host' AVP in the loaded dictionaries."); });
+ CHECK_FCT_DO(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Proxy-Host", &ph_avp_do, ENOENT),
+ { TRACE_ERROR("Unable to find 'Proxy-Host' AVP in the loaded dictionaries."); });
+ CHECK_FCT_DO(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Proxy-Info", &pi_avp_do, ENOENT),
+ { TRACE_ERROR("Unable to find 'Proxy-Info' AVP in the loaded dictionaries."); });
+ CHECK_FCT_DO(fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Proxy-State", &ps_avp_do, ENOENT),
+ { TRACE_ERROR("Unable to find 'Proxy-State' AVP in the loaded dictionaries."); });
+
+ /* Register the callback */
+ CHECK_FCT(fd_rt_fwd_register(rt_ignore_destination_host, NULL, RT_FWD_ALL, &rt_ignore_destination_host_hdl));
+
+ TRACE_DEBUG(INFO, "Extension 'Ignore Destination Host' initialized");
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ /* Unregister the callbacks */
+ CHECK_FCT_DO(fd_rt_fwd_unregister(rt_ignore_destination_host_hdl, NULL), /* continue */);
+ return ;
+}
+
+EXTENSION_ENTRY("rt_ignore_destination_host", rt_ignore_destination_host_entry);
diff --git a/extensions/rt_load_balance/CMakeLists.txt b/extensions/rt_load_balance/CMakeLists.txt
new file mode 100644
index 0000000..d5c491e
--- /dev/null
+++ b/extensions/rt_load_balance/CMakeLists.txt
@@ -0,0 +1,20 @@
+# The rt_load_balance extension
+PROJECT("Routing extension splits requests evenly over multiple hosts, using current load as routing indicator" C)
+
+# List of source files
+SET(RT_LOAD_BALANCE_SRC
+ rt_load_balance.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(rt_load_balance ${RT_LOAD_BALANCE_SRC})
+
+####
+## INSTALL section ##
+
+# We install with the daemon component because it is a base feature.
+INSTALL(TARGETS rt_load_balance
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-daemon)
diff --git a/extensions/rt_load_balance/rt_load_balance.c b/extensions/rt_load_balance/rt_load_balance.c
new file mode 100644
index 0000000..9883a67
--- /dev/null
+++ b/extensions/rt_load_balance/rt_load_balance.c
@@ -0,0 +1,100 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Thomas Klausner <tk@giga.or.at> *
+* *
+* Copyright (c) 2013, 2014 Thomas Klausner *
+* All rights reserved. *
+* *
+* Written under contract by nfotex IT GmbH, http://nfotex.com/ *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* 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 <freeDiameter/extension.h>
+
+/*
+ * Load balancing extension. Send request to least-loaded node.
+ */
+
+/* The callback for load balancing the requests across the peers */
+static int rt_load_balancing(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
+{
+ struct fd_list *lic;
+ struct msg * msg = *pmsg;
+
+ TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
+
+ CHECK_PARAMS(msg && candidates);
+
+ /* Check if it is worth processing the message */
+ if (FD_IS_LIST_EMPTY(candidates))
+ return 0;
+
+ /* load balancing */
+ for (lic = candidates->next; lic != candidates; lic = lic->next) {
+ struct rtd_candidate * cand = (struct rtd_candidate *) lic;
+ struct peer_hdr *peer;
+ long to_receive, to_send, load;
+ int score;
+ CHECK_FCT(fd_peer_getbyid(cand->diamid, cand->diamidlen, 0, &peer));
+ CHECK_FCT(fd_peer_get_load_pending(peer, &to_receive, &to_send));
+ load = to_receive + to_send;
+ /* other routing mechanisms need to add to the
+ * appropriate entries so their base value is high
+ * enough that they are considered */
+
+ /* logarithmic scaling */
+ int load_log = 0;
+ while (load > 0) {
+ load_log++;
+ load /= 2;
+ }
+ score = cand->score;
+ cand->score -= load_log;
+ TRACE_DEBUG(FULL, "evaluated peer `%.*s', score was %d, now %d", (int)cand->diamidlen, cand->diamid, score, cand->score);
+ }
+
+ return 0;
+}
+
+/* handler */
+static struct fd_rt_out_hdl * rt_load_balancing_hdl = NULL;
+
+/* entry point */
+static int rt_load_balance_entry(char * conffile)
+{
+ /* Register the callback */
+ CHECK_FCT(fd_rt_out_register(rt_load_balancing, NULL, 10, &rt_load_balancing_hdl));
+
+ TRACE_DEBUG(INFO, "Extension 'Load Balancing' initialized");
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ /* Unregister the callbacks */
+ CHECK_FCT_DO(fd_rt_out_unregister(rt_load_balancing_hdl, NULL), /* continue */);
+ return ;
+}
+
+EXTENSION_ENTRY("rt_load_balance", rt_load_balance_entry);
diff --git a/extensions/rt_randomize/CMakeLists.txt b/extensions/rt_randomize/CMakeLists.txt
new file mode 100644
index 0000000..bcc7b84
--- /dev/null
+++ b/extensions/rt_randomize/CMakeLists.txt
@@ -0,0 +1,20 @@
+# The rt_randomize extension
+PROJECT("Routing extension randomly increases the routing count for one of the highest-rated hosts, if there are multiple ones" C)
+
+# List of source files
+SET(RT_RANDOMIZE_SRC
+ rt_randomize.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(rt_randomize ${RT_RANDOMIZE_SRC})
+
+####
+## INSTALL section ##
+
+# We install with the daemon component because it is a base feature.
+INSTALL(TARGETS rt_randomize
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-daemon)
diff --git a/extensions/rt_randomize/rt_randomize.c b/extensions/rt_randomize/rt_randomize.c
new file mode 100644
index 0000000..a606451
--- /dev/null
+++ b/extensions/rt_randomize/rt_randomize.c
@@ -0,0 +1,111 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Thomas Klausner <tk@giga.or.at> *
+* *
+* Copyright (c) 2014 Thomas Klausner *
+* All rights reserved. *
+* *
+* Written under contract by nfotex IT GmbH, http://nfotex.com/ *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* 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 <freeDiameter/extension.h>
+
+/*
+ * Load balancing extension. If there are multiple highest-rated hosts with the same score,
+ * randomly increase the score of one of them.
+ */
+
+#include <stdlib.h>
+
+static unsigned int seed;
+
+static int rt_randomizing(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
+{
+ struct fd_list *lic;
+ struct msg * msg = *pmsg;
+ int max_score = -1;
+ int max_score_count = 0;
+
+ TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
+
+ CHECK_PARAMS(msg && candidates);
+
+ /* Check if it is worth processing the message */
+ if (FD_IS_LIST_EMPTY(candidates))
+ return 0;
+
+ /* find out maximal score and how many candidates have it */
+ for (lic = candidates->next; lic != candidates; lic = lic->next) {
+ struct rtd_candidate * cand = (struct rtd_candidate *) lic;
+ if (max_score < cand->score) {
+ max_score = cand->score;
+ max_score_count = 1;
+ }
+ else if (cand->score == max_score) {
+ max_score_count++;
+ }
+ }
+
+ /* if there is more than one with positive score, randomly increase one of their scores by one */
+ if (max_score >= 0 && max_score_count > 1) {
+ int lucky_candidate = rand_r(&seed) % max_score_count;
+ int i = 0;
+
+ for (lic = candidates->next; lic != candidates; lic = lic->next) {
+ struct rtd_candidate * cand = (struct rtd_candidate *) lic;
+ if (cand->score == max_score) {
+ if (i == lucky_candidate) {
+ cand->score++;
+ break;
+ }
+ i++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* handler */
+static struct fd_rt_out_hdl * rt_randomizing_hdl = NULL;
+
+/* entry point */
+static int rt_randomize_entry(char * conffile)
+{
+ /* Register the callback */
+ CHECK_FCT(fd_rt_out_register(rt_randomizing, NULL, 4, &rt_randomizing_hdl));
+ seed = (unsigned int)time(NULL);
+ TRACE_DEBUG(INFO, "Extension 'Randomizing' initialized");
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ /* Unregister the callbacks */
+ CHECK_FCT_DO(fd_rt_out_unregister(rt_randomizing_hdl, NULL), /* continue */);
+ return ;
+}
+
+EXTENSION_ENTRY("rt_randomize", rt_randomize_entry);
diff --git a/extensions/rt_redirect/CMakeLists.txt b/extensions/rt_redirect/CMakeLists.txt
new file mode 100644
index 0000000..63e9f1b
--- /dev/null
+++ b/extensions/rt_redirect/CMakeLists.txt
@@ -0,0 +1,23 @@
+# The rt_redirect extension
+PROJECT("Diameter Redirect messages support" C)
+
+SET(RT_REDIR_SRC
+ rt_redir.h
+ rt_redir.c
+ redir_entries.c
+ redir_expiry.c
+ redir_fwd.c
+ redir_out.c
+ uthash.h
+ )
+
+# Compile as a module
+FD_ADD_EXTENSION(rt_redirect ${RT_REDIR_SRC})
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS rt_redirect
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-daemon)
diff --git a/extensions/rt_redirect/redir_entries.c b/extensions/rt_redirect/redir_entries.c
new file mode 100644
index 0000000..b0126d1
--- /dev/null
+++ b/extensions/rt_redirect/redir_entries.c
@@ -0,0 +1,410 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Authors: Sebastien Decugis <sdecugis@freediameter.net> *
+* and Thomas Klausner <tk@giga.or.at> *
+* *
+* Copyright (c) 2011, 2014, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "rt_redir.h"
+#include "uthash.h"
+
+/* The array with all entries ordered by their data */
+struct redir_line redirects_usages[H_U_MAX + 1];
+
+/* for symmetry reasons, hash tables for all types exist, but only ALL_SESSION and ALL_USER will be used */
+struct redir_entry *redirect_hash_table[H_U_MAX+1];
+
+/* Initialize the array */
+int redir_entry_init()
+{
+ int i;
+
+ TRACE_ENTRY("");
+
+ /* redirects_usages */
+ memset(&redirects_usages, 0, sizeof(redirects_usages));
+
+ for (i = 0; i <= H_U_MAX; i++) {
+ /* only one of the two will be used for each type, but initialize both to be on the safe side */
+
+ /* initialize list */
+ CHECK_POSIX( pthread_rwlock_init( &redirects_usages[i].lock, NULL) );
+ fd_list_init( &redirects_usages[i].sentinel, &redirects_usages[i] );
+
+ /* initialize hash table */
+ redirect_hash_table[i] = NULL;
+ }
+
+ /* initialize the scores */
+ redirects_usages[ DONT_CACHE ].score = FD_SCORE_REDIR_ONCE;
+ redirects_usages[ ALL_SESSION ].score = FD_SCORE_REDIR_SESSION;
+ redirects_usages[ ALL_REALM ].score = FD_SCORE_REDIR_REALM;
+ redirects_usages[ REALM_AND_APPLICATION ].score = FD_SCORE_REDIR_REALM_APP;
+ redirects_usages[ ALL_APPLICATION ].score = FD_SCORE_REDIR_APP;
+ redirects_usages[ ALL_HOST ].score = FD_SCORE_REDIR_HOST;
+ redirects_usages[ ALL_USER ].score = FD_SCORE_REDIR_USER;
+
+ return 0;
+}
+
+int redir_entry_fini()
+{
+ int i;
+ struct redir_entry *current_entry, *tmp;
+
+ /* Empty all entries */
+ CHECK_POSIX_DO( pthread_mutex_lock(&redir_exp_peer_lock), );
+ for (i = 0; i <= H_U_MAX; i++) {
+ CHECK_POSIX_DO( pthread_rwlock_wrlock( &redirects_usages[i].lock), );
+ switch(i) {
+ case ALL_SESSION:
+ case ALL_USER:
+ HASH_ITER(hh, redirect_hash_table[i], current_entry, tmp) {
+ HASH_DEL(redirect_hash_table[i], current_entry);
+ CHECK_FCT_DO( redir_entry_destroy(current_entry), );
+ }
+ break;
+ default:
+ while (!FD_IS_LIST_EMPTY(&redirects_usages[i].sentinel)) {
+ struct redir_entry * e = redirects_usages[i].sentinel.next->o;
+ fd_list_unlink(&e->redir_list);
+ CHECK_FCT_DO( redir_entry_destroy(e), );
+ }
+ }
+ CHECK_POSIX_DO( pthread_rwlock_unlock( &redirects_usages[i].lock), );
+ CHECK_POSIX_DO( pthread_rwlock_destroy( &redirects_usages[i].lock), );
+ }
+ CHECK_POSIX_DO( pthread_mutex_unlock(&redir_exp_peer_lock), );
+
+ return 0;
+}
+
+/* Create a new redir_entry and add the correct data */
+int redir_entry_new(struct redir_entry ** e, struct fd_list * targets, uint32_t rhu, struct msg * qry, DiamId_t nh, size_t nhlen, os0_t oh, size_t ohlen)
+{
+ struct redir_entry * entry = NULL;
+ os0_t s;
+ size_t l;
+
+ TRACE_ENTRY("%p %p %d %p %p %zd %p %zd", e, targets, rhu, qry, nh, nhlen, oh, ohlen)
+ ASSERT(e && targets && (rhu <= H_U_MAX) && qry && nh && nhlen && oh && ohlen);
+
+ CHECK_MALLOC( entry = malloc(sizeof(struct redir_entry)) );
+ memset(entry, 0, sizeof(struct redir_entry));
+
+ entry->eyec = REDIR_ENTRY_EYEC;
+
+ CHECK_MALLOC( entry->from.s = os0dup(nh, nhlen) );
+ entry->from.l = nhlen;
+
+ fd_list_init(&entry->target_peers_list, entry);
+ fd_list_move_end(&entry->target_peers_list, targets);
+
+ fd_list_init(&entry->exp_list, entry);
+
+ entry->type = rhu;
+ /* list entry for putting into redirects_usage; also doubles as pointer into that list so it can be removed easily */
+ fd_list_init(&entry->redir_list, entry);
+ /* finally initialize the data */
+ switch (rhu) {
+ case DONT_CACHE:
+ entry->data.message.msg = qry;
+ break;
+
+ case ALL_SESSION:
+ {
+ /* There is a good chance that the session is already cached in the message, so retrieve it */
+ struct session * sess;
+ CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, qry, &sess, NULL) );
+ if (!sess) {
+ TRACE_DEBUG(INFO, "Received a Redirect indication with usage ALL_SESSION but no Session-Id AVP in the message, defaulting to DONT_CACHE");
+ entry->type = DONT_CACHE;
+ entry->data.message.msg = qry;
+ break;
+ }
+ CHECK_FCT( fd_sess_getsid(sess, &s, &l) );
+ CHECK_MALLOC( entry->data.session.s = os0dup(s, l) );
+ entry->data.session.l = l;
+ }
+ break;
+
+ case ALL_REALM:
+ {
+ /* Search the Destination-Realm of the message */
+ struct avp * dr;
+ struct avp_hdr * ahdr;
+ CHECK_FCT( fd_msg_search_avp(qry, redir_dict_dr, &dr) );
+ if (!dr) {
+ TRACE_DEBUG(INFO, "Received a Redirect indication with usage ALL_REALM but no Destination-Realm AVP in the message, defaulting to DONT_CACHE");
+ entry->type = DONT_CACHE;
+ entry->data.message.msg = qry;
+ break;
+ }
+ CHECK_FCT( fd_msg_avp_hdr( dr, &ahdr ) );
+ CHECK_MALLOC( entry->data.realm.s = os0dup(ahdr->avp_value->os.data, ahdr->avp_value->os.len) );
+ entry->data.realm.l = ahdr->avp_value->os.len;
+ }
+ break;
+
+ case REALM_AND_APPLICATION:
+ {
+ /* Search the Destination-Realm of the message */
+ struct avp * dr;
+ struct avp_hdr * ahdr;
+ CHECK_FCT( fd_msg_search_avp(qry, redir_dict_dr, &dr) );
+ if (!dr) {
+ TRACE_DEBUG(INFO, "Received a Redirect indication with usage REALM_AND_APPLICATION but no Destination-Realm AVP in the message, defaulting to DONT_CACHE");
+ entry->type = DONT_CACHE;
+ entry->data.message.msg = qry;
+ break;
+ }
+ CHECK_FCT( fd_msg_avp_hdr( dr, &ahdr ) );
+ CHECK_MALLOC( entry->data.realm_app.s = os0dup(ahdr->avp_value->os.data, ahdr->avp_value->os.len) );
+ entry->data.realm_app.l = ahdr->avp_value->os.len;
+ }
+ /* and then the application */
+ {
+ struct msg_hdr * hdr;
+ CHECK_FCT( fd_msg_hdr(qry, &hdr) );
+ entry->data.realm_app.a = hdr->msg_appl;
+ }
+ break;
+
+ case ALL_APPLICATION:
+ {
+ struct msg_hdr * hdr;
+ CHECK_FCT( fd_msg_hdr(qry, &hdr) );
+ entry->data.app.a = hdr->msg_appl;
+ }
+ break;
+
+ case ALL_HOST:
+ CHECK_MALLOC( entry->data.host.s = os0dup(oh, ohlen) );
+ entry->data.host.l = ohlen;
+ break;
+
+ case ALL_USER:
+ {
+ /* Search the User-Name of the message */
+ struct avp * un;
+ struct avp_hdr * ahdr;
+ CHECK_FCT( fd_msg_search_avp(qry, redir_dict_un, &un) );
+ if (!un) {
+ TRACE_DEBUG(INFO, "Received a Redirect indication with usage ALL_USER but no User-Name AVP in the message, defaulting to DONT_CACHE");
+ entry->type = DONT_CACHE;
+ entry->data.message.msg = qry;
+ break;
+ }
+ CHECK_FCT( fd_msg_avp_hdr( un, &ahdr ) );
+ CHECK_MALLOC( entry->data.user.s = os0dup(ahdr->avp_value->os.data, ahdr->avp_value->os.len) );
+ entry->data.user.l = ahdr->avp_value->os.len;
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ return EINVAL;
+ }
+
+ /* We're done */
+ *e = entry;
+ return 0;
+}
+
+
+/* Compares two pointers (DONT_CACHE) */
+static int compare_entries_ptr(union matchdata * d1, union matchdata * d2) {
+ unsigned long v1 = (unsigned long) d1->message.msg;
+ unsigned long v2 = (unsigned long) d2->message.msg;
+ if (v1 > v2)
+ return 1;
+ if (v1 < v2)
+ return -1;
+ return 0;
+}
+/* Compare two applications (REALM_AND_APPLICATION and ALL_APPLICATION) */
+static int compare_entries_appl(union matchdata * d1, union matchdata * d2) {
+ if (d1->app.a > d2->app.a)
+ return 1;
+ if (d1->app.a < d2->app.a)
+ return -1;
+ return 0;
+}
+
+/* Compare two strings (ALL_SESSION, ALL_REALM, ALL_HOST, ALL_USER) */
+static int compare_entries_ostr(union matchdata * d1, union matchdata * d2) {
+ return fd_os_cmp(d1->session.s, d1->session.l, d2->session.s, d2->session.l);
+}
+
+/* The array of callbacks */
+int (*redir_entry_cmp_key[H_U_MAX +1])(union matchdata * , union matchdata * ) = {
+ compare_entries_ptr, /* DONT_CACHE */
+ compare_entries_ostr, /* ALL_SESSION */
+ compare_entries_ostr, /* ALL_REALM */
+ compare_entries_appl, /* REALM_AND_APPLICATION */
+ compare_entries_appl, /* ALL_APPLICATION */
+ compare_entries_ostr, /* ALL_HOST */
+ compare_entries_ostr /* ALL_USER */
+};
+
+/* Link the newly created entry into the correct redirects_usages list. The mutex must be held */
+int redir_entry_insert(struct redir_entry * e)
+{
+ struct fd_list * li;
+ struct redir_entry * r = NULL;
+
+ TRACE_ENTRY("%p", e);
+ CHECK_PARAMS(e && (e->eyec == REDIR_ENTRY_EYEC));
+
+ /* Write-Lock the line */
+ CHECK_POSIX( pthread_rwlock_wrlock( RWLOCK_REDIR(e) ) );
+
+ switch (e->type) {
+ case ALL_SESSION:
+ HASH_FIND(hh, redirect_hash_table[e->type], e->data.session.s, e->data.session.l, r);
+ if (r) {
+ /* previously existing entry, delete it from hash and free it */
+ HASH_DELETE(hh, redirect_hash_table[e->type], r);
+ CHECK_FCT_DO( redir_entry_destroy(r), );
+ }
+ HASH_ADD_KEYPTR(hh, redirect_hash_table[e->type], e->data.session.s, e->data.session.l, e);
+ break;
+ case ALL_USER:
+ HASH_FIND(hh, redirect_hash_table[e->type], e->data.user.s, e->data.user.l, r);
+ if (r) {
+ /* previously existing entry, delete it from hash and free it */
+ HASH_DELETE(hh, redirect_hash_table[e->type], r);
+ CHECK_FCT_DO( redir_entry_destroy(r), );
+ }
+ HASH_ADD_KEYPTR(hh, redirect_hash_table[e->type], e->data.user.s, e->data.user.l, e);
+ break;
+ default:
+ for (li = redirects_usages[e->type].sentinel.next; li != &redirects_usages[e->type].sentinel; li = li->next) {
+ struct redir_entry * n = li->o;
+ int cmp = redir_entry_cmp_key[e->type](&e->data, &n->data);
+ if (cmp <= 0)
+ break;
+ }
+
+ fd_list_insert_before(li, &e->redir_list);
+ break;
+ }
+
+ /* unLock the line */
+ CHECK_POSIX( pthread_rwlock_unlock( RWLOCK_REDIR(e) ) );
+
+ return 0;
+}
+
+/* Destroy -- the exp_peer_lock must be held when this function is called */
+int redir_entry_destroy(struct redir_entry * e)
+{
+ struct redir_entry *match;
+ TRACE_ENTRY("%p", e);
+ CHECK_PARAMS(e && (e->eyec == REDIR_ENTRY_EYEC));
+
+ switch (e->type) {
+ case ALL_SESSION:
+ /* If the entry is in the hash table, lock the rwlock also */
+ HASH_FIND(hh, redirect_hash_table[e->type], e->data.session.s, e->data.session.l, match);
+ if (match) {
+ /* TODO: check if e == match? */
+ CHECK_POSIX( pthread_rwlock_wrlock( RWLOCK_REDIR(e) ) );
+ HASH_DELETE(hh, redirect_hash_table[e->type], match);
+ CHECK_POSIX( pthread_rwlock_unlock( RWLOCK_REDIR(e) ) );
+ }
+ break;
+ case ALL_USER:
+ /* If the entry is in the hash table, lock the rwlock also */
+ HASH_FIND(hh, redirect_hash_table[e->type], e->data.user.s, e->data.user.l, match);
+ if (match) {
+ /* TODO: check if e == match? */
+ CHECK_POSIX( pthread_rwlock_wrlock( RWLOCK_REDIR(e) ) );
+ HASH_DELETE(hh, redirect_hash_table[e->type], match);
+ CHECK_POSIX( pthread_rwlock_unlock( RWLOCK_REDIR(e) ) );
+ }
+ break;
+ default:
+ /* If the entry is linked, lock the rwlock also */
+ if (!FD_IS_LIST_EMPTY(&e->redir_list)) {
+ CHECK_POSIX( pthread_rwlock_wrlock( RWLOCK_REDIR(e) ) );
+ fd_list_unlink(&e->redir_list);
+ CHECK_POSIX( pthread_rwlock_unlock( RWLOCK_REDIR(e) ) );
+ }
+ break;
+ }
+
+ /* Now unlink from other list */
+ fd_list_unlink(&e->exp_list);
+
+ /* Empty the targets list */
+ while (!FD_IS_LIST_EMPTY(&e->target_peers_list)) {
+ struct redir_host * h = (struct redir_host *)e->target_peers_list.next->o;
+
+ fd_list_unlink(&h->chain);
+ free(h->id);
+ free(h);
+ }
+
+ /* Now we can destroy the data safely */
+ switch (e->type) {
+ case DONT_CACHE:
+ /* nothing special */
+ break;
+ case ALL_SESSION:
+ free(e->data.session.s);
+ break;
+ case ALL_REALM:
+ free(e->data.realm.s);
+ break;
+ case REALM_AND_APPLICATION:
+ free(e->data.realm_app.s);
+ break;
+ case ALL_APPLICATION:
+ break;
+ case ALL_HOST:
+ free(e->data.host.s);
+ break;
+ case ALL_USER:
+ free(e->data.user.s);
+ break;
+ default:
+ TRACE_DEBUG(INFO, "Invalid redirect type was saved");
+ ASSERT(0);
+ return EINVAL;
+ }
+
+ free(e->from.s);
+
+ free(e);
+ return 0;
+}
diff --git a/extensions/rt_redirect/redir_expiry.c b/extensions/rt_redirect/redir_expiry.c
new file mode 100644
index 0000000..7274684
--- /dev/null
+++ b/extensions/rt_redirect/redir_expiry.c
@@ -0,0 +1,136 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2015, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "rt_redir.h"
+
+/* Expiration management */
+
+
+/* Entries by their ascending expiration date, to accelerate the work of the expire thread */
+static struct fd_list expire_list = FD_LIST_INITIALIZER(expire_list);
+static pthread_cond_t exp_cnd = PTHREAD_COND_INITIALIZER;
+
+pthread_mutex_t redir_exp_peer_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* The thread that handles expired entries cleanup. */
+void * redir_exp_thr_fct(void * arg)
+{
+ fd_log_threadname ( "Redirects/expire" );
+ TRACE_ENTRY( "" );
+
+ CHECK_POSIX_DO( pthread_mutex_lock(&redir_exp_peer_lock), goto fatal_error );
+ pthread_cleanup_push( fd_cleanup_mutex, &redir_exp_peer_lock );
+
+ do {
+ struct timespec now;
+ struct redir_entry * first;
+again:
+ /* Check if there are expiring entries available */
+ if (FD_IS_LIST_EMPTY(&expire_list)) {
+ /* Just wait for a change or cancelation */
+ CHECK_POSIX_DO( pthread_cond_wait( &exp_cnd, &redir_exp_peer_lock ), break /* this might not pop the cleanup handler, but since we ASSERT(0), it is not the big issue... */ );
+ /* Restart the loop on wakeup */
+ goto again;
+ }
+
+ /* Get the pointer to the entry that expires first */
+ first = (struct redir_entry *)(expire_list.next->o);
+
+ /* Get the current time */
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), break );
+
+ /* If first session is not expired, we just wait until it happens */
+ if ( TS_IS_INFERIOR( &now, &first->timeout ) ) {
+
+ CHECK_POSIX_DO2( pthread_cond_timedwait( &exp_cnd, &redir_exp_peer_lock, &first->timeout ),
+ ETIMEDOUT, /* ETIMEDOUT is a normal error, continue */,
+ /* on other error, */ break );
+
+ /* on wakeup, loop */
+ goto again;
+ }
+
+ /* Now, the first entry in the list is expired; destroy it */
+
+ CHECK_FCT_DO( redir_entry_destroy( first ), break );
+
+ } while (1);
+
+ pthread_cleanup_pop( 0 );
+ CHECK_POSIX_DO( pthread_mutex_unlock(&redir_exp_peer_lock), );
+
+fatal_error:
+ TRACE_DEBUG(INFO, "A system error occurred in redirect module! Expiry thread is terminating...");
+ ASSERT(0);
+ return NULL;
+}
+
+/* Sets the timeout value & link in expiry list. The mutex must be held on calling */
+int redir_exp_set(struct redir_entry * e, uint32_t duration)
+{
+ struct fd_list * li;
+ TRACE_ENTRY("%p %d", e, duration);
+ CHECK_PARAMS(e && (e->eyec == REDIR_ENTRY_EYEC) && duration );
+
+ /* Unlink in case it was already set before */
+ fd_list_unlink(&e->exp_list);
+
+ /* Get current time */
+ CHECK_SYS( clock_gettime(CLOCK_REALTIME, &e->timeout) );
+
+ /* Add the duration */
+ e->timeout.tv_sec += duration;
+
+ /* now search the next element in the list */
+ for (li = expire_list.next; li != &expire_list; li = li->next) {
+ struct redir_entry * n = li->o;
+
+ if ( TS_IS_INFERIOR( &e->timeout, &n->timeout ) )
+ break;
+
+ }
+
+ /* Insert before this element */
+ fd_list_insert_before(li, &e->exp_list);
+
+ /* Signal the expiry thread if needed */
+ if (e->exp_list.prev == &expire_list) { /* it is the first element */
+ CHECK_POSIX( pthread_cond_signal(&exp_cnd) );
+ }
+
+ /* Done */
+ return 0;
+}
+
diff --git a/extensions/rt_redirect/redir_fwd.c b/extensions/rt_redirect/redir_fwd.c
new file mode 100644
index 0000000..aa3417e
--- /dev/null
+++ b/extensions/rt_redirect/redir_fwd.c
@@ -0,0 +1,272 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2015, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "rt_redir.h"
+
+/* This structure contains the data to keep when a new peer's connection is attempted (for later) */
+struct redir_task {
+ struct msg * answer; /* the message that was being processed */
+ uint32_t rhu; /* Redirect-Host-Usage value */
+ uint32_t rmct; /* Redirect-Max-Cache-Time value */
+ struct fd_list rh; /* the list of Redirect-Hosts */
+};
+
+/* Received answers FWD callback */
+int redir_fwd_cb(void * cbdata, struct msg ** msg)
+{
+ struct msg * m, * q;
+ struct rt_data *rtd;
+ struct msg_hdr * hdr;
+ union avp_value *a_rc = NULL, *a_rhu = NULL, *a_rmct = NULL, *a_oh = NULL;
+ int known = 0, actives = 0;
+ struct fd_list * li;
+ struct avp * avp;
+ struct redir_task task = { .answer = NULL, .rhu = 0, .rmct = 0, .rh = FD_LIST_INITIALIZER(task.rh) };
+ DiamId_t nh;
+ size_t nhlen;
+ int nbrh = 0;
+ struct redir_entry * entry;
+
+ TRACE_ENTRY("%p %p", cbdata, msg);
+
+ CHECK_PARAMS(msg && *msg);
+
+ m = *msg;
+
+ /* First get the header */
+ CHECK_FCT( fd_msg_hdr(m, &hdr) );
+
+ /* Check if we have an error */
+ ASSERT(!(hdr->msg_flags & CMD_FLAG_REQUEST));
+ if (!(hdr->msg_flags & CMD_FLAG_ERROR)) {
+ /* This answer does not have the E flag, no need to process further */
+ return 0;
+ }
+
+ /* Now get the AVPs we are interested in */
+ CHECK_FCT( fd_msg_browse(m, MSG_BRW_FIRST_CHILD, &avp, NULL) );
+ while (avp) {
+ struct avp_hdr * ahdr;
+
+ CHECK_FCT( fd_msg_avp_hdr( avp, &ahdr ) );
+ if (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) {
+ switch (ahdr->avp_code) {
+ case AC_ORIGIN_HOST:
+ /* Parse this AVP */
+ CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
+ ASSERT( ahdr->avp_value );
+ a_oh = ahdr->avp_value;
+ break;
+
+ case AC_RESULT_CODE:
+ /* Parse this AVP */
+ CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
+ ASSERT( ahdr->avp_value );
+ a_rc = ahdr->avp_value;
+
+ if (a_rc->u32 != ER_DIAMETER_REDIRECT_INDICATION) {
+ /* It is not a REDIRECT error, we don't do anything */
+ goto out;
+ }
+ break;
+
+ case AC_REDIRECT_HOST:
+ {
+ struct redir_host * h = NULL;
+ DiamId_t id = NULL;
+ size_t len = 0;
+ int secure = 0;
+ uint16_t port = 0;
+ int l4 = 0;
+ char proto = 0;
+
+ /* Parse this AVP */
+ CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
+ ASSERT( ahdr->avp_value );
+
+ nbrh++;
+
+ CHECK_FCT_DO( fd_os_parse_DiameterURI(ahdr->avp_value->os.data, ahdr->avp_value->os.len,
+ &id, &len, &secure, &port, &l4, &proto),
+ {
+ TRACE_DEBUG(INFO, "Received an invalid Redirect-Host AVP value ('%.*s'), ignored", (int)ahdr->avp_value->os.len, ahdr->avp_value->os.data);
+ break;
+ } );
+
+ /* Now check if the transport & protocol are supported */
+ if (proto && (proto != 'd')) {
+ TRACE_DEBUG(FULL, "Ignored unsupported non-Diameter Redirect-Host AVP (%.*s)", (int)ahdr->avp_value->os.len, ahdr->avp_value->os.data);
+ free(id);
+ break;
+ }
+ if (l4 && (l4 == IPPROTO_UDP)) {
+ TRACE_DEBUG(FULL, "Ignored unsupported UDP Redirect-Host AVP (%.*s)", (int)ahdr->avp_value->os.len, ahdr->avp_value->os.data);
+ free(id);
+ break;
+ }
+
+ /* It looks OK, save this entry. */
+
+ CHECK_MALLOC( h = malloc(sizeof(struct redir_host)) );
+ memset(h, 0, sizeof(struct redir_host));
+ fd_list_init(&h->chain, h);
+ h->id = id;
+ h->len = len;
+ /* later: secure, port */
+
+ /* The list is kept ordered by id so that it is faster to compare to candidates later */
+ for (li = task.rh.next; li != &task.rh; li = li->next) {
+ struct redir_host * nhost = li->o;
+ if ( fd_os_cmp(id, len, nhost->id, nhost->len) <= 0 )
+ break;
+ }
+ fd_list_insert_before(li, &h->chain);
+ }
+ break;
+
+ case AC_REDIRECT_HOST_USAGE:
+ /* Parse this AVP */
+ CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
+ ASSERT( ahdr->avp_value );
+ a_rhu = ahdr->avp_value;
+ if (a_rhu->u32 > H_U_MAX) {
+ TRACE_DEBUG(INFO, "Received unsupported Redirect-Host-Usage value (%d), defaulting to DONT_CACHE", a_rhu->u32);
+ } else {
+ task.rhu = a_rhu->u32;
+ }
+ break;
+
+ case AC_REDIRECT_MAX_CACHE_TIME:
+ /* Parse this AVP */
+ CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
+ ASSERT( ahdr->avp_value );
+ a_rmct = ahdr->avp_value;
+ task.rmct = a_rmct->u32;
+ break;
+
+ }
+ }
+
+ /* Go to next AVP */
+ CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) );
+ }
+
+ /* Check we have received the necessary information */
+ if (!a_rc) {
+ TRACE_DEBUG(FULL, "Invalid Diameter answer without a Result-Code AVP, Redirect module gave up");
+ goto out;
+ }
+
+ if (!a_oh) {
+ TRACE_DEBUG(FULL, "Invalid Diameter answer without an Origin-Host AVP, Redirect module gave up");
+ goto out;
+ }
+
+ if (FD_IS_LIST_EMPTY(&task.rh)) {
+ TRACE_DEBUG(FULL, "Diameter answer with a DIAMETER_REDIRECT_INDICATION Result-Code AVP but no valid/supported Redirect-Host AVP, Redirect module gave up");
+ goto out;
+ }
+
+ if (a_rhu && (task.rhu != DONT_CACHE) && !a_rmct) {
+ TRACE_DEBUG(FULL, "Invalid Diameter Redirect answer with a Redirect-Host-Usage AVP but no Redirect-Max-Cache-Time, Redirect module gave up");
+ goto out;
+ }
+
+ /* It looks like we can process the Redirect indication */
+
+ /* Search for the peers we already know */
+ for (li = task.rh.next; li != &task.rh; li = li->next) {
+ struct redir_host * h = li->o;
+ struct peer_hdr * peer;
+
+ CHECK_FCT( fd_peer_getbyid( h->id, h->len, 1, &peer ) );
+ if (peer) {
+ known ++;
+ memcpy(h->id, peer->info.pi_diamid, h->len); /* Overwrite the case so we can search case-sensitive from here on */
+ if (fd_peer_get_state(peer) == STATE_OPEN) {
+ actives ++;
+ }
+ }
+ }
+
+ TRACE_DEBUG(FULL, "Redirect module: received %d Redirect-Hosts, %d are known peers, %d have an OPEN connection", nbrh, known, actives);
+
+ /* in this version, we only redirect when there are known active peers. TODO: add new peers via fd_peer_add when no active peer is available */
+
+ if (!actives) {
+ TRACE_DEBUG(INFO, "Unable to comply to Redirect indication: none of the peers included is in OPEN state");
+ goto out;
+ }
+
+ /* From this point, we will re-send the query to a different peer, so stop forwarding the answer here */
+ *msg = NULL;
+
+ /* Get the query's routing data & add the new error */
+ CHECK_FCT( fd_msg_answ_getq(m, &q) );
+ CHECK_FCT( fd_msg_rt_get(q, &rtd) );
+ CHECK_FCT( fd_msg_source_get( m, &nh, &nhlen ) );
+ CHECK_FCT( fd_rtd_error_add(rtd, nh, nhlen, a_oh->os.data, a_oh->os.len, a_rc->u32, NULL, NULL) );
+
+ /* Create a redir_rule */
+ CHECK_FCT( redir_entry_new(&entry, &task.rh, task.rhu, q, nh, nhlen, a_oh->os.data, a_oh->os.len) );
+
+ CHECK_POSIX( pthread_mutex_lock(&redir_exp_peer_lock) );
+ /* Insert in the split list */
+ CHECK_FCT( redir_entry_insert(entry) );
+ /* Set the expiry */
+ CHECK_FCT( redir_exp_set(entry, task.rmct ?: DEFAULT_EXPIRE_TIME) );
+ CHECK_POSIX( pthread_mutex_unlock(&redir_exp_peer_lock) );
+
+ /* Now we can get rid of the received answer and send again the query. */
+ CHECK_FCT( fd_msg_answ_detach(m) );
+ CHECK_FCT( fd_msg_free(m) );
+
+ /* Send it */
+ CHECK_FCT( fd_msg_send(&q, NULL, NULL) );
+
+ /* Done! */
+
+out:
+ while (!FD_IS_LIST_EMPTY(&task.rh)) {
+ struct redir_host * h = task.rh.next->o;
+ fd_list_unlink(&h->chain);
+ free(h->id);
+ free(h);
+ }
+
+ return 0;
+
+}
+
diff --git a/extensions/rt_redirect/redir_out.c b/extensions/rt_redirect/redir_out.c
new file mode 100644
index 0000000..9f80f52
--- /dev/null
+++ b/extensions/rt_redirect/redir_out.c
@@ -0,0 +1,323 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Authors: Sebastien Decugis <sdecugis@freediameter.net> *
+* and Thomas Klausner <tk@giga.or.at> *
+* *
+* Copyright (c) 2013, 2014, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "rt_redir.h"
+
+
+/* Find the data pertinent to a type in the input data */
+static int get_data_to_match(enum redir_h_u type, struct msg *msg, union matchdata * data, int * nodata)
+{
+ TRACE_ENTRY("%d %p %p %p", type, msg, data, nodata);
+
+ /* Initialize the data area */
+ memset(data, 0, sizeof(union matchdata));
+ *nodata = 0;
+
+ /* Now, find the appropriate information, depending on type */
+ switch (type) {
+ case DONT_CACHE:
+ data->message.msg = msg;
+ break;
+
+ case ALL_SESSION:
+ {
+ /* Get the sid from the message */
+ struct session * sess;
+ CHECK_FCT( fd_msg_sess_get(fd_g_config->cnf_dict, msg, &sess, NULL) );
+ if (!sess) {
+ TRACE_DEBUG(ANNOYING, "Message %p cannot match any ALL_SESSION rule since it does not have a Session-Id", msg);
+ *nodata = 1;
+ } else {
+ CHECK_FCT( fd_sess_getsid(sess, &data->session.s, &data->session.l) );
+ }
+ }
+ break;
+
+ case ALL_REALM:
+ {
+ /* Search the Destination-Realm in the message */
+ struct avp * dr;
+ CHECK_FCT( fd_msg_search_avp(msg, redir_dict_dr, &dr) );
+ if (!dr) {
+ TRACE_DEBUG(ANNOYING, "Message %p cannot match any ALL_REALM rule since it does not have a Destination-Realm", msg);
+ *nodata = 1;
+ } else {
+ struct avp_hdr * ahdr;
+ CHECK_FCT( fd_msg_avp_hdr( dr, &ahdr ) );
+ data->realm.s = ahdr->avp_value->os.data;
+ data->realm.l = ahdr->avp_value->os.len;
+ }
+ }
+ break;
+
+ case REALM_AND_APPLICATION:
+ {
+ /* Search the Destination-Realm of the message */
+ struct avp * dr;
+ CHECK_FCT( fd_msg_search_avp(msg, redir_dict_dr, &dr) );
+ if (!dr) {
+ TRACE_DEBUG(ANNOYING, "Message %p cannot match any REALM_AND_APPLICATION rule since it does not have a Destination-Realm", msg);
+ *nodata = 1;
+ } else {
+ struct avp_hdr * ahdr;
+ CHECK_FCT( fd_msg_avp_hdr( dr, &ahdr ) );
+ data->realm_app.s = ahdr->avp_value->os.data;
+ data->realm_app.l = ahdr->avp_value->os.len;
+
+ /* and then the application */
+ {
+ struct msg_hdr * hdr;
+ CHECK_FCT( fd_msg_hdr(msg, &hdr) );
+ data->realm_app.a = hdr->msg_appl;
+ /* Should we forbid application 0? */
+ }
+ }
+ }
+ break;
+
+ case ALL_APPLICATION:
+ {
+ /* Retrieve the application from the message */
+ struct msg_hdr * hdr;
+ CHECK_FCT( fd_msg_hdr(msg, &hdr) );
+ data->app.a = hdr->msg_appl;
+ }
+ break;
+
+ case ALL_HOST:
+ /* This is more complex, we need to match with all candidates in each rule, it'll be done later */
+ break;
+
+ case ALL_USER:
+ {
+ /* Search the User-Name of the message */
+ struct avp * un;
+ CHECK_FCT( fd_msg_search_avp(msg, redir_dict_un, &un) );
+ if (!un) {
+ TRACE_DEBUG(ANNOYING, "Message %p cannot match any ALL_USER rule since it does not have a User-Name", msg);
+ *nodata = 1;
+ } else {
+ struct avp_hdr * ahdr;
+ CHECK_FCT( fd_msg_avp_hdr( un, &ahdr ) );
+ data->user.s = ahdr->avp_value->os.data;
+ data->user.l = ahdr->avp_value->os.len;
+ }
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+
+/* Apply the score from a rule if the candidate list is appropriate */
+static int apply_rule(struct redir_entry * e, struct msg * msg, struct fd_list * candidates)
+{
+ struct fd_list * lic, *lirh;
+ struct rtd_candidate * c_oh = NULL;
+ int cmp;
+
+ TRACE_ENTRY("%p %p %p", e, msg, candidates);
+ ASSERT( e && msg && candidates );
+
+ if (FD_IS_LIST_EMPTY(candidates)) {
+ TRACE_DEBUG(ANNOYING, "Skip Redirect rule since candidates list is empty");
+ return 0;
+ }
+
+ /* Now search common peers between e->target_peers_list and candidates */
+ TRACE_DEBUG(ANNOYING, "Message %p matches a Redirect rule (t:%d, @%p), processing candidates list", msg, e->type, e);
+
+ /* First, decrease the score of the host that we received the previous Redirect from, in case it is in the list */
+ for (lic = candidates->next; lic != candidates; lic = lic->next) {
+ struct rtd_candidate * cand = (struct rtd_candidate *) lic;
+
+ /* Special case: ALL_HOST rules: we decrease the score of the Origin-Host if present */
+ if (e->type == ALL_HOST) {
+ cmp = fd_os_almostcasesrch(cand->diamid, cand->diamidlen, e->data.host.s, e->data.host.l, NULL);
+ if (!cmp) {
+ TRACE_DEBUG(FULL, "Redirect msg %p: peer '%.*s' += %d (previous ALL_HOST Redirect originated from this peer)", msg, (int)cand->diamidlen, cand->diamid, FD_SCORE_SENT_REDIRECT);
+ cand->score += FD_SCORE_SENT_REDIRECT;
+ c_oh = cand;
+ continue;
+ }
+ }
+
+ cmp = fd_os_cmp(cand->diamid, cand->diamidlen, e->from.s, e->from.l);
+ if (!cmp) {
+ TRACE_DEBUG(FULL, "Redirect msg %p: peer '%.*s' += %d (previous Redirect received from this peer)", msg, (int)cand->diamidlen, cand->diamid, FD_SCORE_SENT_REDIRECT);
+ cand->score += FD_SCORE_SENT_REDIRECT;
+ }
+
+ }
+
+ if ((e->type == ALL_HOST) && (c_oh == NULL)) {
+ /* The rule does not apply, we're done */
+ return 0;
+ }
+
+ /* for each candidate, if it is found in the target_peers list, we add the rule's score to this candidate */
+ for (lic = candidates->next; lic != candidates; lic = lic->next) {
+ /* the candidates list is not guaranteed to be ordered at this time, so we cannot avoid the two imbricated loops */
+ struct rtd_candidate * cand = (struct rtd_candidate *) lic;
+
+ /* Is this candidate in the "Redirect-Host" list ? We must search caseinsentive here. */
+ for (lirh = e->target_peers_list.next; lirh != &e->target_peers_list; lirh = lirh->next) {
+ struct redir_host * host = lirh->o;
+ int cont;
+
+ cmp = fd_os_almostcasesrch( cand->diamid, cand->diamidlen, host->id, host->len, &cont );
+
+ if (cmp == 0) {
+ TRACE_DEBUG(FULL, "Redirect msg %p: peer '%.*s' += %d (rule t:%d @%p)", msg, (int)cand->diamidlen, cand->diamid, redirects_usages[e->type].score, e->type, e);
+ cand->score += redirects_usages[e->type].score;
+ break;
+ }
+ if (!cont)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int redir_exist_for_type(int rule_type)
+{
+ int ret;
+
+ switch(rule_type) {
+ case ALL_SESSION:
+ case ALL_USER:
+ ret = redirect_hash_table[rule_type] != NULL;
+ break;
+ default:
+ ret = !FD_IS_LIST_EMPTY(&redirects_usages[rule_type].sentinel);
+ break;
+ }
+ return ret;
+}
+
+static int match_message(int rule_type, struct msg *msg, union matchdata *data, struct fd_list * candidates)
+{
+ struct fd_list * li;
+ struct redir_entry * e = NULL;
+ int ret = 0;
+
+ switch(rule_type) {
+ case ALL_SESSION:
+ HASH_FIND(hh, redirect_hash_table[rule_type], data->session.s, data->session.l, e);
+ if (e) {
+ /* This message matches a rule, apply */
+ CHECK_FCT_DO( ret = apply_rule(e, msg, candidates), break );
+ }
+ break;
+ case ALL_USER:
+ HASH_FIND(hh, redirect_hash_table[rule_type], data->user.s, data->user.l, e);
+ if (e) {
+ /* This message matches a rule, apply */
+ CHECK_FCT_DO( ret = apply_rule(e, msg, candidates), break );
+ }
+ break;
+ default:
+ /* Attempt each rule we have stored */
+ for (li = redirects_usages[rule_type].sentinel.next; li != &redirects_usages[rule_type].sentinel; li = li->next) {
+ e = li->o;
+
+ /* Does it match ? */
+ if (rule_type != ALL_HOST) { /* this one is an exception, we handle it separately */
+ int cmp = redir_entry_cmp_key[rule_type](data, &e->data);
+ if (cmp > 0)
+ continue;
+ if (cmp < 0)
+ break;
+ }
+
+ /* This rule matches (or we are in ALL_HOST), apply */
+ CHECK_FCT_DO( ret = apply_rule(e, msg, candidates), break );
+
+ /* If this was a DONT_CACHE rule, we unlink it, so that it will not be used again */
+ if (rule_type == DONT_CACHE) {
+ li = li->prev;
+ fd_list_unlink( li->next );
+ /* We cannot delete here without taking the mutex, which would mean we have first to release the lock...
+ just let expiry garbage collect the rule */
+ }
+ }
+ }
+
+ return ret;
+}
+
+/* OUT callback */
+int redir_out_cb(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
+{
+ int i, ret = 0;
+ struct msg * msg = *pmsg;
+
+ TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
+
+ for (i = 0; i <= H_U_MAX; i++) {
+ /* Lock the line. We write lock in case of DONT_CACHE so we can directly unlink the entry. read in other cases is sufficient */
+ if (i == DONT_CACHE) {
+ CHECK_POSIX( pthread_rwlock_wrlock( &redirects_usages[i].lock ) );
+ } else {
+ CHECK_POSIX( pthread_rwlock_rdlock( &redirects_usages[i].lock ) );
+ }
+
+ if (redir_exist_for_type(i)) {
+ union matchdata data;
+ int nodata; /* The message does not allow to apply this rule, skip */
+
+ /* Retrieve the data that may match in the message */
+ CHECK_FCT_DO( ret = get_data_to_match(i, msg, &data, &nodata), goto out );
+
+ /* If data found for this type of rule, then try matching it */
+ if (!nodata)
+ ret = match_message(i, msg, &data, candidates);
+ }
+out:
+ CHECK_POSIX( pthread_rwlock_unlock( &redirects_usages[i].lock ) );
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
diff --git a/extensions/rt_redirect/rt_redir.c b/extensions/rt_redirect/rt_redir.c
new file mode 100644
index 0000000..21b5a93
--- /dev/null
+++ b/extensions/rt_redirect/rt_redir.c
@@ -0,0 +1,90 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Authors: Sebastien Decugis <sdecugis@freediameter.net> *
+* and Thomas Klausner <tk@giga.or.at> *
+* *
+* Copyright (c) 2011, 2014, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "rt_redir.h"
+
+struct dict_object * redir_dict_dr = NULL;
+struct dict_object * redir_dict_un = NULL;
+
+static struct fd_rt_fwd_hdl * fwd_hdl = NULL;
+static struct fd_rt_out_hdl * out_hdl = NULL;
+static pthread_t exp_thr = (pthread_t)NULL;
+
+/* Initialize the module */
+static int redir_entry(char * conffile)
+{
+ TRACE_ENTRY("");
+
+ /* Dictionary objects */
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &redir_dict_dr, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &redir_dict_un, ENOENT) );
+
+ /* Initialize the entries array */
+ CHECK_FCT( redir_entry_init() );
+
+ /* Start the expire thread */
+ CHECK_POSIX( pthread_create( &exp_thr, NULL, redir_exp_thr_fct, NULL ) );
+
+ /* Register the callback that receives the answers and processes when it contains a Redirect indication. */
+ CHECK_FCT( fd_rt_fwd_register ( redir_fwd_cb, NULL, RT_FWD_ANS, &fwd_hdl ) );
+
+ /* Register the callback that applies the saved Redirect rules to outgoing messages. */
+ CHECK_FCT( fd_rt_out_register ( redir_out_cb, NULL, 10, &out_hdl ) );
+
+ return 0;
+}
+
+EXTENSION_ENTRY("rt_redirect", redir_entry);
+
+/* And terminate it */
+void fd_ext_fini(void)
+{
+ /* Unregister the callbacks */
+ if (fwd_hdl) {
+ CHECK_FCT_DO( fd_rt_fwd_unregister(fwd_hdl, NULL), );
+ }
+ if (out_hdl) {
+ CHECK_FCT_DO( fd_rt_out_unregister(out_hdl, NULL), );
+ }
+
+ /* Stop the expiry thread */
+ CHECK_FCT_DO( fd_thr_term(&exp_thr), );
+
+ /* Empty all entries */
+ redir_entry_fini();
+
+ return;
+}
diff --git a/extensions/rt_redirect/rt_redir.h b/extensions/rt_redirect/rt_redir.h
new file mode 100644
index 0000000..980d26f
--- /dev/null
+++ b/extensions/rt_redirect/rt_redir.h
@@ -0,0 +1,180 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> and *
+* Thomas Klausner <tk@giga.or.at> *
+* *
+* Copyright (c) 2013, 2014, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Diameter Redirect management */
+#include <freeDiameter/extension.h>
+
+#include "uthash.h"
+
+/* There are 2 locks in this module. The priority is established as follow to avoid deadlocks:
+exp_peer mutex > usages rwlock.
+(e.g., the rwlock can be taken while holding the mutex, but not the other way)
+*/
+
+/* The types of redirects (from Redirect-Host-Usage AVP value) */
+enum redir_h_u {
+ DONT_CACHE = 0,
+ ALL_SESSION,
+ ALL_REALM,
+ REALM_AND_APPLICATION,
+ ALL_APPLICATION,
+ ALL_HOST,
+ ALL_USER
+};
+#define H_U_MAX ALL_USER
+
+/* Eye catcher */
+#define REDIR_ENTRY_EYEC 0x43D14E74
+
+/* Expiration time set for DONT_CACHE tasks, so that the entry is found when the code is called back */
+#define DEFAULT_EXPIRE_TIME 10 /* seconds */
+
+/* Structure to store a parsed Redirect-Host */
+struct redir_host {
+ struct fd_list chain;
+
+ DiamId_t id; /* malloc'd */
+ size_t len;
+ /* We don't use the following yet because we don't support dynamic new connections
+ int secure;
+ uint16_t port;
+ int l4;
+ char proto;
+ */
+};
+
+/* Rule data that is stored depending on Redirect-Host-Usage value */
+union matchdata {
+ /* DONT_CACHE */
+ struct {
+ struct msg * msg; /* The query message for which this rule was created */
+ } message;
+
+ /* ALL_SESSION */
+ struct {
+ os0_t s; /* sid */
+ size_t l;
+ } session;
+
+ /* ALL_REALM */
+ struct {
+ os0_t s; /* Destination-Realm AVP data */
+ size_t l;
+ } realm;
+
+ /* REALM_AND_APPLICATION */
+ struct {
+ application_id_t a; /* message's application */
+ os0_t s; /* Destination-Realm AVP data */
+ size_t l;
+ } realm_app;
+
+ /* ALL_APPLICATION */
+ struct {
+ application_id_t a; /* message's application */
+ } app;
+
+ /* ALL_HOST */
+ struct {
+ os0_t s; /* the Origin-Host of the Redirect message (which may be the next hop or not) */
+ size_t l;
+ } host;
+
+ /* ALL_USER */
+ struct {
+ os0_t s; /* User-Name AVP data */
+ size_t l;
+ } user;
+};
+
+
+/* Structure to store a Redirect indication */
+struct redir_entry {
+ uint32_t eyec; /* must be REDIR_ENTRY_EYEC, used for debug only */
+
+ struct {
+ os0_t s; /* alloc'd, must be freed */
+ size_t l;
+ } from; /* whom this rule was received from (next hop) ? */
+
+ struct fd_list target_peers_list; /* The list of Redirect-Hosts for this entry */
+
+ struct timespec timeout; /* When does this entry expire? */
+ struct fd_list exp_list; /* chain in the expire_list list, ordered by expiration date, protected by exp_peer_lock */
+
+ enum redir_h_u type; /* Type of this entry */
+ struct fd_list redir_list; /* link in redirects_usages lists. Lists are ordered by the data value. Protected by rw locks */
+ union matchdata data; /* The strings are duplicated & must be freed in this structure */
+ UT_hash_handle hh; /* magic entry for hash table */
+};
+
+/* The array where the redir_entries are stored */
+struct redir_line {
+ enum fd_rt_out_score score;
+ pthread_rwlock_t lock; /* protect the list */
+ struct fd_list sentinel; /* list of redir_entry, the "o" field of the sentinel points to the redir_line entry */
+};
+extern struct redir_line redirects_usages[];
+/* the hash table where entries are stored for ALL_SESSION and ALL_USER */
+extern struct redir_entry *redirect_hash_table[];
+
+/* Accelerator to the line lock */
+#define RWLOCK_REDIR( _entry ) ( &(redirects_usages[(_entry)->type].lock) )
+
+/* Lock that must be owned before calling some functions */
+extern pthread_mutex_t redir_exp_peer_lock;
+
+/* Dictionary cached objects */
+extern struct dict_object * redir_dict_dr;
+extern struct dict_object * redir_dict_un;
+
+/* Functions on redir_entry */
+int redir_entry_init();
+int redir_entry_fini();
+int redir_entry_new(struct redir_entry ** e, struct fd_list * targets, uint32_t rhu, struct msg * qry, DiamId_t nh, size_t nhlen, os0_t oh, size_t ohlen);
+extern int (*redir_entry_cmp_key[])(union matchdata * , union matchdata *); /* compare functions */
+int redir_entry_insert(struct redir_entry * e);
+int redir_entry_destroy(struct redir_entry * e);
+
+/* Functions for expiry */
+void * redir_exp_thr_fct(void * arg);
+int redir_exp_set(struct redir_entry * e, uint32_t duration);
+
+/* Forward cb */
+int redir_fwd_cb(void * cbdata, struct msg ** msg);
+
+/* Out callback */
+int redir_out_cb(void * cbdata, struct msg ** pmsg, struct fd_list * candidates);
diff --git a/extensions/rt_redirect/uthash.h b/extensions/rt_redirect/uthash.h
new file mode 100644
index 0000000..f1c3032
--- /dev/null
+++ b/extensions/rt_redirect/uthash.h
@@ -0,0 +1,940 @@
+/*
+Copyright (c) 2003-2013, Troy D. Hanson http://troydhanson.github.com/uthash/
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+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 UTHASH_H
+#define UTHASH_H
+
+#include <string.h> /* memcmp,strlen */
+#include <stddef.h> /* ptrdiff_t */
+#include <stdlib.h> /* exit() */
+
+/* These macros use decltype or the earlier __typeof GNU extension.
+ As decltype is only available in newer compilers (VS2010 or gcc 4.3+
+ when compiling c++ source) this code uses whatever method is needed
+ or, for VS2008 where neither is available, uses casting workarounds. */
+#ifdef _MSC_VER /* MS compiler */
+#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
+#define DECLTYPE(x) (decltype(x))
+#else /* VS2008 or older (or VS2010 in C mode) */
+#define NO_DECLTYPE
+#define DECLTYPE(x)
+#endif
+#else /* GNU, Sun and other compilers */
+#define DECLTYPE(x) (__typeof(x))
+#endif
+
+#ifdef NO_DECLTYPE
+#define DECLTYPE_ASSIGN(dst,src) \
+do { \
+ char **_da_dst = (char**)(&(dst)); \
+ *_da_dst = (char*)(src); \
+} while(0)
+#else
+#define DECLTYPE_ASSIGN(dst,src) \
+do { \
+ (dst) = DECLTYPE(dst)(src); \
+} while(0)
+#endif
+
+/* a number of the hash function use uint32_t which isn't defined on win32 */
+#ifdef _MSC_VER
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+#else
+#include <inttypes.h> /* uint32_t */
+#endif
+
+#define UTHASH_VERSION 1.9.8
+
+#ifndef uthash_fatal
+#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
+#endif
+#ifndef uthash_malloc
+#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
+#endif
+#ifndef uthash_free
+#define uthash_free(ptr,sz) free(ptr) /* free fcn */
+#endif
+
+#ifndef uthash_noexpand_fyi
+#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
+#endif
+#ifndef uthash_expand_fyi
+#define uthash_expand_fyi(tbl) /* can be defined to log expands */
+#endif
+
+/* initial number of buckets */
+#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
+#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
+#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
+
+/* calculate the element whose hash handle address is hhe */
+#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
+
+#define HASH_FIND(hh,head,keyptr,keylen,out) \
+do { \
+ unsigned _hf_bkt,_hf_hashv; \
+ out=NULL; \
+ if (head) { \
+ HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
+ if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
+ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
+ keyptr,keylen,out); \
+ } \
+ } \
+} while (0)
+
+#ifdef HASH_BLOOM
+#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
+#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
+#define HASH_BLOOM_MAKE(tbl) \
+do { \
+ (tbl)->bloom_nbits = HASH_BLOOM; \
+ (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \
+ if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \
+ memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
+ (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
+} while (0)
+
+#define HASH_BLOOM_FREE(tbl) \
+do { \
+ uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \
+} while (0)
+
+#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
+#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
+
+#define HASH_BLOOM_ADD(tbl,hashv) \
+ HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
+
+#define HASH_BLOOM_TEST(tbl,hashv) \
+ HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
+
+#else
+#define HASH_BLOOM_MAKE(tbl)
+#define HASH_BLOOM_FREE(tbl)
+#define HASH_BLOOM_ADD(tbl,hashv)
+#define HASH_BLOOM_TEST(tbl,hashv) (1)
+#define HASH_BLOOM_BYTELEN 0
+#endif
+
+#define HASH_MAKE_TABLE(hh,head) \
+do { \
+ (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \
+ sizeof(UT_hash_table)); \
+ if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \
+ memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
+ (head)->hh.tbl->tail = &((head)->hh); \
+ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
+ (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
+ (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \
+ (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \
+ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
+ if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \
+ memset((head)->hh.tbl->buckets, 0, \
+ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
+ HASH_BLOOM_MAKE((head)->hh.tbl); \
+ (head)->hh.tbl->signature = HASH_SIGNATURE; \
+} while(0)
+
+#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
+ HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add)
+
+#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \
+do { \
+ replaced=NULL; \
+ HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \
+ if (replaced!=NULL) { \
+ HASH_DELETE(hh,head,replaced); \
+ }; \
+ HASH_ADD(hh,head,fieldname,keylen_in,add); \
+} while(0)
+
+#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
+do { \
+ unsigned _ha_bkt; \
+ (add)->hh.next = NULL; \
+ (add)->hh.key = (char*)keyptr; \
+ (add)->hh.keylen = (unsigned)keylen_in; \
+ if (!(head)) { \
+ head = (add); \
+ (head)->hh.prev = NULL; \
+ HASH_MAKE_TABLE(hh,head); \
+ } else { \
+ (head)->hh.tbl->tail->next = (add); \
+ (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
+ (head)->hh.tbl->tail = &((add)->hh); \
+ } \
+ (head)->hh.tbl->num_items++; \
+ (add)->hh.tbl = (head)->hh.tbl; \
+ HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
+ (add)->hh.hashv, _ha_bkt); \
+ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
+ HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
+ HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
+ HASH_FSCK(hh,head); \
+} while(0)
+
+#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
+do { \
+ bkt = ((hashv) & ((num_bkts) - 1)); \
+} while(0)
+
+/* delete "delptr" from the hash table.
+ * "the usual" patch-up process for the app-order doubly-linked-list.
+ * The use of _hd_hh_del below deserves special explanation.
+ * These used to be expressed using (delptr) but that led to a bug
+ * if someone used the same symbol for the head and deletee, like
+ * HASH_DELETE(hh,users,users);
+ * We want that to work, but by changing the head (users) below
+ * we were forfeiting our ability to further refer to the deletee (users)
+ * in the patch-up process. Solution: use scratch space to
+ * copy the deletee pointer, then the latter references are via that
+ * scratch pointer rather than through the repointed (users) symbol.
+ */
+#define HASH_DELETE(hh,head,delptr) \
+do { \
+ unsigned _hd_bkt; \
+ struct UT_hash_handle *_hd_hh_del; \
+ if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \
+ uthash_free((head)->hh.tbl->buckets, \
+ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
+ HASH_BLOOM_FREE((head)->hh.tbl); \
+ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
+ head = NULL; \
+ } else { \
+ _hd_hh_del = &((delptr)->hh); \
+ if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
+ (head)->hh.tbl->tail = \
+ (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
+ (head)->hh.tbl->hho); \
+ } \
+ if ((delptr)->hh.prev) { \
+ ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
+ (head)->hh.tbl->hho))->next = (delptr)->hh.next; \
+ } else { \
+ DECLTYPE_ASSIGN(head,(delptr)->hh.next); \
+ } \
+ if (_hd_hh_del->next) { \
+ ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \
+ (head)->hh.tbl->hho))->prev = \
+ _hd_hh_del->prev; \
+ } \
+ HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
+ HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
+ (head)->hh.tbl->num_items--; \
+ } \
+ HASH_FSCK(hh,head); \
+} while (0)
+
+
+/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
+#define HASH_FIND_STR(head,findstr,out) \
+ HASH_FIND(hh,head,findstr,strlen(findstr),out)
+#define HASH_ADD_STR(head,strfield,add) \
+ HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
+#define HASH_REPLACE_STR(head,strfield,add,replaced) \
+ HASH_REPLACE(hh,head,strfield,strlen(add->strfield),add,replaced)
+#define HASH_FIND_INT(head,findint,out) \
+ HASH_FIND(hh,head,findint,sizeof(int),out)
+#define HASH_ADD_INT(head,intfield,add) \
+ HASH_ADD(hh,head,intfield,sizeof(int),add)
+#define HASH_REPLACE_INT(head,intfield,add,replaced) \
+ HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced)
+#define HASH_FIND_PTR(head,findptr,out) \
+ HASH_FIND(hh,head,findptr,sizeof(void *),out)
+#define HASH_ADD_PTR(head,ptrfield,add) \
+ HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
+#define HASH_REPLACE_PTR(head,ptrfield,add) \
+ HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced)
+#define HASH_DEL(head,delptr) \
+ HASH_DELETE(hh,head,delptr)
+
+/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
+ * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
+ */
+#ifdef HASH_DEBUG
+#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
+#define HASH_FSCK(hh,head) \
+do { \
+ unsigned _bkt_i; \
+ unsigned _count, _bkt_count; \
+ char *_prev; \
+ struct UT_hash_handle *_thh; \
+ if (head) { \
+ _count = 0; \
+ for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
+ _bkt_count = 0; \
+ _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
+ _prev = NULL; \
+ while (_thh) { \
+ if (_prev != (char*)(_thh->hh_prev)) { \
+ HASH_OOPS("invalid hh_prev %p, actual %p\n", \
+ _thh->hh_prev, _prev ); \
+ } \
+ _bkt_count++; \
+ _prev = (char*)(_thh); \
+ _thh = _thh->hh_next; \
+ } \
+ _count += _bkt_count; \
+ if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
+ HASH_OOPS("invalid bucket count %d, actual %d\n", \
+ (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
+ } \
+ } \
+ if (_count != (head)->hh.tbl->num_items) { \
+ HASH_OOPS("invalid hh item count %d, actual %d\n", \
+ (head)->hh.tbl->num_items, _count ); \
+ } \
+ /* traverse hh in app order; check next/prev integrity, count */ \
+ _count = 0; \
+ _prev = NULL; \
+ _thh = &(head)->hh; \
+ while (_thh) { \
+ _count++; \
+ if (_prev !=(char*)(_thh->prev)) { \
+ HASH_OOPS("invalid prev %p, actual %p\n", \
+ _thh->prev, _prev ); \
+ } \
+ _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \
+ _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \
+ (head)->hh.tbl->hho) : NULL ); \
+ } \
+ if (_count != (head)->hh.tbl->num_items) { \
+ HASH_OOPS("invalid app item count %d, actual %d\n", \
+ (head)->hh.tbl->num_items, _count ); \
+ } \
+ } \
+} while (0)
+#else
+#define HASH_FSCK(hh,head)
+#endif
+
+/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
+ * the descriptor to which this macro is defined for tuning the hash function.
+ * The app can #include <unistd.h> to get the prototype for write(2). */
+#ifdef HASH_EMIT_KEYS
+#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
+do { \
+ unsigned _klen = fieldlen; \
+ write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
+ write(HASH_EMIT_KEYS, keyptr, fieldlen); \
+} while (0)
+#else
+#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
+#endif
+
+/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
+#ifdef HASH_FUNCTION
+#define HASH_FCN HASH_FUNCTION
+#else
+#define HASH_FCN HASH_JEN
+#endif
+
+/* The Bernstein hash function, used in Perl prior to v5.6 */
+#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _hb_keylen=keylen; \
+ char *_hb_key=(char*)(key); \
+ (hashv) = 0; \
+ while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \
+ bkt = (hashv) & (num_bkts-1); \
+} while (0)
+
+
+/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
+ * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
+#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _sx_i; \
+ char *_hs_key=(char*)(key); \
+ hashv = 0; \
+ for(_sx_i=0; _sx_i < keylen; _sx_i++) \
+ hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
+ bkt = hashv & (num_bkts-1); \
+} while (0)
+
+#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _fn_i; \
+ char *_hf_key=(char*)(key); \
+ hashv = 2166136261UL; \
+ for(_fn_i=0; _fn_i < keylen; _fn_i++) \
+ hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \
+ bkt = hashv & (num_bkts-1); \
+} while(0)
+
+#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _ho_i; \
+ char *_ho_key=(char*)(key); \
+ hashv = 0; \
+ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \
+ hashv += _ho_key[_ho_i]; \
+ hashv += (hashv << 10); \
+ hashv ^= (hashv >> 6); \
+ } \
+ hashv += (hashv << 3); \
+ hashv ^= (hashv >> 11); \
+ hashv += (hashv << 15); \
+ bkt = hashv & (num_bkts-1); \
+} while(0)
+
+#define HASH_JEN_MIX(a,b,c) \
+do { \
+ a -= b; a -= c; a ^= ( c >> 13 ); \
+ b -= c; b -= a; b ^= ( a << 8 ); \
+ c -= a; c -= b; c ^= ( b >> 13 ); \
+ a -= b; a -= c; a ^= ( c >> 12 ); \
+ b -= c; b -= a; b ^= ( a << 16 ); \
+ c -= a; c -= b; c ^= ( b >> 5 ); \
+ a -= b; a -= c; a ^= ( c >> 3 ); \
+ b -= c; b -= a; b ^= ( a << 10 ); \
+ c -= a; c -= b; c ^= ( b >> 15 ); \
+} while (0)
+
+#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _hj_i,_hj_j,_hj_k; \
+ unsigned char *_hj_key=(unsigned char*)(key); \
+ hashv = 0xfeedbeef; \
+ _hj_i = _hj_j = 0x9e3779b9; \
+ _hj_k = (unsigned)keylen; \
+ while (_hj_k >= 12) { \
+ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \
+ + ( (unsigned)_hj_key[2] << 16 ) \
+ + ( (unsigned)_hj_key[3] << 24 ) ); \
+ _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \
+ + ( (unsigned)_hj_key[6] << 16 ) \
+ + ( (unsigned)_hj_key[7] << 24 ) ); \
+ hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \
+ + ( (unsigned)_hj_key[10] << 16 ) \
+ + ( (unsigned)_hj_key[11] << 24 ) ); \
+ \
+ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
+ \
+ _hj_key += 12; \
+ _hj_k -= 12; \
+ } \
+ hashv += keylen; \
+ switch ( _hj_k ) { \
+ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \
+ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \
+ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \
+ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \
+ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \
+ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \
+ case 5: _hj_j += _hj_key[4]; \
+ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \
+ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \
+ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \
+ case 1: _hj_i += _hj_key[0]; \
+ } \
+ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
+ bkt = hashv & (num_bkts-1); \
+} while(0)
+
+/* The Paul Hsieh hash function */
+#undef get16bits
+#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
+ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
+#define get16bits(d) (*((const uint16_t *) (d)))
+#endif
+
+#if !defined (get16bits)
+#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
+ +(uint32_t)(((const uint8_t *)(d))[0]) )
+#endif
+#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned char *_sfh_key=(unsigned char*)(key); \
+ uint32_t _sfh_tmp, _sfh_len = keylen; \
+ \
+ int _sfh_rem = _sfh_len & 3; \
+ _sfh_len >>= 2; \
+ hashv = 0xcafebabe; \
+ \
+ /* Main loop */ \
+ for (;_sfh_len > 0; _sfh_len--) { \
+ hashv += get16bits (_sfh_key); \
+ _sfh_tmp = (uint32_t)(get16bits (_sfh_key+2)) << 11 ^ hashv; \
+ hashv = (hashv << 16) ^ _sfh_tmp; \
+ _sfh_key += 2*sizeof (uint16_t); \
+ hashv += hashv >> 11; \
+ } \
+ \
+ /* Handle end cases */ \
+ switch (_sfh_rem) { \
+ case 3: hashv += get16bits (_sfh_key); \
+ hashv ^= hashv << 16; \
+ hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18); \
+ hashv += hashv >> 11; \
+ break; \
+ case 2: hashv += get16bits (_sfh_key); \
+ hashv ^= hashv << 11; \
+ hashv += hashv >> 17; \
+ break; \
+ case 1: hashv += *_sfh_key; \
+ hashv ^= hashv << 10; \
+ hashv += hashv >> 1; \
+ } \
+ \
+ /* Force "avalanching" of final 127 bits */ \
+ hashv ^= hashv << 3; \
+ hashv += hashv >> 5; \
+ hashv ^= hashv << 4; \
+ hashv += hashv >> 17; \
+ hashv ^= hashv << 25; \
+ hashv += hashv >> 6; \
+ bkt = hashv & (num_bkts-1); \
+} while(0)
+
+#ifdef HASH_USING_NO_STRICT_ALIASING
+/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
+ * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
+ * MurmurHash uses the faster approach only on CPU's where we know it's safe.
+ *
+ * Note the preprocessor built-in defines can be emitted using:
+ *
+ * gcc -m64 -dM -E - < /dev/null (on gcc)
+ * cc -## a.c (where a.c is a simple test file) (Sun Studio)
+ */
+#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86))
+#define MUR_GETBLOCK(p,i) p[i]
+#else /* non intel */
+#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0)
+#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1)
+#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2)
+#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3)
+#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
+#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
+#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
+#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
+#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
+#else /* assume little endian non-intel */
+#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
+#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
+#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))
+#endif
+#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \
+ (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
+ (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \
+ MUR_ONE_THREE(p))))
+#endif
+#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
+#define MUR_FMIX(_h) \
+do { \
+ _h ^= _h >> 16; \
+ _h *= 0x85ebca6b; \
+ _h ^= _h >> 13; \
+ _h *= 0xc2b2ae35l; \
+ _h ^= _h >> 16; \
+} while(0)
+
+#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ const uint8_t *_mur_data = (const uint8_t*)(key); \
+ const int _mur_nblocks = (keylen) / 4; \
+ uint32_t _mur_h1 = 0xf88D5353; \
+ uint32_t _mur_c1 = 0xcc9e2d51; \
+ uint32_t _mur_c2 = 0x1b873593; \
+ uint32_t _mur_k1 = 0; \
+ const uint8_t *_mur_tail; \
+ const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \
+ int _mur_i; \
+ for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \
+ _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \
+ _mur_k1 *= _mur_c1; \
+ _mur_k1 = MUR_ROTL32(_mur_k1,15); \
+ _mur_k1 *= _mur_c2; \
+ \
+ _mur_h1 ^= _mur_k1; \
+ _mur_h1 = MUR_ROTL32(_mur_h1,13); \
+ _mur_h1 = _mur_h1*5+0xe6546b64; \
+ } \
+ _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \
+ _mur_k1=0; \
+ switch((keylen) & 3) { \
+ case 3: _mur_k1 ^= _mur_tail[2] << 16; \
+ case 2: _mur_k1 ^= _mur_tail[1] << 8; \
+ case 1: _mur_k1 ^= _mur_tail[0]; \
+ _mur_k1 *= _mur_c1; \
+ _mur_k1 = MUR_ROTL32(_mur_k1,15); \
+ _mur_k1 *= _mur_c2; \
+ _mur_h1 ^= _mur_k1; \
+ } \
+ _mur_h1 ^= (keylen); \
+ MUR_FMIX(_mur_h1); \
+ hashv = _mur_h1; \
+ bkt = hashv & (num_bkts-1); \
+} while(0)
+#endif /* HASH_USING_NO_STRICT_ALIASING */
+
+/* key comparison function; return 0 if keys equal */
+#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
+
+/* iterate over items in a known bucket to find desired item */
+#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
+do { \
+ if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \
+ else out=NULL; \
+ while (out) { \
+ if ((out)->hh.keylen == keylen_in) { \
+ if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \
+ } \
+ if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \
+ else out = NULL; \
+ } \
+} while(0)
+
+/* add an item to a bucket */
+#define HASH_ADD_TO_BKT(head,addhh) \
+do { \
+ head.count++; \
+ (addhh)->hh_next = head.hh_head; \
+ (addhh)->hh_prev = NULL; \
+ if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \
+ (head).hh_head=addhh; \
+ if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \
+ && (addhh)->tbl->noexpand != 1) { \
+ HASH_EXPAND_BUCKETS((addhh)->tbl); \
+ } \
+} while(0)
+
+/* remove an item from a given bucket */
+#define HASH_DEL_IN_BKT(hh,head,hh_del) \
+ (head).count--; \
+ if ((head).hh_head == hh_del) { \
+ (head).hh_head = hh_del->hh_next; \
+ } \
+ if (hh_del->hh_prev) { \
+ hh_del->hh_prev->hh_next = hh_del->hh_next; \
+ } \
+ if (hh_del->hh_next) { \
+ hh_del->hh_next->hh_prev = hh_del->hh_prev; \
+ }
+
+/* Bucket expansion has the effect of doubling the number of buckets
+ * and redistributing the items into the new buckets. Ideally the
+ * items will distribute more or less evenly into the new buckets
+ * (the extent to which this is true is a measure of the quality of
+ * the hash function as it applies to the key domain).
+ *
+ * With the items distributed into more buckets, the chain length
+ * (item count) in each bucket is reduced. Thus by expanding buckets
+ * the hash keeps a bound on the chain length. This bounded chain
+ * length is the essence of how a hash provides constant time lookup.
+ *
+ * The calculation of tbl->ideal_chain_maxlen below deserves some
+ * explanation. First, keep in mind that we're calculating the ideal
+ * maximum chain length based on the *new* (doubled) bucket count.
+ * In fractions this is just n/b (n=number of items,b=new num buckets).
+ * Since the ideal chain length is an integer, we want to calculate
+ * ceil(n/b). We don't depend on floating point arithmetic in this
+ * hash, so to calculate ceil(n/b) with integers we could write
+ *
+ * ceil(n/b) = (n/b) + ((n%b)?1:0)
+ *
+ * and in fact a previous version of this hash did just that.
+ * But now we have improved things a bit by recognizing that b is
+ * always a power of two. We keep its base 2 log handy (call it lb),
+ * so now we can write this with a bit shift and logical AND:
+ *
+ * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
+ *
+ */
+#define HASH_EXPAND_BUCKETS(tbl) \
+do { \
+ unsigned _he_bkt; \
+ unsigned _he_bkt_i; \
+ struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
+ UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
+ _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
+ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
+ if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \
+ memset(_he_new_buckets, 0, \
+ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
+ tbl->ideal_chain_maxlen = \
+ (tbl->num_items >> (tbl->log2_num_buckets+1)) + \
+ ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \
+ tbl->nonideal_items = 0; \
+ for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \
+ { \
+ _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \
+ while (_he_thh) { \
+ _he_hh_nxt = _he_thh->hh_next; \
+ HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \
+ _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \
+ if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
+ tbl->nonideal_items++; \
+ _he_newbkt->expand_mult = _he_newbkt->count / \
+ tbl->ideal_chain_maxlen; \
+ } \
+ _he_thh->hh_prev = NULL; \
+ _he_thh->hh_next = _he_newbkt->hh_head; \
+ if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \
+ _he_thh; \
+ _he_newbkt->hh_head = _he_thh; \
+ _he_thh = _he_hh_nxt; \
+ } \
+ } \
+ uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
+ tbl->num_buckets *= 2; \
+ tbl->log2_num_buckets++; \
+ tbl->buckets = _he_new_buckets; \
+ tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \
+ (tbl->ineff_expands+1) : 0; \
+ if (tbl->ineff_expands > 1) { \
+ tbl->noexpand=1; \
+ uthash_noexpand_fyi(tbl); \
+ } \
+ uthash_expand_fyi(tbl); \
+} while(0)
+
+
+/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
+/* Note that HASH_SORT assumes the hash handle name to be hh.
+ * HASH_SRT was added to allow the hash handle name to be passed in. */
+#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
+#define HASH_SRT(hh,head,cmpfcn) \
+do { \
+ unsigned _hs_i; \
+ unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \
+ struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
+ if (head) { \
+ _hs_insize = 1; \
+ _hs_looping = 1; \
+ _hs_list = &((head)->hh); \
+ while (_hs_looping) { \
+ _hs_p = _hs_list; \
+ _hs_list = NULL; \
+ _hs_tail = NULL; \
+ _hs_nmerges = 0; \
+ while (_hs_p) { \
+ _hs_nmerges++; \
+ _hs_q = _hs_p; \
+ _hs_psize = 0; \
+ for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \
+ _hs_psize++; \
+ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
+ ((void*)((char*)(_hs_q->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ if (! (_hs_q) ) break; \
+ } \
+ _hs_qsize = _hs_insize; \
+ while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \
+ if (_hs_psize == 0) { \
+ _hs_e = _hs_q; \
+ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
+ ((void*)((char*)(_hs_q->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ _hs_qsize--; \
+ } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \
+ _hs_e = _hs_p; \
+ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \
+ ((void*)((char*)(_hs_p->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ _hs_psize--; \
+ } else if (( \
+ cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
+ DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
+ ) <= 0) { \
+ _hs_e = _hs_p; \
+ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \
+ ((void*)((char*)(_hs_p->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ _hs_psize--; \
+ } else { \
+ _hs_e = _hs_q; \
+ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
+ ((void*)((char*)(_hs_q->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ _hs_qsize--; \
+ } \
+ if ( _hs_tail ) { \
+ _hs_tail->next = ((_hs_e) ? \
+ ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
+ } else { \
+ _hs_list = _hs_e; \
+ } \
+ _hs_e->prev = ((_hs_tail) ? \
+ ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
+ _hs_tail = _hs_e; \
+ } \
+ _hs_p = _hs_q; \
+ } \
+ _hs_tail->next = NULL; \
+ if ( _hs_nmerges <= 1 ) { \
+ _hs_looping=0; \
+ (head)->hh.tbl->tail = _hs_tail; \
+ DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
+ } \
+ _hs_insize *= 2; \
+ } \
+ HASH_FSCK(hh,head); \
+ } \
+} while (0)
+
+/* This function selects items from one hash into another hash.
+ * The end result is that the selected items have dual presence
+ * in both hashes. There is no copy of the items made; rather
+ * they are added into the new hash through a secondary hash
+ * hash handle that must be present in the structure. */
+#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
+do { \
+ unsigned _src_bkt, _dst_bkt; \
+ void *_last_elt=NULL, *_elt; \
+ UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
+ ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \
+ if (src) { \
+ for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
+ for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \
+ _src_hh; \
+ _src_hh = _src_hh->hh_next) { \
+ _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
+ if (cond(_elt)) { \
+ _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
+ _dst_hh->key = _src_hh->key; \
+ _dst_hh->keylen = _src_hh->keylen; \
+ _dst_hh->hashv = _src_hh->hashv; \
+ _dst_hh->prev = _last_elt; \
+ _dst_hh->next = NULL; \
+ if (_last_elt_hh) { _last_elt_hh->next = _elt; } \
+ if (!dst) { \
+ DECLTYPE_ASSIGN(dst,_elt); \
+ HASH_MAKE_TABLE(hh_dst,dst); \
+ } else { \
+ _dst_hh->tbl = (dst)->hh_dst.tbl; \
+ } \
+ HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
+ HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
+ (dst)->hh_dst.tbl->num_items++; \
+ _last_elt = _elt; \
+ _last_elt_hh = _dst_hh; \
+ } \
+ } \
+ } \
+ } \
+ HASH_FSCK(hh_dst,dst); \
+} while (0)
+
+#define HASH_CLEAR(hh,head) \
+do { \
+ if (head) { \
+ uthash_free((head)->hh.tbl->buckets, \
+ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \
+ HASH_BLOOM_FREE((head)->hh.tbl); \
+ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
+ (head)=NULL; \
+ } \
+} while(0)
+
+#define HASH_OVERHEAD(hh,head) \
+ (size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \
+ ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \
+ (sizeof(UT_hash_table)) + \
+ (HASH_BLOOM_BYTELEN)))
+
+#ifdef NO_DECLTYPE
+#define HASH_ITER(hh,head,el,tmp) \
+for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \
+ el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))
+#else
+#define HASH_ITER(hh,head,el,tmp) \
+for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \
+ el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL))
+#endif
+
+/* obtain a count of items in the hash */
+#define HASH_COUNT(head) HASH_CNT(hh,head)
+#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0)
+
+typedef struct UT_hash_bucket {
+ struct UT_hash_handle *hh_head;
+ unsigned count;
+
+ /* expand_mult is normally set to 0. In this situation, the max chain length
+ * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
+ * the bucket's chain exceeds this length, bucket expansion is triggered).
+ * However, setting expand_mult to a non-zero value delays bucket expansion
+ * (that would be triggered by additions to this particular bucket)
+ * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
+ * (The multiplier is simply expand_mult+1). The whole idea of this
+ * multiplier is to reduce bucket expansions, since they are expensive, in
+ * situations where we know that a particular bucket tends to be overused.
+ * It is better to let its chain length grow to a longer yet-still-bounded
+ * value, than to do an O(n) bucket expansion too often.
+ */
+ unsigned expand_mult;
+
+} UT_hash_bucket;
+
+/* random signature used only to find hash tables in external analysis */
+#define HASH_SIGNATURE 0xa0111fe1
+#define HASH_BLOOM_SIGNATURE 0xb12220f2
+
+typedef struct UT_hash_table {
+ UT_hash_bucket *buckets;
+ unsigned num_buckets, log2_num_buckets;
+ unsigned num_items;
+ struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
+ ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
+
+ /* in an ideal situation (all buckets used equally), no bucket would have
+ * more than ceil(#items/#buckets) items. that's the ideal chain length. */
+ unsigned ideal_chain_maxlen;
+
+ /* nonideal_items is the number of items in the hash whose chain position
+ * exceeds the ideal chain maxlen. these items pay the penalty for an uneven
+ * hash distribution; reaching them in a chain traversal takes >ideal steps */
+ unsigned nonideal_items;
+
+ /* ineffective expands occur when a bucket doubling was performed, but
+ * afterward, more than half the items in the hash had nonideal chain
+ * positions. If this happens on two consecutive expansions we inhibit any
+ * further expansion, as it's not helping; this happens when the hash
+ * function isn't a good fit for the key domain. When expansion is inhibited
+ * the hash will still work, albeit no longer in constant time. */
+ unsigned ineff_expands, noexpand;
+
+ uint32_t signature; /* used only to find hash tables in external analysis */
+#ifdef HASH_BLOOM
+ uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
+ uint8_t *bloom_bv;
+ char bloom_nbits;
+#endif
+
+} UT_hash_table;
+
+typedef struct UT_hash_handle {
+ struct UT_hash_table *tbl;
+ void *prev; /* prev element in app order */
+ void *next; /* next element in app order */
+ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
+ struct UT_hash_handle *hh_next; /* next hh in bucket order */
+ void *key; /* ptr to enclosing struct's key */
+ unsigned keylen; /* enclosing struct's key len */
+ unsigned hashv; /* result of hash-fcn(key) */
+} UT_hash_handle;
+
+#endif /* UTHASH_H */
diff --git a/extensions/test_acct/CMakeLists.txt b/extensions/test_acct/CMakeLists.txt
new file mode 100644
index 0000000..848255e
--- /dev/null
+++ b/extensions/test_acct/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The test_acct extension
+PROJECT("Accounting dummy server" C)
+
+FD_ADD_EXTENSION(test_acct test_acct.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS test_acct
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
+
diff --git a/extensions/test_acct/test_acct.c b/extensions/test_acct/test_acct.c
new file mode 100644
index 0000000..7b648e5
--- /dev/null
+++ b/extensions/test_acct/test_acct.c
@@ -0,0 +1,145 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* This extension simply receives ACR and sends positive ACA after displaying the content,
+but does not commit the data to any storage */
+
+#include <freeDiameter/extension.h>
+
+static struct {
+ struct dict_object * Accounting_Record_Number;
+ struct dict_object * Accounting_Record_Type;
+} tac_dict;
+
+/* Callback for incoming Base Accounting application messages */
+static int tac_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * data, enum disp_action * act)
+{
+ struct msg_hdr *hdr = NULL;
+
+ TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+
+ if (msg == NULL)
+ return EINVAL;
+
+ /* Check what we received */
+ CHECK_FCT( fd_msg_hdr(*msg, &hdr) );
+
+ if (hdr->msg_flags & CMD_FLAG_REQUEST) {
+ /* It was a request, create an answer */
+ struct msg *ans, *qry;
+ struct avp * a = NULL;
+ struct avp_hdr * h = NULL;
+ os0_t s;
+ size_t sl;
+
+ qry = *msg;
+ /* Create the answer message, including the Session-Id AVP */
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+ /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */
+ CHECK_FCT( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ) );
+
+ fd_log_debug("--------------Received the following Accounting message:--------------");
+
+ CHECK_FCT( fd_sess_getsid ( sess, &s, &sl ) );
+ fd_log_debug("Session: %.*s", (int)sl, s);
+
+ /* The AVPs that we copy in the answer */
+ CHECK_FCT( fd_msg_search_avp ( qry, tac_dict.Accounting_Record_Type, &a) );
+ if (a) {
+ CHECK_FCT( fd_msg_avp_hdr( a, &h ) );
+ fd_log_debug("Accounting-Record-Type: %d (%s)", h->avp_value->u32,
+ /* it would be better to search this in the dictionary, but it is only for debug, so ok */
+ (h->avp_value->u32 == 1) ? "EVENT_RECORD" :
+ (h->avp_value->u32 == 2) ? "START_RECORD" :
+ (h->avp_value->u32 == 3) ? "INTERIM_RECORD" :
+ (h->avp_value->u32 == 4) ? "STOP_RECORD" :
+ "<unknown value>"
+ );
+ CHECK_FCT( fd_msg_avp_new ( tac_dict.Accounting_Record_Type, 0, &a ) );
+ CHECK_FCT( fd_msg_avp_setvalue( a, h->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, a ) );
+ }
+ CHECK_FCT( fd_msg_search_avp ( qry, tac_dict.Accounting_Record_Number, &a) );
+ if (a) {
+ CHECK_FCT( fd_msg_avp_hdr( a, &h ) );
+ fd_log_debug("Accounting-Record-Number: %d", h->avp_value->u32);
+ CHECK_FCT( fd_msg_avp_new ( tac_dict.Accounting_Record_Number, 0, &a ) );
+ CHECK_FCT( fd_msg_avp_setvalue( a, h->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, a ) );
+ }
+
+ /* We may also dump other data from the message, such as Accounting session Id, number of packets, ... */
+
+ fd_log_debug("----------------------------------------------------------------------");
+
+ /* Send the answer */
+ CHECK_FCT( fd_msg_send( msg, NULL, NULL ) );
+
+ } else {
+ /* We received an answer message, just discard it */
+ CHECK_FCT( fd_msg_free( *msg ) );
+ *msg = NULL;
+ }
+
+ return 0;
+}
+
+/* entry point: register handler for Base Accounting messages in the daemon */
+static int tac_entry(char * conffile)
+{
+ struct disp_when data;
+
+ TRACE_ENTRY("%p", conffile);
+
+ memset(&tac_dict, 0, sizeof(tac_dict));
+ memset(&data, 0, sizeof(data));
+
+ /* Initialize the dictionary objects we use */
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Base Accounting", &data.app, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Number", &tac_dict.Accounting_Record_Number, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Type", &tac_dict.Accounting_Record_Type, ENOENT) );
+
+ /* Register the dispatch callback */
+ CHECK_FCT( fd_disp_register( tac_cb, DISP_HOW_APPID, &data, NULL, NULL ) );
+
+ /* Advertise the support for the Diameter Base Accounting application in the peer */
+ CHECK_FCT( fd_disp_app_support ( data.app, NULL, 0, 1 ) );
+
+ return 0;
+}
+
+EXTENSION_ENTRY("test_acct", tac_entry);
diff --git a/extensions/test_app/CMakeLists.txt b/extensions/test_app/CMakeLists.txt
new file mode 100644
index 0000000..7557445
--- /dev/null
+++ b/extensions/test_app/CMakeLists.txt
@@ -0,0 +1,31 @@
+# The test_app extension
+PROJECT("Test Diameter Application" C)
+
+# Parser files
+BISON_FILE(ta_conf.y)
+FLEX_FILE(ta_conf.l)
+SET_SOURCE_FILES_PROPERTIES(lex.ta_conf.c ta_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( APP_TEST_SRC
+ test_app.h
+ test_app.c
+ lex.ta_conf.c
+ ta_conf.tab.c
+ ta_conf.tab.h
+ ta_dict.c
+ ta_cli.c
+ ta_bench.c
+ ta_serv.c
+)
+
+# Compile as a module
+FD_ADD_EXTENSION(test_app ${APP_TEST_SRC})
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS test_app
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
diff --git a/extensions/test_app/ta_bench.c b/extensions/test_app/ta_bench.c
new file mode 100644
index 0000000..95aa246
--- /dev/null
+++ b/extensions/test_app/ta_bench.c
@@ -0,0 +1,336 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2015, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Create and send a message, and receive it */
+
+#include "test_app.h"
+#include <stdio.h>
+
+#ifndef __APPLE__ /* they deprecated the semaphore there... */
+#include <semaphore.h>
+
+#define my_sem_t sem_t
+#define my_sem_init sem_init
+#define my_sem_destroy sem_destroy
+#define my_sem_timedwait sem_timedwait
+#define my_sem_post sem_post
+
+#else // on APPLE
+#include <sched.h>
+#include <dispatch/dispatch.h>
+
+#define my_sem_t dispatch_semaphore_t
+
+static int my_sem_init(my_sem_t * s, int pshared, unsigned int value ) {
+ *s = dispatch_semaphore_create(value);
+ if (*s == NULL)
+ return ENOMEM;
+ return 0;
+}
+
+static int my_sem_destroy(my_sem_t *s) {
+ dispatch_release(*s);
+ *s = NULL;
+ return 0;
+}
+
+static int my_sem_timedwait(my_sem_t * s, struct timespec *ts) {
+ struct timespec tsn;
+ int64_t nsec;
+ dispatch_time_t when;
+
+ CHECK_SYS( clock_gettime(CLOCK_REALTIME, &tsn) );
+
+ nsec = (ts->tv_sec * 1000000000) + ts->tv_nsec
+ - (tsn.tv_sec * 1000000000) - tsn.tv_nsec;
+
+ when = dispatch_time ( DISPATCH_TIME_NOW, nsec );
+
+ return dispatch_semaphore_wait ( *s, when ) ? ETIMEDOUT : 0;
+}
+
+static int my_sem_post(my_sem_t *s) {
+ dispatch_semaphore_signal(*s);
+ return 0;
+}
+
+#endif // APPLE
+
+
+
+struct ta_mess_info {
+ int32_t randval; /* a random value to store in Test-AVP */
+ struct timespec ts; /* Time of sending the message */
+};
+
+static my_sem_t ta_sem; /* To handle the concurrency */
+
+/* Cb called when an answer is received */
+static void ta_cb_ans(void * data, struct msg ** msg)
+{
+ struct ta_mess_info * mi = (struct ta_mess_info *)data;
+ struct timespec ts;
+ struct avp * avp;
+ struct avp_hdr * hdr;
+ unsigned long dur;
+
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return );
+
+ /* Value of Result Code */
+ CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_res_code, &avp), return );
+ if (avp) {
+ CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
+ }
+ if (!avp || !hdr || hdr->avp_value->i32 != 2001) {
+ /* error */
+ CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
+ ta_conf->stats.nb_errs++;
+ CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
+ goto end;
+ }
+
+ /* Check value of Test-AVP */
+ CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_avp, &avp), return );
+ if (avp) {
+ CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
+ ASSERT(hdr->avp_value->i32 == mi->randval);
+ }
+
+ /* Compute how long it took */
+ dur = ((ts.tv_sec - mi->ts.tv_sec) * 1000000) + ((ts.tv_nsec - mi->ts.tv_nsec) / 1000);
+
+ /* Add this value to the stats */
+ CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
+
+ if (ta_conf->stats.nb_recv) {
+ /* Ponderate in the avg */
+ ta_conf->stats.avg = (ta_conf->stats.avg * ta_conf->stats.nb_recv + dur) / (ta_conf->stats.nb_recv + 1);
+ /* Min, max */
+ if (dur < ta_conf->stats.shortest)
+ ta_conf->stats.shortest = dur;
+ if (dur > ta_conf->stats.longest)
+ ta_conf->stats.longest = dur;
+ } else {
+ ta_conf->stats.shortest = dur;
+ ta_conf->stats.longest = dur;
+ ta_conf->stats.avg = dur;
+ }
+ ta_conf->stats.nb_recv++;
+
+ CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
+
+end:
+ /* Free the message */
+ CHECK_FCT_DO(fd_msg_free(*msg), );
+ *msg = NULL;
+
+ free(mi);
+
+ /* Post the semaphore */
+ CHECK_SYS_DO( my_sem_post(&ta_sem), );
+
+ return;
+}
+
+/* Create a test message */
+static void ta_bench_test_message()
+{
+ struct msg * req = NULL;
+ struct avp * avp;
+ union avp_value val;
+ struct ta_mess_info * mi = NULL;
+
+ TRACE_DEBUG(FULL, "Creating a new message for sending.");
+
+ /* Create the request */
+ CHECK_FCT_DO( fd_msg_new( ta_cmd_r, MSGFL_ALLOC_ETEID, &req ), goto out );
+
+ /* Create a new session */
+ #define TEST_APP_SID_OPT "app_testb"
+ CHECK_FCT_DO( fd_msg_new_session( req, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
+
+ /* Create the random value to store with the session */
+ mi = malloc(sizeof(struct ta_mess_info));
+ if (mi == NULL) {
+ fd_log_debug("malloc failed: %s", strerror(errno));
+ goto out;
+ }
+
+ mi->randval = (int32_t)random();
+
+ /* Now set all AVPs values */
+
+ /* Set the Destination-Realm AVP */
+ {
+ CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_realm, 0, &avp ), goto out );
+ val.os.data = (unsigned char *)(ta_conf->dest_realm);
+ val.os.len = strlen(ta_conf->dest_realm);
+ CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
+ CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
+ }
+
+ /* Set the Destination-Host AVP if needed*/
+ if (ta_conf->dest_host) {
+ CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_host, 0, &avp ), goto out );
+ val.os.data = (unsigned char *)(ta_conf->dest_host);
+ val.os.len = strlen(ta_conf->dest_host);
+ CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
+ CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
+ }
+
+ /* Set Origin-Host & Origin-Realm */
+ CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out );
+
+ /* Set the User-Name AVP if needed*/
+ if (ta_conf->user_name) {
+ CHECK_FCT_DO( fd_msg_avp_new ( ta_user_name, 0, &avp ), goto out );
+ val.os.data = (unsigned char *)(ta_conf->user_name);
+ val.os.len = strlen(ta_conf->user_name);
+ CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
+ CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
+ }
+
+ /* Set the Test-AVP AVP */
+ {
+ CHECK_FCT_DO( fd_msg_avp_new ( ta_avp, 0, &avp ), goto out );
+ val.i32 = mi->randval;
+ CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
+ CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
+ }
+
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out );
+
+ /* Send the request */
+ CHECK_FCT_DO( fd_msg_send( &req, ta_cb_ans, mi ), goto out );
+
+ /* Increment the counter */
+ CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
+ ta_conf->stats.nb_sent++;
+ CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
+
+out:
+ return;
+}
+
+/* The function called when the signal is received */
+static void ta_bench_start() {
+ struct timespec end_time, now;
+ struct ta_stats start, end;
+ int nsec = 0;
+
+ /* Save the initial stats */
+ CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
+ memcpy(&start, &ta_conf->stats, sizeof(struct ta_stats));
+ CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
+
+ /* We will run for ta_conf->bench_duration seconds */
+ LOG_N("Starting benchmark client, %ds", ta_conf->bench_duration);
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &end_time), );
+ end_time.tv_sec += ta_conf->bench_duration;
+
+ /* Now loop until timeout is reached */
+ do {
+ /* Do not create more that NB_CONCURRENT_MESSAGES in paralel */
+ int ret = my_sem_timedwait(&ta_sem, &end_time);
+ if (ret == -1) {
+ ret = errno;
+ if (ret != ETIMEDOUT) {
+ CHECK_POSIX_DO(ret, ); /* Just to log it */
+ }
+ break;
+ }
+
+ /* Update the current time */
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), );
+
+ if (!TS_IS_INFERIOR(&now, &end_time))
+ break;
+
+ /* Create and send a new test message */
+ ta_bench_test_message();
+ } while (1);
+
+ do {
+ CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), ); /* Re-read the time because we might have spent some time wiating for the mutex */
+ memcpy(&end, &ta_conf->stats, sizeof(struct ta_stats));
+ CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
+
+ /* Now, display the statistics */
+ LOG_N( "------- app_test Benchmark results, end sending +%ds ---------", nsec);
+ if (now.tv_nsec >= end_time.tv_nsec) {
+ LOG_N( " Executing for: %d.%06ld sec",
+ (int)(now.tv_sec + ta_conf->bench_duration - end_time.tv_sec),
+ (long)(now.tv_nsec - end_time.tv_nsec) / 1000);
+ } else {
+ LOG_N( " Executing for: %d.%06ld sec",
+ (int)(now.tv_sec + ta_conf->bench_duration - 1 - end_time.tv_sec),
+ (long)(now.tv_nsec + 1000000000 - end_time.tv_nsec) / 1000);
+ }
+ LOG_N( " %llu messages sent", end.nb_sent - start.nb_sent);
+ LOG_N( " %llu error(s) received", end.nb_errs - start.nb_errs);
+ LOG_N( " %llu answer(s) received", end.nb_recv - start.nb_recv);
+ LOG_N( " Overall:");
+ LOG_N( " fastest: %ld.%06ld sec.", end.shortest / 1000000, end.shortest % 1000000);
+ LOG_N( " slowest: %ld.%06ld sec.", end.longest / 1000000, end.longest % 1000000);
+ LOG_N( " Average: %ld.%06ld sec.", end.avg / 1000000, end.avg % 1000000);
+ LOG_N( " Throughput: %llu messages / sec", (end.nb_recv - start.nb_recv) / (( now.tv_sec + ta_conf->bench_duration - end_time.tv_sec ) + ((now.tv_nsec - end_time.tv_nsec) / 1000000000)));
+ LOG_N( "-------------------------------------");
+
+ nsec ++;
+ sleep(1);
+ } while ( (end.nb_sent - start.nb_sent) > (end.nb_errs - start.nb_errs) + (end.nb_recv - start.nb_recv) );
+ LOG_N( "--------------- Test Complete --------------");
+
+}
+
+
+int ta_bench_init(void)
+{
+ CHECK_SYS( my_sem_init( &ta_sem, 0, ta_conf->bench_concur) );
+
+ CHECK_FCT( fd_event_trig_regcb(ta_conf->signal, "test_app.bench", ta_bench_start ) );
+
+ return 0;
+}
+
+void ta_bench_fini(void)
+{
+ // CHECK_FCT_DO( fd_sig_unregister(ta_conf->signal), /* continue */ );
+
+ CHECK_SYS_DO( my_sem_destroy(&ta_sem), );
+
+ return;
+};
diff --git a/extensions/test_app/ta_cli.c b/extensions/test_app/ta_cli.c
new file mode 100644
index 0000000..686338a
--- /dev/null
+++ b/extensions/test_app/ta_cli.c
@@ -0,0 +1,293 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2015, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Create and send a message, and receive it */
+
+/* Note that we use both sessions and the argument to answer callback to pass the same value.
+ * This is just for the purpose of checking everything went OK.
+ */
+
+#include "test_app.h"
+
+#include <stdio.h>
+
+static struct session_handler * ta_cli_reg = NULL;
+
+struct sess_state {
+ int32_t randval; /* a random value to store in Test-AVP */
+ struct timespec ts; /* Time of sending the message */
+} ;
+
+/* Cb called when an answer is received */
+static void ta_cb_ans(void * data, struct msg ** msg)
+{
+ struct sess_state * mi = NULL;
+ struct timespec ts;
+ struct session * sess;
+ struct avp * avp;
+ struct avp_hdr * hdr;
+ unsigned long dur;
+ int error = 0;
+
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return );
+
+ /* Search the session, retrieve its data */
+ {
+ int new;
+ CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &sess, &new), return );
+ ASSERT( new == 0 );
+
+ CHECK_FCT_DO( fd_sess_state_retrieve( ta_cli_reg, sess, &mi ), return );
+ ASSERT( (void *)mi == data );
+ }
+
+ /* Now log content of the answer */
+ fprintf(stderr, "RECV ");
+
+ /* Value of Test-AVP */
+ CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_avp, &avp), return );
+ if (avp) {
+ CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
+ if (hdr->avp_value->i32 == mi->randval) {
+ fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "Ok");
+ } else {
+ fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "PROBLEM");
+ error++;
+ }
+ } else {
+ fprintf(stderr, "no_Test-AVP ");
+ error++;
+ }
+
+ /* Value of Result Code */
+ CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_res_code, &avp), return );
+ if (avp) {
+ CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
+ fprintf(stderr, "Status: %d ", hdr->avp_value->i32);
+ if (hdr->avp_value->i32 != 2001)
+ error++;
+ } else {
+ fprintf(stderr, "no_Result-Code ");
+ error++;
+ }
+
+ /* Value of Origin-Host */
+ CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_origin_host, &avp), return );
+ if (avp) {
+ CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
+ fprintf(stderr, "From '%.*s' ", (int)hdr->avp_value->os.len, hdr->avp_value->os.data);
+ } else {
+ fprintf(stderr, "no_Origin-Host ");
+ error++;
+ }
+
+ /* Value of Origin-Realm */
+ CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_origin_realm, &avp), return );
+ if (avp) {
+ CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
+ fprintf(stderr, "('%.*s') ", (int)hdr->avp_value->os.len, hdr->avp_value->os.data);
+ } else {
+ fprintf(stderr, "no_Origin-Realm ");
+ error++;
+ }
+
+ CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
+ dur = ((ts.tv_sec - mi->ts.tv_sec) * 1000000) + ((ts.tv_nsec - mi->ts.tv_nsec) / 1000);
+ if (ta_conf->stats.nb_recv) {
+ /* Ponderate in the avg */
+ ta_conf->stats.avg = (ta_conf->stats.avg * ta_conf->stats.nb_recv + dur) / (ta_conf->stats.nb_recv + 1);
+ /* Min, max */
+ if (dur < ta_conf->stats.shortest)
+ ta_conf->stats.shortest = dur;
+ if (dur > ta_conf->stats.longest)
+ ta_conf->stats.longest = dur;
+ } else {
+ ta_conf->stats.shortest = dur;
+ ta_conf->stats.longest = dur;
+ ta_conf->stats.avg = dur;
+ }
+
+ if (error)
+ ta_conf->stats.nb_errs++;
+ else
+ ta_conf->stats.nb_recv++;
+
+
+ CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
+
+ /* Display how long it took */
+ if (ts.tv_nsec > mi->ts.tv_nsec) {
+ fprintf(stderr, "in %d.%06ld sec",
+ (int)(ts.tv_sec - mi->ts.tv_sec),
+ (long)(ts.tv_nsec - mi->ts.tv_nsec) / 1000);
+ } else {
+ fprintf(stderr, "in %d.%06ld sec",
+ (int)(ts.tv_sec + 1 - mi->ts.tv_sec),
+ (long)(1000000000 + ts.tv_nsec - mi->ts.tv_nsec) / 1000);
+ }
+ fprintf(stderr, "\n");
+ fflush(stderr);
+
+ /* Free the message */
+ CHECK_FCT_DO(fd_msg_free(*msg), return);
+ *msg = NULL;
+
+ free(mi);
+
+ return;
+}
+
+/* Create a test message */
+static void ta_cli_test_message()
+{
+ struct msg * req = NULL;
+ struct avp * avp;
+ union avp_value val;
+ struct sess_state * mi = NULL, *svg;
+ struct session *sess = NULL;
+
+ TRACE_DEBUG(FULL, "Creating a new message for sending.");
+
+ /* Create the request */
+ CHECK_FCT_DO( fd_msg_new( ta_cmd_r, MSGFL_ALLOC_ETEID, &req ), goto out );
+
+ /* Create a new session */
+ #define TEST_APP_SID_OPT "app_test"
+ CHECK_FCT_DO( fd_msg_new_session( req, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
+ CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &sess, NULL), goto out );
+
+ /* Create the random value to store with the session */
+ mi = malloc(sizeof(struct sess_state));
+ if (mi == NULL) {
+ fd_log_debug("malloc failed: %s", strerror(errno));
+ goto out;
+ }
+
+ mi->randval = (int32_t)random();
+
+ /* Now set all AVPs values */
+
+ /* Set the Destination-Realm AVP */
+ {
+ CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_realm, 0, &avp ), goto out );
+ val.os.data = (unsigned char *)(ta_conf->dest_realm);
+ val.os.len = strlen(ta_conf->dest_realm);
+ CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
+ CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
+ }
+
+ /* Set the Destination-Host AVP if needed*/
+ if (ta_conf->dest_host) {
+ CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_host, 0, &avp ), goto out );
+ val.os.data = (unsigned char *)(ta_conf->dest_host);
+ val.os.len = strlen(ta_conf->dest_host);
+ CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
+ CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
+ }
+
+ /* Set Origin-Host & Origin-Realm */
+ CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out );
+
+ /* Set the User-Name AVP if needed*/
+ if (ta_conf->user_name) {
+ CHECK_FCT_DO( fd_msg_avp_new ( ta_user_name, 0, &avp ), goto out );
+ val.os.data = (unsigned char *)(ta_conf->user_name);
+ val.os.len = strlen(ta_conf->user_name);
+ CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
+ CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
+ }
+
+ /* Set the Test-AVP AVP */
+ {
+ CHECK_FCT_DO( fd_msg_avp_new ( ta_avp, 0, &avp ), goto out );
+ val.i32 = mi->randval;
+ CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
+ CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
+ }
+
+ /* Set the Test-Payload-AVP AVP */
+ if (ta_conf->long_avp_id) {
+ int l;
+ CHECK_FCT_DO( fd_msg_avp_new ( ta_avp_long, 0, &avp ), goto out );
+ CHECK_MALLOC_DO( val.os.data = malloc(ta_conf->long_avp_len), goto out);
+ val.os.len = ta_conf->long_avp_len;
+ for (l=0; l < ta_conf->long_avp_len; l++)
+ val.os.data[l]=l;
+ CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
+ free(val.os.data);
+ CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
+ }
+
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out );
+
+ /* Keep a pointer to the session data for debug purpose, in real life we would not need it */
+ svg = mi;
+
+ /* Store this value in the session */
+ CHECK_FCT_DO( fd_sess_state_store ( ta_cli_reg, sess, &mi ), goto out );
+
+ /* Log sending the message */
+ fprintf(stderr, "SEND %x to '%s' (%s)\n", svg->randval, ta_conf->dest_realm, ta_conf->dest_host?:"-" );
+ fflush(stderr);
+
+ /* Send the request */
+ CHECK_FCT_DO( fd_msg_send( &req, ta_cb_ans, svg ), goto out );
+
+ /* Increment the counter */
+ CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
+ ta_conf->stats.nb_sent++;
+ CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
+
+out:
+ return;
+}
+
+int ta_cli_init(void)
+{
+ CHECK_FCT( fd_sess_handler_create(&ta_cli_reg, (void *)free, NULL, NULL) );
+
+ CHECK_FCT( fd_event_trig_regcb(ta_conf->signal, "test_app.cli", ta_cli_test_message ) );
+
+ return 0;
+}
+
+void ta_cli_fini(void)
+{
+ // CHECK_FCT_DO( fd_sig_unregister(ta_conf->signal), /* continue */ );
+
+ CHECK_FCT_DO( fd_sess_handler_destroy(&ta_cli_reg, NULL), /* continue */ );
+
+ return;
+};
diff --git a/extensions/test_app/ta_conf.l b/extensions/test_app/ta_conf.l
new file mode 100644
index 0000000..1bae950
--- /dev/null
+++ b/extensions/test_app/ta_conf.l
@@ -0,0 +1,177 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Lex extension's configuration parser.
+ *
+ * The configuration file contains a default priority, and a list of peers with optional overwite priority.
+ * -- see the app_test.conf.sample file for more detail.
+ */
+
+%{
+#include "test_app.h"
+/* Include yacc tokens definitions */
+#include "ta_conf.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+ /* Recognize any integer */
+[-]?[[:digit:]]+ {
+ /* Convert this to an integer value */
+ int ret=0;
+ ret = sscanf(yytext, "%i", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+ /* Recognize quoted strings -- we do not support escaped \" in the string currently. */
+\"[^\"]+\" {
+ /* Match a quoted string. Let's be very permissive. */
+ yylval->string = strdup(yytext+1);
+ if (!yylval->string) {
+ fd_log_debug("Unable to copy the string '%s': %s", yytext, strerror(errno));
+ TRACE_DEBUG(INFO, "strdup failed");
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+ yylval->string[strlen(yytext) - 2] = '\0';
+ return QSTRING;
+ }
+
+ /* Recognize the tokens */
+(?i:"vendor-id") {
+ return VENDOR_ID;
+ }
+
+(?i:"appli-id") {
+ return APPLI_ID;
+ }
+
+(?i:"cmd-id") {
+ return CMD_ID;
+ }
+
+(?i:"avp-id") {
+ return AVP_ID;
+ }
+
+(?i:"long-avp-id") {
+ return LONG_AVP_ID;
+ }
+
+(?i:"long-avp-len") {
+ return LONG_AVP_LEN;
+ }
+
+(?i:"mode") {
+ return MODE;
+ }
+
+(?i:"server") {
+ yylval->integer = MODE_SERV;
+ return INTEGER;
+ }
+
+(?i:"client") {
+ yylval->integer = MODE_CLI;
+ return INTEGER;
+ }
+
+(?i:"both") {
+ yylval->integer = MODE_SERV | MODE_CLI;
+ return INTEGER;
+ }
+
+(?i:"dest-realm") {
+ return DEST_REALM;
+ }
+
+(?i:"dest-host") {
+ return DEST_HOST;
+ }
+
+(?i:"user-name") {
+ return USER_NAME;
+ }
+
+(?i:"Signal") {
+ return SIGNAL;
+ }
+
+(?i:"Benchmark") {
+ return BENCH;
+ }
+
+
+ /* Valid single characters for yyparse */
+[=;] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]"*=>;\n]+ {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/test_app/ta_conf.y b/extensions/test_app/ta_conf.y
new file mode 100644
index 0000000..52e3648
--- /dev/null
+++ b/extensions/test_app/ta_conf.y
@@ -0,0 +1,239 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ * See doc/app_test.conf.sample for configuration file format
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "test_app.h"
+#include "ta_conf.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+#include <string.h>
+#include <errno.h>
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+/* Parse the configuration file */
+int ta_conf_handle(char * conffile)
+{
+ extern FILE * ta_confin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ ta_confin = fopen(conffile, "r");
+ if (ta_confin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(ta_confin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int ta_conflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ char *string; /* The string is allocated by strdup in lex.*/
+ int integer; /* Store integer values */
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+/* Key words */
+%token VENDOR_ID
+%token APPLI_ID
+%token CMD_ID
+%token AVP_ID
+%token LONG_AVP_ID
+%token LONG_AVP_LEN
+%token MODE
+%token DEST_REALM
+%token DEST_HOST
+%token USER_NAME
+%token SIGNAL
+%token BENCH
+
+/* Tokens and types for routing table definition */
+/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */
+%token <string> QSTRING
+
+/* An integer value */
+%token <integer> INTEGER
+
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK */
+ | conffile vendor
+ | conffile appli
+ | conffile cmd
+ | conffile avp
+ | conffile long_avp_id
+ | conffile long_avp_len
+ | conffile mode
+ | conffile dstrealm
+ | conffile dsthost
+ | conffile usrname
+ | conffile signal
+ | conffile bench
+ ;
+
+vendor: VENDOR_ID '=' INTEGER ';'
+ {
+ ta_conf->vendor_id = $3;
+ }
+ ;
+
+appli: APPLI_ID '=' INTEGER ';'
+ {
+ ta_conf->appli_id = $3;
+ }
+ ;
+
+cmd: CMD_ID '=' INTEGER ';'
+ {
+ ta_conf->cmd_id = $3;
+ }
+ ;
+
+avp: AVP_ID '=' INTEGER ';'
+ {
+ ta_conf->avp_id = $3;
+ }
+ ;
+
+long_avp_id: LONG_AVP_ID '=' INTEGER ';'
+ {
+ ta_conf->long_avp_id = $3;
+ }
+ ;
+
+long_avp_len: LONG_AVP_LEN '=' INTEGER ';'
+ {
+ ta_conf->long_avp_len = $3;
+ }
+ ;
+
+mode: MODE '=' INTEGER ';'
+ {
+ ta_conf->mode = $3 | (ta_conf->mode & ~3); /* overwrite the 2 lsb */
+ }
+ ;
+
+bench: BENCH ';'
+ {
+ ta_conf->mode |= MODE_BENCH;
+ }
+ | BENCH INTEGER INTEGER ';'
+ {
+ ta_conf->mode |= MODE_BENCH;
+ ta_conf->bench_duration = $2;
+ ta_conf->bench_concur = $3;
+ }
+ ;
+
+dstrealm: DEST_REALM '=' QSTRING ';'
+ {
+ free(ta_conf->dest_realm);
+ ta_conf->dest_realm = $3;
+ }
+ ;
+
+dsthost: DEST_HOST '=' QSTRING ';'
+ {
+ free(ta_conf->dest_host);
+ ta_conf->dest_host = $3;
+ }
+ ;
+
+usrname: USER_NAME '=' QSTRING ';'
+ {
+ free(ta_conf->user_name);
+ ta_conf->user_name = $3;
+ }
+ ;
+
+signal: SIGNAL '=' INTEGER ';'
+ {
+ ta_conf->signal = $3;
+ }
+ ;
diff --git a/extensions/test_app/ta_dict.c b/extensions/test_app/ta_dict.c
new file mode 100644
index 0000000..2b9c6b3
--- /dev/null
+++ b/extensions/test_app/ta_dict.c
@@ -0,0 +1,166 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Install the dictionary objects */
+
+#include "test_app.h"
+
+struct dict_object * ta_vendor = NULL;
+struct dict_object * ta_appli = NULL;
+struct dict_object * ta_cmd_r = NULL;
+struct dict_object * ta_cmd_a = NULL;
+struct dict_object * ta_avp = NULL;
+struct dict_object * ta_avp_long = NULL;
+
+struct dict_object * ta_sess_id = NULL;
+struct dict_object * ta_origin_host = NULL;
+struct dict_object * ta_origin_realm = NULL;
+struct dict_object * ta_dest_host = NULL;
+struct dict_object * ta_dest_realm = NULL;
+struct dict_object * ta_user_name = NULL;
+struct dict_object * ta_res_code = NULL;
+
+int ta_dict_init(void)
+{
+ TRACE_DEBUG(FULL, "Initializing the dictionary for test");
+
+ /* Create the Test Vendor */
+ {
+ struct dict_vendor_data data;
+ data.vendor_id = ta_conf->vendor_id;
+ data.vendor_name = "app_test vendor";
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_VENDOR, &data, NULL, &ta_vendor));
+ }
+
+ /* Create the Test Application */
+ {
+ struct dict_application_data data;
+ data.application_id = ta_conf->appli_id;
+ data.application_name = "app_test application";
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_APPLICATION, &data, ta_vendor, &ta_appli));
+ }
+
+ /* Create the Test-Request & Test-Answer commands */
+ {
+ struct dict_cmd_data data;
+ data.cmd_code = ta_conf->cmd_id;
+ data.cmd_name = "Test-Request";
+ data.cmd_flag_mask = CMD_FLAG_PROXIABLE | CMD_FLAG_REQUEST;
+ data.cmd_flag_val = CMD_FLAG_PROXIABLE | CMD_FLAG_REQUEST;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_COMMAND, &data, ta_appli, &ta_cmd_r));
+ data.cmd_name = "Test-Answer";
+ data.cmd_flag_val = CMD_FLAG_PROXIABLE;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_COMMAND, &data, ta_appli, &ta_cmd_a));
+ }
+
+ /* Create the Test AVP */
+ {
+ struct dict_avp_data data;
+ data.avp_code = ta_conf->avp_id;
+ data.avp_vendor = ta_conf->vendor_id;
+ data.avp_name = "Test-AVP";
+ data.avp_flag_mask = AVP_FLAG_VENDOR;
+ data.avp_flag_val = AVP_FLAG_VENDOR;
+ data.avp_basetype = AVP_TYPE_INTEGER32;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_AVP, &data, NULL, &ta_avp));
+ }
+
+ /* Create the Test Payload AVP */
+ if (ta_conf->long_avp_id) {
+ struct dict_avp_data data;
+ data.avp_code = ta_conf->long_avp_id;
+ data.avp_vendor = ta_conf->vendor_id;
+ data.avp_name = "Test-Payload-AVP";
+ data.avp_flag_mask = AVP_FLAG_VENDOR;
+ data.avp_flag_val = AVP_FLAG_VENDOR;
+ data.avp_basetype = AVP_TYPE_OCTETSTRING;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_AVP, &data, NULL, &ta_avp_long));
+ }
+
+ /* Now resolve some other useful AVPs */
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &ta_sess_id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &ta_origin_host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &ta_origin_realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &ta_dest_host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &ta_dest_realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &ta_user_name, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &ta_res_code, ENOENT) );
+
+ /* Create the rules for Test-Request and Test-Answer */
+ {
+ struct dict_rule_data data;
+ data.rule_min = 1;
+ data.rule_max = 1;
+
+ /* Session-Id is in first position */
+ data.rule_avp = ta_sess_id;
+ data.rule_position = RULE_FIXED_HEAD;
+ data.rule_order = 1;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
+
+ data.rule_position = RULE_REQUIRED;
+ /* Test-AVP is mandatory */
+ data.rule_avp = ta_avp;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
+
+ /* idem for Origin Host and Realm */
+ data.rule_avp = ta_origin_host;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
+
+ data.rule_avp = ta_origin_realm;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
+
+ /* And Result-Code is mandatory for answers only */
+ data.rule_avp = ta_res_code;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
+
+ /* And Destination-Realm for requests only */
+ data.rule_avp = ta_dest_realm;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
+
+ /* And Destination-Host optional for requests only */
+ data.rule_position = RULE_OPTIONAL;
+ data.rule_min = 0;
+ data.rule_avp = ta_dest_host;
+ CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
+
+ }
+
+ return 0;
+}
diff --git a/extensions/test_app/ta_serv.c b/extensions/test_app/ta_serv.c
new file mode 100644
index 0000000..848c9de
--- /dev/null
+++ b/extensions/test_app/ta_serv.c
@@ -0,0 +1,154 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Install the dispatch callbacks */
+
+#include "test_app.h"
+
+static struct disp_hdl * ta_hdl_fb = NULL; /* handler for fallback cb */
+static struct disp_hdl * ta_hdl_tr = NULL; /* handler for Test-Request req cb */
+
+/* Default callback for the application. */
+static int ta_fb_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ /* This CB should never be called */
+ TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+
+ fd_log_debug("Unexpected message received!");
+
+ return ENOTSUP;
+}
+
+/* Callback for incoming Test-Request messages */
+static int ta_tr_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ struct msg *ans, *qry;
+ struct avp * a;
+
+ TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+
+ if (msg == NULL)
+ return EINVAL;
+
+ /* Value of Origin-Host */
+ if (! (ta_conf->mode & MODE_BENCH)) {
+ fprintf(stderr, "ECHO Test-Request received from ");
+ CHECK_FCT( fd_msg_search_avp ( *msg, ta_origin_host, &a) );
+ if (a) {
+ struct avp_hdr * hdr;
+ CHECK_FCT( fd_msg_avp_hdr( a, &hdr ) );
+ fprintf(stderr, "'%.*s'", (int)hdr->avp_value->os.len, hdr->avp_value->os.data);
+ } else {
+ fprintf(stderr, "no_Origin-Host");
+ }
+ fprintf(stderr, ", replying...\n");
+ }
+
+ /* Create answer header */
+ qry = *msg;
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+ /* Set the Test-AVP AVP */
+ {
+ struct avp * src = NULL;
+ struct avp_hdr * hdr = NULL;
+
+ CHECK_FCT( fd_msg_search_avp ( qry, ta_avp, &src) );
+ CHECK_FCT( fd_msg_avp_hdr( src, &hdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( ta_avp, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, hdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ /* Set the Test-Payload-AVP AVP */
+ if (ta_conf->long_avp_id) {
+ struct avp * src = NULL;
+ struct avp_hdr * hdr = NULL;
+
+ CHECK_FCT( fd_msg_search_avp ( qry, ta_avp_long, &src) );
+ CHECK_FCT( fd_msg_avp_hdr( src, &hdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( ta_avp_long, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, hdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+
+ /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */
+ CHECK_FCT( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ) );
+
+ /* Send the answer */
+ CHECK_FCT( fd_msg_send( msg, NULL, NULL ) );
+
+ /* Add this value to the stats */
+ CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
+ ta_conf->stats.nb_echoed++;
+ CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
+
+ return 0;
+}
+
+int ta_serv_init(void)
+{
+ struct disp_when data;
+
+ TRACE_DEBUG(FULL, "Initializing dispatch callbacks for test");
+
+ memset(&data, 0, sizeof(data));
+ data.app = ta_appli;
+ data.command = ta_cmd_r;
+
+ /* fallback CB if command != Test-Request received */
+ CHECK_FCT( fd_disp_register( ta_fb_cb, DISP_HOW_APPID, &data, NULL, &ta_hdl_fb ) );
+
+ /* Now specific handler for Test-Request */
+ CHECK_FCT( fd_disp_register( ta_tr_cb, DISP_HOW_CC, &data, NULL, &ta_hdl_tr ) );
+
+ return 0;
+}
+
+void ta_serv_fini(void)
+{
+ if (ta_hdl_fb) {
+ (void) fd_disp_unregister(&ta_hdl_fb, NULL);
+ }
+ if (ta_hdl_tr) {
+ (void) fd_disp_unregister(&ta_hdl_tr, NULL);
+ }
+
+ return;
+}
diff --git a/extensions/test_app/test_app.c b/extensions/test_app/test_app.c
new file mode 100644
index 0000000..a89f281
--- /dev/null
+++ b/extensions/test_app/test_app.c
@@ -0,0 +1,223 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * Test application for freeDiameter.
+ */
+
+#include "test_app.h"
+
+/* Initialize the configuration */
+struct ta_conf * ta_conf = NULL;
+static struct ta_conf _conf;
+static pthread_t ta_stats_th = (pthread_t)NULL;
+
+static int ta_conf_init(void)
+{
+ ta_conf = &_conf;
+ memset(ta_conf, 0, sizeof(struct ta_conf));
+
+ /* Set the default values */
+ ta_conf->vendor_id = 999999; /* Dummy value */
+ ta_conf->appli_id = 0xffffff; /* dummy value */
+ ta_conf->cmd_id = 0xfffffe; /* Experimental */
+ ta_conf->avp_id = 0xffffff; /* dummy value */
+ ta_conf->long_avp_len = 5000;
+ ta_conf->mode = MODE_SERV | MODE_CLI;
+ ta_conf->dest_realm = strdup(fd_g_config->cnf_diamrlm);
+ ta_conf->dest_host = NULL;
+ ta_conf->signal = TEST_APP_DEFAULT_SIGNAL;
+ ta_conf->bench_concur = 100;
+ ta_conf->bench_duration = 10;
+
+ /* Initialize the mutex */
+ CHECK_POSIX( pthread_mutex_init(&ta_conf->stats_lock, NULL) );
+
+ return 0;
+}
+
+static void ta_conf_dump(void)
+{
+ if (!TRACE_BOOL(INFO))
+ return;
+ fd_log_debug( "------- app_test configuration dump: ---------");
+ fd_log_debug( " Vendor Id .......... : %u", ta_conf->vendor_id);
+ fd_log_debug( " Application Id ..... : %u", ta_conf->appli_id);
+ fd_log_debug( " Command Id ......... : %u", ta_conf->cmd_id);
+ fd_log_debug( " AVP Id ............. : %u", ta_conf->avp_id);
+ fd_log_debug( " Long AVP Id ........ : %u", ta_conf->long_avp_id);
+ fd_log_debug( " Long AVP len ....... : %zu", ta_conf->long_avp_len);
+ fd_log_debug( " Mode ............... : %s%s%s", ta_conf->mode & MODE_SERV ? "Serv" : "", ta_conf->mode & MODE_CLI ? "Cli" : "", ta_conf->mode & MODE_BENCH ? " (Benchmark)" : "");
+ fd_log_debug( " Destination Realm .. : %s", ta_conf->dest_realm ?: "- none -");
+ fd_log_debug( " Destination Host ... : %s", ta_conf->dest_host ?: "- none -");
+ fd_log_debug( " Signal ............. : %i", ta_conf->signal);
+ fd_log_debug( "------- /app_test configuration dump ---------");
+}
+
+/* Function to display statistics periodically */
+static void * ta_stats(void * arg) {
+
+ struct timespec start, now;
+ struct ta_stats copy;
+
+ /* Get the start time */
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &start), );
+
+ /* Now, loop until canceled */
+ while (1) {
+ /* Display statistics every XX seconds */
+ sleep(ta_conf->bench_duration + 3);
+
+ /* Now, get the current stats */
+ CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
+ memcpy(©, &ta_conf->stats, sizeof(struct ta_stats));
+ CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
+
+ /* Get the current execution time */
+ CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), );
+
+ /* Now, display everything */
+ fd_log_debug( "------- app_test statistics ---------");
+ if (now.tv_nsec >= start.tv_nsec) {
+ fd_log_debug( " Executing for: %d.%06ld sec",
+ (int)(now.tv_sec - start.tv_sec),
+ (long)(now.tv_nsec - start.tv_nsec) / 1000);
+ } else {
+ fd_log_debug( " Executing for: %d.%06ld sec",
+ (int)(now.tv_sec - 1 - start.tv_sec),
+ (long)(now.tv_nsec + 1000000000 - start.tv_nsec) / 1000);
+ }
+
+ if (ta_conf->mode & MODE_SERV) {
+ fd_log_debug( " Server: %llu message(s) echoed", copy.nb_echoed);
+ }
+ if (ta_conf->mode & MODE_CLI) {
+ fd_log_debug( " Client:");
+ fd_log_debug( " %llu message(s) sent", copy.nb_sent);
+ fd_log_debug( " %llu error(s) received", copy.nb_errs);
+ fd_log_debug( " %llu answer(s) received", copy.nb_recv);
+ fd_log_debug( " fastest: %ld.%06ld sec.", copy.shortest / 1000000, copy.shortest % 1000000);
+ fd_log_debug( " slowest: %ld.%06ld sec.", copy.longest / 1000000, copy.longest % 1000000);
+ fd_log_debug( " Average: %ld.%06ld sec.", copy.avg / 1000000, copy.avg % 1000000);
+ }
+ fd_log_debug( "-------------------------------------");
+ }
+
+ return NULL; /* never called */
+}
+
+static struct fd_hook_hdl * hookhdl[2] = { NULL, NULL };
+static void ta_hook_cb_silent(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata) {
+}
+static void ta_hook_cb_oneline(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata) {
+ char * buf = NULL;
+ size_t len;
+
+ CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 0),
+ { LOG_E("Error while dumping a message"); return; } );
+
+ LOG_N("{%d} %s: %s", type, (char *)other ?:"<nil>", buf ?:"<nil>");
+
+ free(buf);
+}
+
+
+/* entry point */
+static int ta_entry(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* Initialize configuration */
+ CHECK_FCT( ta_conf_init() );
+
+ /* Parse configuration file */
+ if (conffile != NULL) {
+ CHECK_FCT( ta_conf_handle(conffile) );
+ }
+
+ TRACE_DEBUG(INFO, "Extension Test_App initialized with configuration: '%s'", conffile);
+ ta_conf_dump();
+
+ /* Install objects definitions for this test application */
+ CHECK_FCT( ta_dict_init() );
+
+ /* Install the handlers for incoming messages */
+ if (ta_conf->mode & MODE_SERV) {
+ CHECK_FCT( ta_serv_init() );
+ }
+
+ /* Start the signal handler thread */
+ if (ta_conf->mode & MODE_CLI) {
+ if (ta_conf->mode & MODE_BENCH) {
+ CHECK_FCT( ta_bench_init() );
+ } else {
+ CHECK_FCT( ta_cli_init() );
+ }
+ }
+
+ /* Advertise the support for the test application in the peer */
+ CHECK_FCT( fd_disp_app_support ( ta_appli, ta_vendor, 1, 0 ) );
+
+ if (ta_conf->mode & MODE_BENCH) {
+ /* Register an empty hook to disable the default handling */
+ CHECK_FCT( fd_hook_register( HOOK_MASK( HOOK_DATA_RECEIVED, HOOK_MESSAGE_RECEIVED, HOOK_MESSAGE_LOCAL, HOOK_MESSAGE_SENT, HOOK_MESSAGE_ROUTING_FORWARD, HOOK_MESSAGE_ROUTING_LOCAL ),
+ ta_hook_cb_silent, NULL, NULL, &hookhdl[0]) );
+ CHECK_FCT( fd_hook_register( HOOK_MASK( HOOK_MESSAGE_ROUTING_ERROR, HOOK_MESSAGE_DROPPED ),
+ ta_hook_cb_oneline, NULL, NULL, &hookhdl[1]) );
+
+ }
+
+ /* Start the statistics thread */
+ CHECK_POSIX( pthread_create(&ta_stats_th, NULL, ta_stats, NULL) );
+
+ return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+ if (ta_conf->mode & MODE_CLI)
+ ta_cli_fini();
+ if (ta_conf->mode & MODE_SERV)
+ ta_serv_fini();
+ if (hookhdl[0])
+ fd_hook_unregister( hookhdl[0] );
+ if (hookhdl[1])
+ fd_hook_unregister( hookhdl[1] );
+ CHECK_FCT_DO( fd_thr_term(&ta_stats_th), );
+ CHECK_POSIX_DO( pthread_mutex_destroy(&ta_conf->stats_lock), );
+}
+
+EXTENSION_ENTRY("test_app", ta_entry);
diff --git a/extensions/test_app/test_app.h b/extensions/test_app/test_app.h
new file mode 100644
index 0000000..8d01a45
--- /dev/null
+++ b/extensions/test_app/test_app.h
@@ -0,0 +1,117 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Header file for the app_test extension.
+ *
+ * This extension provides a way to send configurable messages on the network
+ *
+ * See the app_test.conf.sample file for the format of the configuration file.
+ */
+
+#include <freeDiameter/extension.h>
+#include <signal.h>
+
+#ifndef TEST_APP_DEFAULT_SIGNAL
+#define TEST_APP_DEFAULT_SIGNAL SIGUSR1
+#endif /* TEST_APP_DEFAULT_SIGNAL */
+
+
+/* Mode for the extension */
+#define MODE_SERV 0x1
+#define MODE_CLI 0x2
+#define MODE_BENCH 0x4
+
+/* The module configuration */
+struct ta_conf {
+ uint32_t vendor_id; /* default 999999 */
+ uint32_t appli_id; /* default 123456 */
+ uint32_t cmd_id; /* default 234567 */
+ uint32_t avp_id; /* default 345678 */
+ uint32_t long_avp_id; /* default 0 */
+ size_t long_avp_len; /* default 5000 */
+ int mode; /* default MODE_SERV | MODE_CLI */
+ char * dest_realm; /* default local realm */
+ char * dest_host; /* default NULL */
+ char * user_name; /* default NULL */
+ int signal; /* default TEST_APP_DEFAULT_SIGNAL */
+ int bench_concur; /* default 100 */
+ int bench_duration; /* default 10 */
+ struct ta_stats {
+ unsigned long long nb_echoed; /* server */
+ unsigned long long nb_sent; /* client */
+ unsigned long long nb_recv; /* client */
+ unsigned long long nb_errs; /* client */
+ unsigned long shortest; /* fastest answer, in microseconds */
+ unsigned long longest; /* slowest answer, in microseconds */
+ unsigned long avg; /* average answer time, in microseconds */
+ } stats;
+ pthread_mutex_t stats_lock;
+};
+extern struct ta_conf * ta_conf;
+
+/* Parse the configuration file */
+int ta_conf_handle(char * conffile);
+
+/* Handle incoming messages (server) */
+int ta_serv_init(void);
+void ta_serv_fini(void);
+
+/* Create outgoing message (client) */
+int ta_cli_init(void);
+void ta_cli_fini(void);
+
+/* Benchmark flavour */
+int ta_bench_init(void);
+void ta_bench_fini(void);
+
+/* Initialize dictionary definitions */
+int ta_dict_init(void);
+
+
+/* Some global variables for dictionary */
+extern struct dict_object * ta_vendor;
+extern struct dict_object * ta_appli;
+extern struct dict_object * ta_cmd_r;
+extern struct dict_object * ta_cmd_a;
+extern struct dict_object * ta_avp;
+extern struct dict_object * ta_avp_long;
+
+extern struct dict_object * ta_sess_id;
+extern struct dict_object * ta_origin_host;
+extern struct dict_object * ta_origin_realm;
+extern struct dict_object * ta_dest_host;
+extern struct dict_object * ta_dest_realm;
+extern struct dict_object * ta_user_name;
+extern struct dict_object * ta_res_code;
diff --git a/extensions/test_netemul/CMakeLists.txt b/extensions/test_netemul/CMakeLists.txt
new file mode 100644
index 0000000..507e96a
--- /dev/null
+++ b/extensions/test_netemul/CMakeLists.txt
@@ -0,0 +1,43 @@
+# The test_netemul extension
+PROJECT("Simple Diameter network emulator proxy extension (latency, PDV, duplicates)" C)
+
+# Parser files
+BISON_FILE(test_netemul.y)
+FLEX_FILE(test_netemul.l)
+SET_SOURCE_FILES_PROPERTIES(lex.test_netemul.c test_netemul.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( TNEMUL_SRC
+ test_netemul.c
+ test_netemul.h
+ lex.test_netemul.c
+ test_netemul.tab.c
+ test_netemul.tab.h
+ tne_process.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(test_netemul ${TNEMUL_SRC})
+
+
+# math functions
+CHECK_FUNCTION_EXISTS (sqrt HAVE_SQRT)
+IF (HAVE_SQRT)
+ SET(MATH_LIBS "")
+ELSE (HAVE_SQRT)
+ CHECK_LIBRARY_EXISTS (m sqrt "" HAVE_LIBM)
+ IF (HAVE_LIBM)
+ SET(MATH_LIBS "-lm")
+ ENDIF (HAVE_LIBM)
+ENDIF (HAVE_SQRT)
+
+TARGET_LINK_LIBRARIES(test_netemul ${MATH_LIBS})
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS test_netemul
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
diff --git a/extensions/test_netemul/test_netemul.c b/extensions/test_netemul/test_netemul.c
new file mode 100644
index 0000000..66fe610
--- /dev/null
+++ b/extensions/test_netemul/test_netemul.c
@@ -0,0 +1,106 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * This extension provides a simple Diameter network emulator mechanism.
+ * It allows the introduction of delays and duplicates of Diameter messages.
+ * See test_netemul.conf.sample file for the format of the configuration file.
+ */
+
+#include "test_netemul.h"
+
+/* The configuration structure */
+struct tne_conf tne_conf;
+
+
+
+/* Proxying callback */
+static int tne_fwd_cb(void * cbdata, struct msg ** msg)
+{
+ struct msg * m;
+
+ TRACE_ENTRY("%p %p", cbdata, msg);
+
+ m = *msg;
+ *msg = NULL;
+
+ TRACE_DEBUG(FULL, "[tne] Processing message %p", m);
+ CHECK_FCT( tne_process_message(m) );
+
+ return 0;
+}
+
+
+static struct fd_rt_fwd_hdl * fwd_hdl = NULL;
+
+/* Register the callbacks to the daemon */
+static int tne_main(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ /* Initialize the configuration */
+ memset(&tne_conf, 0, sizeof(tne_conf));
+ tne_conf.lat_avg = 500;
+ tne_conf.lat_dev = 20;
+ tne_conf.dupl_proba = 1E-2;
+
+ /* Parse the configuration file */
+ CHECK_FCT( tne_conf_handle(conffile) );
+
+ /* Initialize the process module */
+ CHECK_FCT( tne_process_init() );
+
+ /* Now, register the proxying callback */
+ CHECK_FCT( fd_rt_fwd_register ( tne_fwd_cb, NULL, RT_FWD_REQ, &fwd_hdl ) );
+
+ return 0;
+}
+
+/* Cleanup the callbacks */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+
+ /* Unregister the module */
+ CHECK_FCT_DO( fd_rt_fwd_unregister ( fwd_hdl, NULL ), /* continue */ );
+
+ /* Destroy the process thread */
+ CHECK_FCT_DO( tne_process_fini ( ), /* continue */ );
+
+ return ;
+}
+
+/* Define the entry point function */
+EXTENSION_ENTRY("test_netemul", tne_main);
diff --git a/extensions/test_netemul/test_netemul.h b/extensions/test_netemul/test_netemul.h
new file mode 100644
index 0000000..0d9d40b
--- /dev/null
+++ b/extensions/test_netemul/test_netemul.h
@@ -0,0 +1,56 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2011, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * See the test_netemul.conf.sample file for the format of the configuration file.
+ */
+
+/* FreeDiameter's common include file */
+#include <freeDiameter/extension.h>
+
+/* Parse the configuration file */
+int tne_conf_handle(char * conffile);
+
+/* The configuration structure */
+extern struct tne_conf {
+ unsigned long lat_avg; /* in milliseconds */
+ unsigned int lat_dev; /* between 0 and 100 */
+ float dupl_proba;
+} tne_conf;
+
+/* Apply the configured process to the message, then send it. */
+int tne_process_message(struct msg * msg);
+int tne_process_init();
+int tne_process_fini();
diff --git a/extensions/test_netemul/test_netemul.l b/extensions/test_netemul/test_netemul.l
new file mode 100644
index 0000000..430e785
--- /dev/null
+++ b/extensions/test_netemul/test_netemul.l
@@ -0,0 +1,119 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Tokenizer */
+
+%{
+#include "test_netemul.h"
+/* Include yacc tokens definitions */
+#include "test_netemul.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+
+ /* Recognize floats */
+[[:digit:]]+"."[[:digit:]]* {
+ /* Convert this to an integer value */
+ int ret=0;
+ ret = sscanf(yytext, "%f", &yylval->decimal);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid float: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return FLOAT;
+ }
+
+ /* Recognize simple integers */
+[[:digit:]]+ {
+ /* Convert this to an integer value */
+ int ret=0;
+ ret = sscanf(yytext, "%lu", &yylval->ulong);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid long: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return ULONG;
+ }
+
+
+
+ /* The key words */
+(?i:"latency_average") { return LATENCY_AVERAGE; }
+(?i:"latency_deviation") { return LATENCY_DEVIATION; }
+(?i:"dupl_proba") { return DUPL_PROBA; }
+(?i:"ms") { return UNIT_MSEC; }
+(?i:"s") { return UNIT_SEC; }
+
+ /* Valid single characters for yyparse */
+[=;%/] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:][:digit:]=;%/\n]+ {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/test_netemul/test_netemul.y b/extensions/test_netemul/test_netemul.y
new file mode 100644
index 0000000..222cf2e
--- /dev/null
+++ b/extensions/test_netemul/test_netemul.y
@@ -0,0 +1,171 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ */
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "test_netemul.h"
+#include "test_netemul.tab.h" /* YYLTYPE */
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+/* Parse the configuration file */
+int tne_conf_handle(char * conffile)
+{
+ extern FILE * test_netemulin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ test_netemulin = fopen(conffile, "r");
+ if (test_netemulin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(test_netemulin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ } else {
+ TRACE_DEBUG(FULL, "[test_netemul] latency: %lu ms (var:%u%%) duplicates: %G probability.", tne_conf.lat_avg, tne_conf.lat_dev, tne_conf.dupl_proba);
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int test_netemullex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ unsigned long ulong;
+ float decimal;
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+%token <ulong> ULONG
+%token <decimal> FLOAT
+
+/* Tokens */
+%token LATENCY_AVERAGE
+%token LATENCY_DEVIATION
+%token DUPL_PROBA
+%token UNIT_SEC
+%token UNIT_MSEC
+
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty */
+ | conffile latency_average
+ | conffile latency_deviation
+ | conffile dupl_proba
+ ;
+
+ /* a server entry */
+latency_average: LATENCY_AVERAGE '=' ULONG UNIT_SEC ';'
+ {
+ tne_conf.lat_avg = $3 * 1000;
+ }
+ |
+ LATENCY_AVERAGE '=' ULONG UNIT_MSEC ';'
+ {
+ tne_conf.lat_avg = $3;
+ }
+ ;
+
+latency_deviation: LATENCY_DEVIATION '=' ULONG '%' ';'
+ {
+ tne_conf.lat_dev = (int)$3;
+ if ((tne_conf.lat_dev < 0) || (tne_conf.lat_dev > 100)) {
+ yyerror (&yylloc, conffile, "Latency_Deviation must be comprised between 0 and 100.");
+ YYERROR;
+ }
+ }
+ ;
+
+dupl_proba: DUPL_PROBA '=' ULONG ';'
+ {
+ tne_conf.dupl_proba = (float) $3;
+ }
+ | DUPL_PROBA '=' FLOAT ';'
+ {
+ tne_conf.dupl_proba = $3;
+ }
+ | DUPL_PROBA '=' ULONG '/' ULONG ';'
+ {
+ tne_conf.dupl_proba = ((float)$3) / ((float)$5) ;
+ }
+ ;
diff --git a/extensions/test_netemul/tne_process.c b/extensions/test_netemul/tne_process.c
new file mode 100644
index 0000000..1bff64c
--- /dev/null
+++ b/extensions/test_netemul/tne_process.c
@@ -0,0 +1,333 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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 "test_netemul.h"
+#include <math.h>
+
+/* This file implements the real processing of the message.
+ The entry point is tne_process_message().
+
+ First, the duplicate filter is applied: with the configured
+ probability, a copy of the message is created. Then, with
+ the tenth probability, a second copy is created, and so on,
+ until the random value tells not to create a copy.
+
+ The original message + all copies are stored in a list, for next step.
+
+ Second step is the latency filter. For each message in the list, a
+ latency value is randomly generated (with a lognormal shape of the
+ random distribution) and stored in the list.
+
+ Finally, when the latency time is over, the message is sent.
+ */
+
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cnd = PTHREAD_COND_INITIALIZER;
+static pthread_t thr = (pthread_t)NULL;
+
+/* The lists below are all protected by the same mutex mtx */
+static struct fd_list input = FD_LIST_INITIALIZER(input); /* messages received from network */
+static struct fd_list forlat = FD_LIST_INITIALIZER(forlat); /* messages after duplicate filter */
+static struct fd_list waitlist = FD_LIST_INITIALIZER(waitlist); /* messages waiting for sending */
+
+struct process_item {
+ struct fd_list chain; /* link into one of the lists. "o" points to the message. */
+ struct timespec ts; /* when the message must be sent */
+};
+
+/******************************************************************/
+/* helper functions */
+
+/* Process all pi in input list and queue in forlat, duplicating when needed */
+static int do_duplicates()
+{
+ TRACE_ENTRY("");
+
+ while (!FD_IS_LIST_EMPTY(&input)) {
+ struct msg * m;
+ struct process_item * pi = (struct process_item *)(input.next);
+
+ /* Take out this pi from input */
+ fd_list_unlink(&pi->chain);
+
+ /* store it in forlat */
+ fd_list_insert_before(&forlat, &pi->chain);
+
+ /* Duplicate eventually, unless deactivated */
+ if (tne_conf.dupl_proba != 0.0) {
+ DiamId_t src;
+ size_t srclen;
+ /* Pick a random value in [0, 1] */
+ double my_rand = drand48();
+ m = pi->chain.o;
+ CHECK_FCT( fd_msg_source_get(m, &src, &srclen) );
+
+ while (my_rand < (double) tne_conf.dupl_proba) {
+ /* create the duplicate */
+ struct process_item * npi;
+ struct msg * nm;
+ struct msg_hdr * nh;
+ unsigned char * buf;
+ size_t len;
+
+ /* Duplicate the message */
+ CHECK_FCT( fd_msg_bufferize(m, &buf, &len) );
+ CHECK_FCT( fd_msg_parse_buffer(&buf, len, &nm) );
+ CHECK_FCT( fd_msg_source_set(nm, src, srclen) );
+ CHECK_FCT( fd_msg_hdr(nm, &nh) );
+ nh->msg_flags |= CMD_FLAG_RETRANSMIT; /* Add the 'T' flag */
+ TRACE_DEBUG(FULL, "[tne] Duplicated message %p as %p", m, nm);
+
+ /* Duplicate the pi */
+ CHECK_MALLOC( npi = malloc(sizeof(struct process_item)) );
+ memset(npi, 0, sizeof(struct process_item));
+ fd_list_init(&npi->chain, nm);
+ memcpy(&npi->ts, &pi->ts, sizeof(struct timespec));
+
+ /* Enqueue the candidate in forlat */
+ fd_list_insert_before(&forlat, &npi->chain);
+
+ /* loop for another duplicate */
+ if (!my_rand)
+ break; /* otherwise, infinite loop */
+ my_rand *= 10.0;
+ }
+ }
+ }
+
+ /* Done */
+ return 0;
+}
+
+/* Generate a random value with a normal distribution, mean 0, variance 1 */
+/* Using Box-Muller algo from Numerical Recipes in C++, 2nd Ed. */
+static double get_rand_norm()
+{
+ double ru1, ru2; /* two random uniform values in -1..1 */
+ double rsq; /* ru1^2 + ru2^2, to ensure we are in the circle */
+
+ /* Get our appropriate 2 random uniform values */
+ do {
+ ru1 = 2.0 * drand48() - 1.0;
+ ru2 = 2.0 * drand48() - 1.0;
+ rsq = ru1 * ru1 + ru2 * ru2;
+ } while ((rsq >= 1.0) || (rsq == 0.0));
+
+ /* Do the Box-Muller transform -- we don't use the 2nd value generated */
+ return ru1 * sqrt( -2.0 * log(rsq) / rsq );
+}
+
+/* Return the latency to add, in ms. */
+static __inline__ unsigned long get_latency()
+{
+ unsigned long lat = tne_conf.lat_avg;
+
+ if (tne_conf.lat_dev) {
+ /* We randomize the value to add */
+ double rn;
+
+ rn = get_rand_norm(); /* this is normal random value with mean = 0 and variance = 1 */
+ rn = rn * ((double)tne_conf.lat_dev) / 100.0; /* now the variance is lat_dev */
+ rn = exp(rn); /* and now, we have a lognormal random value, with geometric mean = 1 */
+
+ lat = (unsigned long)(rn * (double)lat); /* Apply to our mean latency */
+ }
+
+ return lat;
+}
+
+/* Process all pi in forlat and add a random latency, then requeue in order into waitlist */
+static int do_latency()
+{
+ TRACE_ENTRY("");
+
+ while (!FD_IS_LIST_EMPTY(&forlat)) {
+ struct process_item * pi = (struct process_item *)(forlat.next);
+ struct fd_list * li;
+
+ /* Take out this pi from forlat */
+ fd_list_unlink(&pi->chain);
+
+ /* If there is a latency to add */
+ if (tne_conf.lat_avg) {
+ unsigned long l = get_latency();
+ TRACE_DEBUG(FULL, "[tne] Set %lu ms latency for %p", l, pi->chain.o);
+ pi->ts.tv_sec += l / 1000;
+ l %= 1000;
+ pi->ts.tv_nsec += l * 1000000;
+ if (pi->ts.tv_nsec >= 1000000000) {
+ pi->ts.tv_sec += 1;
+ pi->ts.tv_nsec -= 1000000000;
+ }
+ }
+
+ for (li = waitlist.prev; li != &waitlist; li=li->prev) {
+ struct process_item * p = (struct process_item *)li;
+ if (TS_IS_INFERIOR( &p->ts, &pi->ts ))
+ break; /* we must insert after this one */
+ }
+
+ /* store it */
+ fd_list_insert_after(li, &pi->chain);
+ }
+
+ /* Done */
+ return 0;
+}
+
+/* Send all messages in waitlist that have passed their latency period */
+static int send_all_ready()
+{
+ struct timespec now;
+
+ TRACE_ENTRY("");
+
+ CHECK_SYS( clock_gettime(CLOCK_REALTIME, &now) );
+
+ while (!FD_IS_LIST_EMPTY(&waitlist)) {
+ struct msg * m;
+ struct process_item * pi = (struct process_item *)(waitlist.next);
+
+ if (!TS_IS_INFERIOR( &pi->ts, &now))
+ break; /* We sent already all we could */
+
+ /* Take out this pi and send the message */
+ fd_list_unlink(&pi->chain);
+ m = pi->chain.o;
+ free(pi);
+
+ TRACE_DEBUG(FULL, "[tne] Sending now %p", m);
+ CHECK_FCT( fd_msg_send(&m, NULL, NULL) );
+ }
+
+ return 0;
+
+}
+
+
+/******************************************************************/
+/* the processing thread */
+static void * tne_process_th(void * arg)
+{
+ TRACE_ENTRY("%p", arg);
+
+ /* Name the thread */
+ fd_log_threadname ( "test_netemul/process" );
+
+ CHECK_POSIX_DO( pthread_mutex_lock(&mtx), goto error );
+ pthread_cleanup_push( fd_cleanup_mutex, &mtx );
+
+ /* The loop */
+ while (1) {
+ /* First, test if we are canceled */
+ pthread_testcancel();
+
+ /* Send all messages that are ready (free resources before using new ones) */
+ CHECK_FCT_DO( send_all_ready(), break );
+
+ /* Now process the new messages in input list for duplicate filter */
+ CHECK_FCT_DO( do_duplicates(), break );
+
+ /* Now compute the latency for each new item */
+ CHECK_FCT_DO( do_latency(), break );
+
+ /* Now, wait then loop */
+ if (FD_IS_LIST_EMPTY(&waitlist)) {
+ CHECK_POSIX_DO( pthread_cond_wait(&cnd, &mtx), break );
+ } else {
+ CHECK_POSIX_DO2( pthread_cond_timedwait(&cnd, &mtx, &((struct process_item *)(waitlist.next))->ts),
+ ETIMEDOUT, /* ETIMEDOUT is a normal return value, continue */,
+ /* on other error, */ break );
+ }
+
+ /* loop */
+ }
+
+ pthread_cleanup_pop( 0 );
+ CHECK_POSIX_DO( pthread_mutex_unlock(&mtx), );
+error:
+ TRACE_DEBUG(INFO, "A fatal error occurred in test_netemul/process thread!");
+ ASSERT(0);
+ CHECK_FCT_DO(fd_core_shutdown(), );
+ return NULL;
+}
+
+/******************************************************************/
+/* functions visible from outside this file */
+int tne_process_init()
+{
+ CHECK_POSIX( pthread_create(&thr, NULL, tne_process_th, NULL) );
+
+ #if 0 /* debug */
+ int i;
+ for (i=0; i< 20; i++) {
+ printf("LAT: %lu\n", get_latency());
+ }
+ #endif /* 0 */
+
+ return 0;
+}
+
+
+int tne_process_fini()
+{
+ CHECK_FCT( fd_thr_term(&thr) );
+ return 0;
+}
+
+
+int tne_process_message(struct msg * msg)
+{
+ struct process_item * pi;
+
+ TRACE_ENTRY("%p", msg);
+
+ /* Create a new pi for this message */
+ CHECK_MALLOC( pi = malloc(sizeof(struct process_item)) );
+ memset(pi, 0, sizeof(struct process_item));
+ fd_list_init(&pi->chain, msg);
+ CHECK_SYS(clock_gettime(CLOCK_REALTIME, &pi->ts));
+
+ /* Store it in the input list */
+ CHECK_POSIX( pthread_mutex_lock(&mtx) );
+ fd_list_insert_before(&input, &pi->chain);
+ CHECK_POSIX( pthread_mutex_unlock(&mtx) );
+
+ /* Wake up the process thread so that it processes the message */
+ CHECK_POSIX( pthread_cond_signal(&cnd) );
+
+ /* done */
+ return 0;
+}
diff --git a/extensions/test_rt_any/CMakeLists.txt b/extensions/test_rt_any/CMakeLists.txt
new file mode 100644
index 0000000..f6b494c
--- /dev/null
+++ b/extensions/test_rt_any/CMakeLists.txt
@@ -0,0 +1,13 @@
+# The test_rt_any extension
+PROJECT("Random routing extension (for tests)" C)
+
+# Compile as a module
+FD_ADD_EXTENSION(test_rt_any test_rt_any.c)
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS test_rt_any
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
diff --git a/extensions/test_rt_any/test_rt_any.c b/extensions/test_rt_any/test_rt_any.c
new file mode 100644
index 0000000..fd2c3c8
--- /dev/null
+++ b/extensions/test_rt_any/test_rt_any.c
@@ -0,0 +1,77 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Sebastien Decugis <sdecugis@freediameter.net> *
+* *
+* Copyright (c) 2013, WIDE Project and NICT *
+* All rights reserved. *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the WIDE Project or NICT nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of WIDE Project and *
+* NICT. *
+* *
+* 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. *
+*********************************************************************************************************/
+
+/*
+ * Test-only extension for routing: gives a random positive score to any candidate peer.
+ */
+#include <freeDiameter/extension.h>
+#include <stdlib.h>
+
+/* The callback */
+static int tra_out_cb(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
+{
+ struct msg * msg = *pmsg;
+ struct fd_list * li;
+
+ TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
+
+ for (li = candidates->next; li != candidates; li = li->next) {
+ struct rtd_candidate *c = (struct rtd_candidate *) li;
+ c->score = (int)lrand48();
+ }
+
+ return 0;
+}
+
+static struct fd_rt_out_hdl * out_hdl = NULL;
+
+/* Register the callbacks to the daemon */
+static int tra_main(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+ CHECK_FCT( fd_rt_out_register ( tra_out_cb, NULL, 0 /* we call it late so that it replaces previous scores */, &out_hdl ) );
+ return 0;
+}
+
+/* Cleanup the callbacks */
+void fd_ext_fini(void)
+{
+ TRACE_ENTRY();
+ CHECK_FCT_DO( fd_rt_out_unregister ( out_hdl, NULL ), /* continue */ );
+ return ;
+}
+
+/* Define the entry point function */
+EXTENSION_ENTRY("test_rt_any", tra_main);
diff --git a/extensions/test_sip/CMakeLists.txt b/extensions/test_sip/CMakeLists.txt
new file mode 100644
index 0000000..2b2c9e9
--- /dev/null
+++ b/extensions/test_sip/CMakeLists.txt
@@ -0,0 +1,30 @@
+# The test_sip extension
+PROJECT("Diameter-SIP client Test Application (RFC4740)" C)
+
+FIND_PACKAGE(MySQL REQUIRED)
+INCLUDE_DIRECTORIES(${MySQL_INCLUDE_DIR})
+
+# List of source files
+SET( TEST_SIP_SRC
+ test_sip.c
+ test_sip.h
+ multimediaauth.c
+ locationinfo.c
+ locationinfosl.c
+ registrationtermination.c
+ userauthorization.c
+ serverassignment.c
+)
+
+# Compile as a module
+FD_ADD_EXTENSION(test_sip ${TEST_SIP_SRC})
+
+TARGET_LINK_LIBRARIES(test_sip ${MySQL_LIBRARIES})
+
+
+####
+## INSTALL section ##
+
+INSTALL(TARGETS test_sip
+ LIBRARY DESTINATION ${INSTALL_EXTENSIONS_SUFFIX}
+ COMPONENT freeDiameter-debug-tools)
diff --git a/extensions/test_sip/locationinfo.c b/extensions/test_sip/locationinfo.c
new file mode 100644
index 0000000..98e89f9
--- /dev/null
+++ b/extensions/test_sip/locationinfo.c
@@ -0,0 +1,122 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "test_sip.h"
+
+//Called to send a LIR
+int test_sip_LIR_cb()
+{
+ struct dict_object * lir_model=NULL;
+ struct msg * message=NULL;
+ struct avp *avp=NULL;
+ union avp_value value;
+
+ //Fake values START
+ char *sip_aor="sip:aw-lappy@tera.ics.keio.ac.jp";
+ size_t aor_len=strlen(sip_aor);
+ char *destination_realm="tera.ics.keio.ac.jp";
+ size_t destination_realmlen=strlen(destination_realm);
+ char *destination_host="suika.tera.ics.keio.ac.jp";
+ size_t destination_hostlen=strlen(destination_host);
+ //Fake values STOP
+
+ //Create the base message for an RTR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &lir_model, ENOENT) );
+ CHECK_FCT( fd_msg_new (lir_model, 0, &message));
+
+
+
+ // Create a new session
+ {
+ CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
+ }
+
+ //Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = 6;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ //Auth_Session_State
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ value.i32=1;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //Origin_Host & Origin_Realm
+ CHECK_FCT( fd_msg_add_origin ( message, 0 ));
+
+ //Destination_Host
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
+ value.os.data=(unsigned char *)destination_host;
+ value.os.len=destination_hostlen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ //Destination_Realm
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Realm, 0, &avp ) );
+ value.os.data=(unsigned char *)destination_realm;
+ value.os.len=destination_realmlen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //SIP_AOR
+ {
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)sip_aor;
+ value.os.len=aor_len;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+
+ }
+
+ CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
+
+ return 0;
+}
+
+int test_sip_LIA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+
+ return 0;
+}
diff --git a/extensions/test_sip/locationinfosl.c b/extensions/test_sip/locationinfosl.c
new file mode 100644
index 0000000..53c8494
--- /dev/null
+++ b/extensions/test_sip/locationinfosl.c
@@ -0,0 +1,124 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "test_sip.h"
+
+//Called to send a LIR
+int test_sipSL_LIR_cb()
+{
+ struct dict_object * lir_model=NULL;
+ struct msg * message=NULL;
+ struct avp *avp=NULL;
+ union avp_value value;
+
+ //Fake values START
+ char *sip_aor="sip:aw-lappy@tera.ics.keio.ac.jp";
+ size_t aor_len=strlen(sip_aor);
+ char *destination_realm="tera.ics.keio.ac.jp";
+ size_t destination_realmlen=strlen(destination_realm);
+ char *destination_host="biwa.tera.ics.keio.ac.jp";
+ size_t destination_hostlen=strlen(destination_host);
+ //Fake values STOP
+
+ //Create the base message for an RTR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &lir_model, ENOENT) );
+ CHECK_FCT( fd_msg_new (lir_model, 0, &message));
+
+
+
+ // Create a new session
+ {
+ CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
+ }
+
+ //Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = 6;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ //Auth_Session_State
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ value.i32=1;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //Origin_Host & Origin_Realm
+ CHECK_FCT( fd_msg_add_origin ( message, 0 ));
+
+ //Destination_Host
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
+ value.os.data=(unsigned char *)destination_host;
+ value.os.len=destination_hostlen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ //Destination_Realm
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Realm, 0, &avp ) );
+ value.os.data=(unsigned char *)destination_realm;
+ value.os.len=destination_realmlen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+
+
+ //SIP_AOR
+ {
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)sip_aor;
+ value.os.len=aor_len;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+
+ }
+
+ CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
+
+ return 0;
+}
+
+int test_sipSL_LIA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+
+ return 0;
+}
diff --git a/extensions/test_sip/multimediaauth.c b/extensions/test_sip/multimediaauth.c
new file mode 100644
index 0000000..b1edb8d
--- /dev/null
+++ b/extensions/test_sip/multimediaauth.c
@@ -0,0 +1,786 @@
+/********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+********************************************************************************************************/
+#include "test_sip.h"
+
+
+int test_sip_MAA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+/*
+ struct msg *ans, *qry;
+ struct avp *avp, *a2, *authdataitem;
+ struct msg_hdr * header = NULL;
+ struct avp_hdr * avphdr=NULL, *avpheader=NULL, *avpheader_auth=NULL,*digestheader=NULL;
+ union avp_value val;
+ int found_cnonce=0;
+ struct avp * tempavp=NULL,*sipAuthentication=NULL,*sipAuthenticate=NULL;
+ char * result;
+ char password[51];
+ int idx=0, idx2=0, number_of_auth_items=0,i=0;
+ //Flags and variables for Database
+ int sipurinotstored=0, authenticationpending=0, querylen=0, usernamelen=0;
+ char *query=NULL,*username=NULL;
+
+ //The nonce we will store and retrieve in session
+ struct ds_nonce *storednonce=NULL;
+
+
+ TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+
+ if (msg == NULL)
+ return EINVAL;
+
+
+ // Create answer header
+ qry = *msg;
+ CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+ ans = *msg;
+
+
+
+ // Add the appropriate command code & Auth-Application-Id
+ {
+
+ CHECK_FCT( fd_msg_hdr ( *msg, &header ) );
+ header->msg_flags = CMD_FLAG_PROXIABLE;
+ header->msg_code = 286;
+ header->msg_appl = 6;
+
+
+ // Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ ASSERT(avp);
+ val.i32 = header->msg_appl;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &val ) );
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+ }
+ }
+
+
+ // Add the Auth-Session-State AVP
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+
+
+ // Check if method is REGISTER then User-Name must be present
+ {
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Method, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avpheader ));
+
+
+ char *method=NULL;
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.User_Name, &avp) );
+ if(avp!=NULL)
+ {
+
+ int not_found=1;
+ MYSQL_RES *res=NULL;
+ MYSQL_ROW row;
+
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ //We allocate the double size of username because at worst it can be all quotes
+ username=malloc(avphdr->avp_value->os.len*2+1);
+ //We purify username not to have forbidden characters
+ usernamelen=mysql_real_escape_string(conn, username, avphdr->avp_value->os.data, avphdr->avp_value->os.len);
+
+
+ if((strncmp(avpheader->avp_value->os.data,"REGISTER",avpheader->avp_value->os.len)==0))
+ {
+ not_found=1;
+
+ //We copy username in query
+ querylen=SQL_GETPASSWORD_LEN + usernamelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_GETPASSWORD, username);
+
+
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ goto out;
+ }
+
+
+
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(row[0]!="")
+ {
+ strcpy(password,row[0]);
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+
+ if(not_found)
+ {
+ TRACE_DEBUG(FULL,"The user %s doesn't exist!",username);
+ result="DIAMETER_ERROR_USER_UNKNOWN";
+ free(username);
+ goto out;
+ }
+
+
+
+ //Now that we know the user exist, we get the list of AOR owned by this user
+ querylen=SQL_GETSIPAOR_LEN + usernamelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_GETSIPAOR, username);
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ goto out;
+ }
+
+ //We retrieve the SIP-AOR from AVP to check if the user can us it
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ not_found=1;
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(strncmp(avphdr->avp_value->os.data,row[0],avphdr->avp_value->os.len)==0)
+ {
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+
+ if(not_found)
+ {
+ TRACE_DEBUG(FULL,"The user %s can't use this SIP-AOR!",username);
+ result="DIAMETER_ERROR_IDENTITIES_DONT_MATCH";
+ free(username);
+ goto out;
+ }
+
+ }
+
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ));
+
+ if(avphdr!=NULL)
+ {
+ char *sipuri=NULL;
+ int sipurilen=0;
+
+ //We allocate the double size of SIP-URI because at worst it can be all quotes
+ sipuri=malloc(avphdr->avp_value->os.len*2+1);
+ //We purify SIP-URI not to have forbidden characters
+ sipurilen=mysql_real_escape_string(conn, sipuri, avphdr->avp_value->os.data, avphdr->avp_value->os.len);
+
+
+ //We get the SIP-URI assignated to the user
+ querylen=SQL_GETSIPURI_LEN + usernamelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_GETSIPURI, username);
+
+ //We make the query
+ request_mysql(query);
+ res=mysql_use_result(conn);
+ if(res==NULL)
+ {
+ //We couldn't make the request
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ goto out;
+ }
+ not_found=1;
+ while ((row = mysql_fetch_row(res)) != NULL)
+ {
+ if(strncmp(avphdr->avp_value->os.data,row[0],avphdr->avp_value->os.len)==0)
+ {
+ not_found=0;
+ break;
+ }
+ }
+ mysql_free_result(res);
+ free(query);
+
+ if(not_found)
+ {
+ //We update the SIP_URI for the user and we flag "authentication in progress"
+ querylen=SQL_SETSIPURI_LEN + usernamelen + sipurilen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_SETSIPURI, sipuri, username);
+
+ //We make the query
+ request_mysql(query);
+
+ free(query);
+ authenticationpending=1;
+ }
+ free(sipuri);
+
+ }
+ else
+ sipurinotstored=1;
+
+ }
+ else
+ {
+ result="DIAMETER_USER_NAME_REQUIRED";
+ goto out;
+ }
+
+
+ free(method);
+
+ }
+
+
+ //TODO: remove loop for authdataitem because RFC say only one (wait for answer from Garcia)
+ // How many Auth Data Items?
+ CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Number_Auth_Items, &avp) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avpheader ) );
+
+
+ if(avp!=NULL)
+ {
+ CHECK_FCT(fd_msg_search_avp ( qry, sip_dict.SIP_Auth_Data_Item, &avp));
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ if(avp!=NULL)
+ {
+ //First is Authentication Scheme
+ CHECK_FCT(fd_msg_browse ( avp, MSG_BRW_FIRST_CHILD, &avp, NULL) );
+ CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
+
+ //Digest-Authentication?
+ if(avphdr->avp_value->i32==0)
+ {
+
+ for(idx=0;idx<avpheader->avp_value->i32;idx++)
+ {
+ //We look for SIP Auth items
+ CHECK_FCT(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL) );
+
+ if(avp!=NULL)
+ {
+
+ CHECK_FCT( fd_msg_avp_hdr( avp,&avphdr ));
+
+ if(avphdr->avp_code==380) //We only create Auth-Data-Item to answer Auth-Data-Item
+ {
+ // Add the Auth-Data-Item AVP
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Auth_Data_Item, 0, &authdataitem ) );
+
+ // Add the Authentication Scheme AVP
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Authentication_Scheme, 0, &a2 ) );
+ val.i32=0; //We only know Digest Authentication
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( authdataitem, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+
+ //We need to know if there is a Cnonce attribute (only in the second MAR request)
+
+ //CHECK_FCT(fd_msg_browse ( avp, MSG_BRW_WALK, &avp, NULL) );
+
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_CNonce, &a2 ));
+
+ if(a2!=NULL)
+ found_cnonce=1;
+ else
+ found_cnonce=0;
+
+ if(!found_cnonce)
+ {
+ //
+ We are in the case of first access request so we need to challenge the user.
+
+ TRACE_DEBUG(FULL,"First Authorization in progress...");
+
+ // Create a new session //this create a new session Id !!!
+ //CHECK_FCT_DO( fd_sess_new( &sess, fd_g_config->cnf_diamid, "test_sip", 7), goto out );
+
+
+ // Create the SIP-Authenticate AVP
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Authenticate, 0, &sipAuthenticate ) );
+ }
+
+ // Add the Digest QOP AVP
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_QOP, 0, &a2 ) );
+ val.os.data="auth";
+ val.os.len=strlen(val.os.data);
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthenticate, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+ // Add the Digest Nonce AVP
+ {
+ uint8_t buffer[NONCE_SIZE];
+ char nonce[NONCE_SIZE * 2 + 1];
+
+
+ gcry_create_nonce ((uint8_t *)buffer, sizeof(buffer));
+
+ for(i=0;i<NONCE_SIZE;i++)
+ sprintf(&nonce[2 * i], "%2.2hhx", buffer[i]);
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_Nonce, 0, &a2 ) );
+
+
+ //We store the nonce (storednonce structure) inside the session
+ storednonce=malloc(sizeof(struct ds_nonce));
+ memset(storednonce,0,sizeof(struct ds_nonce));
+ CHECK_MALLOC(storednonce->nonce=malloc(NONCE_SIZE*2+1));
+ memcpy(storednonce->nonce,(char *)nonce,NONCE_SIZE*2+1);
+ CHECK_FCT( fd_sess_state_store ( ds_sess_hdl, sess, &storednonce ));
+
+ val.os.data=nonce;
+ val.os.len=NONCE_SIZE * 2;
+
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthenticate, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+ // Add the Digest Algorithm AVP
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_Algorithm, 0, &a2 ) );
+ val.os.data="MD5";
+ val.os.len=strlen(val.os.data);
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthenticate, MSG_BRW_LAST_CHILD, a2 ) );
+
+ }
+ // Add the Digest Realm AVP
+ {
+ tempavp=avp;
+
+ avpheader_auth=walk_digest(tempavp, 104);
+ if(avpheader_auth!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_Realm, 0, &a2 ) );
+ CHECK_FCT( fd_msg_avp_setvalue( a2, avpheader_auth->avp_value ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthenticate, MSG_BRW_LAST_CHILD, a2 ) );
+
+ }
+ }
+
+
+ //We add SIP Authenticate to Auth Data Item
+ CHECK_FCT( fd_msg_avp_add( authdataitem, MSG_BRW_LAST_CHILD, sipAuthenticate ) );
+ //We add Auth Data Item to Answer
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, authdataitem ) );
+
+ number_of_auth_items++;
+ if(sipurinotstored)
+ result="DIAMETER_SUCCESS_AUTH_SENT_SERVER_NOT_STORED";
+ else
+ result="DIAMETER_MULTI_ROUND_AUTH";
+ found_cnonce=0;
+ }
+ else
+ {
+ //
+ We are in the case of access request after challenge so we need to check credentials.
+
+ TRACE_DEBUG(FULL,"Authentication after challenge");
+
+ // Search the session, retrieve its data
+ {
+ //int new=0;
+
+ //TRACE_DEBUG(FULL,"new: *%d*",new);
+ //ASSERT( new == 0 );
+ CHECK_FCT( fd_sess_state_retrieve( ds_sess_hdl, sess, &storednonce ));
+ if(storednonce ==NULL)
+ {
+ result="DIAMETER_UNABLE_TO_COMPLY";
+
+ if(username!=NULL)
+ free(username);
+ goto out;
+ }
+ }
+
+ // Create the SIP-Authentication-Info AVP
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Authentication_Info, 0, &sipAuthentication ) );
+ }
+
+
+
+ // Add the Digest response Auth AVP
+ {
+ //uint8_t bufferresp[DIGEST_LEN];
+ //char response[DIGEST_LEN*2+1];
+ int i=0;
+
+ //We extract all the data we need
+ tempavp=avp;
+
+ char * digest_username=NULL, *digest_uri=NULL, *digest_response=NULL, *digest_realm=NULL, *digest_nonce=NULL, *digest_method=NULL, *digest_qop=NULL, *digest_algorithm=NULL, *digest_cnonce=NULL, *digest_noncecount=NULL;
+
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Nonce, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+
+ digest_nonce = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_nonce, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_nonce[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_nonce);
+ TRACE_DEBUG(FULL,"Stored Nonce:*%s*",storednonce->nonce);
+
+ if(strcmp(digest_nonce,storednonce->nonce)!=0)
+ {
+ free(digest_nonce);
+ free(storednonce->nonce);
+ free(storednonce);
+ result="DIAMETER_UNABLE_TO_COMPLY";
+
+ if(username!=NULL)
+ free(username);
+ goto out;
+ }
+
+ }
+
+ }
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Response, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_response = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_response, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_response[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_response);
+ }
+
+ }
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Realm, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_realm = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_realm, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_realm[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_realm);
+ }
+ }
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Method, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_method = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_method, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_method[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_method);
+ }
+ }
+ else
+ digest_method="";
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_URI, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_uri = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_uri, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_uri[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_uri);
+ }
+ }
+
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_QOP, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_qop = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_qop, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_qop[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_qop);
+ }
+ }
+ else
+ digest_qop=NULL;
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Algorithm, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_algorithm = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_algorithm, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_algorithm[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_algorithm);
+ }
+ }
+ else
+ digest_algorithm=NULL;
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_CNonce, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_cnonce = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_cnonce, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_cnonce[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_cnonce);
+ }
+ }
+ else
+ digest_cnonce="";
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Nonce_Count, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_noncecount = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_noncecount, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_noncecount[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_noncecount);
+ }
+ }
+ else
+ digest_noncecount="";
+ CHECK_FCT(fd_avp_search_avp (avp, sip_dict.Digest_Username, &a2 ));
+ if(a2!=NULL)
+ {
+ CHECK_FCT( fd_msg_avp_hdr( a2, &digestheader ) );
+ if(digestheader!=NULL)
+ {
+ digest_username = malloc(digestheader->avp_value->os.len + 1);
+ memcpy(digest_username, digestheader->avp_value->os.data,
+ digestheader->avp_value->os.len);
+ digest_username[digestheader->avp_value->os.len]='\0';
+ TRACE_DEBUG(FULL,"Element:*%s*",digest_username);
+ }
+ }
+ //TODO: replace by authentication function
+
+ HASHHEX HA1;
+ HASHHEX HA2 = "";
+ HASHHEX response, responseauth;
+
+
+ DigestCalcHA1(digest_algorithm, digest_username, digest_realm, password, digest_nonce,digest_cnonce, HA1);
+
+ DigestCalcResponse(HA1, digest_nonce, digest_noncecount, digest_cnonce, digest_qop,digest_method, digest_uri, HA2, response);
+
+
+ // We check that the Digest-Response is the same (UA, Diameter)
+ if(strcmp(response,digest_response)!=0)
+ {
+ TRACE_DEBUG(FULL,"Response calculated by Diameter server:%s",response);
+ TRACE_DEBUG(FULL,"Response calculated by UA:%s",digest_response);
+ TRACE_DEBUG(INFO,"Digest-Response does not match!");
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ free(digest_algorithm);
+ free(digest_cnonce);
+ free(digest_nonce);
+ free(digest_noncecount);
+ free(digest_method);
+ free(digest_username);
+ free(digest_uri);
+ free(digest_qop);
+ free(digest_response);
+ free(digest_realm);
+ free(storednonce->nonce);
+ free(storednonce);
+ if(username!=NULL)
+ free(username);
+ goto out;
+
+ }
+ //We calculate Digest_Response_Auth
+ DigestCalcResponseAuth(HA1, digest_nonce, digest_noncecount, digest_cnonce, digest_qop,digest_method, digest_uri, HA2, responseauth);
+
+ TRACE_DEBUG(FULL,"Response calculated by Diameter server:%s",response);
+ TRACE_DEBUG(FULL,"Response calculated by UA:%s",digest_response);
+ if(strcmp(digest_qop,"auth-int")==0)
+ {
+ //Digest-HA1 MUST be used instead of Digest-Response-Auth if Digest-Qop is 'auth-int'.
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_HA1, 0, &a2 ) );
+ val.os.data=HA1;
+ val.os.len=HASHHEXLEN+1;
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthentication, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+ else
+ {
+ //Digest-Response-Auth MUST be used instead of Digest-HA1 if Digest-Qop is 'auth'.
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Digest_Response_Auth, 0, &a2 ) );
+ val.os.data=responseauth;
+ val.os.len=DIGEST_LEN*2;
+ CHECK_FCT( fd_msg_avp_setvalue( a2, &val ) );
+ CHECK_FCT( fd_msg_avp_add( sipAuthentication, MSG_BRW_LAST_CHILD, a2 ) );
+ }
+ free(digest_algorithm);
+ free(digest_cnonce);
+ free(digest_nonce);
+ free(digest_noncecount);
+ free(digest_method);
+ free(digest_username);
+ free(digest_uri);
+ free(digest_qop);
+ free(digest_response);
+ free(digest_realm);
+ free(storednonce->nonce);
+ free(storednonce);
+
+ number_of_auth_items++;
+ }
+
+
+ //We add SIP Authentication-Info to Auth Data Item
+ CHECK_FCT( fd_msg_avp_add( authdataitem, MSG_BRW_LAST_CHILD, sipAuthentication ) );
+ //We add Auth Data Item to Answer
+ CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, authdataitem ) );
+
+
+ if(username!=NULL && authenticationpending)
+ {
+ //We clear the flag "authentication pending"
+ querylen=SQL_CLEARFLAG_LEN + usernamelen;
+ query = malloc(querylen+2);
+ snprintf(query, querylen+1, SQL_CLEARFLAG, username);
+
+ //We make the query
+ request_mysql(query);
+
+ free(query);
+ }
+
+ if(sipurinotstored)
+ result="DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED";
+ else
+ result="DIAMETER_SUCCESS";
+ found_cnonce=0;
+ }
+ }
+ }
+ else
+ TRACE_DEBUG(INFO,"No auth data items!");
+ }
+ //Add SIP_Number_Auth_Items AVP
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Number_Auth_Items, 0, &avp ) );
+ val.i32 = number_of_auth_items;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &val ) );
+ CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+
+ }
+ else
+ {
+ TRACE_DEBUG(INFO,"We only support DIGEST for now, unable to comply");
+ result="DIAMETER_ERROR_AUTH_SCHEME_NOT_SUPPORTED";
+ if(username!=NULL)
+ free(username);
+ goto out;
+ }
+ }
+ }
+ else
+ {
+ //TODO: remove this because Number_Auth_Items is not compulsory
+ TRACE_DEBUG(FULL,"Number-Auth-Items is not included.");
+ result="DIAMETER_UNABLE_TO_COMPLY";
+ if(username!=NULL)
+ free(username);
+ goto out;
+ }
+
+ if(username!=NULL)
+ free(username);
+
+
+out:
+ // Set the Origin-Host, Origin-Realm, Result-Code AVPs
+ CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
+
+
+ // Send the answer
+ CHECK_FCT( fd_msg_send( msg, NULL, NULL ) );
+
+*/
+ return 0;
+}
+
diff --git a/extensions/test_sip/registrationtermination.c b/extensions/test_sip/registrationtermination.c
new file mode 100644
index 0000000..5286e73
--- /dev/null
+++ b/extensions/test_sip/registrationtermination.c
@@ -0,0 +1,43 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "test_sip.h"
+
+
+int test_sip_RTR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+
+ return 0;
+}
diff --git a/extensions/test_sip/serverassignment.c b/extensions/test_sip/serverassignment.c
new file mode 100644
index 0000000..887ed28
--- /dev/null
+++ b/extensions/test_sip/serverassignment.c
@@ -0,0 +1,165 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "test_sip.h"
+
+//Called to send a UAR
+int test_sip_SAR_cb()
+{
+ struct dict_object * sar_model=NULL;
+ struct msg * message=NULL;
+ struct avp *avp=NULL;
+ union avp_value value;
+
+ //Fake values START
+ char *sip_aor="sip:aw-lappy@tera.ics.keio.ac.jp";
+ size_t aor_len=strlen(sip_aor);
+ char *destination_realm="tera.ics.keio.ac.jp";
+ size_t destination_realmlen=strlen(destination_realm);
+ char *destination_host="suika.tera.ics.keio.ac.jp";
+ size_t destination_hostlen=strlen(destination_host);
+ char *username="aw-lappy";
+ size_t usernamelen=strlen(username);
+ char *sipserveruri="sip:ichigo@tera.ics.keio.ac.jp";
+ size_t sipserverurilen=strlen(sipserveruri);
+ // char *visitednetwork="Pink";
+ //size_t visitednetworklen=strlen(visitednetwork);
+ //int registrationtype = 2;
+ int data_already_available=0;
+ int assignment_type=0;
+ //Fake values STOP
+
+ //Create the base message for an RTR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Server-Assignment-Request", &sar_model, ENOENT) );
+ CHECK_FCT( fd_msg_new (sar_model, 0, &message));
+
+
+
+ // Create a new session
+ {
+ CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
+ }
+
+ //Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = 6;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, avp) );
+ }
+ //Auth_Session_State
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ value.i32=1;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //Origin_Host & Origin_Realm
+ CHECK_FCT( fd_msg_add_origin ( message, 0 ));
+
+ //Destination_Host
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
+ value.os.data=(unsigned char *)destination_host;
+ value.os.len=destination_hostlen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ //Destination_Realm
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Realm, 0, &avp ) );
+ value.os.data=(unsigned char *)destination_realm;
+ value.os.len=destination_realmlen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //SIP_AOR
+ {
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)sip_aor;
+ value.os.len=aor_len;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+
+ }
+ //Username
+ {
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.User_Name, 0, &avp ) );
+ value.os.data=(unsigned char *)username;
+ value.os.len=usernamelen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+
+ }
+ //SIP_User_Data_Already_Available
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Data_Already_Available, 0, &avp ) );
+ value.i32=data_already_available;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //SIP_Server_Assignment_Type;
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_Assignment_Type, 0, &avp ) );
+ value.i32=assignment_type;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ //SIP_server_uri
+ {
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_URI, 0, &avp ) );
+ value.os.data=(unsigned char *)sipserveruri;
+ value.os.len=sipserverurilen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+
+ }
+
+ CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
+
+ return 0;
+}
+
+int test_sip_SAA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+
+ return 0;
+}
diff --git a/extensions/test_sip/test_sip.c b/extensions/test_sip/test_sip.c
new file mode 100644
index 0000000..463fcd9
--- /dev/null
+++ b/extensions/test_sip/test_sip.c
@@ -0,0 +1,241 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+
+#include"test_sip.h"
+
+struct disp_hdl * test_sip_MAR_hdl=NULL;
+struct disp_hdl * test_sip_LIR_hdl=NULL;
+struct disp_hdl * test_sip_UAR_hdl=NULL;
+struct disp_hdl * test_sip_SAR_hdl=NULL;
+struct disp_hdl * test_sip_PPA_hdl=NULL;
+struct disp_hdl * test_sip_RTA_hdl=NULL;
+
+struct disp_hdl * test_sip_MAA_hdl=NULL;
+struct disp_hdl * test_sip_LIA_hdl=NULL;
+struct disp_hdl * test_sip_UAA_hdl=NULL;
+struct disp_hdl * test_sip_SAA_hdl=NULL;
+struct disp_hdl * test_sip_PPR_hdl=NULL;
+struct disp_hdl * test_sip_RTR_hdl=NULL;
+
+
+struct disp_hdl * test_sip_default_hdl=NULL;
+
+//configuration stucture
+struct ts_conf * ts_conf=NULL;
+static struct ts_conf test_sip_conf;
+
+
+//dictionary of SIP
+struct sip_dict sip_dict;
+
+int test_sip_default_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act)
+{
+ TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+
+ return 0;
+}
+
+
+/*
+void dump_config()
+{
+ TRACE_DEBUG(FULL,"***Configuration of TEST Diameter-SIP extension***");
+ TRACE_DEBUG(FULL,"# username: *%s*",ts_conf->username);
+ TRACE_DEBUG(FULL,"# password: *%s*",ts_conf->password);
+ TRACE_DEBUG(FULL,"# sip_aor: *%s*",ts_conf->sip_aor);
+ TRACE_DEBUG(FULL,"# destination_realm: *%s*",ts_conf->destination_realm);
+ TRACE_DEBUG(FULL,"# destination_sip: *%s*",ts_conf->destination_sip);
+ TRACE_DEBUG(FULL,"***End of TEST Diameter-SIP configuration extension***");
+}
+*/
+static int ts_conf_init(void)
+{
+ ts_conf=&test_sip_conf;
+ //memset(app_sip_conf, 0, sizeof(struct ts_conf));
+
+
+ return 0;
+}
+
+/* entry point */
+int ts_entry(char * conffile)
+{
+ TRACE_ENTRY("%p", conffile);
+
+ struct dict_object * app=NULL;
+ struct disp_when data;
+
+
+ //TODO: activate again configuration file
+ CHECK_FCT( ts_conf_init() );
+ /* Initialize configuration
+ //CHECK_FCT( ts_conf_init() );
+
+
+ //We parse the configuration file
+ if (conffile != NULL) {
+ CHECK_FCT( ts_conf_handle(conffile) );
+ }
+ else
+ {
+ TRACE_DEBUG(INFO, "We need a configuration file for Diameter-SIP extension. See doc/ for an example.");
+ }
+
+ //We can dump the configuration extracted from app_sip.conf
+ dump_config();
+ */
+
+
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Session Initiation Protocol (SIP) Application", &app, ENOENT) );
+ CHECK_FCT( fd_disp_app_support ( app, NULL, 1, 0 ) );
+
+
+
+ //We set useful AVPs
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Session-State", &sip_dict.Auth_Session_State, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &sip_dict.Auth_Application_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &sip_dict.Destination_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &sip_dict.Destination_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sip_dict.Session_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host", &sip_dict.Redirect_Host, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host-Usage", &sip_dict.Redirect_Host_Usage, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Auth-Data-Item", &sip_dict.SIP_Auth_Data_Item, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authorization", &sip_dict.SIP_Authorization, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authenticate", &sip_dict.SIP_Authenticate, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Number-Auth-Items", &sip_dict.SIP_Number_Auth_Items, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Scheme", &sip_dict.SIP_Authentication_Scheme, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authentication-Info", &sip_dict.SIP_Authentication_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-URI", &sip_dict.SIP_Server_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-Capabilities", &sip_dict.SIP_Server_Capabilities, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Mandatory-Capability", &sip_dict.SIP_Mandatory_Capability, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Optional-Capability", &sip_dict.SIP_Optional_Capability, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Method", &sip_dict.SIP_Method, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-AOR", &sip_dict.SIP_AOR, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Deregistration-Reason", &sip_dict.SIP_Deregistration_Reason, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Code", &sip_dict.SIP_Reason_Code, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Info", &sip_dict.SIP_Reason_Info, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Accounting-Information", &sip_dict.SIP_Accounting_Information, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Accounting-Server-URI", &sip_dict.SIP_Accounting_Server_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Credit-Control-Server-URI", &sip_dict.SIP_Credit_Control_Server_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-Assignment-Type", &sip_dict.SIP_Server_Assignment_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Item-Number", &sip_dict.SIP_Item_Number, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Authorization-Type", &sip_dict.SIP_User_Authorization_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Supported-User-Data-Type", &sip_dict.SIP_Supported_User_Data_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data", &sip_dict.SIP_User_Data, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Type", &sip_dict.SIP_User_Data_Type, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Contents", &sip_dict.SIP_User_Data_Contents, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-User-Data-Already-Available", &sip_dict.SIP_User_Data_Already_Available, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Visited-Network-Id", &sip_dict.SIP_Visited_Network_Id, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Realm", &sip_dict.Digest_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-URI", &sip_dict.Digest_URI, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce", &sip_dict.Digest_Nonce, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-CNonce", &sip_dict.Digest_CNonce, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Method", &sip_dict.Digest_Method, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce-Count", &sip_dict.Digest_Nonce_Count, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Realm", &sip_dict.Digest_Realm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Response", &sip_dict.Digest_Response, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Response-Auth", &sip_dict.Digest_Response_Auth, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Username", &sip_dict.Digest_Username, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Algorithm", &sip_dict.Digest_Algorithm, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-QoP", &sip_dict.Digest_QOP, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &sip_dict.User_Name, ENOENT) );
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-HA1", &sip_dict.Digest_HA1, ENOENT) );
+
+
+ //Register Application
+ memset(&data, 0, sizeof(data));
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Session Initiation Protocol (SIP) Application", &data.app, ENOENT) );
+
+
+ //**Command Codes
+ /**/
+ //MAA
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Multimedia-Auth-Answer", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( test_sip_MAA_cb, DISP_HOW_CC, &data, NULL, &test_sip_MAA_hdl ) );
+
+ //UAA
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "User-Authorization-Answer", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( test_sip_UAA_cb, DISP_HOW_CC, &data, NULL, &test_sip_UAA_hdl ) );
+
+ //RTR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Request", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( test_sip_RTR_cb, DISP_HOW_CC, &data, NULL, &test_sip_RTR_hdl ) );
+
+ //LIA
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Answer", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( test_sip_LIA_cb, DISP_HOW_CC, &data, NULL, &test_sip_LIA_hdl ) );
+
+ //LIA
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Server-Assignment-Answer", &data.command, ENOENT) );
+ CHECK_FCT( fd_disp_register( test_sip_SAA_cb, DISP_HOW_CC, &data, NULL, &test_sip_SAA_hdl ) );
+
+ //Callback for unexpected messages
+ CHECK_FCT( fd_disp_register( test_sip_default_cb, DISP_HOW_APPID, &data, NULL, &test_sip_default_hdl ) );
+
+ /*
+ //We start database connection
+ if(start_mysql_connection())
+ return 1;
+ */
+
+ //CHECK_FCT( fd_event_trig_regcb(30, "test_sip", (void *)test_sipSL_LIR_cb ) );
+ CHECK_FCT( fd_event_trig_regcb(30, "test_sip", (void *)test_sip_SAR_cb ) );
+ CHECK_FCT( fd_event_trig_regcb(31, "test_sip", (void *)test_sip_LIR_cb ) );
+
+ return 0;
+}
+
+//Cleanup callback
+void fd_ext_fini(void)
+{
+ /*
+ if (test_sip_MAR_cb) {
+ (void) fd_disp_unregister(&test_sip_MAR_hdl);
+ CHECK_FCT_DO( fd_sess_handler_destroy(&ts_sess_hdl),return);
+ }
+ */
+ //We close database connection
+ //close_mysql_connection();
+
+
+
+ TRACE_ENTRY();
+ return ;
+}
+
+EXTENSION_ENTRY("test_sip", ts_entry, "dict_sip");
+
diff --git a/extensions/test_sip/test_sip.h b/extensions/test_sip/test_sip.h
new file mode 100644
index 0000000..e2ebf21
--- /dev/null
+++ b/extensions/test_sip/test_sip.h
@@ -0,0 +1,125 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include <freeDiameter/extension.h>
+#include <sys/time.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+GCC_DIAG_OFF("-Wdeprecated-declarations")
+#include <gcrypt.h>
+GCC_DIAG_ON("-Wdeprecated-declarations")
+#include <string.h>
+#include <mysql.h>
+
+/* The module configuration */
+struct ts_conf {
+ char * destination_sip;
+ char * destination_realm;
+ char * username;
+ char * password;
+ char * sip_aor;
+};
+extern struct ts_conf * ts_conf;
+
+//Storage for some useful AVPs
+struct sip_dict{
+ struct dict_object * Auth_Session_State;
+ struct dict_object * Auth_Application_Id;
+ struct dict_object * Destination_Host;
+ struct dict_object * User_Name;
+ struct dict_object * Session_Id;
+ struct dict_object * Redirect_Host;
+ struct dict_object * Redirect_Host_Usage;
+ struct dict_object * SIP_Auth_Data_Item;
+ struct dict_object * SIP_Accounting_Information;
+ struct dict_object * SIP_Accounting_Server_URI;
+ struct dict_object * SIP_Credit_Control_Server_URI;
+ struct dict_object * SIP_Server_Assignment_Type;
+ struct dict_object * SIP_Item_Number;
+ struct dict_object * SIP_User_Authorization_Type;
+ struct dict_object * SIP_Supported_User_Data_Type;
+ struct dict_object * SIP_User_Data;
+ struct dict_object * SIP_User_Data_Type;
+ struct dict_object * SIP_User_Data_Contents;
+ struct dict_object * SIP_User_Data_Already_Available;
+ struct dict_object * SIP_Visited_Network_Id;
+ struct dict_object * SIP_Authorization;
+ struct dict_object * SIP_Authenticate;
+ struct dict_object * SIP_Number_Auth_Items;
+ struct dict_object * SIP_Authentication_Scheme;
+ struct dict_object * SIP_Authentication_Info;
+ struct dict_object * SIP_Server_URI;
+ struct dict_object * SIP_Server_Capabilities;
+ struct dict_object * SIP_Mandatory_Capability;
+ struct dict_object * SIP_Optional_Capability;
+ struct dict_object * SIP_Method;
+ struct dict_object * SIP_AOR;
+ struct dict_object * SIP_Deregistration_Reason;
+ struct dict_object * SIP_Reason_Code;
+ struct dict_object * SIP_Reason_Info;
+ struct dict_object * Digest_URI;
+ struct dict_object * Digest_Nonce;
+ struct dict_object * Digest_Nonce_Count;
+ struct dict_object * Digest_CNonce;
+ struct dict_object * Digest_Realm;
+ struct dict_object * Digest_Response;
+ struct dict_object * Digest_Response_Auth;
+ struct dict_object * Digest_Username;
+ struct dict_object * Digest_Method;
+ struct dict_object * Digest_QOP;
+ struct dict_object * Digest_Algorithm;
+ struct dict_object * Digest_HA1;
+ struct dict_object * Destination_Realm;
+};
+
+extern struct sip_dict sip_dict;
+extern struct session_handler * ts_sess_hdl;
+
+int ts_entry();
+void fd_ext_fini(void);
+
+int test_sip_LIR_cb();
+int test_sip_UAR_cb();
+int test_sip_SAR_cb();
+int test_sipSL_LIR_cb();
+
+int test_sip_default_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int test_sip_MAA_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int test_sip_RTR_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int test_sip_UAA_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int test_sip_LIA_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int test_sip_SAA_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
+int test_sipSL_LIA_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act);
diff --git a/extensions/test_sip/test_sip.l b/extensions/test_sip/test_sip.l
new file mode 100644
index 0000000..668591d
--- /dev/null
+++ b/extensions/test_sip/test_sip.l
@@ -0,0 +1,137 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. *
+* *
+* All rights reserved. *
+* Based on ta_conf.l (Sebastien Decugis <sdecugis@freediameter.net>) *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+
+
+%{
+#include "test_sip.h"
+/* Include yacc tokens definitions */
+#include "test_sip.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { \
+ yylloc->first_column = yylloc->last_column + 1; \
+ yylloc->last_column = yylloc->first_column + yyleng - 1; \
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+ /* Update the line count */
+\n {
+ yylloc->first_line++;
+ yylloc->last_line++;
+ yylloc->last_column=0;
+ }
+
+ /* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+ ;
+ /* Eat all comments */
+#.*$ ;
+
+ /* Recognize any integer */
+[-]?[[:digit:]]+ {
+ /* Convert this to an integer value */
+ int ret=0;
+ ret = sscanf(yytext, "%i", &yylval->integer);
+ if (ret != 1) {
+ /* No matching: an error occurred */
+ fd_log_debug("Unable to convert the value '%s' to a valid number: %s", yytext, strerror(errno));
+ return LEX_ERROR; /* trig an error in yacc parser */
+ /* Maybe we could REJECT instead of failing here? */
+ }
+ return INTEGER;
+ }
+
+ /* Recognize quoted strings -- we do not support escaped \" in the string currently. */
+\"[^\"]+\" {
+ /* Match a quoted string. Let's be very permissive. */
+ yylval->string = strdup(yytext+1);
+ if (!yylval->string) {
+ fd_log_debug("Unable to copy the string '%s': %s", yytext, strerror(errno));
+ TRACE_DEBUG(INFO, "strdup failed");
+ return LEX_ERROR; /* trig an error in yacc parser */
+ }
+ yylval->string[strlen(yytext) - 2] = '\0';
+ return QSTRING;
+ }
+
+
+
+
+ /* Recognize the tokens */
+(?i:"username") {
+ return TESTSIP_USERNAME;
+ }
+
+(?i:"password") {
+ return TESTSIP_PASSWORD;
+ }
+
+(?i:"sip_aor") {
+ return TESTSIP_SIPAOR;
+ }
+
+(?i:"destination_realm") {
+ return TESTSIP_DESTREALM;
+ }
+
+(?i:"destination_sip") {
+ return TESTSIP_DESTSIP;
+ }
+
+
+
+
+ /* Valid single characters for yyparse */
+[=;] { return yytext[0]; }
+
+ /* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]"*=>;\n]+ {
+ fd_log_debug("Unrecognized text on line %d col %d: '%s'.", yylloc->first_line, yylloc->first_column, yytext);
+ return LEX_ERROR;
+ }
+
+%%
diff --git a/extensions/test_sip/test_sip.y b/extensions/test_sip/test_sip.y
new file mode 100644
index 0000000..e699c28
--- /dev/null
+++ b/extensions/test_sip/test_sip.y
@@ -0,0 +1,175 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. *
+* *
+* All rights reserved. *
+* Based on ta_conf.y (Sebastien Decugis <sdecugis@freediameter.net>) *
+* *
+* Redistribution and use of this software in source and binary forms, with or without modification, are *
+* permitted provided that the following conditions are met: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+
+/* For development only : */
+%debug
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations
+%pure-parser
+
+%{
+#include "test_sip.h"
+#include "test_sip.tab.h" /* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+#include <string.h>
+#include <errno.h>
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+/* Parse the configuration file */
+int ts_conf_handle(char * conffile)
+{
+ extern FILE * test_sipin;
+ int ret;
+
+ TRACE_ENTRY("%p", conffile);
+
+ TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+
+ test_sipin = fopen(conffile, "r");
+ if (test_sipin == NULL) {
+ ret = errno;
+ fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
+ TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
+ return ret;
+ }
+
+ ret = yyparse(conffile);
+
+ fclose(test_sipin);
+
+ if (ret != 0) {
+ TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+/* The Lex parser prototype */
+int test_sipflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+ TRACE_DEBUG(INFO, "Error in configuration parsing");
+
+ if (ploc->first_line != ploc->last_line)
+ fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+ else if (ploc->first_column != ploc->last_column)
+ fd_log_debug("%s:%d.%d-%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+ else
+ fd_log_debug("%s:%d.%d : %s", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+ char *string; /* The string is allocated by strdup in lex.*/
+ int integer; /* Store integer values */
+}
+
+/* In case of error in the lexical analysis */
+%token LEX_ERROR
+
+/* Key words */
+%token TESTSIP_DESTREALM
+%token TESTSIP_DESTSIP
+%token TESTSIP_PASSWORD
+%token TESTSIP_SIPAOR
+%token TESTSIP_USERNAME
+
+/* Tokens and types for routing table definition */
+/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */
+%token <string> QSTRING
+
+/* An integer value */
+%token <integer> INTEGER
+
+/* -------------------------------------- */
+%%
+
+ /* The grammar definition */
+conffile: /* empty grammar is OK */
+ | conffile destination_realm
+ | conffile destination_sip
+ | conffile username
+ | conffile password
+ | conffile sip_aor
+ ;
+
+destination_realm: TESTSIP_DESTREALM '=' QSTRING ';'
+ {
+ free(ts_conf->destination_realm);
+ ts_conf->destination_realm = $3;
+ }
+ ;
+
+destination_sip: TESTSIP_DESTSIP '=' QSTRING ';'
+ {
+ free(ts_conf->destination_sip);
+ ts_conf->destination_sip = $3;
+ }
+ ;
+
+username: TESTSIP_USERNAME '=' QSTRING ';'
+ {
+ free(ts_conf->username);
+ ts_conf->username = $3;
+ }
+ ;
+
+password: TESTSIP_PASSWORD '=' QSTRING ';'
+ {
+ free(ts_conf->password);
+ ts_conf->password = $3;
+ }
+ ;
+
+sip_aor: TESTSIP_SIPAOR '=' QSTRING ';'
+ {
+ free(ts_conf->sip_aor);
+ ts_conf->sip_aor = $3;
+ }
+ ;
diff --git a/extensions/test_sip/userauthorization.c b/extensions/test_sip/userauthorization.c
new file mode 100644
index 0000000..e07a5ad
--- /dev/null
+++ b/extensions/test_sip/userauthorization.c
@@ -0,0 +1,156 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License) *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
+* *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (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: *
+* *
+* * Redistributions of source code must retain the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above *
+* copyright notice, this list of conditions and the *
+* following disclaimer in the documentation and/or other *
+* materials provided with the distribution. *
+* *
+* * Neither the name of the Teraoka Laboratory nor the *
+* names of its contributors may be used to endorse or *
+* promote products derived from this software without *
+* specific prior written permission of Teraoka Laboratory *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+*********************************************************************************************************/
+#include "test_sip.h"
+
+//Called to send a UAR
+int test_sip_UAR_cb()
+{
+ struct dict_object * uar_model=NULL;
+ struct msg * message=NULL;
+ struct avp *avp=NULL;
+ union avp_value value;
+
+ //Fake values START
+ char *sip_aor="sip:aw-lappy@tera.ics.keio.ac.jp";
+ size_t aor_len=strlen(sip_aor);
+ char *destination_realm="tera.ics.keio.ac.jp";
+ size_t destination_realmlen=strlen(destination_realm);
+ char *destination_host="suika.tera.ics.keio.ac.jp";
+ size_t destination_hostlen=strlen(destination_host);
+ char *username="aw-lappy";
+ size_t usernamelen=strlen(username);
+ char *visitednetwork="Pink";
+ size_t visitednetworklen=strlen(visitednetwork);
+ int registrationtype = 2;
+ //Fake values STOP
+
+ //Create the base message for an RTR
+ CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "User-Authorization-Request", &uar_model, ENOENT) );
+ CHECK_FCT( fd_msg_new (uar_model, 0, &message));
+
+
+
+ // Create a new session
+ {
+ CHECK_FCT( fd_msg_new_session( message, (os0_t)"appsip", CONSTSTRLEN("appsip") ) );
+ }
+
+ //Add the Auth-Application-Id
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+ value.i32 = 6;
+ CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, avp) );
+ }
+
+ //Auth_Session_State
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+ value.i32=1;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //Origin_Host & Origin_Realm
+ CHECK_FCT( fd_msg_add_origin ( message, 0 ));
+
+ //Destination_Host
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
+ value.os.data=(unsigned char *)destination_host;
+ value.os.len=destination_hostlen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+ //Destination_Realm
+ {
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Realm, 0, &avp ) );
+ value.os.data=(unsigned char *)destination_realm;
+ value.os.len=destination_realmlen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+ }
+
+ //SIP_AOR
+ {
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+ value.os.data=(unsigned char *)sip_aor;
+ value.os.len=aor_len;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+
+ }
+ //Username
+ {
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.User_Name, 0, &avp ) );
+ value.os.data=(unsigned char *)username;
+ value.os.len=usernamelen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+
+ }
+ //Visited Network
+ {
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Visited_Network_Id, 0, &avp ) );
+ value.os.data=(unsigned char *)visitednetwork;
+ value.os.len=visitednetworklen;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+
+ }
+ //Authorization Type
+ {
+
+ CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_User_Authorization_Type, 0, &avp ) );
+ value.i32=registrationtype;
+ CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+ CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+
+ }
+
+ CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
+
+ return 0;
+}
+
+int test_sip_UAA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
+{
+
+ return 0;
+}