mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr.git
synced 2025-11-02 05:03:31 +00:00
Compare commits
42 Commits
osmith/aut
...
1.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed939154f8 | ||
|
|
268a33e58b | ||
|
|
8804a2335a | ||
|
|
c27bc90ae6 | ||
|
|
f80ab768d0 | ||
|
|
5decd49713 | ||
|
|
c5f034b13d | ||
|
|
01155eaee6 | ||
|
|
e4143234c8 | ||
|
|
6263cf350a | ||
|
|
63eefabdde | ||
|
|
7a4765325d | ||
|
|
53f6067e97 | ||
|
|
8023d246f2 | ||
|
|
00aea9e0d9 | ||
|
|
023c6524a2 | ||
|
|
1d02b51a68 | ||
|
|
78a9f92fda | ||
|
|
ad8866e86e | ||
|
|
6156950634 | ||
|
|
65f51535d0 | ||
|
|
386381662c | ||
|
|
777860ddb5 | ||
|
|
1d0a030aa4 | ||
|
|
3ca9a1fd4f | ||
|
|
b74769f1b4 | ||
|
|
140dffd8f7 | ||
|
|
d63ec88dba | ||
|
|
e427bb299f | ||
|
|
d456fced21 | ||
|
|
c772e525ef | ||
|
|
83a41471da | ||
|
|
b4f25a0d1a | ||
|
|
b246580900 | ||
|
|
0c13953ed0 | ||
|
|
77a1bf66e6 | ||
|
|
37a5b70195 | ||
|
|
4d7cbfcc9a | ||
|
|
bfeea69cab | ||
|
|
3f9d1977df | ||
|
|
608e2e483f | ||
|
|
60673e7f77 |
16
.gitignore
vendored
16
.gitignore
vendored
@@ -70,3 +70,19 @@ doc/manuals/common
|
||||
doc/manuals/build
|
||||
|
||||
contrib/osmo-hlr.spec
|
||||
/debian/.debhelper/
|
||||
/debian/libosmo-gsup-client-dev/
|
||||
/debian/files
|
||||
/debian/autoreconf.after
|
||||
/debian/autoreconf.before
|
||||
/debian/libosmo-gsup-client0/
|
||||
/debian/libosmo-mslookup0/
|
||||
/debian/osmo-hlr-dbg/
|
||||
/debian/tmp/
|
||||
/doc/manuals/vty/hlr_vty_reference.xml
|
||||
/debian/libosmo-mslookup-dev/
|
||||
/debian/osmo-hlr-doc/
|
||||
/debian/osmo-hlr/
|
||||
/debian/osmo-mslookup-utils/
|
||||
/debian/*.log
|
||||
/debian/*.substvars
|
||||
|
||||
@@ -23,10 +23,9 @@ GIT Repository
|
||||
|
||||
You can clone from the official osmo-hlr.git repository using
|
||||
|
||||
git clone git://git.osmocom.org/osmo-hlr.git
|
||||
git clone https://git.osmocom.org/osmo-hlr.git
|
||||
git clone https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr
|
||||
|
||||
There is a cgit interface at https://git.osmocom.org/osmo-hlr/
|
||||
There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr>
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
14
configure.ac
14
configure.ac
@@ -41,11 +41,11 @@ PKG_PROG_PKG_CONFIG([0.20])
|
||||
|
||||
PKG_CHECK_MODULES(TALLOC, [talloc >= 2.0.1])
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.1.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.4.0)
|
||||
|
||||
PKG_CHECK_MODULES(SQLITE3, sqlite3)
|
||||
|
||||
@@ -93,6 +93,7 @@ AC_ARG_ENABLE(werror,
|
||||
if test x"$werror" = x"yes"
|
||||
then
|
||||
WERROR_FLAGS="-Werror"
|
||||
WERROR_FLAGS+=" -Werror=implicit-int -Werror=int-conversion -Werror=old-style-definition"
|
||||
WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
|
||||
WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
|
||||
CFLAGS="$CFLAGS $WERROR_FLAGS"
|
||||
@@ -107,7 +108,7 @@ if test "x$enable_ext_tests" = "xyes" ; then
|
||||
AM_PATH_PYTHON
|
||||
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
|
||||
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
|
||||
AC_MSG_ERROR([Please install git://osmocom.org/python/osmo-python-tests to run the VTY/CTRL tests.])
|
||||
AC_MSG_ERROR([Please install https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests to run the VTY/CTRL tests.])
|
||||
fi
|
||||
fi
|
||||
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
|
||||
@@ -206,7 +207,6 @@ AC_OUTPUT(
|
||||
tests/Makefile
|
||||
tests/auc/Makefile
|
||||
tests/auc/gen_ts_55_205_test_sets/Makefile
|
||||
tests/gsup_server/Makefile
|
||||
tests/gsup/Makefile
|
||||
tests/db/Makefile
|
||||
tests/db_upgrade/Makefile
|
||||
|
||||
@@ -27,7 +27,7 @@ check_upgrade_required() {
|
||||
msg "nothing to do (no existing database)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
if open_db 2>/dev/null; then
|
||||
msg "nothing to do (database version is up to date)"
|
||||
exit 0
|
||||
@@ -70,14 +70,14 @@ create_backup() {
|
||||
upgrade() {
|
||||
msg "performing database upgrade"
|
||||
osmo-hlr-db-tool -s -U -l "$DB" create
|
||||
|
||||
|
||||
if ! open_db 2>/dev/null; then
|
||||
err "failed to open the database after upgrade"
|
||||
err "osmo-hlr-db-tool output:"
|
||||
open_db
|
||||
# exit because of "set -e"
|
||||
fi
|
||||
|
||||
|
||||
msg "database upgrade successful"
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ BuildRequires: python3
|
||||
%if 0%{?suse_version}
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%endif
|
||||
BuildRequires: pkgconfig(libosmoabis) >= 1.1.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.5.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.5.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.5.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.5.0
|
||||
BuildRequires: pkgconfig(libosmoabis) >= 1.4.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.8.0
|
||||
BuildRequires: pkgconfig(sqlite3)
|
||||
BuildRequires: pkgconfig(talloc) >= 2.0.1
|
||||
# only needed for populate_hlr_db.pl
|
||||
@@ -75,19 +75,19 @@ and External USSD Entities (EUSEs) using this library to implement clients.
|
||||
This subpackage contains libraries and header files for developing
|
||||
applications that want to make use of libosmo-gsup-client.
|
||||
|
||||
%package -n libosmo-mslookup0
|
||||
%package -n libosmo-mslookup1
|
||||
Summary: Osmocom MS lookup library
|
||||
License: GPL-2.0-or-later
|
||||
Group: System/Libraries
|
||||
|
||||
%description -n libosmo-mslookup0
|
||||
%description -n libosmo-mslookup1
|
||||
This shared library contains routines for looking up mobile subscribers.
|
||||
|
||||
%package -n libosmo-mslookup-devel
|
||||
Summary: Development files for the Osmocom MS lookup library
|
||||
License: GPL-2.0-or-later
|
||||
Group: Development/Libraries/C and C++
|
||||
Requires: libosmo-mslookup0 = %{version}
|
||||
Requires: libosmo-mslookup1 = %{version}
|
||||
|
||||
%description -n libosmo-mslookup-devel
|
||||
This shared library contains routines for looking up mobile subscribers.
|
||||
@@ -146,8 +146,8 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
|
||||
%post -n libosmo-gsup-client0 -p /sbin/ldconfig
|
||||
%postun -n libosmo-gsup-client0 -p /sbin/ldconfig
|
||||
%post -n libosmo-mslookup0 -p /sbin/ldconfig
|
||||
%postun -n libosmo-mslookup0 -p /sbin/ldconfig
|
||||
%post -n libosmo-mslookup1 -p /sbin/ldconfig
|
||||
%postun -n libosmo-mslookup1 -p /sbin/ldconfig
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
@@ -179,8 +179,8 @@ make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
%{_libdir}/libosmo-gsup-client.so
|
||||
%{_libdir}/pkgconfig/libosmo-gsup-client.pc
|
||||
|
||||
%files -n libosmo-mslookup0
|
||||
%{_libdir}/libosmo-mslookup.so.0*
|
||||
%files -n libosmo-mslookup1
|
||||
%{_libdir}/libosmo-mslookup.so.1*
|
||||
|
||||
%files -n libosmo-mslookup-devel
|
||||
%dir %{_includedir}/osmocom
|
||||
|
||||
@@ -5,8 +5,11 @@ Documentation=https://osmocom.org/projects/osmo-hlr/wiki/OsmoHLR
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
StateDirectory=osmocom
|
||||
WorkingDirectory=%S/osmocom
|
||||
ExecStart=/usr/bin/osmo-hlr -c /etc/osmocom/osmo-hlr.cfg -l /var/lib/osmocom/hlr.db
|
||||
RestartSec=2
|
||||
ProtectHome=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
88
debian/changelog
vendored
88
debian/changelog
vendored
@@ -1,3 +1,91 @@
|
||||
osmo-hlr (1.6.0) unstable; urgency=medium
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* db_auc: hexparse_stmt(): check value returned by osmo_hexparse()
|
||||
|
||||
[ Max ]
|
||||
* Set working directory in systemd service file
|
||||
* Ignore .deb build byproducts
|
||||
* Debian: bump copyright year to match current
|
||||
* Debian: reformat package description
|
||||
* systemd: enable basic hardening
|
||||
* Debian: install osmo-hlr-dgsm.cfg as example config
|
||||
* hlr_vty.c: fix typo
|
||||
* ctrl: take both address and port from vty config
|
||||
|
||||
[ Harald Welte ]
|
||||
* Support building with -Werror=strict-prototypes / -Werror=old-style-definition
|
||||
* Add -Werror=implicit-int -Werror=int-conversion -Werror=old-style-definition
|
||||
|
||||
[ arehbein ]
|
||||
* osmo-hlr: Transition to use of 'telnet_init_default'
|
||||
|
||||
[ Oliver Smith ]
|
||||
* osmo_mdns_rfc_record_decode: check ret of talloc
|
||||
* osmo_mdns_rfc_record_decode: proper free on err
|
||||
* mslookup: use apn functions from libosmocore
|
||||
* osmo_mdns_rfc_record/question_encode: remove ctx
|
||||
|
||||
[ Keith ]
|
||||
* Vty: Fixup config shown/written from vty
|
||||
|
||||
[ Neels Hofmeyr ]
|
||||
* fix memleak of proxy_subscr_listentry
|
||||
|
||||
[ Alexander Couzens ]
|
||||
* Add vty `reject-cause` to set the reject cause
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 16:49:14 +0100
|
||||
|
||||
osmo-hlr (1.5.0) unstable; urgency=medium
|
||||
|
||||
[ Oliver Smith ]
|
||||
* treewide: remove FSF address
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* fixup: debian: remove unneeded dependency libdbd-sqlite3
|
||||
* debian: add new 'osmo-mslookup-utils' package
|
||||
* tests: use 'check_PROGRAMS' instead of 'noinst_PROGRAMS'
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* ctrl: Mark function as static
|
||||
* tests: Allow specyfing specific ctrl test to run
|
||||
* tests/ctrl: Move ERROR test scenario to proper file
|
||||
* Fix db_subscr_create() not returning -EEXIST expected by VTY subscriber create cmd
|
||||
* ctrl: Introduce cmd SET subscriber.create <imsi>
|
||||
* ctrl: Introduce CTRL command subscriber.by-*.msisdn
|
||||
* cosmetic: hlr_vty_subscr.c: Fix trailing whitespace
|
||||
* ctrl: Introduce cmd SET subscriber.delete <imsi>
|
||||
* ctrl: Introduce CTRL command subscriber.by-*.aud2g <algo[,ki]>
|
||||
* ctrl: Introduce CTRL command subscriber.by-*.aud3g <algo[,KI,(op|opc),OP_C[,ind_bitlen]]>
|
||||
* doc: Document new subscriber CTRL commands
|
||||
|
||||
[ Harald Welte ]
|
||||
* update git URLs (git -> https; gitea)
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 28 Jun 2022 18:38:31 +0200
|
||||
|
||||
osmo-hlr (1.4.0) unstable; urgency=medium
|
||||
|
||||
[ Keith ]
|
||||
* Correct configuration written from vty
|
||||
* vty: enable show subscribers filtered by IMEI
|
||||
|
||||
[ Harald Welte ]
|
||||
* add README.md file as customary for cgit, github, gitlab, etc.
|
||||
|
||||
[ Oliver Smith ]
|
||||
* Add post-upgrade script for automatic db upgrade
|
||||
* debian/control: remove dh-systemd build-depend
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* db: Avoid use uninitialized rc if running 0 statements
|
||||
|
||||
[ Neels Hofmeyr ]
|
||||
* db v6: determine 3G AUC IND from VLR name
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 16 Nov 2021 14:56:41 +0100
|
||||
|
||||
osmo-hlr (1.3.0) unstable; urgency=medium
|
||||
|
||||
[ Alexander Couzens ]
|
||||
|
||||
34
debian/control
vendored
34
debian/control
vendored
@@ -5,26 +5,26 @@ Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
||||
Build-Depends: debhelper (>= 9),
|
||||
pkg-config,
|
||||
dh-autoreconf,
|
||||
dh-systemd (>= 1.5),
|
||||
autotools-dev,
|
||||
python3-minimal,
|
||||
libosmocore-dev (>= 1.5.0),
|
||||
libosmo-abis-dev (>= 1.1.0),
|
||||
libosmo-netif-dev (>= 1.1.0),
|
||||
libosmocore-dev (>= 1.8.0),
|
||||
libosmo-abis-dev (>= 1.4.0),
|
||||
libosmo-netif-dev (>= 1.3.0),
|
||||
libsqlite3-dev,
|
||||
sqlite3,
|
||||
osmo-gsm-manuals-dev (>= 1.1.0)
|
||||
osmo-gsm-manuals-dev (>= 1.4.0)
|
||||
Standards-Version: 3.9.6
|
||||
Vcs-Browser: http://cgit.osmocom.org/osmo-hlr
|
||||
Vcs-Git: git://git.osmocom.org/osmo-hlr
|
||||
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr
|
||||
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-hlr
|
||||
Homepage: https://projects.osmocom.org/projects/osmo-hlr
|
||||
|
||||
Package: osmo-hlr
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libdbd-sqlite3
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: Osmocom Home Location Register
|
||||
OsmoHLR is a Osmocom implementation of HLR (Home Location Registrar) which works over GSUP
|
||||
protocol. The subscribers are store in sqlite DB. It supports both 2G and 3G authentication.
|
||||
OsmoHLR is a Osmocom implementation of HLR (Home Location Registrar) which
|
||||
works over GSUP protocol. The subscribers are store in sqlite DB.
|
||||
It supports both 2G and 3G authentication.
|
||||
|
||||
Package: osmo-hlr-dbg
|
||||
Architecture: any
|
||||
@@ -59,7 +59,7 @@ Description: Development headers of Osmocom GSUP client library
|
||||
.
|
||||
This package contains the development headers.
|
||||
|
||||
Package: libosmo-mslookup0
|
||||
Package: libosmo-mslookup1
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
@@ -73,7 +73,7 @@ Package: libosmo-mslookup-dev
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends: ${misc:Depends},
|
||||
libosmo-mslookup0 (= ${binary:Version}),
|
||||
libosmo-mslookup1 (= ${binary:Version}),
|
||||
libosmocore-dev
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Description: Development headers of Osmocom MS lookup library
|
||||
@@ -81,6 +81,16 @@ Description: Development headers of Osmocom MS lookup library
|
||||
.
|
||||
This package contains the development headers.
|
||||
|
||||
Package: osmo-mslookup-utils
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Depends: ${shlibs:Depends},
|
||||
libosmo-mslookup1 (= ${binary:Version}),
|
||||
${misc:Depends}
|
||||
Multi-Arch: same
|
||||
Description: Utilities for Osmocom MS lookup
|
||||
This package contains a simple MS lookup client utility.
|
||||
|
||||
Package: osmo-hlr-doc
|
||||
Architecture: all
|
||||
Section: doc
|
||||
|
||||
2
debian/copyright
vendored
2
debian/copyright
vendored
@@ -3,7 +3,7 @@ Upstream-Name: OsmoHLR
|
||||
Source: http://cgit.osmocom.org/osmo-hlr/
|
||||
|
||||
Files: *
|
||||
Copyright: 2016-2017 Sysmocom s. f. m. c. GmbH <info@sysmocom.de>
|
||||
Copyright: 2016-2022 Sysmocom s. f. m. c. GmbH <info@sysmocom.de>
|
||||
License: AGPL-3+
|
||||
|
||||
License: AGPL-3+
|
||||
|
||||
2
debian/osmo-hlr.install
vendored
2
debian/osmo-hlr.install
vendored
@@ -5,5 +5,5 @@
|
||||
/usr/share/doc/osmo-hlr/sql/hlr.sql
|
||||
/usr/share/doc/osmo-hlr/sql/hlr_data.sql
|
||||
/usr/share/doc/osmo-hlr/examples/osmo-hlr.cfg
|
||||
/usr/share/doc/osmo-hlr/examples/osmo-hlr-dgsm.cfg
|
||||
/usr/share/osmocom/osmo-hlr-post-upgrade.sh
|
||||
/var/lib/osmocom
|
||||
|
||||
1
debian/osmo-mslookup-utils.install
vendored
Normal file
1
debian/osmo-mslookup-utils.install
vendored
Normal file
@@ -0,0 +1 @@
|
||||
usr/bin/osmo-mslookup-client
|
||||
@@ -1,6 +1,10 @@
|
||||
EXTRA_DIST = example_subscriber_add_update_delete.vty \
|
||||
EXTRA_DIST = \
|
||||
example_subscriber_add_update_delete.vty \
|
||||
example_subscriber_aud2g.ctrl \
|
||||
example_subscriber_aud3g.ctrl \
|
||||
example_subscriber_cs_ps_enabled.ctrl \
|
||||
example_subscriber_info.ctrl \
|
||||
example_subscriber_msisdn.ctrl \
|
||||
osmohlr-usermanual.adoc \
|
||||
osmohlr-usermanual-docinfo.xml \
|
||||
osmohlr-vty-reference.xml \
|
||||
|
||||
@@ -5,6 +5,16 @@ The actual protocol is described in <<common-control-if>>, the variables common
|
||||
to all programs using it are described in <<ctrl_common_vars>>. This section
|
||||
describes the CTRL interface variables specific to OsmoHLR.
|
||||
|
||||
Subscribers can be created and deleted using the following SET commands:
|
||||
|
||||
.Subscriber management commands available on OsmoHLR's Control interface
|
||||
[options="header",width="100%",cols="35%,65%"]
|
||||
|===
|
||||
|Command|Comment
|
||||
|subscriber.create '123456'|Create a new subscriber with IMSI "123456" to the database. Returns database ID of the subscriber being created.
|
||||
|subscriber.delete '123456'|Delete subscriber with IMSI "123456" from database. Returns database ID of the subscriber being deleted.
|
||||
|===
|
||||
|
||||
All subscriber variables are available by different selectors, which are freely
|
||||
interchangeable:
|
||||
|
||||
@@ -28,6 +38,9 @@ Each of the above selectors feature all of these control variables:
|
||||
|subscriber.by-\*.*info-all*|R|No||List both 'info' and 'info-aud' in one
|
||||
|subscriber.by-\*.*cs-enabled*|RW|No|'1' or '0'|Enable/disable circuit-switched access
|
||||
|subscriber.by-\*.*ps-enabled*|RW|No|'1' or '0'|Enable/disable packet-switched access
|
||||
|subscriber.by-\*.*msisdn*|RW|No|valid MSISDN string|Get/Set assigned MSISDN
|
||||
|subscriber.by-\*.*aud2g*|RW|No|'algo[,KI]'|Get/Set 2g Authentication Data
|
||||
|subscriber.by-\*.*aud2g*|RW|No|'algo[,KI,("op"|"opc"),OP_C[,ind_bitlen]]'|Get/Set 3g Authentication Data
|
||||
|===
|
||||
|
||||
=== subscriber.by-*.info, info-aud, info-all
|
||||
@@ -104,3 +117,63 @@ commands:
|
||||
----
|
||||
include::../example_subscriber_cs_ps_enabled.ctrl[]
|
||||
----
|
||||
|
||||
=== subscriber.by-*.msisdn
|
||||
|
||||
Get or set the MSISDN currently assigned to a subscriber.
|
||||
|
||||
|
||||
This is an example transcript that illustrates use of this command:
|
||||
|
||||
----
|
||||
include::../example_subscriber_msisdn.ctrl[]
|
||||
----
|
||||
|
||||
=== subscriber.by-*.aud2g
|
||||
|
||||
Get or set the 2G Authentication data of a subscriber.
|
||||
|
||||
The information is stored/retrieved as a comma separated list of fields:
|
||||
|
||||
----
|
||||
algo[,KI]
|
||||
----
|
||||
|
||||
Where::
|
||||
* *KI* is the KI as a hexadecimal string.
|
||||
* *algo* is one of the following algorithms: _none, xor, comp128v1, comp128v2,
|
||||
comp128v3_.
|
||||
|
||||
All values are case insensitive.
|
||||
|
||||
This is an example transcript that illustrates use of this command:
|
||||
|
||||
----
|
||||
include::../example_subscriber_aud2g.ctrl[]
|
||||
----
|
||||
|
||||
=== subscriber.by-*.aud3g
|
||||
|
||||
Get or set the 3G Authentication data of a subscriber.
|
||||
|
||||
The information is stored/retrieved as a comma separated list of fields:
|
||||
|
||||
----
|
||||
algo[,KI,("op"|"opc"),OP_C[,ind_bitlen]]
|
||||
----
|
||||
|
||||
Where:
|
||||
* *KI* is the KI as a hexadecimal string.
|
||||
* *algo* is one of the following algorithms: _none, xor, milenage_.
|
||||
* "op" or "opc" indicates whether next field is an OP or OPC value.
|
||||
* *OP_C* contains an OP or OPC values as hexadecimal string, based on what the
|
||||
previous field specifies.
|
||||
* *ind_bitlen* is set to 5 by default if not provided.
|
||||
|
||||
All values are case insensitive.
|
||||
|
||||
This is an example transcript that illustrates use of this command:
|
||||
|
||||
----
|
||||
include::../example_subscriber_aud3g.ctrl[]
|
||||
----
|
||||
|
||||
14
doc/manuals/example_subscriber_aud2g.ctrl
Normal file
14
doc/manuals/example_subscriber_aud2g.ctrl
Normal file
@@ -0,0 +1,14 @@
|
||||
GET 1 subscriber.by-imsi-901991234567891.aud2g
|
||||
GET_REPLY 1 subscriber.by-imsi-901991234567891.aud2g none
|
||||
|
||||
SET 2 subscriber.by-imsi-901991234567891.aud2g xor,c01ffedc1cadaeac1d1f1edacac1ab0a
|
||||
SET_REPLY 2 subscriber.by-imsi-901991234567891.aud2g OK
|
||||
|
||||
GET 3 subscriber.by-imsi-901991234567891.aud2g
|
||||
GET_REPLY 3 subscriber.by-imsi-901991234567891.aud2g XOR,c01ffedc1cadaeac1d1f1edacac1ab0a
|
||||
|
||||
SET 4 subscriber.by-imsi-901991234567891.aud2g none
|
||||
SET_REPLY 4 subscriber.by-imsi-901991234567891.aud2g OK
|
||||
|
||||
GET 5 subscriber.by-imsi-901991234567891.aud2g
|
||||
GET_REPLY 5 subscriber.by-imsi-901991234567891.aud2g none
|
||||
20
doc/manuals/example_subscriber_aud3g.ctrl
Normal file
20
doc/manuals/example_subscriber_aud3g.ctrl
Normal file
@@ -0,0 +1,20 @@
|
||||
GET 117 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 117 subscriber.by-imsi-901991234567891.aud3g none
|
||||
|
||||
SET 118 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,FB2A3D1B360F599ABAB99DB8669F8308
|
||||
SET_REPLY 118 subscriber.by-imsi-901991234567891.aud3g OK
|
||||
|
||||
GET 119 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 119 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,fb2a3d1b360f599abab99db8669f8308,5
|
||||
|
||||
SET 120 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,FB2A3D1B360F599ABAB99DB8669F8308,7
|
||||
SET_REPLY 120 subscriber.by-imsi-901991234567891.aud3g OK
|
||||
|
||||
GET 121 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 121 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,fb2a3d1b360f599abab99db8669f8308,7
|
||||
|
||||
SET 122 subscriber.by-imsi-901991234567891.aud3g none
|
||||
SET_REPLY 122 subscriber.by-imsi-901991234567891.aud3g OK
|
||||
|
||||
GET 123 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 123 subscriber.by-imsi-901991234567891.aud3g none
|
||||
8
doc/manuals/example_subscriber_msisdn.ctrl
Normal file
8
doc/manuals/example_subscriber_msisdn.ctrl
Normal file
@@ -0,0 +1,8 @@
|
||||
GET 1 subscriber.by-imsi-901991234567891.msisdn
|
||||
GET_REPLY 1 subscriber.by-imsi-901991234567891.msisdn none
|
||||
|
||||
SET 2 subscriber.by-imsi-901991234567891.msisdn 555666
|
||||
SET_REPLY 2 subscriber.by-imsi-901991234567891.msisdn OK
|
||||
|
||||
GET 3 subscriber.by-imsi-901991234567891.msisdn
|
||||
GET_REPLY 3 subscriber.by-imsi-901991234567891.msisdn 555666
|
||||
@@ -30,5 +30,4 @@ enum hlr_ctrl_node {
|
||||
_LAST_CTRL_NODE_HLR
|
||||
};
|
||||
|
||||
int hlr_ctrl_cmds_install();
|
||||
struct ctrl_handle *hlr_controlif_setup(struct hlr *hlr);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <osmocom/gsupclient/cni_peer_id.h>
|
||||
#include <osmocom/gsm/gsup.h>
|
||||
|
||||
struct hlr;
|
||||
|
||||
@@ -40,6 +41,9 @@ enum stmt_idx {
|
||||
DB_STMT_SET_LAST_LU_SEEN_PS,
|
||||
DB_STMT_EXISTS_BY_IMSI,
|
||||
DB_STMT_EXISTS_BY_MSISDN,
|
||||
DB_STMT_IND_ADD,
|
||||
DB_STMT_IND_SELECT,
|
||||
DB_STMT_IND_DEL,
|
||||
_NUM_DB_STMT
|
||||
};
|
||||
|
||||
@@ -173,6 +177,9 @@ int db_subscr_lu(struct db_context *dbc, int64_t subscr_id,
|
||||
int db_subscr_purge(struct db_context *dbc, const char *by_imsi,
|
||||
bool purge_val, bool is_ps);
|
||||
|
||||
int db_ind(struct db_context *dbc, const struct osmo_cni_peer_id *vlr, unsigned int *ind);
|
||||
int db_ind_del(struct db_context *dbc, const struct osmo_cni_peer_id *vlr);
|
||||
|
||||
/*! Call sqlite3_column_text() and copy result to a char[].
|
||||
* \param[out] buf A char[] used as sizeof() arg(!) and osmo_strlcpy() target.
|
||||
* \param[in] stmt An sqlite3_stmt*.
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <osmocom/gsupclient/cni_peer_id.h>
|
||||
#include <osmocom/gsupclient/gsup_req.h>
|
||||
|
||||
#define OSMO_DGSM_DEFAULT_RESULT_TIMEOUT_MS 2000
|
||||
#define LOG_DGSM(imsi, level, fmt, args...) \
|
||||
LOGP(DDGSM, level, "(IMSI-%s) " fmt, imsi, ##args)
|
||||
|
||||
|
||||
@@ -42,8 +42,6 @@ struct osmo_gsup_conn {
|
||||
//struct oap_state oap_state;
|
||||
struct tlv_parsed ccm;
|
||||
|
||||
unsigned int auc_3g_ind; /*!< IND index used for UMTS AKA SQN */
|
||||
|
||||
/* Set when Location Update is received: */
|
||||
bool supports_cs; /* client supports OSMO_GSUP_CN_DOMAIN_CS */
|
||||
bool supports_ps; /* client supports OSMO_GSUP_CN_DOMAIN_PS */
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/ipa.h>
|
||||
#include <osmocom/core/tdef.h>
|
||||
@@ -48,7 +49,6 @@ struct hlr {
|
||||
|
||||
/* Control Interface */
|
||||
struct ctrl_handle *ctrl;
|
||||
const char *ctrl_bind_addr;
|
||||
|
||||
/* Local bind addr */
|
||||
char *gsup_bind_addr;
|
||||
@@ -56,6 +56,8 @@ struct hlr {
|
||||
|
||||
struct llist_head euse_list;
|
||||
struct hlr_euse *euse_default;
|
||||
enum gsm48_gmm_cause reject_cause;
|
||||
enum gsm48_gmm_cause no_proxy_reject_cause;
|
||||
|
||||
/* NCSS (call independent) session guard timeout value */
|
||||
int ncss_guard_timeout;
|
||||
|
||||
@@ -37,7 +37,13 @@ enum hlr_vty_node {
|
||||
MSLOOKUP_CLIENT_NODE,
|
||||
};
|
||||
|
||||
|
||||
#define A38_XOR_MIN_KEY_LEN 12
|
||||
#define A38_XOR_MAX_KEY_LEN 16
|
||||
#define A38_COMP128_KEY_LEN 16
|
||||
#define MILENAGE_KEY_LEN 16
|
||||
|
||||
int hlr_vty_is_config_node(struct vty *vty, int node);
|
||||
int hlr_vty_go_parent(struct vty *vty);
|
||||
void hlr_vty_init(void);
|
||||
void hlr_vty_init(void *hlr_ctx);
|
||||
void dgsm_vty_init(void);
|
||||
|
||||
@@ -11,6 +11,7 @@ enum {
|
||||
DMSLOOKUP,
|
||||
DLU,
|
||||
DDGSM,
|
||||
DCTRL,
|
||||
};
|
||||
|
||||
extern const struct log_info hlr_log_info;
|
||||
|
||||
@@ -99,15 +99,12 @@ struct osmo_mdns_rfc_record {
|
||||
uint8_t *rdata;
|
||||
};
|
||||
|
||||
char *osmo_mdns_rfc_qname_encode(void *ctx, const char *domain);
|
||||
char *osmo_mdns_rfc_qname_decode(void *ctx, const char *qname, size_t qname_len);
|
||||
|
||||
void osmo_mdns_rfc_header_encode(struct msgb *msg, const struct osmo_mdns_rfc_header *hdr);
|
||||
int osmo_mdns_rfc_header_decode(const uint8_t *data, size_t data_len, struct osmo_mdns_rfc_header *hdr);
|
||||
|
||||
int osmo_mdns_rfc_question_encode(void *ctx, struct msgb *msg, const struct osmo_mdns_rfc_question *qst);
|
||||
int osmo_mdns_rfc_question_encode(struct msgb *msg, const struct osmo_mdns_rfc_question *qst);
|
||||
struct osmo_mdns_rfc_question *osmo_mdns_rfc_question_decode(void *ctx, const uint8_t *data, size_t data_len);
|
||||
|
||||
int osmo_mdns_rfc_record_encode(void *ctx, struct msgb *msg, const struct osmo_mdns_rfc_record *rec);
|
||||
int osmo_mdns_rfc_record_encode(struct msgb *msg, const struct osmo_mdns_rfc_record *rec);
|
||||
struct osmo_mdns_rfc_record *osmo_mdns_rfc_record_decode(void *ctx, const uint8_t *data, size_t data_len,
|
||||
size_t *record_len);
|
||||
|
||||
10
sql/hlr.sql
10
sql/hlr.sql
@@ -79,8 +79,16 @@ CREATE TABLE auc_3g (
|
||||
ind_bitlen INTEGER NOT NULL DEFAULT 5
|
||||
);
|
||||
|
||||
CREATE TABLE ind (
|
||||
-- 3G auth IND pool to be used for this VLR
|
||||
ind INTEGER PRIMARY KEY,
|
||||
-- VLR identification, usually the GSUP source_name
|
||||
vlr TEXT NOT NULL,
|
||||
UNIQUE (vlr)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_subscr_imsi ON subscriber (imsi);
|
||||
|
||||
-- Set HLR database schema version number
|
||||
-- Note: This constant is currently duplicated in src/db.c and must be kept in sync!
|
||||
PRAGMA user_version = 5;
|
||||
PRAGMA user_version = 6;
|
||||
|
||||
402
src/ctrl.c
402
src/ctrl.c
@@ -31,12 +31,16 @@
|
||||
#include <osmocom/hlr/hlr.h>
|
||||
#include <osmocom/hlr/ctrl.h>
|
||||
#include <osmocom/hlr/db.h>
|
||||
#include <osmocom/hlr/hlr_vty.h>
|
||||
|
||||
#define SEL_BY "by-"
|
||||
#define SEL_BY_IMSI SEL_BY "imsi-"
|
||||
#define SEL_BY_MSISDN SEL_BY "msisdn-"
|
||||
#define SEL_BY_ID SEL_BY "id-"
|
||||
|
||||
extern bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
|
||||
int *minlen, int *maxlen);
|
||||
|
||||
#define hexdump_buf(buf) osmo_hexdump_nospc((void*)buf, sizeof(buf))
|
||||
|
||||
static bool startswith(const char *str, const char *start)
|
||||
@@ -197,6 +201,77 @@ static void print_subscr_info_aud3g(struct ctrl_cmd *cmd, struct osmo_sub_auth_d
|
||||
aud->u.umts.sqn);
|
||||
}
|
||||
|
||||
CTRL_CMD_DEFINE_WO_NOVRF(subscr_create, "create");
|
||||
static int set_subscr_create(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct hlr_subscriber subscr;
|
||||
struct hlr *hlr = data;
|
||||
const char *imsi = cmd->value;
|
||||
int rc;
|
||||
|
||||
if (!osmo_imsi_str_valid(imsi)) {
|
||||
cmd->reply = "Invalid IMSI value.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Create the subscriber in the DB */
|
||||
rc = db_subscr_create(g_hlr->dbc, imsi, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS);
|
||||
if (rc) {
|
||||
if (rc == -EEXIST)
|
||||
cmd->reply = "Subscriber already exists.";
|
||||
else
|
||||
cmd->reply = "Cannot create subscriber.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
LOGP(DCTRL, LOGL_INFO, "Created subscriber IMSI='%s'\n",
|
||||
imsi);
|
||||
|
||||
/* Retrieve data of newly created subscriber: */
|
||||
rc = db_subscr_get_by_imsi(hlr->dbc, imsi, &subscr);
|
||||
if (rc < 0) {
|
||||
cmd->reply = "Failed retrieving ID of newly created subscriber.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
cmd->reply = talloc_asprintf(cmd, "%" PRIu64, subscr.id);
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
||||
CTRL_CMD_DEFINE_WO_NOVRF(subscr_delete, "delete");
|
||||
static int set_subscr_delete(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct hlr_subscriber subscr;
|
||||
struct hlr *hlr = data;
|
||||
const char *imsi = cmd->value;
|
||||
int rc;
|
||||
|
||||
if (!osmo_imsi_str_valid(imsi)) {
|
||||
cmd->reply = "Invalid IMSI value.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Retrieve data of newly created subscriber: */
|
||||
rc = db_subscr_get_by_imsi(hlr->dbc, imsi, &subscr);
|
||||
if (rc < 0) {
|
||||
cmd->reply = "Subscriber doesn't exist.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Create the subscriber in the DB */
|
||||
rc = db_subscr_delete_by_id(g_hlr->dbc, subscr.id);
|
||||
if (rc) {
|
||||
cmd->reply = "Cannot delete subscriber.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
LOGP(DCTRL, LOGL_INFO, "Deleted subscriber IMSI='%s'\n",
|
||||
imsi);
|
||||
|
||||
cmd->reply = talloc_asprintf(cmd, "%" PRIu64, subscr.id);
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
||||
CTRL_CMD_DEFINE_RO(subscr_info, "info");
|
||||
static int get_subscr_info(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
@@ -351,17 +426,302 @@ static int set_subscr_cs_enabled(struct ctrl_cmd *cmd, void *data)
|
||||
return set_subscr_cs_ps_enabled(cmd, data, false);
|
||||
}
|
||||
|
||||
int hlr_ctrl_cmds_install()
|
||||
CTRL_CMD_DEFINE(subscr_msisdn, "msisdn");
|
||||
static int verify_subscr_msisdn(struct ctrl_cmd *cmd, const char *value, void *data)
|
||||
{
|
||||
int rc = 0;
|
||||
struct hlr_subscriber subscr;
|
||||
if (!value)
|
||||
return 1;
|
||||
if (strlen(value) > sizeof(subscr.msisdn) - 1)
|
||||
return 1;
|
||||
if (strcmp(value, "none") != 0 && !osmo_msisdn_str_valid(value))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int get_subscr_msisdn(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct hlr_subscriber subscr;
|
||||
struct hlr *hlr = data;
|
||||
const char *by_selector = cmd->node;
|
||||
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_aud);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_all);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_ps_enabled);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_cs_enabled);
|
||||
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||
return CTRL_CMD_ERROR;
|
||||
|
||||
return rc;
|
||||
if (strlen(subscr.msisdn) == 0)
|
||||
snprintf(subscr.msisdn, sizeof(subscr.msisdn), "none");
|
||||
|
||||
cmd->reply = talloc_asprintf(cmd, "%s", subscr.msisdn);
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
static int set_subscr_msisdn(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct hlr_subscriber subscr;
|
||||
struct hlr *hlr = data;
|
||||
const char *by_selector = cmd->node;
|
||||
const char *msisdn;
|
||||
|
||||
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||
return CTRL_CMD_ERROR;
|
||||
|
||||
if (strcmp(cmd->value, "none") == 0)
|
||||
msisdn = NULL;
|
||||
else
|
||||
msisdn = cmd->value;
|
||||
|
||||
if (db_subscr_update_msisdn_by_imsi(g_hlr->dbc, subscr.imsi, msisdn)) {
|
||||
cmd->reply = "Update MSISDN failed";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
cmd->reply = "OK";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
||||
/* value format: <algo[,KI]> */
|
||||
CTRL_CMD_DEFINE(subscr_aud2g, "aud2g");
|
||||
static int verify_subscr_aud2g(struct ctrl_cmd *cmd, const char *value, void *data)
|
||||
{
|
||||
if (!value)
|
||||
return 1;
|
||||
if (strcasecmp(value, "none") != 0 && !strchr(value, ','))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int get_subscr_aud2g(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct hlr_subscriber subscr;
|
||||
struct hlr *hlr = data;
|
||||
const char *by_selector = cmd->node;
|
||||
struct osmo_sub_auth_data aud2g;
|
||||
struct osmo_sub_auth_data aud3g_unused;
|
||||
int rc;
|
||||
|
||||
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||
return CTRL_CMD_ERROR;
|
||||
|
||||
rc = db_get_auth_data(hlr->dbc, subscr.imsi, &aud2g, &aud3g_unused, NULL);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
break;
|
||||
case -ENOENT:
|
||||
case -ENOKEY:
|
||||
aud2g.algo = OSMO_AUTH_ALG_NONE;
|
||||
break;
|
||||
default:
|
||||
cmd->reply = "Error retrieving data from database.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
if (aud2g.algo == OSMO_AUTH_ALG_NONE) {
|
||||
cmd->reply = "none";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
||||
cmd->reply = talloc_asprintf(cmd, "%s,%s", osmo_auth_alg_name(aud2g.algo),
|
||||
hexdump_buf(aud2g.u.gsm.ki));
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
static int set_subscr_aud2g(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct hlr_subscriber subscr;
|
||||
struct hlr *hlr = data;
|
||||
const char *by_selector = cmd->node;
|
||||
char *tmp = NULL, *tok, *saveptr;
|
||||
int minlen = 0;
|
||||
int maxlen = 0;
|
||||
struct sub_auth_data_str aud2g = {
|
||||
.type = OSMO_AUTH_TYPE_GSM
|
||||
};
|
||||
|
||||
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||
return CTRL_CMD_ERROR;
|
||||
|
||||
tmp = talloc_strdup(cmd, cmd->value);
|
||||
if (!tmp) {
|
||||
cmd->reply = "OOM";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Parse alg_type: */
|
||||
tok = strtok_r(tmp, ",", &saveptr);
|
||||
if (!tok) {
|
||||
cmd->reply = "Invalid format";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
if (strcmp(tok, "none") == 0) {
|
||||
aud2g.algo = OSMO_AUTH_ALG_NONE;
|
||||
} else if (!auth_algo_parse(tok, &aud2g.algo, &minlen, &maxlen)) {
|
||||
cmd->reply = "Unknown auth algorithm.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
if (aud2g.algo != OSMO_AUTH_ALG_NONE) {
|
||||
tok = strtok_r(NULL, "\0", &saveptr);
|
||||
if (!tok) {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
aud2g.u.gsm.ki = tok;
|
||||
if (!osmo_is_hexstr(aud2g.u.gsm.ki, minlen * 2, maxlen * 2, true)) {
|
||||
cmd->reply = "Invalid KI.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud2g)) {
|
||||
cmd->reply = "Update aud2g failed.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
cmd->reply = "OK";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
||||
/* value format: <algo[,KI,(op|opc),OP_C[,ind_bitlen]]> */
|
||||
CTRL_CMD_DEFINE(subscr_aud3g, "aud3g");
|
||||
static int verify_subscr_aud3g(struct ctrl_cmd *cmd, const char *value, void *data)
|
||||
{
|
||||
if (!value)
|
||||
return 1;
|
||||
if (strcasecmp(value, "none") != 0 && !strchr(value, ','))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int get_subscr_aud3g(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct hlr_subscriber subscr;
|
||||
struct hlr *hlr = data;
|
||||
const char *by_selector = cmd->node;
|
||||
struct osmo_sub_auth_data aud2g_unused;
|
||||
struct osmo_sub_auth_data aud3g;
|
||||
int rc;
|
||||
|
||||
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||
return CTRL_CMD_ERROR;
|
||||
|
||||
rc = db_get_auth_data(hlr->dbc, subscr.imsi, &aud2g_unused, &aud3g, NULL);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
break;
|
||||
case -ENOENT:
|
||||
case -ENOKEY:
|
||||
aud3g.algo = OSMO_AUTH_ALG_NONE;
|
||||
break;
|
||||
default:
|
||||
cmd->reply = "Error retrieving data from database.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
if (aud3g.algo == OSMO_AUTH_ALG_NONE) {
|
||||
cmd->reply = "none";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
||||
cmd->reply = talloc_asprintf(cmd, "%s,%s,%s,%s,%u", osmo_auth_alg_name(aud3g.algo),
|
||||
osmo_hexdump_nospc_c(cmd, aud3g.u.umts.k, sizeof(aud3g.u.umts.k)),
|
||||
aud3g.u.umts.opc_is_op ? "OP" : "OPC",
|
||||
osmo_hexdump_nospc_c(cmd, aud3g.u.umts.opc, sizeof(aud3g.u.umts.opc)),
|
||||
aud3g.u.umts.ind_bitlen);
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
static int set_subscr_aud3g(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct hlr_subscriber subscr;
|
||||
struct hlr *hlr = data;
|
||||
const char *by_selector = cmd->node;
|
||||
char *tmp = NULL, *tok, *saveptr;
|
||||
int minlen = 0;
|
||||
int maxlen = 0;
|
||||
struct sub_auth_data_str aud3g = {
|
||||
.type = OSMO_AUTH_TYPE_UMTS,
|
||||
.u.umts = {
|
||||
.ind_bitlen = 5,
|
||||
},
|
||||
};
|
||||
bool ind_bitlen_present;
|
||||
|
||||
if (!get_subscriber(hlr->dbc, by_selector, &subscr, cmd))
|
||||
return CTRL_CMD_ERROR;
|
||||
|
||||
tmp = talloc_strdup(cmd, cmd->value);
|
||||
if (!tmp) {
|
||||
cmd->reply = "OOM";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Parse alg_type: */
|
||||
tok = strtok_r(tmp, ",", &saveptr);
|
||||
if (!tok) {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
if (strcmp(tok, "none") == 0) {
|
||||
aud3g.algo = OSMO_AUTH_ALG_NONE;
|
||||
} else if (!auth_algo_parse(tok, &aud3g.algo, &minlen, &maxlen)) {
|
||||
cmd->reply = "Unknown auth algorithm.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
if (aud3g.algo != OSMO_AUTH_ALG_NONE) {
|
||||
/* Parse K */
|
||||
tok = strtok_r(NULL, ",", &saveptr);
|
||||
if (!tok) {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
aud3g.u.umts.k = tok;
|
||||
if (!osmo_is_hexstr(aud3g.u.umts.k, minlen * 2, maxlen * 2, true)) {
|
||||
cmd->reply = "Invalid KI.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Parse OP/OPC choice */
|
||||
tok = strtok_r(NULL, ",", &saveptr);
|
||||
if (!tok) {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
if (strcasecmp(tok, "op") == 0) {
|
||||
aud3g.u.umts.opc_is_op = true;
|
||||
} else if (strcasecmp(tok, "opc") == 0) {
|
||||
aud3g.u.umts.opc_is_op = false;
|
||||
} else {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
/* Parse OP/OPC value */
|
||||
ind_bitlen_present = !!strchr(saveptr, ',');
|
||||
tok = strtok_r(NULL, ind_bitlen_present ? "," : "\0", &saveptr);
|
||||
if (!tok) {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
aud3g.u.umts.opc = tok;
|
||||
if (!osmo_is_hexstr(aud3g.u.umts.opc, MILENAGE_KEY_LEN * 2, MILENAGE_KEY_LEN * 2, true)) {
|
||||
cmd->reply = talloc_asprintf(cmd, "Invalid OP/OPC.");
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
if (ind_bitlen_present) {
|
||||
/* Parse bitlen_ind */
|
||||
tok = strtok_r(NULL, "\0", &saveptr);
|
||||
if (!tok || tok[0] == '\0') {
|
||||
cmd->reply = "Invalid format.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
aud3g.u.umts.ind_bitlen = atoi(tok);
|
||||
}
|
||||
}
|
||||
|
||||
if (db_subscr_update_aud_by_id(g_hlr->dbc, subscr.id, &aud3g)) {
|
||||
cmd->reply = "Update aud3g failed.";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
cmd->reply = "OK";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
|
||||
static int hlr_ctrl_node_lookup(void *data, vector vline, int *node_type,
|
||||
@@ -389,14 +749,30 @@ static int hlr_ctrl_node_lookup(void *data, vector vline, int *node_type,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int hlr_ctrl_cmds_install(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR, &cmd_subscr_create);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR, &cmd_subscr_delete);
|
||||
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_aud);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_info_all);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_ps_enabled);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_cs_enabled);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_msisdn);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_aud2g);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_SUBSCR_BY, &cmd_subscr_aud3g);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct ctrl_handle *hlr_controlif_setup(struct hlr *hlr)
|
||||
{
|
||||
int rc;
|
||||
struct ctrl_handle *hdl = ctrl_interface_setup_dynip2(hlr,
|
||||
hlr->ctrl_bind_addr,
|
||||
OSMO_CTRL_PORT_HLR,
|
||||
hlr_ctrl_node_lookup,
|
||||
_LAST_CTRL_NODE_HLR);
|
||||
struct ctrl_handle *hdl = ctrl_interface_setup2(hlr, OSMO_CTRL_PORT_HLR, hlr_ctrl_node_lookup,
|
||||
_LAST_CTRL_NODE_HLR);
|
||||
if (!hdl)
|
||||
return NULL;
|
||||
|
||||
|
||||
31
src/db.c
31
src/db.c
@@ -28,7 +28,7 @@
|
||||
#include "db_bootstrap.h"
|
||||
|
||||
/* This constant is currently duplicated in sql/hlr.sql and must be kept in sync! */
|
||||
#define CURRENT_SCHEMA_VERSION 5
|
||||
#define CURRENT_SCHEMA_VERSION 6
|
||||
|
||||
#define SEL_COLUMNS \
|
||||
"id," \
|
||||
@@ -93,6 +93,9 @@ static const char *stmt_sql[] = {
|
||||
[DB_STMT_SET_LAST_LU_SEEN_PS] = "UPDATE subscriber SET last_lu_seen_ps = datetime($val, 'unixepoch') WHERE id = $subscriber_id",
|
||||
[DB_STMT_EXISTS_BY_IMSI] = "SELECT 1 FROM subscriber WHERE imsi = $imsi",
|
||||
[DB_STMT_EXISTS_BY_MSISDN] = "SELECT 1 FROM subscriber WHERE msisdn = $msisdn",
|
||||
[DB_STMT_IND_ADD] = "INSERT INTO ind (vlr) VALUES ($vlr)",
|
||||
[DB_STMT_IND_SELECT] = "SELECT ind FROM ind WHERE vlr = $vlr",
|
||||
[DB_STMT_IND_DEL] = "DELETE FROM ind WHERE vlr = $vlr",
|
||||
};
|
||||
|
||||
static void sql3_error_log_cb(void *arg, int err_code, const char *msg)
|
||||
@@ -234,7 +237,7 @@ void db_close(struct db_context *dbc)
|
||||
|
||||
static int db_run_statements(struct db_context *dbc, const char **statements, size_t statements_count)
|
||||
{
|
||||
int rc;
|
||||
int rc = 0;
|
||||
int i;
|
||||
for (i = 0; i < statements_count; i++) {
|
||||
const char *stmt_str = statements[i];
|
||||
@@ -487,6 +490,29 @@ static int db_upgrade_v5(struct db_context *dbc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int db_upgrade_v6(struct db_context *dbc)
|
||||
{
|
||||
int rc;
|
||||
const char *statements[] = {
|
||||
"CREATE TABLE ind (\n"
|
||||
" -- 3G auth IND pool to be used for this VLR\n"
|
||||
" ind INTEGER PRIMARY KEY,\n"
|
||||
" -- VLR identification, usually the GSUP source_name\n"
|
||||
" vlr TEXT NOT NULL,\n"
|
||||
" UNIQUE (vlr)\n"
|
||||
")"
|
||||
,
|
||||
"PRAGMA user_version = 6",
|
||||
};
|
||||
|
||||
rc = db_run_statements(dbc, statements, ARRAY_SIZE(statements));
|
||||
if (rc != SQLITE_DONE) {
|
||||
LOGP(DDB, LOGL_ERROR, "Unable to update HLR database schema to version 6\n");
|
||||
return rc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
typedef int (*db_upgrade_func_t)(struct db_context *dbc);
|
||||
static db_upgrade_func_t db_upgrade_path[] = {
|
||||
db_upgrade_v1,
|
||||
@@ -494,6 +520,7 @@ static db_upgrade_func_t db_upgrade_path[] = {
|
||||
db_upgrade_v3,
|
||||
db_upgrade_v4,
|
||||
db_upgrade_v5,
|
||||
db_upgrade_v6,
|
||||
};
|
||||
|
||||
static int db_get_user_version(struct db_context *dbc)
|
||||
|
||||
@@ -95,7 +95,10 @@ static int hexparse_stmt(uint8_t *dst, size_t dst_len, sqlite3_stmt *stmt, int c
|
||||
LOGAUC(imsi, LOGL_ERROR, "Error reading %s\n", col_name);
|
||||
return -EIO;
|
||||
}
|
||||
osmo_hexparse((void *)text, dst, dst_len);
|
||||
|
||||
if (osmo_hexparse((void *)text, dst, dst_len) != col_len)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
108
src/db_hlr.c
108
src/db_hlr.c
@@ -45,7 +45,8 @@
|
||||
* \param[in,out] dbc database context.
|
||||
* \param[in] imsi ASCII string of IMSI digits, is validated.
|
||||
* \param[in] flags Bitmask of DB_SUBSCR_FLAG_*.
|
||||
* \returns 0 on success, -EINVAL on invalid IMSI, -EIO on database error.
|
||||
* \returns 0 on success, -EINVAL on invalid IMSI, -EEXIST if subscriber with
|
||||
* provided imsi already exists, -EIO on other database errors.
|
||||
*/
|
||||
int db_subscr_create(struct db_context *dbc, const char *imsi, uint8_t flags)
|
||||
{
|
||||
@@ -73,6 +74,8 @@ int db_subscr_create(struct db_context *dbc, const char *imsi, uint8_t flags)
|
||||
if (rc != SQLITE_DONE) {
|
||||
LOGHLR(imsi, LOGL_ERROR, "Cannot create subscriber: SQL error: (%d) %s\n",
|
||||
rc, sqlite3_errmsg(dbc->db));
|
||||
if (rc == SQLITE_CONSTRAINT_UNIQUE)
|
||||
return -EEXIST;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -972,3 +975,106 @@ out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _db_ind_run(struct db_context *dbc, sqlite3_stmt *stmt, const char *vlr, bool reset)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!db_bind_text(stmt, "$vlr", vlr))
|
||||
return -EIO;
|
||||
|
||||
/* execute the statement */
|
||||
rc = sqlite3_step(stmt);
|
||||
if (reset)
|
||||
db_remove_reset(stmt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int _db_ind_add(struct db_context *dbc, const char *vlr)
|
||||
{
|
||||
sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_ADD];
|
||||
if (_db_ind_run(dbc, stmt, vlr, true) != SQLITE_DONE) {
|
||||
LOGP(DDB, LOGL_ERROR, "Cannot create IND entry for %s\n", osmo_quote_str_c(OTC_SELECT, vlr, -1));
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _db_ind_del(struct db_context *dbc, const char *vlr)
|
||||
{
|
||||
sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_DEL];
|
||||
_db_ind_run(dbc, stmt, vlr, true);
|
||||
/* We don't really care about the result. If it didn't exist, then that was the goal anyway. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _db_ind_get(struct db_context *dbc, const char *vlr, unsigned int *ind)
|
||||
{
|
||||
int ret = 0;
|
||||
sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_SELECT];
|
||||
int rc = _db_ind_run(dbc, stmt, vlr, false);
|
||||
if (rc == SQLITE_DONE) {
|
||||
/* Does not exist yet */
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
} else if (rc != SQLITE_ROW) {
|
||||
LOGP(DDB, LOGL_ERROR, "Error executing SQL: %d\n", rc);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
OSMO_ASSERT(ind);
|
||||
*ind = sqlite3_column_int64(stmt, 0);
|
||||
out:
|
||||
db_remove_reset(stmt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _db_ind(struct db_context *dbc, const struct osmo_cni_peer_id *vlr,
|
||||
unsigned int *ind, bool del)
|
||||
{
|
||||
const char *vlr_name = NULL;
|
||||
int rc;
|
||||
|
||||
switch (vlr->type) {
|
||||
case OSMO_CNI_PEER_ID_IPA_NAME:
|
||||
if (vlr->ipa_name.len < 2 || vlr->ipa_name.val[vlr->ipa_name.len - 1] != '\0') {
|
||||
LOGP(DDB, LOGL_ERROR, "Expecting VLR ipa_name to be zero terminated; found %s\n",
|
||||
osmo_ipa_name_to_str(&vlr->ipa_name));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
vlr_name = (const char*)vlr->ipa_name.val;
|
||||
break;
|
||||
default:
|
||||
LOGP(DDB, LOGL_ERROR, "Unsupported osmo_cni_peer_id type: %s\n",
|
||||
osmo_cni_peer_id_type_name(vlr->type));
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (del)
|
||||
return _db_ind_del(dbc, vlr_name);
|
||||
|
||||
rc = _db_ind_get(dbc, vlr_name, ind);
|
||||
if (!rc)
|
||||
return 0;
|
||||
|
||||
/* Does not exist yet, create. */
|
||||
rc = _db_ind_add(dbc, vlr_name);
|
||||
if (rc) {
|
||||
LOGP(DDB, LOGL_ERROR, "Error creating IND entry for %s\n", osmo_quote_str_c(OTC_SELECT, vlr_name, -1));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* To be sure, query again from scratch. */
|
||||
return _db_ind_get(dbc, vlr_name, ind);
|
||||
}
|
||||
|
||||
int db_ind(struct db_context *dbc, const struct osmo_cni_peer_id *vlr, unsigned int *ind)
|
||||
{
|
||||
return _db_ind(dbc, vlr, ind, false);
|
||||
}
|
||||
|
||||
int db_ind_del(struct db_context *dbc, const struct osmo_cni_peer_id *vlr)
|
||||
{
|
||||
return _db_ind(dbc, vlr, NULL, true);
|
||||
}
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* $Id: dbd_helper.c,v 1.44 2011/08/09 11:14:14 mhoenicka Exp $
|
||||
*/
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ void dgsm_init(void *ctx)
|
||||
|
||||
g_hlr->mslookup.server.local_attach_max_age = 60 * 60;
|
||||
|
||||
g_hlr->mslookup.client.result_timeout_milliseconds = 2000;
|
||||
g_hlr->mslookup.client.result_timeout_milliseconds = OSMO_DGSM_DEFAULT_RESULT_TIMEOUT_MS;
|
||||
|
||||
g_hlr->gsup_unit_name.unit_name = "HLR";
|
||||
g_hlr->gsup_unit_name.serno = "unnamed-HLR";
|
||||
@@ -191,7 +191,7 @@ void dgsm_start(void *ctx)
|
||||
dgsm_mdns_client_config_apply();
|
||||
}
|
||||
|
||||
void dgsm_stop()
|
||||
void dgsm_stop(void)
|
||||
{
|
||||
g_hlr->mslookup.allow_startup = false;
|
||||
mslookup_server_mdns_config_apply();
|
||||
|
||||
@@ -447,8 +447,8 @@ int config_write_mslookup(struct vty *vty)
|
||||
llist_for_each_entry(msc, &g_hlr->mslookup.server.local_site_services, entry) {
|
||||
if (!osmo_ipa_name_cmp(&mslookup_server_msc_wildcard, &msc->name))
|
||||
continue;
|
||||
vty_out(vty, " msc %s%s", osmo_ipa_name_to_str(&msc->name), VTY_NEWLINE);
|
||||
config_write_msc_services(vty, " ", msc);
|
||||
vty_out(vty, " msc ipa-name %s%s", osmo_ipa_name_to_str(&msc->name), VTY_NEWLINE);
|
||||
config_write_msc_services(vty, " ", msc);
|
||||
}
|
||||
|
||||
/* If the server is disabled, still output the above to not lose the service config. */
|
||||
@@ -475,6 +475,10 @@ int config_write_mslookup(struct vty *vty)
|
||||
vty_out(vty, " mdns domain-suffix %s%s",
|
||||
g_hlr->mslookup.client.mdns.domain_suffix,
|
||||
VTY_NEWLINE);
|
||||
if (g_hlr->mslookup.client.result_timeout_milliseconds != OSMO_DGSM_DEFAULT_RESULT_TIMEOUT_MS)
|
||||
vty_out(vty, " timeout %u%s",
|
||||
g_hlr->mslookup.client.result_timeout_milliseconds,
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
||||
@@ -317,43 +317,6 @@ static int osmo_gsup_server_closed_cb(struct ipa_server_conn *conn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add conn to the clients list in a way that conn->auc_3g_ind takes the lowest
|
||||
* unused integer and the list of clients remains sorted by auc_3g_ind.
|
||||
* Keep this function non-static to allow linking in a unit test. */
|
||||
void osmo_gsup_server_add_conn(struct llist_head *clients,
|
||||
struct osmo_gsup_conn *conn)
|
||||
{
|
||||
struct osmo_gsup_conn *c;
|
||||
struct osmo_gsup_conn *prev_conn;
|
||||
|
||||
c = llist_first_entry_or_null(clients, struct osmo_gsup_conn, list);
|
||||
|
||||
/* Is the first index, 0, unused? */
|
||||
if (!c || c->auc_3g_ind > 0) {
|
||||
conn->auc_3g_ind = 0;
|
||||
llist_add(&conn->list, clients);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Look for a gap later on */
|
||||
prev_conn = NULL;
|
||||
llist_for_each_entry(c, clients, list) {
|
||||
/* skip first item, we know it has auc_3g_ind == 0. */
|
||||
if (!prev_conn) {
|
||||
prev_conn = c;
|
||||
continue;
|
||||
}
|
||||
if (c->auc_3g_ind > prev_conn->auc_3g_ind + 1)
|
||||
break;
|
||||
prev_conn = c;
|
||||
}
|
||||
|
||||
OSMO_ASSERT(prev_conn);
|
||||
|
||||
conn->auc_3g_ind = prev_conn->auc_3g_ind + 1;
|
||||
llist_add(&conn->list, &prev_conn->list);
|
||||
}
|
||||
|
||||
static void update_fd_settings(int fd)
|
||||
{
|
||||
int ret;
|
||||
@@ -386,10 +349,9 @@ static int osmo_gsup_server_accept_cb(struct ipa_server_link *link, int fd)
|
||||
|
||||
/* link data structure with server structure */
|
||||
conn->server = gsups;
|
||||
osmo_gsup_server_add_conn(&gsups->clients, conn);
|
||||
llist_add_tail(&conn->list, &gsups->clients);
|
||||
|
||||
LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d (IND=%u)\n",
|
||||
conn->conn->addr, conn->conn->port, conn->auc_3g_ind);
|
||||
LOGP(DLGSUP, LOGL_INFO, "New GSUP client %s:%d\n", conn->conn->addr, conn->conn->port);
|
||||
|
||||
update_fd_settings(fd);
|
||||
|
||||
|
||||
27
src/hlr.c
27
src/hlr.c
@@ -281,13 +281,14 @@ int hlr_subscr_nam(struct hlr *hlr, struct hlr_subscriber *subscr, bool nam_val,
|
||||
***********************************************************************/
|
||||
|
||||
/* process an incoming SAI request */
|
||||
static int rx_send_auth_info(unsigned int auc_3g_ind, struct osmo_gsup_req *req)
|
||||
static int rx_send_auth_info(struct osmo_gsup_req *req)
|
||||
{
|
||||
struct osmo_gsup_message gsup_out = {
|
||||
.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT,
|
||||
};
|
||||
bool separation_bit = false;
|
||||
int num_auth_vectors = OSMO_GSUP_MAX_NUM_AUTH_INFO;
|
||||
unsigned int auc_3g_ind;
|
||||
int rc;
|
||||
|
||||
subscr_create_on_demand(req->gsup.imsi);
|
||||
@@ -298,6 +299,14 @@ static int rx_send_auth_info(unsigned int auc_3g_ind, struct osmo_gsup_req *req)
|
||||
if (req->gsup.num_auth_vectors > 0 &&
|
||||
req->gsup.num_auth_vectors <= OSMO_GSUP_MAX_NUM_AUTH_INFO)
|
||||
num_auth_vectors = req->gsup.num_auth_vectors;
|
||||
rc = db_ind(g_hlr->dbc, &req->source_name, &auc_3g_ind);
|
||||
if (rc) {
|
||||
LOG_GSUP_REQ(req, LOGL_ERROR,
|
||||
"Unable to determine 3G auth IND for source %s (rc=%d),"
|
||||
" generating tuples with IND = 0\n",
|
||||
osmo_cni_peer_id_to_str(&req->source_name), rc);
|
||||
auc_3g_ind = 0;
|
||||
}
|
||||
|
||||
rc = db_get_auc(g_hlr->dbc, req->gsup.imsi, auc_3g_ind,
|
||||
gsup_out.auth_vectors,
|
||||
@@ -315,7 +324,7 @@ static int rx_send_auth_info(unsigned int auc_3g_ind, struct osmo_gsup_req *req)
|
||||
" Returning slightly inaccurate cause 'IMSI Unknown' via GSUP");
|
||||
return rc;
|
||||
case -ENOENT:
|
||||
osmo_gsup_req_respond_err(req, GMM_CAUSE_IMSI_UNKNOWN, "IMSI unknown");
|
||||
osmo_gsup_req_respond_err(req, g_hlr->reject_cause, "IMSI unknown");
|
||||
return rc;
|
||||
default:
|
||||
osmo_gsup_req_respond_err(req, GMM_CAUSE_NET_FAIL, "failure to look up IMSI in db");
|
||||
@@ -517,7 +526,7 @@ static int read_cb(struct osmo_gsup_conn *conn, struct msgb *msg)
|
||||
switch (req->gsup.message_type) {
|
||||
/* requests sent to us */
|
||||
case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
|
||||
rx_send_auth_info(conn->auc_3g_ind, req);
|
||||
rx_send_auth_info(req);
|
||||
break;
|
||||
case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
|
||||
rx_upd_loc_req(conn, req);
|
||||
@@ -559,12 +568,12 @@ static int read_cb(struct osmo_gsup_conn *conn, struct msgb *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_usage()
|
||||
static void print_usage(void)
|
||||
{
|
||||
printf("Usage: osmo-hlr\n");
|
||||
}
|
||||
|
||||
static void print_help()
|
||||
static void print_help(void)
|
||||
{
|
||||
printf(" -h --help This text.\n");
|
||||
printf(" -c --config-file filename The config file to use.\n");
|
||||
@@ -750,6 +759,8 @@ int main(int argc, char **argv)
|
||||
g_hlr->db_file_path = talloc_strdup(g_hlr, HLR_DEFAULT_DB_FILE_PATH);
|
||||
g_hlr->mslookup.server.mdns.domain_suffix = talloc_strdup(g_hlr, OSMO_MDNS_DOMAIN_SUFFIX_DEFAULT);
|
||||
g_hlr->mslookup.client.mdns.domain_suffix = talloc_strdup(g_hlr, OSMO_MDNS_DOMAIN_SUFFIX_DEFAULT);
|
||||
g_hlr->reject_cause = GMM_CAUSE_IMSI_UNKNOWN;
|
||||
g_hlr->no_proxy_reject_cause = GMM_CAUSE_IMSI_UNKNOWN;
|
||||
|
||||
/* Init default (call independent) SS session guard timeout value */
|
||||
g_hlr->ncss_guard_timeout = NCSS_GUARD_TIMEOUT_DEFAULT;
|
||||
@@ -766,7 +777,7 @@ int main(int argc, char **argv)
|
||||
osmo_stats_init(hlr_ctx);
|
||||
vty_init(&vty_info);
|
||||
ctrl_vty_init(hlr_ctx);
|
||||
hlr_vty_init();
|
||||
hlr_vty_init(hlr_ctx);
|
||||
dgsm_vty_init();
|
||||
osmo_cpu_sched_vty_init(hlr_ctx);
|
||||
handle_options(argc, argv);
|
||||
@@ -807,8 +818,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* start telnet after reading config for vty_get_bind_addr() */
|
||||
rc = telnet_init_dynif(hlr_ctx, NULL, vty_get_bind_addr(),
|
||||
OSMO_VTY_PORT_HLR);
|
||||
rc = telnet_init_default(hlr_ctx, NULL, OSMO_VTY_PORT_HLR);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -821,7 +831,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
proxy_init(g_hlr->gs);
|
||||
|
||||
g_hlr->ctrl_bind_addr = ctrl_vty_get_bind_addr();
|
||||
g_hlr->ctrl = hlr_controlif_setup(g_hlr);
|
||||
|
||||
dgsm_start(hlr_ctx);
|
||||
|
||||
@@ -51,7 +51,7 @@ static struct {
|
||||
.db_upgrade = false,
|
||||
};
|
||||
|
||||
static void print_help()
|
||||
static void print_help(void)
|
||||
{
|
||||
printf("\n");
|
||||
printf("Usage: osmo-hlr-db-tool [-l <hlr.db>] [create|import-nitb-db <nitb.db>]\n");
|
||||
|
||||
@@ -25,7 +25,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
#include <osmocom/vty/vty.h>
|
||||
#include <osmocom/vty/stats.h>
|
||||
#include <osmocom/vty/command.h>
|
||||
@@ -40,6 +43,36 @@
|
||||
#include <osmocom/hlr/hlr_ussd.h>
|
||||
#include <osmocom/hlr/gsup_server.h>
|
||||
|
||||
static const struct value_string gsm48_gmm_cause_vty_names[] = {
|
||||
{ GMM_CAUSE_IMSI_UNKNOWN, "imsi-unknown" },
|
||||
{ GMM_CAUSE_ILLEGAL_MS, "illegal-ms" },
|
||||
{ GMM_CAUSE_PLMN_NOTALLOWED, "plmn-not-allowed" },
|
||||
{ GMM_CAUSE_LA_NOTALLOWED, "la-not-allowed" },
|
||||
{ GMM_CAUSE_ROAMING_NOTALLOWED, "roaming-not-allowed" },
|
||||
{ GMM_CAUSE_NO_SUIT_CELL_IN_LA, "no-suitable-cell-in-la" },
|
||||
{ GMM_CAUSE_NET_FAIL, "net-fail" },
|
||||
{ GMM_CAUSE_CONGESTION, "congestion" },
|
||||
{ GMM_CAUSE_GSM_AUTH_UNACCEPT, "auth-unacceptable" },
|
||||
{ GMM_CAUSE_PROTO_ERR_UNSPEC, "proto-error-unspec" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
/* TS 24.008 4.4.4.7 */
|
||||
static const struct value_string gsm48_gmm_cause_vty_descs[] = {
|
||||
{ GMM_CAUSE_IMSI_UNKNOWN, " #02: (IMSI unknown in HLR)" },
|
||||
{ GMM_CAUSE_ILLEGAL_MS, " #03 (Illegal MS)" },
|
||||
{ GMM_CAUSE_PLMN_NOTALLOWED, " #11: (PLMN not allowed)" },
|
||||
{ GMM_CAUSE_LA_NOTALLOWED, " #12: (Location Area not allowed)" },
|
||||
{ GMM_CAUSE_ROAMING_NOTALLOWED, " #13: (Roaming not allowed in this location area)" },
|
||||
{ GMM_CAUSE_NO_SUIT_CELL_IN_LA, " #15: (No Suitable Cells In Location Area [continue search in PLMN])." },
|
||||
{ GMM_CAUSE_NET_FAIL, " #17: (Network Failure)" },
|
||||
{ GMM_CAUSE_CONGESTION, " #22: (Congestion)" },
|
||||
{ GMM_CAUSE_GSM_AUTH_UNACCEPT, " #23: (GSM authentication unacceptable [UMTS])" },
|
||||
{ GMM_CAUSE_PROTO_ERR_UNSPEC, "#111: (Protocol error, unspecified)" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
|
||||
struct cmd_node hlr_node = {
|
||||
HLR_NODE,
|
||||
"%s(config-hlr)# ",
|
||||
@@ -73,6 +106,15 @@ DEFUN(cfg_gsup,
|
||||
static int config_write_hlr(struct vty *vty)
|
||||
{
|
||||
vty_out(vty, "hlr%s", VTY_NEWLINE);
|
||||
|
||||
if (g_hlr->reject_cause != GMM_CAUSE_IMSI_UNKNOWN)
|
||||
vty_out(vty, " reject-cause not-found %s%s",
|
||||
get_value_string_or_null(gsm48_gmm_cause_vty_names,
|
||||
(uint32_t) g_hlr->reject_cause), VTY_NEWLINE);
|
||||
if (g_hlr->no_proxy_reject_cause != GMM_CAUSE_IMSI_UNKNOWN)
|
||||
vty_out(vty, " reject-cause no-proxy %s%s",
|
||||
get_value_string_or_null(gsm48_gmm_cause_vty_names,
|
||||
(uint32_t) g_hlr->no_proxy_reject_cause), VTY_NEWLINE);
|
||||
if (g_hlr->store_imei)
|
||||
vty_out(vty, " store-imei%s", VTY_NEWLINE);
|
||||
if (g_hlr->db_file_path && strcmp(g_hlr->db_file_path, HLR_DEFAULT_DB_FILE_PATH))
|
||||
@@ -116,8 +158,8 @@ static void show_one_conn(struct vty *vty, const struct osmo_gsup_conn *conn)
|
||||
rc = osmo_gsup_conn_ccm_get(conn, (uint8_t **) &name, IPAC_IDTAG_SERNR);
|
||||
OSMO_ASSERT(rc);
|
||||
|
||||
vty_out(vty, " '%s' from %s:%5u, CS=%u, PS=%u, 3G_IND=%u%s",
|
||||
name, isc->addr, isc->port, conn->supports_cs, conn->supports_ps, conn->auc_3g_ind,
|
||||
vty_out(vty, " '%s' from %s:%5u, CS=%u, PS=%u%s",
|
||||
name, isc->addr, isc->port, conn->supports_cs, conn->supports_ps,
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
@@ -158,7 +200,7 @@ DEFUN(cfg_hlr_gsup_ipa_name,
|
||||
{
|
||||
if (vty->type != VTY_FILE) {
|
||||
vty_out(vty, "gsup/ipa-name: The GSUP IPA name cannot be changed at run-time; "
|
||||
"It can only be set in the configuraton file.%s", VTY_NEWLINE);
|
||||
"It can only be set in the configuration file.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
@@ -358,6 +400,21 @@ DEFUN(cfg_ncss_guard_timeout, cfg_ncss_guard_timeout_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DEFUN(cfg_reject_cause, cfg_reject_cause_cmd,
|
||||
"reject-cause TYPE CAUSE", "") /* Dynamically Generated */
|
||||
{
|
||||
int cause_code = get_string_value(gsm48_gmm_cause_vty_names, argv[1]);
|
||||
OSMO_ASSERT(cause_code >= 0);
|
||||
|
||||
if (strcmp(argv[0], "not-found") == 0)
|
||||
g_hlr->reject_cause = (enum gsm48_gmm_cause) cause_code;
|
||||
if (strcmp(argv[0], "no-proxy") == 0)
|
||||
g_hlr->no_proxy_reject_cause = (enum gsm48_gmm_cause) cause_code;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_store_imei, cfg_store_imei_cmd,
|
||||
"store-imei",
|
||||
"Save the IMEI in the database when receiving Check IMEI requests. Note that an MSC does not necessarily send"
|
||||
@@ -450,8 +507,22 @@ int hlr_vty_is_config_node(struct vty *vty, int node)
|
||||
}
|
||||
}
|
||||
|
||||
void hlr_vty_init(void)
|
||||
void hlr_vty_init(void *hlr_ctx)
|
||||
{
|
||||
cfg_reject_cause_cmd.string =
|
||||
vty_cmd_string_from_valstr(hlr_ctx,
|
||||
gsm48_gmm_cause_vty_names,
|
||||
"reject-cause (not-found|no-proxy) (", "|", ")",
|
||||
VTY_DO_LOWER);
|
||||
|
||||
cfg_reject_cause_cmd.doc =
|
||||
vty_cmd_string_from_valstr(hlr_ctx,
|
||||
gsm48_gmm_cause_vty_descs,
|
||||
"GSUP/GMM cause to be sent\n"
|
||||
"in the case the IMSI could not be found in the database\n"
|
||||
"in the case no remote HLR reponded to mslookup GSUP request\n",
|
||||
"\n", "", 0);
|
||||
|
||||
logging_vty_add_cmds();
|
||||
osmo_talloc_vty_add_cmds();
|
||||
osmo_stats_vty_add_cmds();
|
||||
@@ -478,6 +549,7 @@ void hlr_vty_init(void)
|
||||
install_element(HLR_NODE, &cfg_ussd_defaultroute_cmd);
|
||||
install_element(HLR_NODE, &cfg_ussd_no_defaultroute_cmd);
|
||||
install_element(HLR_NODE, &cfg_ncss_guard_timeout_cmd);
|
||||
install_element(HLR_NODE, &cfg_reject_cause_cmd);
|
||||
install_element(HLR_NODE, &cfg_store_imei_cmd);
|
||||
install_element(HLR_NODE, &cfg_no_store_imei_cmd);
|
||||
install_element(HLR_NODE, &cfg_subscr_create_on_demand_cmd);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <osmocom/hlr/hlr.h>
|
||||
#include <osmocom/hlr/db.h>
|
||||
#include <osmocom/hlr/timestamp.h>
|
||||
#include <osmocom/hlr/hlr_vty.h>
|
||||
|
||||
struct vty;
|
||||
|
||||
@@ -346,7 +347,7 @@ DEFUN(subscriber_create,
|
||||
int rc;
|
||||
struct hlr_subscriber subscr;
|
||||
const char *imsi = argv[0];
|
||||
|
||||
|
||||
if (!osmo_imsi_str_valid(imsi)) {
|
||||
vty_out(vty, "%% Not a valid IMSI: %s%s", imsi, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
@@ -470,14 +471,8 @@ static bool is_hexkey_valid(struct vty *vty, const char *label,
|
||||
#define AUTH_ALG_TYPES_3G_HELP \
|
||||
"Use Milenage algorithm\n"
|
||||
|
||||
#define A38_XOR_MIN_KEY_LEN 12
|
||||
#define A38_XOR_MAX_KEY_LEN 16
|
||||
#define A38_COMP128_KEY_LEN 16
|
||||
|
||||
#define MILENAGE_KEY_LEN 16
|
||||
|
||||
static bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
|
||||
int *minlen, int *maxlen)
|
||||
bool auth_algo_parse(const char *alg_str, enum osmo_auth_algo *algo,
|
||||
int *minlen, int *maxlen)
|
||||
{
|
||||
if (!strcasecmp(alg_str, "none")) {
|
||||
*algo = OSMO_AUTH_ALG_NONE;
|
||||
@@ -636,7 +631,7 @@ DEFUN(subscriber_aud3g,
|
||||
.ind_bitlen = ind_bitlen,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
if (!auth_algo_parse(alg_type, &aud3g.algo, &minlen, &maxlen)) {
|
||||
vty_out(vty, "%% Unknown auth algorithm: '%s'%s", alg_type, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
|
||||
@@ -43,6 +43,12 @@ const struct log_info_cat hlr_log_info_cat[] = {
|
||||
.color = "\033[1;35m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
[DCTRL] = {
|
||||
.name = "DCTRL",
|
||||
.description = "Osmocom CTRL interface",
|
||||
.color = "\033[1;30m",
|
||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||
},
|
||||
};
|
||||
|
||||
const struct log_info hlr_log_info = {
|
||||
|
||||
@@ -136,7 +136,7 @@ static void lu_start(struct osmo_gsup_req *update_location_req)
|
||||
}
|
||||
|
||||
if (db_subscr_get_by_imsi(g_hlr->dbc, update_location_req->gsup.imsi, &lu->subscr) < 0) {
|
||||
lu_failure(lu, GMM_CAUSE_IMSI_UNKNOWN, "Subscriber does not exist");
|
||||
lu_failure(lu, g_hlr->reject_cause, "Subscriber does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ static struct osmo_fsm lu_fsm = {
|
||||
.cleanup = lu_fsm_cleanup,
|
||||
};
|
||||
|
||||
static __attribute__((constructor)) void lu_fsm_init()
|
||||
static __attribute__((constructor)) void lu_fsm_init(void)
|
||||
{
|
||||
OSMO_ASSERT(osmo_fsm_register(&lu_fsm) == 0);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# This is _NOT_ the library release version, it's an API version.
|
||||
# Please read chapter "Library interface versions" of the libtool documentation
|
||||
# before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html
|
||||
LIBVERSION=0:0:0
|
||||
LIBVERSION=1:0:0
|
||||
|
||||
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)/include
|
||||
AM_CFLAGS = -fPIC -Wall $(PCSC_CFLAGS) $(TALLOC_CFLAGS) $(LIBOSMOCORE_CFLAGS)
|
||||
|
||||
@@ -40,7 +40,7 @@ int osmo_mdns_msg_request_encode(void *ctx, struct msgb *msg, const struct osmo_
|
||||
qst.domain = req->domain;
|
||||
qst.qtype = req->type;
|
||||
qst.qclass = OSMO_MDNS_RFC_CLASS_IN;
|
||||
if (osmo_mdns_rfc_question_encode(ctx, msg, &qst) != 0)
|
||||
if (osmo_mdns_rfc_question_encode(msg, &qst) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -106,7 +106,7 @@ int osmo_mdns_msg_answer_encode(void *ctx, struct msgb *msg, const struct osmo_m
|
||||
rec.rdlength = ans_record->length;
|
||||
rec.rdata = ans_record->data;
|
||||
|
||||
if (osmo_mdns_rfc_record_encode(ctx, msg, &rec) != 0)
|
||||
if (osmo_mdns_rfc_record_encode(msg, &rec) != 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,91 +27,9 @@
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/bitvec.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/gsm/apn.h>
|
||||
#include <osmocom/mslookup/mdns_rfc.h>
|
||||
|
||||
/*
|
||||
* Encode/decode IEs
|
||||
*/
|
||||
|
||||
/*! Encode a domain string as qname (RFC 1035 4.1.2).
|
||||
* \param[in] domain multiple labels separated by dots, e.g. "sip.voice.1234.msisdn".
|
||||
* \returns allocated buffer with length-value pairs for each label (e.g. 0x03 "sip" 0x05 "voice" ...), NULL on error.
|
||||
*/
|
||||
char *osmo_mdns_rfc_qname_encode(void *ctx, const char *domain)
|
||||
{
|
||||
char *domain_dup;
|
||||
char *domain_iter;
|
||||
char buf[OSMO_MDNS_RFC_MAX_NAME_LEN + 2] = ""; /* len(qname) is len(domain) +1 */
|
||||
struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) };
|
||||
char *label;
|
||||
|
||||
if (strlen(domain) > OSMO_MDNS_RFC_MAX_NAME_LEN)
|
||||
return NULL;
|
||||
|
||||
domain_iter = domain_dup = talloc_strdup(ctx, domain);
|
||||
while ((label = strsep(&domain_iter, "."))) {
|
||||
size_t len = strlen(label);
|
||||
|
||||
/* Empty domain, dot at start, two dots in a row, or ending with a dot */
|
||||
if (!len)
|
||||
goto error;
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "%c%s", (char)len, label);
|
||||
}
|
||||
|
||||
talloc_free(domain_dup);
|
||||
return talloc_strdup(ctx, buf);
|
||||
|
||||
error:
|
||||
talloc_free(domain_dup);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Decode a domain string from a qname (RFC 1035 4.1.2).
|
||||
* \param[in] qname buffer with length-value pairs for each label (e.g. 0x03 "sip" 0x05 "voice" ...)
|
||||
* \param[in] qname_max_len amount of bytes that can be read at most from the memory location that qname points to.
|
||||
* \returns allocated buffer with domain string, multiple labels separated by dots (e.g. "sip.voice.1234.msisdn"),
|
||||
* NULL on error.
|
||||
*/
|
||||
char *osmo_mdns_rfc_qname_decode(void *ctx, const char *qname, size_t qname_max_len)
|
||||
{
|
||||
const char *next_label, *qname_end = qname + qname_max_len;
|
||||
char buf[OSMO_MDNS_RFC_MAX_NAME_LEN + 1];
|
||||
int i = 0;
|
||||
|
||||
if (qname_max_len < 1)
|
||||
return NULL;
|
||||
|
||||
while (*qname) {
|
||||
size_t len;
|
||||
|
||||
if (i >= qname_max_len)
|
||||
return NULL;
|
||||
|
||||
len = *qname;
|
||||
next_label = qname + len + 1;
|
||||
|
||||
if (next_label >= qname_end || i + len > OSMO_MDNS_RFC_MAX_NAME_LEN)
|
||||
return NULL;
|
||||
|
||||
if (i) {
|
||||
/* Two dots in a row is not allowed */
|
||||
if (buf[i - 1] == '.')
|
||||
return NULL;
|
||||
|
||||
buf[i] = '.';
|
||||
i++;
|
||||
}
|
||||
|
||||
memcpy(buf + i, qname + 1, len);
|
||||
i += len;
|
||||
qname = next_label;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
|
||||
return talloc_strdup(ctx, buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode/decode message sections
|
||||
*/
|
||||
@@ -151,20 +69,17 @@ int osmo_mdns_rfc_header_decode(const uint8_t *data, size_t data_len, struct osm
|
||||
/*! Encode question section (RFC 1035 4.1.2).
|
||||
* \param[in] msgb mesage buffer to which the encoded data will be appended.
|
||||
*/
|
||||
int osmo_mdns_rfc_question_encode(void *ctx, struct msgb *msg, const struct osmo_mdns_rfc_question *qst)
|
||||
int osmo_mdns_rfc_question_encode(struct msgb *msg, const struct osmo_mdns_rfc_question *qst)
|
||||
{
|
||||
char *qname;
|
||||
size_t qname_len;
|
||||
uint8_t *qname_buf;
|
||||
uint8_t *buf;
|
||||
size_t buf_len;
|
||||
|
||||
/* qname */
|
||||
qname = osmo_mdns_rfc_qname_encode(ctx, qst->domain);
|
||||
if (!qname)
|
||||
buf_len = strlen(qst->domain) + 1;
|
||||
buf = msgb_put(msg, buf_len);
|
||||
if (osmo_apn_from_str(buf, buf_len, qst->domain) < 0)
|
||||
return -EINVAL;
|
||||
qname_len = strlen(qname) + 1;
|
||||
qname_buf = msgb_put(msg, qname_len);
|
||||
memcpy(qname_buf, qname, qname_len);
|
||||
talloc_free(qname);
|
||||
msgb_put_u8(msg, 0x00);
|
||||
|
||||
/* qtype and qclass */
|
||||
msgb_put_u16(msg, qst->qtype);
|
||||
@@ -182,21 +97,25 @@ struct osmo_mdns_rfc_question *osmo_mdns_rfc_question_decode(void *ctx, const ui
|
||||
if (data_len < 6)
|
||||
return NULL;
|
||||
|
||||
/* qname */
|
||||
ret = talloc_zero(ctx, struct osmo_mdns_rfc_question);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->domain = osmo_mdns_rfc_qname_decode(ret, (const char *)data, qname_len);
|
||||
if (!ret->domain) {
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* qname */
|
||||
ret->domain = talloc_size(ret, qname_len - 1);
|
||||
if (!ret->domain)
|
||||
goto error;
|
||||
if (!osmo_apn_to_str(ret->domain, data, qname_len - 1))
|
||||
goto error;
|
||||
|
||||
/* qtype and qclass */
|
||||
ret->qtype = osmo_load16be(data + qname_len);
|
||||
ret->qclass = osmo_load16be(data + qname_len + 2);
|
||||
|
||||
return ret;
|
||||
error:
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -206,20 +125,17 @@ struct osmo_mdns_rfc_question *osmo_mdns_rfc_question_decode(void *ctx, const ui
|
||||
/*! Encode one resource record (RFC 1035 4.1.3).
|
||||
* \param[in] msgb mesage buffer to which the encoded data will be appended.
|
||||
*/
|
||||
int osmo_mdns_rfc_record_encode(void *ctx, struct msgb *msg, const struct osmo_mdns_rfc_record *rec)
|
||||
int osmo_mdns_rfc_record_encode(struct msgb *msg, const struct osmo_mdns_rfc_record *rec)
|
||||
{
|
||||
char *name;
|
||||
size_t name_len;
|
||||
uint8_t *buf;
|
||||
size_t buf_len;
|
||||
|
||||
/* name */
|
||||
name = osmo_mdns_rfc_qname_encode(ctx, rec->domain);
|
||||
if (!name)
|
||||
buf_len = strlen(rec->domain) + 1;
|
||||
buf = msgb_put(msg, buf_len);
|
||||
if (osmo_apn_from_str(buf, buf_len, rec->domain) < 0)
|
||||
return -EINVAL;
|
||||
name_len = strlen(name) + 1;
|
||||
buf = msgb_put(msg, name_len);
|
||||
memcpy(buf, name, name_len);
|
||||
talloc_free(name);
|
||||
msgb_put_u8(msg, 0x00);
|
||||
|
||||
/* type, class, ttl, rdlength */
|
||||
msgb_put_u16(msg, rec->type);
|
||||
@@ -237,15 +153,26 @@ int osmo_mdns_rfc_record_encode(void *ctx, struct msgb *msg, const struct osmo_m
|
||||
struct osmo_mdns_rfc_record *osmo_mdns_rfc_record_decode(void *ctx, const uint8_t *data, size_t data_len,
|
||||
size_t *record_len)
|
||||
{
|
||||
struct osmo_mdns_rfc_record *ret = talloc_zero(ctx, struct osmo_mdns_rfc_record);
|
||||
struct osmo_mdns_rfc_record *ret;
|
||||
size_t name_len;
|
||||
|
||||
/* name */
|
||||
ret->domain = osmo_mdns_rfc_qname_decode(ret, (const char *)data, data_len - 10);
|
||||
/* name length: represented as a series of labels, and terminated by a
|
||||
* label with zero length (RFC 1035 3.3). A label with zero length is a
|
||||
* NUL byte. */
|
||||
name_len = strnlen((const char *)data, data_len - 10) + 1;
|
||||
if (data[name_len])
|
||||
return NULL;
|
||||
|
||||
/* allocate ret + ret->domain */
|
||||
ret = talloc_zero(ctx, struct osmo_mdns_rfc_record);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->domain = talloc_size(ctx, name_len - 1);
|
||||
if (!ret->domain)
|
||||
goto error;
|
||||
name_len = strlen(ret->domain) + 2;
|
||||
if (name_len + 10 > data_len)
|
||||
|
||||
/* name */
|
||||
if (!osmo_apn_to_str(ret->domain, data, name_len - 1))
|
||||
goto error;
|
||||
|
||||
/* type, class, ttl, rdlength */
|
||||
@@ -259,7 +186,7 @@ struct osmo_mdns_rfc_record *osmo_mdns_rfc_record_decode(void *ctx, const uint8_
|
||||
/* rdata */
|
||||
ret->rdata = talloc_memdup(ret, data + name_len + 10, ret->rdlength);
|
||||
if (!ret->rdata)
|
||||
return NULL;
|
||||
goto error;
|
||||
|
||||
*record_len = name_len + 10 + ret->rdlength;
|
||||
return ret;
|
||||
|
||||
@@ -53,7 +53,7 @@ static void print_version(void)
|
||||
"\n");
|
||||
}
|
||||
|
||||
static void print_help()
|
||||
static void print_help(void)
|
||||
{
|
||||
print_version();
|
||||
printf(
|
||||
@@ -555,7 +555,7 @@ int socket_init(const char *sock_path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void socket_close()
|
||||
void socket_close(void)
|
||||
{
|
||||
struct socket_client *c, *n;
|
||||
llist_for_each_entry_safe(c, n, &globals.socket_clients, entry)
|
||||
|
||||
@@ -49,7 +49,7 @@ static void set_result(struct osmo_mslookup_result *result,
|
||||
result->age = age;
|
||||
}
|
||||
|
||||
const struct mslookup_service_host *mslookup_server_get_local_gsup_addr()
|
||||
const struct mslookup_service_host *mslookup_server_get_local_gsup_addr(void)
|
||||
{
|
||||
static struct mslookup_service_host gsup_bind = {};
|
||||
struct mslookup_service_host *host;
|
||||
|
||||
@@ -121,7 +121,7 @@ void osmo_mslookup_server_mdns_stop(struct osmo_mslookup_server_mdns *server)
|
||||
talloc_free(server);
|
||||
}
|
||||
|
||||
void mslookup_server_mdns_config_apply()
|
||||
void mslookup_server_mdns_config_apply(void)
|
||||
{
|
||||
/* Check whether to start/stop/restart mDNS server */
|
||||
bool should_run;
|
||||
|
||||
16
src/proxy.c
16
src/proxy.c
@@ -29,6 +29,7 @@
|
||||
#include <osmocom/gsupclient/gsup_client.h>
|
||||
#include <osmocom/gsupclient/gsup_req.h>
|
||||
|
||||
#include <osmocom/hlr/hlr.h>
|
||||
#include <osmocom/hlr/logging.h>
|
||||
#include <osmocom/hlr/proxy.h>
|
||||
#include <osmocom/hlr/remote_hlr.h>
|
||||
@@ -80,7 +81,19 @@ static void proxy_deferred_gsup_req_add(struct proxy *proxy, struct osmo_gsup_re
|
||||
static void proxy_pending_req_remote_hlr_connect_result(struct osmo_gsup_req *req, struct remote_hlr *remote_hlr)
|
||||
{
|
||||
if (!remote_hlr || !remote_hlr_is_up(remote_hlr)) {
|
||||
osmo_gsup_req_respond_err(req, GMM_CAUSE_IMSI_UNKNOWN, "Proxy: Failed to connect to home HLR");
|
||||
/* Do not respond with an error to a CHECK_IMEI_REQUEST as osmo-msc will send a LU Reject Cause #6
|
||||
* Just respond ACK and deal with the IMSI check that comes next. */
|
||||
if (req->gsup.message_type == OSMO_GSUP_MSGT_CHECK_IMEI_REQUEST) {
|
||||
/* Accept all IMEIs */
|
||||
struct osmo_gsup_message gsup_reply = (struct osmo_gsup_message){
|
||||
.message_type = OSMO_GSUP_MSGT_CHECK_IMEI_RESULT,
|
||||
.imei_result = OSMO_GSUP_IMEI_RESULT_ACK,
|
||||
};
|
||||
osmo_gsup_req_respond(req, &gsup_reply, false, true);
|
||||
return;
|
||||
}
|
||||
osmo_gsup_req_respond_err(req, g_hlr->no_proxy_reject_cause,
|
||||
"Proxy: Failed to connect to home HLR");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -190,6 +203,7 @@ int proxy_subscr_create_or_update(struct proxy *proxy, const struct proxy_subscr
|
||||
int _proxy_subscr_del(struct proxy_subscr_listentry *e)
|
||||
{
|
||||
llist_del(&e->entry);
|
||||
talloc_free(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
SUBDIRS = \
|
||||
auc \
|
||||
gsup_server \
|
||||
db \
|
||||
gsup \
|
||||
db_upgrade \
|
||||
@@ -70,6 +69,9 @@ vty-test:
|
||||
|
||||
CTRL_TEST_DB = hlr_ctrl_test.db
|
||||
|
||||
# Run a specific test with: 'make ctrl-test CTRL_TEST=test_subscriber.ctrl'
|
||||
CTRL_TEST ?= *.ctrl
|
||||
|
||||
# To update the CTRL script from current application behavior,
|
||||
# pass -u to ctrl_script_runner.py by doing:
|
||||
# make ctrl-test U=-u
|
||||
@@ -80,7 +82,7 @@ ctrl-test:
|
||||
osmo_verify_transcript_ctrl.py -v \
|
||||
-p 4259 \
|
||||
-r "$(top_builddir)/src/osmo-hlr -c $(top_srcdir)/doc/examples/osmo-hlr.cfg -l $(CTRL_TEST_DB)" \
|
||||
$(U) $(srcdir)/*.ctrl
|
||||
$(U) $(srcdir)/$(CTRL_TEST)
|
||||
-rm -f $(CTRL_TEST_DB)
|
||||
-rm $(CTRL_TEST_DB)-*
|
||||
|
||||
|
||||
@@ -23,9 +23,7 @@ EXTRA_DIST = \
|
||||
auc_ts_55_205_test_sets.err \
|
||||
$(NULL)
|
||||
|
||||
check_PROGRAMS = auc_ts_55_205_test_sets
|
||||
|
||||
noinst_PROGRAMS = auc_test
|
||||
check_PROGRAMS = auc_test auc_ts_55_205_test_sets
|
||||
|
||||
auc_test_SOURCES = \
|
||||
auc_test.c \
|
||||
|
||||
@@ -509,7 +509,7 @@ static void test_gen_vectors_3g_xor(void)
|
||||
}
|
||||
|
||||
/* Test a variety of invalid authentication data combinations */
|
||||
void test_gen_vectors_bad_args()
|
||||
void test_gen_vectors_bad_args(void)
|
||||
{
|
||||
struct osmo_auth_vector vec;
|
||||
uint8_t auts[14];
|
||||
|
||||
@@ -100,7 +100,7 @@ int rand_get(uint8_t *rand, unsigned int len)
|
||||
|
||||
FUNCTIONS
|
||||
|
||||
int main()
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
printf("3GPP TS 55.205 Test Sets\n");
|
||||
void *tall_ctx = talloc_named_const(NULL, 1, "test");
|
||||
|
||||
@@ -246,7 +246,7 @@ static int db_subscr_lu_str(struct db_context *dbc, int64_t subscr_id,
|
||||
return db_subscr_lu(dbc, subscr_id, &vlr_nr, is_ps, NULL);
|
||||
}
|
||||
|
||||
static void test_subscr_create_update_sel_delete()
|
||||
static void test_subscr_create_update_sel_delete(void)
|
||||
{
|
||||
int64_t id0, id1, id2, id_short;
|
||||
comment_start();
|
||||
@@ -262,13 +262,13 @@ static void test_subscr_create_update_sel_delete()
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0);
|
||||
ASSERT_SEL(imsi, imsi2, 0);
|
||||
id2 = g_subscr.id;
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||
ASSERT_SEL(imsi, imsi0, 0);
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||
ASSERT_SEL(imsi, imsi1, 0);
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EIO);
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||
ASSERT_RC(db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EEXIST);
|
||||
ASSERT_SEL(imsi, imsi2, 0);
|
||||
|
||||
ASSERT_RC(db_subscr_create(dbc, "123456789 000003", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), -EINVAL);
|
||||
@@ -541,7 +541,7 @@ static const struct sub_auth_data_str *mk_aud_3g(enum osmo_auth_algo algo,
|
||||
return &aud;
|
||||
}
|
||||
|
||||
static void test_subscr_aud()
|
||||
static void test_subscr_aud(void)
|
||||
{
|
||||
int64_t id;
|
||||
|
||||
@@ -783,7 +783,7 @@ static void test_subscr_aud()
|
||||
|
||||
/* Make each key too short in this test. Note that we can't set them longer than the allowed size without changing the
|
||||
* table structure. */
|
||||
static void test_subscr_aud_invalid_len()
|
||||
static void test_subscr_aud_invalid_len(void)
|
||||
{
|
||||
int64_t id;
|
||||
|
||||
@@ -845,7 +845,7 @@ static void test_subscr_aud_invalid_len()
|
||||
comment_end();
|
||||
}
|
||||
|
||||
static void test_subscr_sqn()
|
||||
static void test_subscr_sqn(void)
|
||||
{
|
||||
int64_t id;
|
||||
|
||||
@@ -918,6 +918,50 @@ static void test_subscr_sqn()
|
||||
comment_end();
|
||||
}
|
||||
|
||||
static void test_ind(void)
|
||||
{
|
||||
comment_start();
|
||||
|
||||
#define ASSERT_IND(VLR, IND) do { \
|
||||
unsigned int ind; \
|
||||
struct osmo_cni_peer_id vlr; \
|
||||
OSMO_ASSERT(!osmo_cni_peer_id_set_str(&vlr, OSMO_CNI_PEER_ID_IPA_NAME, VLR)); \
|
||||
ASSERT_RC(db_ind(dbc, &vlr, &ind), 0); \
|
||||
fprintf(stderr, "%s ind = %u\n\n", osmo_quote_str((char*)vlr.ipa_name.val, vlr.ipa_name.len), ind); \
|
||||
if (ind != (IND)) \
|
||||
fprintf(stderr, " ERROR: expected " #IND "\n"); \
|
||||
} while (0)
|
||||
#define IND_DEL(VLR) do { \
|
||||
struct osmo_cni_peer_id vlr; \
|
||||
OSMO_ASSERT(!osmo_cni_peer_id_set_str(&vlr, OSMO_CNI_PEER_ID_IPA_NAME, VLR)); \
|
||||
ASSERT_RC(db_ind_del(dbc, &vlr), 0); \
|
||||
fprintf(stderr, "%s ind deleted\n\n", osmo_quote_str((char*)vlr.ipa_name.val, vlr.ipa_name.len)); \
|
||||
} while (0)
|
||||
|
||||
ASSERT_IND("msc-23", 1);
|
||||
ASSERT_IND("sgsn-11", 2);
|
||||
ASSERT_IND("msc-42", 3);
|
||||
ASSERT_IND("sgsn-22", 4);
|
||||
ASSERT_IND("msc-0x17", 5);
|
||||
ASSERT_IND("sgsn-0xaa", 6);
|
||||
ASSERT_IND("msc-42", 3);
|
||||
ASSERT_IND("sgsn-22", 4);
|
||||
ASSERT_IND("msc-0x17", 5);
|
||||
ASSERT_IND("sgsn-0xaa", 6);
|
||||
ASSERT_IND("sgsn-0xbb", 7);
|
||||
ASSERT_IND("msc-0x2a", 8);
|
||||
ASSERT_IND("msc-42", 3);
|
||||
ASSERT_IND("sgsn-22", 4);
|
||||
ASSERT_IND("msc-23", 1);
|
||||
ASSERT_IND("sgsn-11", 2);
|
||||
|
||||
IND_DEL("msc-0x17"); /* dropped IND == 5 */
|
||||
ASSERT_IND("msc-0x2a", 8); /* known CS remains where it is */
|
||||
ASSERT_IND("any-unknown", 9); /* new VLR takes a new IND from the end */
|
||||
|
||||
comment_end();
|
||||
}
|
||||
|
||||
static struct {
|
||||
bool verbose;
|
||||
} cmdline_opts = {
|
||||
@@ -1002,6 +1046,7 @@ int main(int argc, char **argv)
|
||||
test_subscr_aud();
|
||||
test_subscr_aud_invalid_len();
|
||||
test_subscr_sqn();
|
||||
test_ind();
|
||||
|
||||
printf("Done\n");
|
||||
db_close(dbc);
|
||||
|
||||
@@ -27,7 +27,7 @@ struct hlr_subscriber {
|
||||
.imsi = '123456789000002',
|
||||
}
|
||||
|
||||
db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
||||
db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||
DAUC IMSI='123456789000000': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||
|
||||
db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0
|
||||
@@ -36,10 +36,10 @@ struct hlr_subscriber {
|
||||
.imsi = '123456789000000',
|
||||
}
|
||||
|
||||
db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
||||
db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||
DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||
|
||||
db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
||||
db_subscr_create(dbc, imsi1, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||
DAUC IMSI='123456789000001': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||
|
||||
db_subscr_get_by_imsi(dbc, imsi1, &g_subscr) --> 0
|
||||
@@ -48,10 +48,10 @@ struct hlr_subscriber {
|
||||
.imsi = '123456789000001',
|
||||
}
|
||||
|
||||
db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
||||
db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||
DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||
|
||||
db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EIO
|
||||
db_subscr_create(dbc, imsi2, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EEXIST
|
||||
DAUC IMSI='123456789000002': Cannot create subscriber: SQL error: (2067) UNIQUE constraint failed: subscriber.imsi
|
||||
|
||||
db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> 0
|
||||
@@ -1613,3 +1613,83 @@ db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> -ENOENT
|
||||
|
||||
===== test_subscr_sqn: SUCCESS
|
||||
|
||||
|
||||
===== test_ind
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"msc-23\0" ind = 1
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"sgsn-11\0" ind = 2
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"msc-42\0" ind = 3
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"sgsn-22\0" ind = 4
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"msc-0x17\0" ind = 5
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"sgsn-0xaa\0" ind = 6
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"msc-42\0" ind = 3
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"sgsn-22\0" ind = 4
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"msc-0x17\0" ind = 5
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"sgsn-0xaa\0" ind = 6
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"sgsn-0xbb\0" ind = 7
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"msc-0x2a\0" ind = 8
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"msc-42\0" ind = 3
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"sgsn-22\0" ind = 4
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"msc-23\0" ind = 1
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"sgsn-11\0" ind = 2
|
||||
|
||||
db_ind_del(dbc, &vlr) --> 0
|
||||
|
||||
"msc-0x17\0" ind deleted
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"msc-0x2a\0" ind = 8
|
||||
|
||||
db_ind(dbc, &vlr, &ind) --> 0
|
||||
|
||||
"any-unknown\0" ind = 9
|
||||
|
||||
===== test_ind: SUCCESS
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 2
|
||||
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 3
|
||||
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 4
|
||||
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 5
|
||||
DDB Database <PATH>test.db' has been upgraded to HLR DB schema version 6
|
||||
DMAIN Cmdline option --db-check: Database was opened successfully, quitting.
|
||||
|
||||
Resulting db:
|
||||
@@ -117,6 +118,13 @@ algo_id_3g|ind_bitlen|k|op|opc|sqn|subscriber_id
|
||||
5|5|44444444444444444444444444444444|44444444444444444444444444444444||0|5
|
||||
5|5|55555555555555555555555555555555||55555555555555555555555555555555|0|6
|
||||
|
||||
Table: ind
|
||||
name|type|notnull|dflt_value|pk
|
||||
ind|INTEGER|0||1
|
||||
vlr|TEXT|1||0
|
||||
|
||||
Table ind contents:
|
||||
|
||||
Table: subscriber
|
||||
name|type|notnull|dflt_value|pk
|
||||
ggsn_number|VARCHAR(15)|0||0
|
||||
@@ -171,5 +179,5 @@ osmo-hlr --database $db --db-check --config-file $srcdir/osmo-hlr.cfg
|
||||
rc = 0
|
||||
DMAIN hlr starting
|
||||
DDB using database: <PATH>test.db
|
||||
DDB Database <PATH>test.db' has HLR DB schema version 5
|
||||
DDB Database <PATH>test.db' has HLR DB schema version 6
|
||||
DMAIN Cmdline option --db-check: Database was opened successfully, quitting.
|
||||
|
||||
@@ -17,7 +17,7 @@ EXTRA_DIST = \
|
||||
gsup_test.err \
|
||||
$(NULL)
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
check_PROGRAMS = \
|
||||
gsup_test \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
AM_CPPFLAGS = \
|
||||
$(all_includes) \
|
||||
$(NULL)
|
||||
|
||||
AM_CFLAGS = \
|
||||
-Wall \
|
||||
-ggdb3 \
|
||||
-I$(top_srcdir)/include \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(LIBOSMOGSM_CFLAGS) \
|
||||
$(LIBOSMOABIS_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
AM_LDFLAGS = \
|
||||
-no-install \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
gsup_server_test.ok \
|
||||
gsup_server_test.err \
|
||||
$(NULL)
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
gsup_server_test \
|
||||
$(NULL)
|
||||
|
||||
gsup_server_test_SOURCES = \
|
||||
gsup_server_test.c \
|
||||
$(NULL)
|
||||
|
||||
gsup_server_test_LDADD = \
|
||||
$(top_srcdir)/src/gsup_server.c \
|
||||
$(top_srcdir)/src/gsup_router.c \
|
||||
$(top_srcdir)/src/gsup_send.c \
|
||||
$(top_srcdir)/src/gsupclient/cni_peer_id.c \
|
||||
$(top_srcdir)/src/gsupclient/gsup_req.c \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
$(LIBOSMOABIS_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
.PHONY: update_exp
|
||||
update_exp:
|
||||
$(builddir)/gsup_server_test >"$(srcdir)/gsup_server_test.ok" 2>"$(srcdir)/gsup_server_test.err"
|
||||
@@ -1,145 +0,0 @@
|
||||
/* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/hlr/gsup_server.h>
|
||||
|
||||
#define comment_start() printf("\n===== %s\n", __func__)
|
||||
#define comment_end() printf("===== %s: SUCCESS\n\n", __func__)
|
||||
#define btw(fmt, args...) printf("\n" fmt "\n", ## args)
|
||||
|
||||
#define VERBOSE_ASSERT(val, expect_op, fmt) \
|
||||
do { \
|
||||
printf(#val " == " fmt "\n", (val)); \
|
||||
OSMO_ASSERT((val) expect_op); \
|
||||
} while (0)
|
||||
|
||||
void osmo_gsup_server_add_conn(struct llist_head *clients,
|
||||
struct osmo_gsup_conn *conn);
|
||||
|
||||
static void test_add_conn(void)
|
||||
{
|
||||
struct llist_head _list;
|
||||
struct llist_head *clients = &_list;
|
||||
struct osmo_gsup_conn conn_inst[23] = {};
|
||||
struct osmo_gsup_conn *conn;
|
||||
unsigned int i;
|
||||
|
||||
comment_start();
|
||||
|
||||
INIT_LLIST_HEAD(clients);
|
||||
|
||||
btw("Add 10 items");
|
||||
for (i = 0; i < 10; i++) {
|
||||
osmo_gsup_server_add_conn(clients, &conn_inst[i]);
|
||||
printf("conn_inst[%u].auc_3g_ind == %u\n", i, conn_inst[i].auc_3g_ind);
|
||||
OSMO_ASSERT(clients->next == &conn_inst[0].list);
|
||||
}
|
||||
|
||||
btw("Expecting a list of 0..9");
|
||||
i = 0;
|
||||
llist_for_each_entry(conn, clients, list) {
|
||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
||||
OSMO_ASSERT(conn->auc_3g_ind == i);
|
||||
OSMO_ASSERT(conn == &conn_inst[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
btw("Punch two holes in the sequence in arbitrary order,"
|
||||
" a larger one from 2..4 and a single one at 7.");
|
||||
llist_del(&conn_inst[4].list);
|
||||
llist_del(&conn_inst[2].list);
|
||||
llist_del(&conn_inst[3].list);
|
||||
llist_del(&conn_inst[7].list);
|
||||
|
||||
btw("Expecting a list of 0,1, 5,6, 8,9");
|
||||
i = 0;
|
||||
llist_for_each_entry(conn, clients, list) {
|
||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
||||
i++;
|
||||
}
|
||||
|
||||
btw("Add conns, expecting them to take the open slots");
|
||||
osmo_gsup_server_add_conn(clients, &conn_inst[12]);
|
||||
VERBOSE_ASSERT(conn_inst[12].auc_3g_ind, == 2, "%u");
|
||||
|
||||
osmo_gsup_server_add_conn(clients, &conn_inst[13]);
|
||||
VERBOSE_ASSERT(conn_inst[13].auc_3g_ind, == 3, "%u");
|
||||
|
||||
osmo_gsup_server_add_conn(clients, &conn_inst[14]);
|
||||
VERBOSE_ASSERT(conn_inst[14].auc_3g_ind, == 4, "%u");
|
||||
|
||||
osmo_gsup_server_add_conn(clients, &conn_inst[17]);
|
||||
VERBOSE_ASSERT(conn_inst[17].auc_3g_ind, == 7, "%u");
|
||||
|
||||
osmo_gsup_server_add_conn(clients, &conn_inst[18]);
|
||||
VERBOSE_ASSERT(conn_inst[18].auc_3g_ind, == 10, "%u");
|
||||
|
||||
btw("Expecting a list of 0..10");
|
||||
i = 0;
|
||||
llist_for_each_entry(conn, clients, list) {
|
||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
||||
OSMO_ASSERT(conn->auc_3g_ind == i);
|
||||
i++;
|
||||
}
|
||||
|
||||
btw("Does it also work for the first item?");
|
||||
llist_del(&conn_inst[0].list);
|
||||
|
||||
btw("Expecting a list of 1..10");
|
||||
i = 0;
|
||||
llist_for_each_entry(conn, clients, list) {
|
||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
||||
OSMO_ASSERT(conn->auc_3g_ind == i + 1);
|
||||
i++;
|
||||
}
|
||||
|
||||
btw("Add another conn, should take auc_3g_ind == 0");
|
||||
osmo_gsup_server_add_conn(clients, &conn_inst[20]);
|
||||
VERBOSE_ASSERT(conn_inst[20].auc_3g_ind, == 0, "%u");
|
||||
|
||||
btw("Expecting a list of 0..10");
|
||||
i = 0;
|
||||
llist_for_each_entry(conn, clients, list) {
|
||||
printf("conn[%u].auc_3g_ind == %u\n", i, conn->auc_3g_ind);
|
||||
OSMO_ASSERT(conn->auc_3g_ind == i);
|
||||
i++;
|
||||
}
|
||||
|
||||
btw("If a client reconnects, it will (likely) get the same auc_3g_ind");
|
||||
VERBOSE_ASSERT(conn_inst[5].auc_3g_ind, == 5, "%u");
|
||||
llist_del(&conn_inst[5].list);
|
||||
conn_inst[5].auc_3g_ind = 423;
|
||||
osmo_gsup_server_add_conn(clients, &conn_inst[5]);
|
||||
VERBOSE_ASSERT(conn_inst[5].auc_3g_ind, == 5, "%u");
|
||||
|
||||
comment_end();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
printf("test_gsup_server.c\n");
|
||||
|
||||
test_add_conn();
|
||||
|
||||
printf("Done\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
test_gsup_server.c
|
||||
|
||||
===== test_add_conn
|
||||
|
||||
Add 10 items
|
||||
conn_inst[0].auc_3g_ind == 0
|
||||
conn_inst[1].auc_3g_ind == 1
|
||||
conn_inst[2].auc_3g_ind == 2
|
||||
conn_inst[3].auc_3g_ind == 3
|
||||
conn_inst[4].auc_3g_ind == 4
|
||||
conn_inst[5].auc_3g_ind == 5
|
||||
conn_inst[6].auc_3g_ind == 6
|
||||
conn_inst[7].auc_3g_ind == 7
|
||||
conn_inst[8].auc_3g_ind == 8
|
||||
conn_inst[9].auc_3g_ind == 9
|
||||
|
||||
Expecting a list of 0..9
|
||||
conn[0].auc_3g_ind == 0
|
||||
conn[1].auc_3g_ind == 1
|
||||
conn[2].auc_3g_ind == 2
|
||||
conn[3].auc_3g_ind == 3
|
||||
conn[4].auc_3g_ind == 4
|
||||
conn[5].auc_3g_ind == 5
|
||||
conn[6].auc_3g_ind == 6
|
||||
conn[7].auc_3g_ind == 7
|
||||
conn[8].auc_3g_ind == 8
|
||||
conn[9].auc_3g_ind == 9
|
||||
|
||||
Punch two holes in the sequence in arbitrary order, a larger one from 2..4 and a single one at 7.
|
||||
|
||||
Expecting a list of 0,1, 5,6, 8,9
|
||||
conn[0].auc_3g_ind == 0
|
||||
conn[1].auc_3g_ind == 1
|
||||
conn[2].auc_3g_ind == 5
|
||||
conn[3].auc_3g_ind == 6
|
||||
conn[4].auc_3g_ind == 8
|
||||
conn[5].auc_3g_ind == 9
|
||||
|
||||
Add conns, expecting them to take the open slots
|
||||
conn_inst[12].auc_3g_ind == 2
|
||||
conn_inst[13].auc_3g_ind == 3
|
||||
conn_inst[14].auc_3g_ind == 4
|
||||
conn_inst[17].auc_3g_ind == 7
|
||||
conn_inst[18].auc_3g_ind == 10
|
||||
|
||||
Expecting a list of 0..10
|
||||
conn[0].auc_3g_ind == 0
|
||||
conn[1].auc_3g_ind == 1
|
||||
conn[2].auc_3g_ind == 2
|
||||
conn[3].auc_3g_ind == 3
|
||||
conn[4].auc_3g_ind == 4
|
||||
conn[5].auc_3g_ind == 5
|
||||
conn[6].auc_3g_ind == 6
|
||||
conn[7].auc_3g_ind == 7
|
||||
conn[8].auc_3g_ind == 8
|
||||
conn[9].auc_3g_ind == 9
|
||||
conn[10].auc_3g_ind == 10
|
||||
|
||||
Does it also work for the first item?
|
||||
|
||||
Expecting a list of 1..10
|
||||
conn[0].auc_3g_ind == 1
|
||||
conn[1].auc_3g_ind == 2
|
||||
conn[2].auc_3g_ind == 3
|
||||
conn[3].auc_3g_ind == 4
|
||||
conn[4].auc_3g_ind == 5
|
||||
conn[5].auc_3g_ind == 6
|
||||
conn[6].auc_3g_ind == 7
|
||||
conn[7].auc_3g_ind == 8
|
||||
conn[8].auc_3g_ind == 9
|
||||
conn[9].auc_3g_ind == 10
|
||||
|
||||
Add another conn, should take auc_3g_ind == 0
|
||||
conn_inst[20].auc_3g_ind == 0
|
||||
|
||||
Expecting a list of 0..10
|
||||
conn[0].auc_3g_ind == 0
|
||||
conn[1].auc_3g_ind == 1
|
||||
conn[2].auc_3g_ind == 2
|
||||
conn[3].auc_3g_ind == 3
|
||||
conn[4].auc_3g_ind == 4
|
||||
conn[5].auc_3g_ind == 5
|
||||
conn[6].auc_3g_ind == 6
|
||||
conn[7].auc_3g_ind == 7
|
||||
conn[8].auc_3g_ind == 8
|
||||
conn[9].auc_3g_ind == 9
|
||||
conn[10].auc_3g_ind == 10
|
||||
|
||||
If a client reconnects, it will (likely) get the same auc_3g_ind
|
||||
conn_inst[5].auc_3g_ind == 5
|
||||
conn_inst[5].auc_3g_ind == 5
|
||||
===== test_add_conn: SUCCESS
|
||||
|
||||
Done
|
||||
@@ -32,148 +32,6 @@ struct qname_enc_dec_test {
|
||||
size_t qname_max_len; /* default: strlen(qname) + 1 */
|
||||
};
|
||||
|
||||
static const struct qname_enc_dec_test qname_enc_dec_test_data[] = {
|
||||
{
|
||||
/* OK: typical mslookup domain */
|
||||
.domain = "hlr.1234567.imsi",
|
||||
.qname = "\x03" "hlr" "\x07" "1234567" "\x04" "imsi",
|
||||
},
|
||||
{
|
||||
/* Wrong format: double dot */
|
||||
.domain = "hlr..imsi",
|
||||
.qname = NULL,
|
||||
},
|
||||
{
|
||||
/* Wrong format: double dot */
|
||||
.domain = "hlr",
|
||||
.qname = "\x03hlr\0\x03imsi",
|
||||
},
|
||||
{
|
||||
/* Wrong format: dot at end */
|
||||
.domain = "hlr.",
|
||||
.qname = NULL,
|
||||
},
|
||||
{
|
||||
/* Wrong format: dot at start */
|
||||
.domain = ".hlr",
|
||||
.qname = NULL,
|
||||
},
|
||||
{
|
||||
/* Wrong format: empty */
|
||||
.domain = "",
|
||||
.qname = NULL,
|
||||
},
|
||||
{
|
||||
/* OK: maximum length */
|
||||
.domain =
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"12345"
|
||||
,
|
||||
.qname =
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\x05" "12345"
|
||||
},
|
||||
{
|
||||
/* Error: too long domain */
|
||||
.domain =
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"123456789." "123456789." "123456789." "123456789." "123456789."
|
||||
"12345toolong"
|
||||
,
|
||||
.qname = NULL,
|
||||
},
|
||||
{
|
||||
/* Error: too long qname */
|
||||
.domain = NULL,
|
||||
.qname =
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
"\t123456789\t123456789\t123456789\t123456789\t123456789"
|
||||
},
|
||||
{
|
||||
/* Error: wrong token length in qname */
|
||||
.domain = NULL,
|
||||
.qname = "\x03" "hlr" "\x07" "1234567" "\x05" "imsi",
|
||||
},
|
||||
{
|
||||
/* Error: wrong token length in qname */
|
||||
.domain = NULL,
|
||||
.qname = "\x02" "hlr" "\x07" "1234567" "\x04" "imsi",
|
||||
},
|
||||
{
|
||||
/* Wrong format: token length at end of qname */
|
||||
.domain = NULL,
|
||||
.qname = "\x03hlr\x03",
|
||||
},
|
||||
{
|
||||
/* Error: overflow in label length */
|
||||
.domain = NULL,
|
||||
.qname = "\x03" "hlr" "\x07" "1234567" "\x04" "imsi",
|
||||
.qname_max_len = 17,
|
||||
},
|
||||
};
|
||||
|
||||
void test_enc_dec_rfc_qname(void *ctx)
|
||||
{
|
||||
char quote_buf[300];
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "-- %s --\n", __func__);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qname_enc_dec_test_data); i++) {
|
||||
const struct qname_enc_dec_test *t = &qname_enc_dec_test_data[i];
|
||||
char *res;
|
||||
|
||||
if (t->domain) {
|
||||
fprintf(stderr, "domain: %s\n", osmo_quote_str_buf2(quote_buf, sizeof(quote_buf), t->domain, -1));
|
||||
fprintf(stderr, "exp: %s\n", osmo_quote_str_buf2(quote_buf, sizeof(quote_buf), t->qname, -1));
|
||||
res = osmo_mdns_rfc_qname_encode(ctx, t->domain);
|
||||
fprintf(stderr, "res: %s\n", osmo_quote_str_buf2(quote_buf, sizeof(quote_buf), res, -1));
|
||||
if (t->qname == res || (t->qname && res && strcmp(t->qname, res) == 0))
|
||||
fprintf(stderr, "=> OK\n");
|
||||
else
|
||||
fprintf(stderr, "=> ERROR\n");
|
||||
if (res)
|
||||
talloc_free(res);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
if (t->qname) {
|
||||
size_t qname_max_len = t->qname_max_len;
|
||||
if (qname_max_len)
|
||||
fprintf(stderr, "qname_max_len: %lu\n", qname_max_len);
|
||||
else
|
||||
qname_max_len = strlen(t->qname) + 1;
|
||||
|
||||
fprintf(stderr, "qname: %s\n", osmo_quote_str_buf2(quote_buf, sizeof(quote_buf), t->qname, -1));
|
||||
fprintf(stderr, "exp: %s\n", osmo_quote_str_buf2(quote_buf, sizeof(quote_buf), t->domain, -1));
|
||||
res = osmo_mdns_rfc_qname_decode(ctx, t->qname, qname_max_len);
|
||||
fprintf(stderr, "res: %s\n", osmo_quote_str_buf2(quote_buf, sizeof(quote_buf), res, -1));
|
||||
if (t->domain == res || (t->domain && res && strcmp(t->domain, res) == 0))
|
||||
fprintf(stderr, "=> OK\n");
|
||||
else
|
||||
fprintf(stderr, "=> ERROR\n");
|
||||
if (res)
|
||||
talloc_free(res);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define PRINT_HDR(hdr, name) \
|
||||
fprintf(stderr, "header %s:\n" \
|
||||
".id = %i\n" \
|
||||
@@ -216,7 +74,7 @@ static const struct osmo_mdns_rfc_header header_enc_dec_test_data[] = {
|
||||
},
|
||||
};
|
||||
|
||||
void test_enc_dec_rfc_header()
|
||||
void test_enc_dec_rfc_header(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -241,7 +99,7 @@ void test_enc_dec_rfc_header()
|
||||
}
|
||||
}
|
||||
|
||||
void test_enc_dec_rfc_header_einval()
|
||||
void test_enc_dec_rfc_header_einval(void)
|
||||
{
|
||||
struct osmo_mdns_rfc_header out = {0};
|
||||
struct msgb *msg = msgb_alloc(4096, "dns_test");
|
||||
@@ -289,7 +147,7 @@ void test_enc_dec_rfc_question(void *ctx)
|
||||
struct msgb *msg = msgb_alloc(4096, "dns_test");
|
||||
|
||||
PRINT_QST(&in, "in");
|
||||
assert(osmo_mdns_rfc_question_encode(ctx, msg, &in) == 0);
|
||||
assert(osmo_mdns_rfc_question_encode(msg, &in) == 0);
|
||||
fprintf(stderr, "encoded: %s\n", osmo_hexdump(msgb_data(msg), msgb_length(msg)));
|
||||
out = osmo_mdns_rfc_question_decode(ctx, msgb_data(msg), msgb_length(msg));
|
||||
assert(out);
|
||||
@@ -353,7 +211,7 @@ void test_enc_dec_rfc_record(void *ctx)
|
||||
size_t record_len;
|
||||
|
||||
PRINT_REC(&in, "in");
|
||||
assert(osmo_mdns_rfc_record_encode(ctx, msg, &in) == 0);
|
||||
assert(osmo_mdns_rfc_record_encode(msg, &in) == 0);
|
||||
fprintf(stderr, "encoded: %s\n", osmo_hexdump(msgb_data(msg), msgb_length(msg)));
|
||||
out = osmo_mdns_rfc_record_decode(ctx, msgb_data(msg), msgb_length(msg), &record_len);
|
||||
fprintf(stderr, "record_len: %lu\n", record_len);
|
||||
@@ -578,7 +436,7 @@ static void test_result_from_answer(void *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *ctx = talloc_named_const(NULL, 0, "main");
|
||||
osmo_init_logging2(ctx, NULL);
|
||||
@@ -589,7 +447,6 @@ int main()
|
||||
log_set_print_category_hex(osmo_stderr_target, 0);
|
||||
log_set_use_color(osmo_stderr_target, 0);
|
||||
|
||||
test_enc_dec_rfc_qname(ctx);
|
||||
test_enc_dec_rfc_header();
|
||||
test_enc_dec_rfc_header_einval();
|
||||
test_enc_dec_rfc_question(ctx);
|
||||
|
||||
@@ -1,85 +1,3 @@
|
||||
-- test_enc_dec_rfc_qname --
|
||||
domain: "hlr.1234567.imsi"
|
||||
exp: "\3hlr\a1234567\4imsi"
|
||||
res: "\3hlr\a1234567\4imsi"
|
||||
=> OK
|
||||
|
||||
qname: "\3hlr\a1234567\4imsi"
|
||||
exp: "hlr.1234567.imsi"
|
||||
res: "hlr.1234567.imsi"
|
||||
=> OK
|
||||
|
||||
domain: "hlr..imsi"
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
domain: "hlr"
|
||||
exp: "\3hlr"
|
||||
res: "\3hlr"
|
||||
=> OK
|
||||
|
||||
qname: "\3hlr"
|
||||
exp: "hlr"
|
||||
res: "hlr"
|
||||
=> OK
|
||||
|
||||
domain: "hlr."
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
domain: ".hlr"
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
domain: ""
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
domain: "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.12345"
|
||||
exp: "\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\512345"
|
||||
res: "\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\512345"
|
||||
=> OK
|
||||
|
||||
qname: "\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\512345"
|
||||
exp: "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.12345"
|
||||
res: "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.12345"
|
||||
=> OK
|
||||
|
||||
domain: "123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.12345toolong"
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
qname: "\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\t123456789\
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
qname: "\3hlr\a1234567\5imsi"
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
qname: "\2hlr\a1234567\4imsi"
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
qname: "\3hlr\3"
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
qname_max_len: 17
|
||||
qname: "\3hlr\a1234567\4imsi"
|
||||
exp: NULL
|
||||
res: NULL
|
||||
=> OK
|
||||
|
||||
-- test_enc_dec_rfc_header --
|
||||
header in:
|
||||
.id = 1337
|
||||
|
||||
@@ -80,14 +80,14 @@ static int server_recv(struct osmo_fd *osmo_fd, unsigned int what)
|
||||
return n;
|
||||
}
|
||||
|
||||
static void server_init()
|
||||
static void server_init(void)
|
||||
{
|
||||
fprintf(stderr, "%s\n", __func__);
|
||||
server_mc = osmo_mdns_sock_init(ctx, TEST_IP, TEST_PORT, server_recv, NULL, 0);
|
||||
OSMO_ASSERT(server_mc);
|
||||
}
|
||||
|
||||
static void server_stop()
|
||||
static void server_stop(void)
|
||||
{
|
||||
fprintf(stderr, "%s\n", __func__);
|
||||
OSMO_ASSERT(server_mc);
|
||||
@@ -98,7 +98,7 @@ static void server_stop()
|
||||
struct osmo_mslookup_client* client;
|
||||
struct osmo_mslookup_client_method* client_method;
|
||||
|
||||
static void client_init()
|
||||
static void client_init(void)
|
||||
{
|
||||
fprintf(stderr, "%s\n", __func__);
|
||||
client = osmo_mslookup_client_new(ctx);
|
||||
@@ -117,7 +117,7 @@ static void client_recv(struct osmo_mslookup_client *client, uint32_t request_ha
|
||||
osmo_mslookup_client_request_cancel(client, request_handle);
|
||||
}
|
||||
|
||||
static void client_query()
|
||||
static void client_query(void)
|
||||
{
|
||||
struct osmo_mslookup_id id = {.type = OSMO_MSLOOKUP_ID_IMSI,
|
||||
.imsi = "123456789012345"};
|
||||
@@ -134,7 +134,7 @@ static void client_query()
|
||||
osmo_mslookup_client_request(client, &query, &handling);
|
||||
}
|
||||
|
||||
static void client_stop()
|
||||
static void client_stop(void)
|
||||
{
|
||||
fprintf(stderr, "%s\n", __func__);
|
||||
osmo_mslookup_client_free(client);
|
||||
@@ -154,7 +154,7 @@ const struct timeval fake_time_start_time = { 0, 0 };
|
||||
osmo_timers_update(); \
|
||||
} while (0)
|
||||
|
||||
static void fake_time_start()
|
||||
static void fake_time_start(void)
|
||||
{
|
||||
struct timespec *clock_override;
|
||||
|
||||
@@ -167,7 +167,7 @@ static void fake_time_start()
|
||||
osmo_clock_override_enable(CLOCK_MONOTONIC, true);
|
||||
fake_time_passes(0, 0);
|
||||
}
|
||||
static void test_server_client()
|
||||
static void test_server_client(void)
|
||||
{
|
||||
fprintf(stderr, "-- %s --\n", __func__);
|
||||
server_init();
|
||||
@@ -190,7 +190,7 @@ static void test_server_client()
|
||||
client_stop();
|
||||
}
|
||||
|
||||
bool is_multicast_enabled()
|
||||
bool is_multicast_enabled(void)
|
||||
{
|
||||
bool ret = true;
|
||||
struct addrinfo *ai;
|
||||
@@ -222,7 +222,7 @@ bool is_multicast_enabled()
|
||||
/*
|
||||
* Run all tests
|
||||
*/
|
||||
int main()
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (!is_multicast_enabled()) {
|
||||
fprintf(stderr, "ERROR: multicast is disabled! (OS#4361)");
|
||||
|
||||
@@ -147,7 +147,7 @@ const struct timeval fake_time_start_time = { 0, 0 };
|
||||
osmo_timers_update(); \
|
||||
} while (0)
|
||||
|
||||
static void fake_time_start()
|
||||
static void fake_time_start(void)
|
||||
{
|
||||
struct timespec *clock_override;
|
||||
|
||||
@@ -169,7 +169,7 @@ static void result_cb_once(struct osmo_mslookup_client *client,
|
||||
LOGP(DMSLOOKUP, LOGL_DEBUG, "result_cb(): %s\n", osmo_mslookup_result_name_c(ctx, query, result));
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ctx = talloc_named_const(NULL, 0, "main");
|
||||
osmo_init_logging2(ctx, NULL);
|
||||
|
||||
@@ -50,7 +50,7 @@ const char *domains[] = {
|
||||
"qwerty.1.qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmm",
|
||||
};
|
||||
|
||||
void test_osmo_mslookup_query_init_from_domain_str()
|
||||
void test_osmo_mslookup_query_init_from_domain_str(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(domains); i++) {
|
||||
@@ -68,7 +68,7 @@ void test_osmo_mslookup_query_init_from_domain_str()
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ctx = talloc_named_const(NULL, 0, "main");
|
||||
osmo_init_logging2(ctx, NULL);
|
||||
|
||||
@@ -47,6 +47,7 @@ OsmoHLR(config-hlr)# ?
|
||||
no Negate a command or set its defaults
|
||||
ussd USSD Configuration
|
||||
ncss-guard-timeout Set guard timer for NCSS (call independent SS) session activity
|
||||
reject-cause GSUP/GMM cause to be sent
|
||||
store-imei Save the IMEI in the database when receiving Check IMEI requests. Note that an MSC does not necessarily send Check IMEI requests (for OsmoMSC, you may want to set 'check-imei-rqd 1').
|
||||
subscriber-create-on-demand Make a new record when a subscriber is first seen.
|
||||
OsmoHLR(config-hlr)# list
|
||||
@@ -61,6 +62,7 @@ OsmoHLR(config-hlr)# list
|
||||
ussd default-route external EUSE
|
||||
no ussd default-route
|
||||
ncss-guard-timeout <0-255>
|
||||
reject-cause (not-found|no-proxy) (imsi-unknown|illegal-ms|plmn-not-allowed|la-not-allowed|roaming-not-allowed|no-suitable-cell-in-la|net-fail|congestion|auth-unacceptable|proto-error-unspec)
|
||||
store-imei
|
||||
no store-imei
|
||||
subscriber-create-on-demand (no-msisdn|<3-15>) (none|cs|ps|cs+ps)
|
||||
@@ -349,15 +351,15 @@ mslookup
|
||||
service foo.bar at 123.45.67.89 1011
|
||||
service baz.bar at 121.31.41.5 1617
|
||||
service baz.bar at a:b:c::d 1819
|
||||
msc MSC-1
|
||||
msc msc-901-70-23
|
||||
service foo.bar at 76.54.32.10 1234
|
||||
service baz.bar at 12.11.10.98 7654
|
||||
service baz.bar at dd:cc:bb::a 3210
|
||||
msc msc-901-70-42
|
||||
service foo.bar at 1.1.1.1 1111
|
||||
service baz.bar at 2.2.2.2 2222
|
||||
service baz.bar at 2222:2222:2222::2 2222
|
||||
msc ipa-name MSC-1
|
||||
msc ipa-name msc-901-70-23
|
||||
service foo.bar at 76.54.32.10 1234
|
||||
service baz.bar at 12.11.10.98 7654
|
||||
service baz.bar at dd:cc:bb::a 3210
|
||||
msc ipa-name msc-901-70-42
|
||||
service foo.bar at 1.1.1.1 1111
|
||||
service baz.bar at 2.2.2.2 2222
|
||||
service baz.bar at 2222:2222:2222::2 2222
|
||||
client
|
||||
gateway-proxy 1.2.3.4 4222
|
||||
mdns bind 239.192.23.42 4266
|
||||
@@ -404,12 +406,12 @@ mslookup
|
||||
mdns bind 239.192.23.42 4266
|
||||
service foo.bar at 123.45.67.89 1011
|
||||
service baz.bar at 121.31.41.5 1617
|
||||
msc MSC-1
|
||||
msc msc-901-70-23
|
||||
service foo.bar at 76.54.32.10 1234
|
||||
service baz.bar at 12.11.10.98 7654
|
||||
msc msc-901-70-42
|
||||
service foo.bar at 1.1.1.1 1111
|
||||
msc ipa-name MSC-1
|
||||
msc ipa-name msc-901-70-23
|
||||
service foo.bar at 76.54.32.10 1234
|
||||
service baz.bar at 12.11.10.98 7654
|
||||
msc ipa-name msc-901-70-42
|
||||
service foo.bar at 1.1.1.1 1111
|
||||
client
|
||||
mdns bind 239.192.23.42 4266
|
||||
...
|
||||
@@ -437,12 +439,12 @@ mslookup
|
||||
service foo.bar at 123.45.67.89 1011
|
||||
service baz.bar at 121.31.41.5 1617
|
||||
service gsup.hlr at 23.42.17.11 4223
|
||||
msc MSC-1
|
||||
msc msc-901-70-23
|
||||
service foo.bar at 76.54.32.10 1234
|
||||
service baz.bar at 12.11.10.98 7654
|
||||
msc msc-901-70-42
|
||||
service foo.bar at 1.1.1.1 1111
|
||||
msc ipa-name MSC-1
|
||||
msc ipa-name msc-901-70-23
|
||||
service foo.bar at 76.54.32.10 1234
|
||||
service baz.bar at 12.11.10.98 7654
|
||||
msc ipa-name msc-901-70-42
|
||||
service foo.bar at 1.1.1.1 1111
|
||||
client
|
||||
mdns bind 239.192.23.42 4266
|
||||
...
|
||||
|
||||
@@ -610,5 +610,102 @@ periodic_lu_timer 0
|
||||
periodic_rau_tau_timer 0
|
||||
lmsi 00000000
|
||||
|
||||
GET 101 subscriber.by-id-0x0123.info
|
||||
ERROR 101 Invalid value part of 'by-xxx-value' selector.
|
||||
SET 101 subscriber.create 901991234567891
|
||||
SET_REPLY 101 subscriber.create 124
|
||||
|
||||
GET 102 subscriber.by-id-124.info
|
||||
GET_REPLY 102 subscriber.by-id-124.info
|
||||
id 124
|
||||
imsi 901991234567891
|
||||
nam_cs 1
|
||||
nam_ps 1
|
||||
ms_purged_cs 0
|
||||
ms_purged_ps 0
|
||||
periodic_lu_timer 0
|
||||
periodic_rau_tau_timer 0
|
||||
lmsi 00000000
|
||||
|
||||
GET 103 subscriber.by-imsi-901991234567891.msisdn
|
||||
GET_REPLY 103 subscriber.by-imsi-901991234567891.msisdn none
|
||||
|
||||
SET 104 subscriber.by-imsi-901991234567891.msisdn 555666
|
||||
SET_REPLY 104 subscriber.by-imsi-901991234567891.msisdn OK
|
||||
|
||||
GET 105 subscriber.by-imsi-901991234567891.msisdn
|
||||
GET_REPLY 105 subscriber.by-imsi-901991234567891.msisdn 555666
|
||||
|
||||
SET 106 subscriber.by-imsi-901991234567891.msisdn 888000
|
||||
SET_REPLY 106 subscriber.by-imsi-901991234567891.msisdn OK
|
||||
|
||||
GET 107 subscriber.by-imsi-901991234567891.msisdn
|
||||
GET_REPLY 107 subscriber.by-imsi-901991234567891.msisdn 888000
|
||||
|
||||
GET 108 subscriber.by-imsi-901991234567891.info
|
||||
GET_REPLY 108 subscriber.by-imsi-901991234567891.info
|
||||
id 124
|
||||
imsi 901991234567891
|
||||
msisdn 888000
|
||||
nam_cs 1
|
||||
nam_ps 1
|
||||
ms_purged_cs 0
|
||||
ms_purged_ps 0
|
||||
periodic_lu_timer 0
|
||||
periodic_rau_tau_timer 0
|
||||
lmsi 00000000
|
||||
|
||||
SET 109 subscriber.by-imsi-901991234567891.msisdn none
|
||||
SET_REPLY 109 subscriber.by-imsi-901991234567891.msisdn OK
|
||||
|
||||
GET 110 subscriber.by-imsi-901991234567891.msisdn
|
||||
GET_REPLY 110 subscriber.by-imsi-901991234567891.msisdn none
|
||||
|
||||
GET 111 subscriber.by-imsi-901991234567891.info
|
||||
GET_REPLY 111 subscriber.by-imsi-901991234567891.info
|
||||
id 124
|
||||
imsi 901991234567891
|
||||
nam_cs 1
|
||||
nam_ps 1
|
||||
ms_purged_cs 0
|
||||
ms_purged_ps 0
|
||||
periodic_lu_timer 0
|
||||
periodic_rau_tau_timer 0
|
||||
lmsi 00000000
|
||||
|
||||
GET 112 subscriber.by-imsi-901991234567891.aud2g
|
||||
GET_REPLY 112 subscriber.by-imsi-901991234567891.aud2g none
|
||||
|
||||
SET 113 subscriber.by-imsi-901991234567891.aud2g xor,c01ffedc1cadaeac1d1f1edacac1ab0a
|
||||
SET_REPLY 113 subscriber.by-imsi-901991234567891.aud2g OK
|
||||
|
||||
GET 114 subscriber.by-imsi-901991234567891.aud2g
|
||||
GET_REPLY 114 subscriber.by-imsi-901991234567891.aud2g XOR,c01ffedc1cadaeac1d1f1edacac1ab0a
|
||||
|
||||
SET 115 subscriber.by-imsi-901991234567891.aud2g none
|
||||
SET_REPLY 115 subscriber.by-imsi-901991234567891.aud2g OK
|
||||
|
||||
GET 116 subscriber.by-imsi-901991234567891.aud2g
|
||||
GET_REPLY 116 subscriber.by-imsi-901991234567891.aud2g none
|
||||
|
||||
GET 117 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 117 subscriber.by-imsi-901991234567891.aud3g none
|
||||
|
||||
SET 118 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,FB2A3D1B360F599ABAB99DB8669F8308
|
||||
SET_REPLY 118 subscriber.by-imsi-901991234567891.aud3g OK
|
||||
|
||||
GET 119 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 119 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OP,fb2a3d1b360f599abab99db8669f8308,5
|
||||
|
||||
SET 120 subscriber.by-imsi-901991234567891.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,FB2A3D1B360F599ABAB99DB8669F8308,7
|
||||
SET_REPLY 120 subscriber.by-imsi-901991234567891.aud3g OK
|
||||
|
||||
GET 121 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 121 subscriber.by-imsi-901991234567891.aud3g MILENAGE,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,fb2a3d1b360f599abab99db8669f8308,7
|
||||
|
||||
SET 122 subscriber.by-imsi-901991234567891.aud3g none
|
||||
SET_REPLY 122 subscriber.by-imsi-901991234567891.aud3g OK
|
||||
|
||||
GET 123 subscriber.by-imsi-901991234567891.aud3g
|
||||
GET_REPLY 123 subscriber.by-imsi-901991234567891.aud3g none
|
||||
|
||||
SET 124 subscriber.delete 901991234567891
|
||||
SET_REPLY 124 subscriber.delete 124
|
||||
|
||||
@@ -105,3 +105,51 @@ GET 46 subscriber.by-imsi-1234567890123456.ps-enabled
|
||||
ERROR 46 Invalid value part of 'by-xxx-value' selector.
|
||||
GET 47 subscriber.by-imsi-1234567890123456.cs-enabled
|
||||
ERROR 47 Invalid value part of 'by-xxx-value' selector.
|
||||
|
||||
GET 48 subscriber.by-id-0x0123.info
|
||||
ERROR 48 Invalid value part of 'by-xxx-value' selector.
|
||||
|
||||
SET 49 subscriber.create zzz
|
||||
ERROR 49 Invalid IMSI value.
|
||||
|
||||
SET 50 subscriber.create 901990000000001
|
||||
ERROR 50 Subscriber already exists.
|
||||
|
||||
SET 51 subscriber.by-imsi-1234567890123456.msisdn hellobadmsisdn
|
||||
ERROR 51 Value failed verification.
|
||||
|
||||
SET 52 subscriber.delete 100000
|
||||
ERROR 52 Subscriber doesn't exist.
|
||||
|
||||
SET 53 subscriber.delete zzz
|
||||
ERROR 53 Invalid IMSI value.
|
||||
|
||||
SET 54 subscriber.by-imsi-901990000000003.aud2g foobar
|
||||
ERROR 54 Value failed verification.
|
||||
|
||||
SET 55 subscriber.by-imsi-901990000000003.aud2g foobar,2134
|
||||
ERROR 55 Unknown auth algorithm.
|
||||
|
||||
SET 56 subscriber.by-imsi-901990000000003.aud2g xor,2134
|
||||
ERROR 56 Invalid KI.
|
||||
|
||||
SET 57 subscriber.by-imsi-901990000000003.aud3g foobar
|
||||
ERROR 57 Value failed verification.
|
||||
|
||||
SET 58 subscriber.by-imsi-901990000000003.aud3g foobar,2134
|
||||
ERROR 58 Unknown auth algorithm.
|
||||
|
||||
SET 60 subscriber.by-imsi-901990000000003.aud3g milenage,2134
|
||||
ERROR 60 Invalid KI.
|
||||
|
||||
SET 61 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,AAA
|
||||
ERROR 61 Invalid format.
|
||||
|
||||
SET 62 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC
|
||||
ERROR 62 Invalid format.
|
||||
|
||||
SET 63 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,zzz
|
||||
ERROR 63 Invalid OP/OPC.
|
||||
|
||||
SET 64 subscriber.by-imsi-901990000000003.aud3g milenage,c01ffedc1cadaeac1d1f1edacac1ab0a,OPC,fb2a3d1b360f599abab99db8669f8308,
|
||||
ERROR 64 Invalid format.
|
||||
|
||||
@@ -22,13 +22,6 @@ cat $abs_srcdir/gsup/gsup_test.err > experr
|
||||
AT_CHECK([$abs_top_builddir/tests/gsup/gsup_test], [], [expout], [experr])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([gsup_server])
|
||||
AT_KEYWORDS([gsup_server])
|
||||
cat $abs_srcdir/gsup_server/gsup_server_test.ok > expout
|
||||
cat $abs_srcdir/gsup_server/gsup_server_test.err > experr
|
||||
AT_CHECK([$abs_top_builddir/tests/gsup_server/gsup_server_test], [], [expout], [experr])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([db])
|
||||
AT_KEYWORDS([db])
|
||||
cat $abs_srcdir/db/db_test.ok > expout
|
||||
|
||||
Reference in New Issue
Block a user