diff options
| author | Sukchan Lee <acetcom@gmail.com> | 2021-03-21 13:14:26 +0900 |
|---|---|---|
| committer | Sukchan Lee <acetcom@gmail.com> | 2021-03-21 13:14:26 +0900 |
| commit | 32d46d3f43485e171b1e28117d0db049dfc829b0 (patch) | |
| tree | b3506d614932f50730e023391600287676ac0c08 /contrib | |
| parent | e07f3955e6d0f59f272fd21d3b21a5e2eac17426 (diff) | |
Release freeDiameter v1.5.0main
Diffstat (limited to 'contrib')
| -rw-r--r-- | contrib/PKI/ca_script2/Makefile | 6 | ||||
| -rw-r--r-- | contrib/debian/changelog | 216 | ||||
| -rw-r--r-- | contrib/dict_json/dictionary_dcca_3gpp.json | 84 | ||||
| -rw-r--r-- | contrib/test_Gx/main_gx.c | 49 | ||||
| -rw-r--r-- | contrib/tools/README | 9 | ||||
| -rwxr-xr-x | contrib/tools/csv_to_fd | 662 | ||||
| -rw-r--r-- | contrib/tools/diameter-rfcs.csv | 202 | ||||
| -rwxr-xr-x | contrib/tools/grep_fd_dict_dump | 11 | ||||
| -rwxr-xr-x | contrib/tools/org_to_csv | 19 | ||||
| -rwxr-xr-x | contrib/tools/org_to_fd.pl | 75 |
10 files changed, 1177 insertions, 156 deletions
diff --git a/contrib/PKI/ca_script2/Makefile b/contrib/PKI/ca_script2/Makefile index 845176e..c40ea1e 100644 --- a/contrib/PKI/ca_script2/Makefile +++ b/contrib/PKI/ca_script2/Makefile @@ -25,7 +25,7 @@ all: help # Help message help: - @echo "\n\ + @printf -- "\n\ Available commands:\n\ make init topca=name\n\ Creates the initial top-level CA structure\n\ @@ -172,7 +172,7 @@ gencrl: @if [ -z "$(ca)" ]; then echo "Missing parameter. Ex: make gencrl ca=ca.testbed.aaa"; exit 1; fi # Create the CRL @CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl ca $(CONFIG) -gencrl -out $(DATA_DIR)/$(ca)/public/crl/$(ca).pem - @ln -s crl/$(ca).pem $(DATA_DIR)/$(ca)/public/local.pem - @ln -s local.pem $(DATA_DIR)/$(ca)/public/`openssl crl -noout -hash < $(DATA_DIR)/$(ca)/public/crl/$(ca).pem`.r0 + @ln -f -s crl/$(ca).pem $(DATA_DIR)/$(ca)/public/local.pem + @ln -f -s local.pem $(DATA_DIR)/$(ca)/public/`openssl crl -noout -hash < $(DATA_DIR)/$(ca)/public/crl/$(ca).pem`.r0 # End of file... diff --git a/contrib/debian/changelog b/contrib/debian/changelog index 526d9ef..2ef9f32 100644 --- a/contrib/debian/changelog +++ b/contrib/debian/changelog @@ -1,4 +1,174 @@ -freediameter (1.2.1) UNRELEASED; urgency=low +freediameter (UNRELEASED) UNRELEASED; urgency=low + + * + +freediameter (1.5.0) RELEASED; urgency=low + + * freeDiameter: + - Add -g to help + - Change -d and -q to control syslog level, as per stdout logging. + - Syslog to LOG_DAEMON. + - Actually syslog to LOG_DEBUG, now that -d/-q are used. + - Add -p pidfile + - SCTP client: bind to local endpoints configured with ListenOn so + that the SCTP INIT only contains those local endpoint addresses, + matching what is advertised in the CER. + * Base dictionary: Add rules for Experimental-Result. + * All extensions: Hide symbols except for fd_ext_init(), fd_ext_fini(), + and fd_ext_depends. + * dbg_dict_dump.fdx: add extension to write the dictionary + to the given file or to the log. + * dbg_dict_dump_json.fdx: add extension to write the dictionary as JSON + to the given file or stdout. + * dict_dcca_3gpp.fdx: Update to 3GPP Release 15, adding many standards. + This adds 96 TYPEs, 145 ENUMVALs, 791 AVPs, 52 RULEs. + There are various breaking changes (documented below). + * contrib/dictionary_dcca_3gpp.json: Remove non-3GPP AVPs that are + actually from base IETF RFCs: + - MIP6-Feature-Vector (124). IETF RFC 5447 + - Service-Selection (493). IETF RFC 5778 + - Mobile-Node-Identifier (506). IETF RFC 5779 + - QoS-Capability (578). IETF RFC 5777. + * New API: fd_msg_add_result(): set Result-Code or Experimental-Result. + * New API: log level FD_LOG_INFO. + * fd_conf_dump(): fix formatting of local endpoints. + * fd_msg_search_avp(): support searching avp as well as msg. + * Fix compiler warnings. + * Add ERRORS_ON_WARNINGS cmake boolean to enable fatal compiler warnings. + * New tool: grep_fd_dict_dump: cleanup fd_dict_dump() output in logs. + * New tool: csv_to_fd: convert .csv with AVP tables to freeDiameter C or JSON. + * New tool: org_to_csv: convert .org files into .csv files. + + * dict_dcca_3gpp.fdx changes per update to 3GPP Release 15 as at 2019-12: + - AVP changes: + - 3GPP-CG-IPv6-Address (14) renamed to 3GPP-CG-Ipv6-Address (14). + - 3GPP-GGSN-IPv6-Address (16) renamed to 3GPP-GGSN-Ipv6-Address (16). + - 3GPP-IPv6-DNS-Servers (17) renamed to 3GPP-Ipv6-DNS-Servers (17). + - 3GPP-SGSN-IPv6-Address (15) renamed to 3GPP-SGSN-Ipv6-Address (15). + - 3GPP2-BSID (9010) flag M MUST. + - 3GPP2-BSID (9010) type changed from OctetString to UTF8String. + - ADC-Revalidation-Time (2801) Time removed in 3GPP TS 29.212 V12.1.0 (2013-06). + - ADC-Rule-Base-Name (1095) flag M MUST. + - ADC-Rule-Definition (1094) flag M MUST. + - ADC-Rule-Install (1092) flag M MUST. + - ADC-Rule-Name (1096) flag M MUST. + - ADC-Rule-Remove (1093) flag M MUST. + - ADC-Rule-Report (1097) flag M MUST. + - Application-Service-Type (2102) type changed from UTF8String to Enumerated. + - Application-Session-Id (2103) type changed from UTF8String to Unsigned32. + - Call-Barring-Infor-List (1488) renamed to Call-Barring-Info (1488). + - External-Identifier (28) OctetString replaced by External-Identifier (3111) UTF8String. + - LCS-Requestor-Id (1239) renamed to LCS-Requestor-ID (1239). + - LCS-Requestor-Id-String (1240) renamed to LCS-Requestor-ID-String (1240). + - MBMS-BMSC-SSM-IPv6-Address (919) renamed to MBMS-BMSC-SSM-Ipv6-Address (919). + - MBMS-GGSN-IPv6-Address (917) renamed to MBMS-GGSN-Ipv6-Address (917). + - MBMSGW-Address (2307) renamed to MBMS-GW-Address (2307). + - Measurement-Period-LTE (1656) code changed to Measurement-Period-LTE (1655). + - Measurement-Period-UMTS (1655) code changed to Measurement-Period-UMTS (1656). + - MME-LocationInformation (1600) renamed to MME-Location-Information(1600). + - PDG-Address (895) Address removed in 3GPP TS 32.299 V12.6.0 (2014-09). + - PDG-Charging-Id (896) Unsigned32 removed in 3GPP TS 32.299 V12.6.0 (2014-09). + - PDN-Connection-ID (1065) flag M MUST NOT. + - PoC-User-Role-info-Units (1254) renamed to PoC-User-Role-Info-Units (1254). + - PS-to-CS-Session-Continuity (1099) flag M MUST NOT. + - SS-Status (1477) type changed from Grouped to OctetString. + - Status (2702) renamed to Status-AS-Code (2702). + - WAG-Address (890) Address removed in 3GPP TS 32.299 V12.6.0 (2014-09). + - WAG-PLMN-Id (891) OctetString removed in 3GPP TS 32.299 V12.6.0 (2014-09). + - WLAN-Information (875) Grouped removed in 3GPP TS 32.299 V12.6.0 (2014-09). + - WLAN-Radio-Container (892) Grouped removed in 3GPP TS 32.299 V12.6.0 (2014-09). + - WLAN-Session-Id (1246) UTF8String removed in 3GPP TS 32.299 V12.6.0 (2014-09). + - WLAN-Technology (893) Unsigned32 removed in 3GPP TS 32.299 V12.6.0 (2014-09). + - WLAN-UE-Local-IPAddress (894) Address removed in 3GPP TS 32.299 V12.6.0 (2014-09). + - AVP renames: + - Rename Call-Barring-Infor-List (1488) to Call-Barring-Info (1488). + - Rename LCS-Requestor-Id (1239) to LCS-Requestor-ID (1239). + - Rename LCS-Requestor-Id-String (1240) to LCS-Requestor-ID-String (1240). + - Rename MBMSGW-Address (2307) to MBMS-GW-Address (2307). + - Rename MME-LocationInformation (1600) to MME-Location-Information(1600). + - Rename PoC-User-Role-info-Units (1254) to PoC-User-Role-Info-Units (1254). + - Rename Status (2702) to Status-AS-Code (2702). + - AVP name conflicts: + - Time-Window (3818) in 3GPP TS 29.345 V12.1.0 (2014-12) predates + Time-Window-29.154 (4204) in 3GPP TS 29.154 V13.1.0 (2016-03). + - Add Enumerated(3GPP/Experimental-Result-Code). 145 values. + - Update standards: + - 3GPP TS 29.061 V15.5.0 (2018-12). 15 AVPs. + - 3GPP TS 29.173 V15.0.0 (2018-06). 1 AVP. + - 3GPP TS 29.212 V15.9.0 (2019-12). 46 AVPs. + - 3GPP TS 29.214 V15.7.0 (2019-09). 27 AVPs. + - 3GPP TS 29.229 V15.2.0 (2019-09). 8 AVPs. + - 3GPP TS 29.272 V15.10.0 (2019-12). 44 AVPs. + - 3GPP TS 29.329 V15.2.0 (2019-09). 5 AVPs. + - 3GPP TS 32.299 V15.7.0 (2019-06). 154 AVPs. + - Add standards: + - 3GPP TS 29.109 V15.0.0 (2017-06). 21 AVPs. + - 3GPP TS 29.128 V15.6.0 (2019-09). 25 AVPs. + - 3GPP TS 29.153 V15.1.0 (2019-09). 2 AVPs. + - 3GPP TS 29.154 V15.3.0 (2019-09). 16 AVPs. + - 3GPP TS 29.172 V15.2.0 (2019-12). 66 AVPs. + - 3GPP TS 29.209 V6.8.0 (2011-09). 2 AVPs. + - 3GPP TS 29.215 V15.2.0 (2019-09). 9 AVPs. + - 3GPP TS 29.217 V15.1.0 (2019-09). 14 AVPs. + - 3GPP TS 29.219 V15.3.0 (2019-09). 7 AVPs. + - 3GPP TS 29.234 V11.2.0 (2013-06). 19 AVPs. + - 3GPP TS 29.273 V15.4.0 (2019-09). 40 AVPs. + - 3GPP TS 29.283 V15.1.0 (2019-09). 16 AVPs. + - 3GPP TS 29.336 V15.7.0 (2019-09). 79 AVPs. + - 3GPP TS 29.337 V15.0.0 (2018-06). 4 AVPs. + - 3GPP TS 29.338 V15.1.0 (2018-12). 34 AVPs. + - 3GPP TS 29.343 V15.1.0 (2019-09). 13 AVPs. + - 3GPP TS 29.344 V15.1.0 (2019-09). 7 AVPs. + - 3GPP TS 29.345 V15.1.0 (2019-09). 68 AVPs. + - 3GPP TS 29.368 V15.1.0 (2019-09). 12 AVPs. + - 3GPP TS 29.388 V15.1.0 (2019-09). 3 AVPs. + - 3GPP TS 29.389 V15.1.0 (2019-09). 3 AVPs. + - 3GPP TS 29.468 V15.8.0 (2019-12). 33 AVPs. + - 3GPP TS 29.561 V16.3.0 (2020-03). 9 AVPs. + +freediameter (1.4.0) RELEASED; urgency=low + + * New API: fd_fifo_set_max to change the capacity of a queue. + * New configuration stanza for Relays: ProcessingPeersPattern and ProcessingPeersMinimum + * New configuration stanza for scalability: RoutingInThreads and RoutingOutThreads + * some coding style cleanups + * Improvements on rt_load_balance algorithm + * Improvements on logging & locking behaviors + * More tolerant to invalid messages and answers. + * Improvements on shutdown behaviors. + * test_ccload: new extension: generates random + Credit-Control-Requests and counts how many are answered/give an + error/get no answer. Start it with SIGUSR2, stop it with a second + SIGUSR2. Statistics are printed on exit. + * test_cc: new extension. Automatically replies to + Credit-Control-Requests. Copies minimally necessary data from + the Request. + * Fixed testcnx failing due to expired CA certificate + +freediameter (1.3.2) RELEASED; urgency=low + + * acl_wl: add configuration reload support (using SIGUSR1). + * Reduce deprecation warnings. + +freediameter (1.3.1) RELEASED; urgency=low + + * test_as: new extension. Automatically replies to Abort-Session-Requests + with a diameter success message. + * dbg_loglevel: new extension. Reads debug level from config file + and supports configuration reload using SIGUSR1; this allows + changing the loglevel at runtime. + * rt_rewrite: new extension. Modify messages - move data from one + AVP to another or drop AVPs completely. + * rt_deny_by_size: new extension. discard Diameter messages that are + larger than a configurable size. Has reload support (using + SIGUSR1). + * freeDiameterd: add syslog() support ('-s' command line flag) + * rt_ereg: add configuration reload support (using SIGUSR1). Support + grouped AVPs. Support multiple separate AVPs. + * rt_default: add configuration reload support (using SIGUSR1) + * Various bugfixes + +freediameter (1.2.1) RELEASED; urgency=low * New extension: rt_randomize (load-balancing on possible destinations) * New contrib: Gx extension. @@ -18,7 +188,7 @@ freediameter (1.2.1) UNRELEASED; urgency=low -- Sebastien Decugis <sdecugis@freediameter.net> Sat, 30 Jan 2016 23:38:03 +0800 -freediameter (1.2.0) UNRELEASED; urgency=low +freediameter (1.2.0) RELEASED; urgency=low * Major changes in the logging system to be more syslog and production friendly * New extension: dict_dcca_3gpp @@ -56,7 +226,7 @@ freediameter (1.2.0) UNRELEASED; urgency=low -- Sebastien Decugis <sdecugis@freediameter.net> Sat, 14 Sep 2013 18:08:07 +0800 -freediameter (1.1.6) UNRELEASED; urgency=low +freediameter (1.1.6) RELEASED; urgency=low * Fix major issue in 1.1.5 preventing to send answers to a received message. * New command-line option: --enable_msg_log=( DROPPED | RECEIVED | SENT | NODELIVER | TIMING ) @@ -71,7 +241,7 @@ freediameter (1.1.6) UNRELEASED; urgency=low -- Sebastien Decugis <sdecugis@freediameter.net> Sun, 03 Mar 2013 07:40:43 +0100 -freediameter (1.1.5) UNRELEASED; urgency=low +freediameter (1.1.5) RELEASED; urgency=low * Added compatibility with MAC OS X * Fix behavior of timeout whe nsending messages to allow re-send. @@ -80,7 +250,7 @@ freediameter (1.1.5) UNRELEASED; urgency=low -- Sebastien Decugis <sdecugis@freediameter.net> Sat, 03 Nov 2012 17:58:11 +0100 -freediameter (1.1.4) UNRELEASED; urgency=low +freediameter (1.1.4) RELEASED; urgency=low * Compatibility with GnuTLS 3.x versions / updated packaging files accordingly * Fix crash on Sparc 64 (possibly other 64b machines) @@ -89,14 +259,14 @@ freediameter (1.1.4) UNRELEASED; urgency=low -- Sebastien Decugis <sdecugis@freediameter.net> Fri, 24 Aug 2012 00:17:05 +0200 -freediameter (1.1.3) UNRELEASED; urgency=low +freediameter (1.1.3) RELEASED; urgency=low * Fixed a memory leak * Clean-up of some extensions -- Sebastien Decugis <sdecugis@freediameter.net> Tue, 03 Jul 2012 08:15:49 +0200 -freediameter (1.1.2) UNRELEASED; urgency=low +freediameter (1.1.2) RELEASED; urgency=low * FIFO queues are now capped to avoid memory exhaustion. * Cleanups in MIPv6 dictionaries. @@ -108,7 +278,7 @@ freediameter (1.1.2) UNRELEASED; urgency=low -- Sebastien Decugis <sdecugis@freediameter.net> Tue, 21 Feb 2012 18:38:10 +0100 -freediameter (1.1.1) UNRELEASED; urgency=low +freediameter (1.1.1) RELEASED; urgency=low * Bug fix release * Supports newer GNUTLS versions @@ -117,9 +287,9 @@ freediameter (1.1.1) UNRELEASED; urgency=low -- Sebastien Decugis <sdecugis@nict.go.jp> Fri, 30 Sep 2011 21:56:50 +0200 -freediameter (1.1.0) UNRELEASED; urgency=low +freediameter (1.1.0) RELEASED; urgency=low - * Source package restructured. Most of the + * Source package restructured. Most of the framework now contained in the libfdcore library. libfreeDiameter renamed as libfdproto. This closes #15. @@ -131,52 +301,52 @@ freediameter (1.1.0) UNRELEASED; urgency=low to RADIUS (closes #25) * Allow default signals such as SIGTSTP (ctrl-z) to be used with freeDiameterd - * Improved DiameterIdentity handling (esp. interationalization issues), - and improve efficiency of some string operations in peers, sessions, + * Improved DiameterIdentity handling (esp. interationalization issues), + and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7) * Cleanup in the session module to free only unreferenced sessions (#16) * Removed fd_cpu_flush_cache(), replaced by more robust alternatives. - * Improved peer state machine algorithm to counter SCTP multistream race + * Improved peer state machine algorithm to counter SCTP multistream race condition. * New extension rt_redirect.fdx that handles the Diameter Redirect errors. - * New extension app_redirect that allows sending Redirect indications to + * New extension app_redirect that allows sending Redirect indications to other peers. See doc/app_redirect.conf.sample for more information. * Added incomplete dictionary extension for rfc4006 (DCCA), courtesy of Konstantin Chekushin <koch@lmt.lv> -- Sebastien Decugis <sdecugis@freediameter.net> Tue, 29 Mar 2011 10:41:19 +0900 -freediameter (1.0.4) UNRELEASED; urgency=low +freediameter (1.0.4) RELEASED; urgency=low - * Added new API to specify timeout on receiving answer (#10) + * Added new API to specify timeout on receiving answer (#10) * Bumped API version number accordingly. * New test_netemul extension (simple network emulator proxy) * Improved API compatibility to C++ compilers -- Sebastien Decugis <sdecugis@nict.go.jp> Tue, 11 Jan 2011 12:28:22 +0900 -freediameter (1.0.3) UNRELEASED; urgency=low +freediameter (1.0.3) RELEASED; urgency=low * Fixed a couple of issues for portability (#21, #22, #23) * Fixed issue with ListenOn bit ordering (#20) * Added dictionary support for MIPv6 application objects. * Added dictionary support for legacy XML files. - * Added python interface dbg_interactive (experimental). + * Added python interface dbg_interactive (experimental). * Added parameters to fd_disp_register() and fd_sess_handler_create(), Bumped API version number accordingly. -- Sebastien Decugis <sdecugis@nict.go.jp> Tue, 14 Dec 2010 11:39:29 +0900 -freediameter (1.0.2) UNRELEASED; urgency=low +freediameter (1.0.2) RELEASED; urgency=low * Fix an issue in app_diameap.fdx with user names (#18) - * Allow DH parameters loaded from a file (#17) + * Allow DH parameters loaded from a file (#17) * Fixed a few compilation warnings on 64bits architectures. * New ALL_EXTENSIONS build option. -- Sebastien Decugis <sdecugis@nict.go.jp> Wed, 27 Oct 2010 11:17:32 +0900 -freediameter (1.0.1) UNRELEASED; urgency=low +freediameter (1.0.1) RELEASED; urgency=low * app_acct.fdx: new set of PHP scripts available in source contrib/app_acct_tools @@ -198,12 +368,12 @@ freediameter (1.0.1) UNRELEASED; urgency=low freediameter (1.0.0-2) experimental; urgency=low - * Official release 1.0.0 + * Official release 1.0.0 -- Sebastien Decugis <sdecugis@nict.go.jp> Thu, 29 Jul 2010 17:27:13 +0900 freediameter (1.0.0-1) experimental; urgency=low * Initial Release. - + -- Sebastien Decugis <sdecugis@nict.go.jp> Wed, 19 May 2010 15:36:54 +0900 diff --git a/contrib/dict_json/dictionary_dcca_3gpp.json b/contrib/dict_json/dictionary_dcca_3gpp.json index d8de49f..d829c16 100644 --- a/contrib/dict_json/dictionary_dcca_3gpp.json +++ b/contrib/dict_json/dictionary_dcca_3gpp.json @@ -33,21 +33,21 @@ "Max": 1 }, { - "AVP": "Used-Service-Unit", + "AVP": "Used-Service-Unit" }, { "AVP": "Tariff-Change-Usage", "Max": 1 }, { - "AVP": "Service-Identifier", + "AVP": "Service-Identifier" }, { "AVP": "Rating-Group", "Max": 1 }, { - "AVP": "G-S-U-Pool-Reference", + "AVP": "G-S-U-Pool-Reference" }, { "AVP": "Validity-Time", @@ -2930,36 +2930,6 @@ "Vendor": 10415 }, { - "Code": 28, - "Flags": { - "Must": "V", - "MustNot": "M" - }, - "Name": "External-Identifier", - "Type": "OctetString", - "Vendor": 10415 - }, - { - "Code": 124, - "Flags": { - "Must": "M", - "MustNot": "VP" - }, - "Name": "MIP6-Feature-Vector", - "Type": "Unsigned64", - "Vendor": 10415 - }, - { - "Code": 493, - "Flags": { - "Must": "M", - "MustNot": "VP" - }, - "Name": "Service-Selection", - "Type": "UTF8String", - "Vendor": 10415 - }, - { "Code": 500, "Flags": { "Must": "VM", @@ -3020,16 +2990,6 @@ "Vendor": 10415 }, { - "Code": 506, - "Flags": { - "Must": "M", - "MustNot": "VP" - }, - "Name": "Mobile-Node-Identifier", - "Type": "UTF8String", - "Vendor": 10415 - }, - { "Code": 507, "Flags": { "Must": "VM", @@ -3560,16 +3520,6 @@ "Vendor": 10415 }, { - "Code": 578, - "Flags": { - "Must": "M", - "MustNot": "VP" - }, - "Name": "QoS-Capability", - "Type": "Grouped", - "Vendor": 10415 - }, - { "Code": 600, "Flags": { "Must": "VM", @@ -7956,7 +7906,7 @@ "MustNot": "" }, "Name": "SS-Status", - "Type": "Grouped", + "Type": "OctetString", "Vendor": 10415 }, { @@ -8065,7 +8015,7 @@ "Must": "VM", "MustNot": "" }, - "Name": "Call-Barring-Infor-List", + "Name": "Call-Barring-Info", "Type": "Grouped", "Vendor": 10415 }, @@ -8435,7 +8385,7 @@ "Must": "V", "MustNot": "M" }, - "Name": "MME-LocationInformation", + "Name": "MME-Location-Information", "Type": "Grouped", "Vendor": 10415 }, @@ -10850,6 +10800,16 @@ "Vendor": 10415 }, { + "Code": 3111, + "Flags": { + "Must": "V", + "MustNot": "M" + }, + "Name": "External-Identifier", + "Type": "UTF8String", + "Vendor": 10415 + }, + { "Code": 3401, "Flags": { "Must": "VM", @@ -12588,7 +12548,7 @@ }, { "AVP": "Event-Trigger", - "Vendor": 10415, + "Vendor": 10415 }, { "AVP": "Event-Report-Indication", @@ -12686,7 +12646,7 @@ "Vendor": 10415 }, { - "AVP": "Subscription-Id", + "AVP": "Subscription-Id" }, { "AVP": "Abort-Cause", @@ -12753,7 +12713,7 @@ "Max": 1 }, { - "AVP": "Class", + "AVP": "Class" } ] }, @@ -12848,11 +12808,11 @@ "Max": 1 }, { - "AVP": "Class", - }, + "AVP": "Class" + } ] - }, + } ], "Vendors": [ { diff --git a/contrib/test_Gx/main_gx.c b/contrib/test_Gx/main_gx.c index 7811661..7faff5f 100644 --- a/contrib/test_Gx/main_gx.c +++ b/contrib/test_Gx/main_gx.c @@ -700,53 +700,6 @@ out: } -/* 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; -} static int cca_cb( struct msg ** msg, struct avp * t_avp , @@ -784,7 +737,7 @@ static int cca_cb( struct msg ** msg, CHECK_FCT(fd_msg_search_avp ( *msg, chrg_rule_grp, &g_avp )); - CHECK_FCT(fd_avp_search_avp(g_avp, chrg_rule_name, &avp)); + CHECK_FCT(fd_msg_search_avp(g_avp, chrg_rule_name, &avp)); if(avp) { CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata)); diff --git a/contrib/tools/README b/contrib/tools/README index bbb235d..11f5bad 100644 --- a/contrib/tools/README +++ b/contrib/tools/README @@ -1,2 +1,11 @@ +csv_to_fd converts CSV files containing RADIUS or Diameter AVP tables +into various formats, including freeDiameter C code and JSON documents. + +grep_fd_dict_dump processes stdin for the output of fd_dict_dump() +or dbg_dict_dump.fdx and reformats to remove pointer addresses, +to allow diff of output between freeDiameter invocations. + +org_to_csv converts org files into CSV files, suitable for csv_to_fd. + org_to_fd.pl converts org files like diameter-rfcs.org to C fragments that can be included in freeDiameter code. diff --git a/contrib/tools/csv_to_fd b/contrib/tools/csv_to_fd new file mode 100755 index 0000000..d39fc0a --- /dev/null +++ b/contrib/tools/csv_to_fd @@ -0,0 +1,662 @@ +#!/usr/bin/env python + +""" +Convert 8 column CSV files containing RADIUS or Diameter AVP tables +into various formats. + +Format of the CSV files is one of: +- Row per 3GPP AVP tables: + Name, Code, Section, DataType, Must, May, ShouldNot, MustNot + - Name: + AVP Name. String, validated as ALPHA *(ALPHA / DIGIT / "-") + per RFC 6733 section 3.2. + May start with a DIGIT (e.g., "3GPP-IMSI"). + - Code: + AVP Code. Integer, 0..4294967295. + - Section: + Section in relevant standard. String. + - DataType: + AVP Data Type. String, validated per basic and derived types in: + - RFC 6733 section 4.2 + - RFC 6733 section 4.3 + - RFC 7155 section 4.1 + - Must, May, ShouldNot, MustNot: + Flags, possibly comma or space separated: M, P, V + +- Comment row. First cell: + # Comment text 'Comment text' + #= '/*========*/' + # Blank line + +- Parameter row: + @Parameter,Value [, ...] + Supported Parameter terms: + standard Standard name. E.g. '3GPP TS 29.272', 'RFC 6733'. + vendor Vendor number. + +""" + +from __future__ import print_function +from __future__ import with_statement + +import abc +import csv +import collections +import json +import re +import optparse +import os +import sys + +CSV_COLUMN_NAMES = [ + 'name', + 'code', + 'section', + 'datatype', + 'must', + 'may', + 'shouldnot', + 'mustnot', +] + +DERIVED_TO_BASE = { + 'Address': 'OctetString', # RFC 6733 section 4.3.1 + 'Time': 'OctetString', # RFC 6733 section 4.3.1 + 'UTF8String': 'OctetString', # RFC 6733 section 4.3.1 + 'DiameterIdentity': 'OctetString', # RFC 6733 section 4.3.1 + 'DiameterURI': 'OctetString', # RFC 6733 section 4.3.1 + 'Enumerated': 'Integer32', # RFC 6733 section 4.3.1 + 'IPFilterRule': 'OctetString', # RFC 6733 section 4.3.1 + 'QoSFilterRule': 'OctetString', # RFC 7155 section 4.1.1 +} + +# See https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers +VENDOR_TO_NAME = { + 0: '', + 193: 'Ericsson', + 8164: 'Starent', + 10415: '3GPP', +} + + +class Avp(object): + """Store an AVP row.""" + + # Regex to validate avp-name per RFC 6733 section 3.2, + # with changes: + # - Allow avp-name to start with numbers (for 3GPP) + # - Allow '.' in avp-name, for existing dict_dcca_3gpp usage. +# TODO: if starts with digit, ensure contains a letter somewhere? + _name_re = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9-\.]*$') + + # Regex to validate flags: M, P, V, comma, space + _flags_re = re.compile(r'^[MPV, ]*$') + + __slots__ = CSV_COLUMN_NAMES + [ + 'filename', 'line_num', 'standard', 'vendor', ] + + def __init__(self, name, code, section, datatype, + must, may, shouldnot, mustnot, extra_cells=[], + filename='', line_num=0, standard='', vendor=0): + # Members from CSV row + self.name = name + self.code = int(code) + self.section = section + self.datatype = datatype + self.must = must + self.may = may + self.shouldnot = shouldnot + self.mustnot = mustnot + # Members from file state + self.filename = filename + self.line_num = line_num + self.standard = standard + self.vendor = vendor + # Validate CSV fields + if not self._name_re.match(self.name): + raise ValueError('Invalid AVP name "{}"'.format(self.name)) + if (self.code < 0 or self.code > 4294967295): + raise ValueError('AVP "{}" invalid code {}'.format( + self.name, self.code)) + if (self.datatype not in ( + 'OctetString', 'Integer32', 'Integer64', 'Unsigned32', + 'Unsigned64', 'Float32', 'Float64', 'Grouped') + and self.datatype not in DERIVED_TO_BASE): + raise ValueError('{} invalid data type "{}"'.format( + self.description(), self.datatype)) + # Validate flags + flags = collections.Counter() + for val, desc in [ + (self.must, 'Must'), + (self.may, 'May'), + (self.shouldnot, 'Should Not'), + (self.mustnot, 'Must Not'), + ]: + if not self._flags_re.match(val): + raise ValueError('{} invalid {} Flags "{}"'.format( + self.description(), desc, val)) + flags.update(val) + # Check occurrence of M,V in Must,May,ShouldNot,MustNot + for flag in 'MV': + # TODO: can AVP flags not appear at all? + # if flags[flag] == 0: + # raise ValueError('{} Flag "{}" not set'.format( + # self.description(), flag)) + if flags[flag] > 1: + raise ValueError('{} Flag "{}" set {} times'.format( + self.description(), flag, flags[flag])) + # Compare V presence against vendor + if 'V' in self.must: + if self.vendor == 0: + raise ValueError('{} Flag "V" set for vendor 0'.format( + self.description())) + else: + if self.vendor != 0: + raise ValueError('{} Flag "V" not set for vendor {}'.format( + self.description(), self.vendor)) + + @property + def __dict__(self): + return {s: getattr(self, s) for s in self.__slots__} + + def __eq__(self, other): + """Equality comparison of Avp instances. + Considered equal if name, vendor, code, datatype, and flags are equal. + """ + if other is self: + return True + if type(other) is not type(self): + return NotImplemented + return ( + other.name, other.vendor, other.code, other.datatype, + other.must, other.may, other.shouldnot, other.mustnot, + ) == ( + self.name, self.vendor, self.code, self.datatype, + self.must, self.may, self.shouldnot, self.mustnot, + ) + + def __ne__(self, other): + return not self == other + + def description(self): + return 'AVP "{}" ({})'.format(self.name, self.code) + + +class Processor(object): + """Interface for processor of Avp.""" + + __metaclass__ = abc.ABCMeta + + @classmethod + def cls_name(cls): + """Return the name, lower-case, without "processor" suffix.""" + suffix = 'processor' + name = cls.__name__.lower() + if name.endswith(suffix): + return name[:-len(suffix)] + return name + + @classmethod + def cls_desc(cls): + """Return the first line of the docstring.""" + if cls.__doc__ is None: + return "" + return cls.__doc__.split('\n')[0] + + @abc.abstractmethod + def filename(self, filename): + """Called when a file is opened.""" + pass + + @abc.abstractmethod + def avp(self, avp): + """Process a validated Avp.""" + pass + + @abc.abstractmethod + def comment(self, comment, filename, line_num): + """Process a comment row: + #comment, + """ + pass + + @abc.abstractmethod + def generate(self): + """Invoked after all rows processed.""" + pass + + @abc.abstractmethod + def parameter(self, name, value): + """Process a parameter row: + @name,value. + """ + pass + + +class DebugProcessor(Processor): + """Display the CSV parsing.""" + + def filename(self, filename): + print('File: {}'.format(filename)) + + def avp(self, avp): + avpdict = vars(avp) + print('AVP: {name}, {code}, {datatype}'.format(**avpdict)) + + def comment(self, comment, filename, line_num): + print('Comment: {}'.format(comment)) + + def generate(self): + print('Generate') + + def parameter(self, name, value): + print('Parameter: {} {}'.format(name, value)) + + +class NoopProcessor(Processor): + """Validate the CSV; no other output.""" + + def filename(self, filename): + pass + + def avp(self, avp): + pass + + def comment(self, comment, filename, line_num): + pass + + def generate(self): + pass + + def parameter(self, name, value): + pass + + +class FdcProcessor(Processor): + """Generate freeDiameter C code. + + Comment cells are parsed as: + # text comment /* text comment */ + #= /*==============*/ + # [blank line] + """ + + COMMENT_WIDTH = 64 + + class AvpFunction(object): + """Maintain per-function state to create DICT_AVP entries. + """ + + def __init__(self, name): + self.__name = name + self.__lines = [] + self.__derived = set() + + @property + def name(self): + """Return name.""" + return self.__name + + @property + def lines(self): + """Return all lines.""" + return self.__lines + + @lines.setter + def lines(self, value): + """Set to append a line.""" + self.__lines.append(value) + + @property + def derived(self): + """Return list of all derived values.""" + return list(self.__derived) + + @derived.setter + def derived(self, value): + """Set to store a derived type.""" + self.__derived.add(value) + + def __init__(self): + self._filenames = [] + self._functions = collections.OrderedDict() + + def filename(self, filename): + self._filenames.append(os.path.basename(filename)) + + def avp(self, avp): + comment = '{name}, {datatype}, code {code}'.format(**vars(avp)) + if avp.section != '': + comment += ', section {}'.format(avp.section) + self.add_comment(comment) + self.add('\t{') + self.add('\t\tstruct dict_avp_data data = {') +# TODO: remove comments? + self.add('\t\t\t{},\t/* Code */'.format(avp.code)) + self.add('\t\t\t{},\t/* Vendor */'.format(avp.vendor)) + self.add('\t\t\t\"{}\",\t/* Name */'.format(avp.name)) + self.add('\t\t\t{},\t/* Fixed flags */'.format( + self.build_flags(', '.join([avp.must, avp.mustnot])))) + self.add('\t\t\t{},\t/* Fixed flag values */'.format( + self.build_flags(avp.must))) +# TODO: add trailing comma? + self.add('\t\t\tAVP_TYPE_{}\t/* base type of data */'.format( + DERIVED_TO_BASE.get(avp.datatype, avp.datatype).upper())) + self.add('\t\t};') + avp_type = 'NULL' + if avp.datatype == 'Enumerated': + self.add('\t\tstruct dict_object\t*type;') + vendor_prefix = '' + if avp.vendor != 0: + vendor_prefix = '{}/'.format(VENDOR_TO_NAME[avp.vendor]) + self.add( + '\t\tstruct dict_type_data\t tdata = {{ AVP_TYPE_INTEGER32, ' + '"Enumerated({prefix}{name})", NULL, NULL, NULL }};'.format( + prefix=vendor_prefix, name=avp.name)) +# XXX: add enumerated values + self.add('\t\tCHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);') + avp_type = "type" + elif avp.datatype in DERIVED_TO_BASE: + avp_type = '{}_type'.format(avp.datatype) + self.derived(avp.datatype) + self.add('\t\tCHECK_dict_new(DICT_AVP, &data, {}, NULL);'.format( + avp_type)) +# TODO: remove ; on scope brace + self.add('\t};') + self.add('') + + def comment(self, comment, filename, line_num): + if comment == '': + self.add('') + elif comment == '=': + self.add_header() + elif comment.startswith(' '): + self.add_comment(comment[1:]) + else: + raise ValueError('Unsupported comment "{}"'.format(comment)) + + def generate(self): + fp = sys.stdout + self.write_introduction(fp) + for func in self._functions: + self.write_function(fp, self._functions[func]) + + def parameter(self, name, value): + pass + + # internal methods + + def current_avpfunction(self): + """Return current AvpFunction to update. + + Note: allows for easier future enhancement to generate separate + C functions per AVP groups such as: by csv file, standard, or vendor. + """ + name = 'add_avps' + if name not in self._functions: + self._functions[name] = self.AvpFunction(name) + return self._functions[name] + + def add(self, line): + self.current_avpfunction().lines = line + + def derived(self, value): + self.current_avpfunction().derived = value + + def build_c_token(self, value): + """Convert a string into a valid C token.""" + return re.sub(r'[^\w]', '_', value) + + def build_flags(self, flags): + result = [] + if 'V' in flags: + result.append('AVP_FLAG_VENDOR') + if 'M' in flags: + result.append('AVP_FLAG_MANDATORY') + if not result: + return '0'; + return ' |'.join(result) + + def add_comment(self, comment): + self.add(self.format_comment(comment)) + + def add_header(self): + self.add(self.format_header()) + + def format_comment(self, comment): + return '\t/* {:<{width}} */'.format(comment, width=self.COMMENT_WIDTH) + + def format_header(self): + return '\t/*={:=<{width}}=*/'.format('', width=self.COMMENT_WIDTH) + + def write_introduction(self, fp): + """Write the introduction to the generated file.""" + fp.write('''\ +/* +Generated by: +\tcsv_to_fd -p {processor} {files} + +Do not modify; modify the source .csv files instead. +*/ + +#include <freeDiameter/extension.h> + +#define CHECK_dict_new( _type, _data, _parent, _ref ) \\ +\tCHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, \ +(_type), (_data), (_parent), (_ref)) ); + +#define CHECK_dict_search( _type, _criteria, _what, _result ) \\ +\tCHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, \ +(_type), (_criteria), (_what), (_result), ENOENT) ); +'''.format( + processor=self.cls_name(), + files=' '.join(self._filenames))) + + def write_function(self, fp, avpfunction): + """Generate a function from AvpFunction.""" + function = self.build_c_token(avpfunction.name) + # Function start + fp.write('''\ + +int {}() +{{ +'''.format(function)) + + # Create variables used by derived type validation + for derived in avpfunction.derived: + fp.write('''\ +\tstruct dict_object * {name}_type = NULL; +\tCHECK_dict_search(DICT_TYPE, TYPE_BY_NAME, "{name}", &{name}_type); + +'''.format(name=derived)) + + # Write generated DICT_AVP creation + fp.write('\n'.join(avpfunction.lines)) + + # Write function end + fp.write('''\ + +\treturn 0; +}} /* {}() */ +'''.format(function)) + + +class JsonProcessor(Processor): + """Generate freeDiameter JSON object. + """ + + def __init__(self): + self.avps = [] + + def filename(self, filename): + pass + + def avp(self, avp): + flags = collections.OrderedDict([ + ('Must', self.build_flags(avp.must)), + ('MustNot', self.build_flags(avp.mustnot)), + ]) + row = collections.OrderedDict([ + ('Code', avp.code), + ('Flags', flags), + ('Name', avp.name), + ('Type', avp.datatype), + ('Vendor', avp.vendor), + ]) + self.avps.append(row) + + def comment(self, comment, filename, line_num): + pass + + def generate(self): + doc = {"AVPs": self.avps} + print(json.dumps(doc, indent=2)) + + def parameter(self, name, value): + pass + + def build_flags(self, flags): + result = [] + if 'V' in flags: + result.append('V') + if 'M' in flags: + result.append('M') + return ''.join(result) + + +def avp_conflict(description, avp, conflict): + """Raise error for duplicate or conflicting AVPs. + """ + if avp == conflict: + raise ValueError( + '{} {} duplicated in' + ' file "{}" line {}'.format( + avp.description(), description, + conflict.filename, conflict.line_num)) + else: + raise ValueError( + '{} {} conflicts with {}' + ' in file "{}" line {}'.format( + avp.description(), description, + conflict.description(), + conflict.filename, conflict.line_num)) + + +def main(): + """Main application entry. + """ + + # Build dict of name: NameProcessor + processors = { + cls.cls_name(): cls + for cls in Processor.__subclasses__() + } + + # Build Processor name to desc + processor_help = '\n'.join( + [' {:8} {}'.format(key, processors[key].cls_desc()) + for key in sorted(processors)]) + + # Custom OptionParser with improved help + class MyParser(optparse.OptionParser): + """Custom OptionParser without epilog formatting.""" + def format_help(self, formatter=None): + return """\ +{} +Supported PROCESSOR options: +{} +""".format( + optparse.OptionParser.format_help(self, formatter), + processor_help) + + # Parse options + parser = MyParser( + usage='%prog [-h] [-p PROCESSOR] FILE ...', + description="""\ +Convert CSV files FILE ... containing RADIUS or Diameter AVP tables +into various formats using the specified processor PROCESSOR. +""") + parser.add_option( + '-p', '--processor', + default='noop', + help='AVP processor. One of: {}. [%default]'.format( + ', '.join(processors.keys()))) + (opts, args) = parser.parse_args() + if len(args) < 1: + parser.error('Incorrect number of arguments. Use -h for help.') + + # Find processor + try: + avpproc = processors[opts.processor]() + except KeyError as e: + parser.error('Unknown processor "{}".'.format(opts.processor)) + + # dict of [vendor][code] : Avp + avp_codes = collections.defaultdict(dict) + + # dict of [vendor][name] : Avp + avp_names = collections.defaultdict(dict) + + # Process files + for filename in args: + avpproc.filename(filename) + with open(filename, 'r') as csvfile: + csvdata = csv.DictReader(csvfile, CSV_COLUMN_NAMES, + restkey='extra_cells', restval='') + standard = '' + vendor = 0 + errors = [] + for row in csvdata: + try: + if csvdata.restkey in row: + raise ValueError('Extra cells: {}'.format( + ','.join(row[csvdata.restkey]))) + if row['name'] in (None, '', 'Attribute Name'): + continue + elif row['name'].startswith('#'): + comment = row['name'][1:] + avpproc.comment(comment, filename, csvdata.line_num) + elif row['name'].startswith('@'): + parameter = row['name'][1:] + value = row['code'] + if False: + pass + elif parameter == 'standard': + standard = value + elif parameter == 'vendor': + vendor = int(value) + else: + raise ValueError('Unknown parameter "{}"'.format( + parameter)) + avpproc.parameter(parameter, value) + else: + avp = Avp(filename=filename, line_num=csvdata.line_num, + standard=standard, vendor=vendor, + **row) + # Ensure AVP vendor/code not already defined + if avp.code in avp_codes[avp.vendor]: + conflict = avp_codes[avp.vendor][avp.code] + avp_conflict('Code', avp, conflict) + avp_codes[avp.vendor][avp.code] = avp + # Ensure AVP vendor/name not already defined + if avp.name in avp_names[avp.vendor]: + conflict = avp_names[avp.vendor][avp.name] + avp_conflict('Name', avp, conflict) + avp_names[avp.vendor][avp.name] = avp + # Process AVP + avpproc.avp(avp) + except (TypeError, ValueError) as e: + errors.append('CSV file "{}" line {}: {}\n'.format( + filename, csvdata.line_num, e)) + if errors: + sys.stderr.write(''.join(errors)) + sys.exit(1) + + # Generate result + avpproc.generate() + + +if __name__ == '__main__': + main() + +# vim: set et sw=4 sts=4 : diff --git a/contrib/tools/diameter-rfcs.csv b/contrib/tools/diameter-rfcs.csv new file mode 100644 index 0000000..ed25e4b --- /dev/null +++ b/contrib/tools/diameter-rfcs.csv @@ -0,0 +1,202 @@ +Attribute Name,Code,Section defined,Value Type,MUST,MAY,SHOULD NOT,MUST NOT
+@vendor,0,,,,,,
+@standard,RFC 3588,,,,,,
+#=,,,,,,,
+# RFC 3588 - Diameter #,,,,,,,
+#=,,,,,,,
+#,,,,,,,
+Acct-Interim-Interval,85,9.8.2,Unsigned32,M,P,,V
+Accounting-Realtime-Required,483,9.8.7,Enumerated,M,P,,V
+Acct-Multi-Session-Id,50,9.8.5,UTF8String,M,P,,V
+Accounting-Record-Number,485,9.8.3,Unsigned32,M,P,,V
+Accounting-Record-Type,480,9.8.1,Enumerated,M,P,,V
+Accounting-Session-Id,44,9.8.4,OctetString,M,P,,V
+Accounting-Sub-Session-Id,287,9.8.6,Unsigned64,M,P,,V
+Acct-Application-Id,259,6.9,Unsigned32,M,P,,V
+Auth-Application-Id,258,6.8,Unsigned32,M,P,,V
+Auth-Request-Type,274,8.7,Enumerated,M,P,,V
+Authorization-Lifetime,291,8.9,Unsigned32,M,P,,V
+Auth-Grace-Period,276,8.10,Unsigned32,M,P,,V
+Auth-Session-State,277,8.11,Enumerated,M,P,,V
+Re-Auth-Request-Type,285,8.12,Enumerated,M,P,,V
+Class,25,8.20,OctetString,M,P,,V
+Destination-Host,293,6.5,DiameterIdentity,M,P,,V
+Destination-Realm,283,6.6,DiameterIdentity,M,P,,V
+Disconnect-Cause,273,5.4.3,Enumerated,M,P,,V
+E2E-Sequence-AVP,300,6.15,Grouped,M,P,,V
+Error-Message,281,7.3,UTF8String,,P,,"V,M"
+Error-Reporting-Host,294,7.4,DiameterIdentity,,P,,"V,M"
+Event-Timestamp,55,8.21,Time,M,P,,V
+Experimental-Result,297,7.6,Grouped,M,P,,V
+Experimental-Result-Code,298,7.7,Unsigned32,M,P,,V
+Failed-AVP,279,7.5,Grouped,M,P,,V
+Firmware-Revision,267,5.3.4,Unsigned32,,,,"P,V,M"
+Host-IP-Address,257,5.3.5,Address,M,P,,V
+Inband-Security-Id,299,6.10,Unsigned32,M,P,,V
+Multi-Round-Time-Out,272,8.19,Unsigned32,M,P,,V
+Origin-Host,264,6.3,DiameterIdentity,M,P,,V
+Origin-Realm,296,6.4,DiameterIdentity,M,P,,V
+Origin-State-Id,278,8.16,Unsigned32,M,P,,V
+Product-Name,269,5.3.7,UTF8String,,,,"P,V,M"
+Proxy-Host,280,6.7.3,DiameterIdentity,M,,,"P,V"
+Proxy-Info,284,6.7.2,Grouped,M,,,"P,V"
+Proxy-State,33,6.7.4,OctetString,M,,,"P,V"
+Redirect-Host,292,6.12,DiameterURI,M,P,,V
+Redirect-Host-Usage,261,6.13,Enumerated,M,P,,V
+Redirect-Max-Cache-Time,262,6.14,Unsigned32,M,P,,V
+Result-Code,268,7.1,Unsigned32,M,P,,V
+Route-Record,282,6.7.1,DiameterIdentity,M,,,"P,V"
+Session-Id,263,8.8,UTF8String,M,P,,V
+Session-Timeout,27,8.13,Unsigned32,M,P,,V
+Session-Binding,270,8.17,Unsigned32,M,P,,V
+Session-Server-Failover,271,8.18,Enumerated,M,P,,V
+Supported-Vendor-Id,265,5.3.6,Unsigned32,M,P,,V
+Termination-Cause,295,8.15,Enumerated,M,P,,V
+User-Name,1,8.14,UTF8String,M,P,,V
+Vendor-Id,266,5.3.3,Unsigned32,M,P,,V
+Vendor-Specific-Application-Id,260,6.11,Grouped,M,P,,V
+@standard,RFC 4005,,,,,,
+#=,,,,,,,
+# RFC 4005 - NAS #,,,,,,,
+#=,,,,,,,
+#,,,,,,,
+NAS-Port,5,4.2,Unsigned32,M,P,,V
+NAS-Port-Id,87,4.3,UTF8String,M,P,,V
+NAS-Port-Type,61,4.4,Enumerated,M,P,,V
+Called-Station-Id,30,4.5,UTF8String,M,P,,V
+Calling-Station-Id,31,4.6,UTF8String,M,P,,V
+Connect-Info,77,4.7,UTF8String,M,P,,V
+Originating-Line-Info,94,4.8,OctetString,,"M,P",,V
+Reply-Message,18,4.9,UTF8String,M,P,,V
+User-Password,2,5.1,OctetString,M,P,,V
+Password-Retry,75,5.2,Unsigned32,M,P,,V
+Prompt,76,5.3,Enumerated,M,P,,V
+CHAP-Auth,402,5.4,Grouped,M,P,,V
+CHAP-Algorithm,403,5.5,Enumerated,M,P,,V
+CHAP-Ident,404,5.6,OctetString,M,P,,V
+CHAP-Response,405,5.7,OctetString,M,P,,V
+CHAP-Challenge,60,5.8,OctetString,M,P,,V
+ARAP-Password,70,5.9,OctetString,M,P,,V
+ARAP-Challenge-Response,84,5.10,OctetString,M,P,,V
+ARAP-Security,73,5.11,Unsigned32,M,P,,V
+ARAP-Security-Data,74,5.12,OctetString,M,P,,V
+Service-Type,6,6.1,Enumerated,M,P,,V
+Callback-Number,19,6.2,UTF8String,M,P,,V
+Callback-Id,20,6.3,UTF8String,M,P,,V
+Idle-Timeout,28,6.4,Unsigned32,M,P,,V
+Port-Limit,62,6.5,Unsigned32,M,P,,V
+NAS-Filter-Rule,400,6.6,IPFilterRule,M,P,,V
+Filter-Id,11,6.7,UTF8String,M,P,,V
+Configuration-Token,78,6.8,OctetString,M,,,"P,V"
+QoS-Filter-Rule,407,6.9,QoSFilterRule,,,,
+Framed-Protocol,7,6.10.1,Enumerated,M,P,,V
+Framed-Routing,10,6.10.2,Enumerated,M,P,,V
+Framed-MTU,12,6.10.3,Unsigned32,M,P,,V
+Framed-Compression,13,6.10.4,Enumerated,M,P,,V
+Framed-IP-Address,8,6.11.1,OctetString,M,P,,V
+Framed-IP-Netmask,9,6.11.2,OctetString,M,P,,V
+Framed-Route,22,6.11.3,UTF8String,M,P,,V
+Framed-Pool,88,6.11.4,OctetString,M,P,,V
+Framed-Interface-Id,96,6.11.5,Unsigned64,M,P,,V
+Framed-IPv6-Prefix,97,6.11.6,OctetString,M,P,,V
+Framed-IPv6-Route,99,6.11.7,UTF8String,M,P,,V
+Framed-IPv6-Pool,100,6.11.8,OctetString,M,P,,V
+Framed-IPX-Network,23,6.12.1,UTF8String,M,P,,V
+Framed-Appletalk-Link,37,6.13.1,Unsigned32,M,P,,V
+Framed-Appletalk-Network,38,6.13.2,Unsigned32,M,P,,V
+Framed-Appletalk-Zone,39,6.13.3,OctetString,M,P,,V
+ARAP-Features,71,6.14.1,OctetString,M,P,,V
+ARAP-Zone-Access,72,6.14.2,Enumerated,M,P,,V
+Login-IP-Host,14,6.15.1,OctetString,M,P,,V
+Login-IPv6-Host,98,6.15.2,OctetString,M,P,,V
+Login-Service,15,6.15.3,Enumerated,M,P,,V
+Login-TCP-Port,16,6.16.1,Unsigned32,M,P,,V
+Login-LAT-Service,34,6.17.1,OctetString,M,P,,V
+Login-LAT-Node,35,6.17.2,OctetString,M,P,,V
+Login-LAT-Group,36,6.17.3,OctetString,M,P,,V
+Login-LAT-Port,63,6.17.4,OctetString,M,P,,V
+Tunneling,401,7.1,Grouped,M,P,,V
+Tunnel-Type,64,7.2,Enumerated,M,P,,V
+Tunnel-Medium-Type,65,7.3,Enumerated,M,P,,V
+Tunnel-Client-Endpoint,66,7.4,UTF8String,M,P,,V
+Tunnel-Server-Endpoint,67,7.5,UTF8String,M,P,,V
+Tunnel-Password,69,7.6,OctetString,M,P,,V
+Tunnel-Private-Group-Id,81,7.7,OctetString,M,P,,V
+Tunnel-Assignment-Id,82,7.8,OctetString,M,P,,V
+Tunnel-Preference,83,7.9,Unsigned32,M,P,,V
+Tunnel-Client-Auth-Id,90,7.10,UTF8String,M,P,,V
+Tunnel-Server-Auth-Id,91,7.11,UTF8String,M,P,,V
+Accounting-Input-Octets,363,8.1,Unsigned64,M,P,,V
+Accounting-Output-Octets,364,8.2,Unsigned64,M,P,,V
+Accounting-Input-Packets,365,8.3,Unsigned64,M,P,,V
+Accounting-Output-Packets,366,8.4,Unsigned64,M,P,,V
+Acct-Session-Time,46,8.5,Unsigned32,M,P,,V
+Acct-Authentic,45,8.6,Enumerated,M,P,,V
+Acounting-Auth-Method,406,8.7,Enumerated,M,P,,V
+Acct-Delay-Time,41,8.8,Unsigned32,M,P,,V
+Acct-Link-Count,51,8.9,Unsigned32,M,P,,V
+Acct-Tunnel-Connection,68,8.10,OctetString,M,P,,V
+Acct-Tunnel-Packets-Lost,86,8.11,Unsigned32,M,P,,V
+NAS-Identifier,32,9.3.1,UTF8String,M,P,,V
+NAS-IP-Address,4,9.3.2,OctetString,M,P,,V
+NAS-IPv6-Address,95,9.3.3,OctetString,M,P,,V
+State,24,9.3.4,OctetString,M,P,,V
+# Termination-Cause already in RFC 3588,295,9.3.5,Enumerated,M,P,,V
+#,,,,,,,
+Origin-AAA-Protocol,408,9.3.6,Enumerated,M,P,,V
+@standard,RFC 4006,,,,,,
+#=,,,,,,,
+# RFC 4006 - DCCA #,,,,,,,
+#=,,,,,,,
+#,,,,,,,
+CC-Correlation-Id,411,8.1,OctetString,,"P,M",,V
+CC-Input-Octets,412,8.24,Unsigned64,M,P,,V
+CC-Money,413,8.22,Grouped,M,P,,V
+CC-Output-Octets,414,8.25,Unsigned64,M,P,,V
+CC-Request-Number,415,8.2,Unsigned32,M,P,,V
+CC-Request-Type,416,8.3,Enumerated,M,P,,V
+CC-Service-Specific-Units,417,8.26,Unsigned64,M,P,,V
+CC-Session-Failover,418,8.4,Enumerated,M,P,,V
+CC-Sub-Session-Id,419,8.5,Unsigned64,M,P,,V
+CC-Time,420,8.21,Unsigned32,M,P,,V
+CC-Total-Octets,421,8.23,Unsigned64,M,P,,V
+CC-Unit-Type,454,8.32,Enumerated,M,P,,V
+Check-Balance-Result,422,8.6,Enumerated,M,P,,V
+Cost-Information,423,8.7,Grouped,M,P,,V
+Cost-Unit,424,8.12,UTF8String,M,P,,V
+Credit-Control,426,8.13,Enumerated,M,P,,V
+Credit-Control-Failure-Handling,427,8.14,Enumerated,M,P,,V
+Currency-Code,425,8.11,Unsigned32,M,P,,V
+Direct-Debiting-Failure-Handling,428,8.15,Enumerated,M,P,,V
+Exponent,429,8.9,Integer32,M,P,,V
+Final-Unit-Action,449,8.35,Enumerated,M,P,,V
+Final-Unit-Indication,430,8.34,Grouped,M,P,,V
+Granted-Service-Unit,431,8.17,Grouped,M,P,,V
+G-S-U-Pool-Identifier,453,8.31,Unsigned32,M,P,,V
+G-S-U-Pool-Reference,457,8.30,Grouped,M,P,,V
+Multiple-Services-Credit-Control,456,8.16,Grouped,M,P,,V
+Multiple-Services-Indicator,455,8.40,Enumerated,M,P,,V
+Rating-Group,432,8.29,Unsigned32,M,P,,V
+Redirect-Address-Type,433,8.38,Enumerated,M,P,,V
+Redirect-Server,434,8.37,Grouped,M,P,,V
+Redirect-Server-Address,435,8.39,UTF8String,M,P,,V
+Requested-Action,436,8.41,Enumerated,M,P,,V
+Requested-Service-Unit,437,8.18,Grouped,M,P,,V
+Restriction-Filter-Rule,438,8.36,IPFilterRule,M,P,,V
+Service-Context-Id,461,8.42,UTF8String,M,P,,V
+Service-Identifier,439,8.28,Unsigned32,M,P,,V
+Service-Parameter-Info,440,8.43,Grouped,,"P,M",,V
+Service-Parameter-Type,441,8.44,Unsigned32,,"P,M",,V
+Service-Parameter-Value,442,8.45,OctetString,,"P,M",,V
+Subscription-Id,443,8.46,Grouped,M,P,,V
+Subscription-Id-Data,444,8.48,UTF8String,M,P,,V
+Subscription-Id-Type,450,8.47,Enumerated,M,P,,V
+Tariff-Change-Usage,452,8.27,Enumerated,M,P,,V
+Tariff-Time-Change,451,8.20,Time,M,P,,V
+Unit-Value,445,8.8,Grouped,M,P,,V
+Used-Service-Unit,446,8.19,Grouped,M,P,,V
+User-Equipment-Info,458,8.49,Grouped,,"P,M",,V
+User-Equipment-Info-Type,459,8.50,Enumerated,,"P,M",,V
+User-Equipment-Info-Value,460,8.51,OctetString,,"P,M",,V
+Value-Digits,447,8.10,Integer64,M,P,,V
+Validity-Time,448,8.33,Unsigned32,M,P,,V
diff --git a/contrib/tools/grep_fd_dict_dump b/contrib/tools/grep_fd_dict_dump new file mode 100755 index 0000000..375fb5e --- /dev/null +++ b/contrib/tools/grep_fd_dict_dump @@ -0,0 +1,11 @@ +#!/bin/sh + +# Grep stdin for the output of fd_dict_dump() and reformat to remove +# pointer addresses. Use to post-process the output of dict_dump.fdx +# into a format that's diff-able between freeDiameter invocations. + +egrep '^ *{dict|VENDOR|APPLICATION|TYPE|ENUMVAL|AVP|COMMAND|RULE' \ + | sed \ + -e 's/{dict.*}(@0x[^ ]*): //' \ + -e 's/{dict(0x[^ ]*) : \(.*\)}/\1/' \ + -e 's/p:[^ ]* //' diff --git a/contrib/tools/org_to_csv b/contrib/tools/org_to_csv new file mode 100755 index 0000000..e87f6ad --- /dev/null +++ b/contrib/tools/org_to_csv @@ -0,0 +1,19 @@ +#!/usr/bin/env python + +""" +Convert |-separated 11-column .org files to CSV, +with first and last empty columns ignored. +""" + +import csv +import fileinput +import re +import sys + +csvout = csv.writer(sys.stdout) +for line in fileinput.input(): + row = re.split(r'\s*\|\s*', line) + row.extend([''] * (10 - len(row))) + csvout.writerow(row[1:10]) + +# vim: set et sw=4 sts=4 : diff --git a/contrib/tools/org_to_fd.pl b/contrib/tools/org_to_fd.pl index 96c06b7..a0825d6 100755 --- a/contrib/tools/org_to_fd.pl +++ b/contrib/tools/org_to_fd.pl @@ -1,12 +1,15 @@ #!/usr/bin/env perl use strict; +use File::Basename; use Getopt::Std; +my ($progname) = basename($0); + our ($opt_V, $opt_v); -# default to 3GPP -my ($vendor) = 10415; -my ($vendor_name) = "3GPP"; +# default to Base +my ($vendor) = 0; +my ($vendor_name) = ""; sub convert_must_to_flags($) { my ($allmust) = @_; @@ -21,7 +24,7 @@ sub base_type($) { my ($type) = @_; return "AVP_TYPE_GROUPED" if ($type =~ m/Grouped/); - return "AVP_TYPE_OCTETSTRING" if ($type =~ m/(Address|DiameterIdentity|DiameterURI|OctetString|IPFilterRule|Time|UTF8String)/); + return "AVP_TYPE_OCTETSTRING" if ($type =~ m/(Address|DiameterIdentity|DiameterURI|OctetString|IPFilterRule|Time|UTF8String|QoSFilterRule)/); return "AVP_TYPE_INTEGER32" if ($type =~ m/Enumerated|Integer32/); return "AVP_TYPE_INTEGER64" if ($type =~ m/Integer64/); return "AVP_TYPE_UNSIGNED32" if ($type =~ m/Unsigned32/); @@ -29,7 +32,19 @@ sub base_type($) { return "AVP_TYPE_FLOAT32" if ($type =~ m/Float32/); return "AVP_TYPE_FLOAT64" if ($type =~ m/Float64/); - return "UNKNOWN TYPE: $type"; + die("unknown type '$type'"); +} + + +my ($comment_width) = 64; + +sub print_header() { + printf "\t/*=%s=*/\n", '=' x $comment_width; +} + +sub print_comment($) { + my ($str) = @_; + printf "\t/* %-*s */\n", $comment_width, $str; } sub print_insert($$) { @@ -39,8 +54,8 @@ sub print_insert($$) { if ($type =~ m/(Grouped|OctetString|Integer32|Integer64|Unsigned32|Unsigned64|Float32|Float64)/) { $avp_type = "NULL"; } elsif ($type =~ m/Enumerated/) { - print "\t\tstruct dict_object *type;\n"; - print "\t\tstruct dict_type_data tdata = { AVP_TYPE_INTEGER32, \"Enumerated(" . ($vendor_name ? "$vendor_name/" : "") ."$name)\", NULL, NULL, NULL };\n"; + print "\t\tstruct dict_object\t*type;\n"; + print "\t\tstruct dict_type_data\t tdata = { AVP_TYPE_INTEGER32, \"Enumerated(" . ($vendor_name ? "$vendor_name/" : "") ."$name)\", NULL, NULL, NULL };\n"; # XXX: add enumerated values print "\t\tCHECK_dict_new(DICT_TYPE, &tdata, NULL, &type);\n"; $avp_type = "type"; @@ -52,8 +67,8 @@ sub print_insert($$) { } sub usage($) { - die("usage: org_to_fd.pl [-V vendor_name -v vendor_code] [file ...]\n"); - exit(@_); + print STDERR "usage: $progname [-V vendor_name] [-v vendor_code] [file ...]\n"; + exit(1); } getopts("V:v:") || usage(1); @@ -61,29 +76,45 @@ getopts("V:v:") || usage(1); if (defined($opt_v)) { $vendor = $opt_v; if (!defined($opt_V)) { - usage(1); + usage(1); } $vendor_name = $opt_V; } -print "\t/* The following is created automatically. Do not modify. */\n"; -print "\t/* Changes will be lost during the next update. Modify the source org file instead. */\n\n"; +print_header(); +print_comment("Start of generated data."); +print_comment(""); +print_comment("The following is created automatically with:"); +print_comment(" org_to_fd.pl -V '$vendor_name' -v $vendor"); +print_comment("Changes will be lost during the next update."); +print_comment("Do not modify; modify the source .org file instead."); +print_header(); +print "\n"; while (<>) { - my ($dummy, $name, $code, $section, $type, $must, $may, $shouldnot, $mustnot, $encr) = split /\|/; + my ($dummy, $name, $code, $section, $type, $must, $may, $shouldnot, $mustnot, $encr) = split /\s*\|\s*/; next if ($name =~ m/Attribute Name/); - if ($name =~ m/ # (.*)/) { - print "\t/* $1 */\n"; + if ($name =~ m/# (.*)/) { + print_comment($1); + next; + } + if ($name =~ m/#/) { + print("\n"); next; } - - $name =~ s/ *//g; - $code =~ s/ *//g; - $type =~ s/ *//g; + if ($name =~ m/\s/) { + die("name '$name' contains space"); + } - print "\t/* $name */\n\t{\n\t\tstruct dict_avp_data data = {\n"; + my ($desc) = $name; + $desc .= ", " . $type; + $desc .= ", code " . $code; + $desc .= ", section " . $section if $section ne ""; + print_comment($desc); + print "\t{\n"; + print "\t\tstruct dict_avp_data data = {\n"; print "\t\t\t$code,\t/* Code */\n"; print "\t\t\t$vendor,\t/* Vendor */\n"; print "\t\t\t\"$name\",\t/* Name */\n"; @@ -94,3 +125,7 @@ while (<>) { print_insert($type, $name); print "\t};\n\n"; } + +print_header(); +print_comment("End of generated data."); +print_header(); |
