[PATCH] libosmocore[master]: add osmo_imsi_str_valid() and osmo_msisdn_str_valid()

Neels Hofmeyr gerrit-no-reply at lists.osmocom.org
Thu Oct 5 15:45:08 UTC 2017


Review at  https://gerrit.osmocom.org/4144

add osmo_imsi_str_valid() and osmo_msisdn_str_valid()

Add GSM23003_IMSI_MIN_DIGITS definition.
Add regression test gsm23003_test.c to test the two new functions.

Will be used by OsmoHLR to validate VTY and CTRL input.

Change-Id: I1e94f5b0717b947d2a7a7d36bacdf04a75cb3522
---
M include/osmocom/gsm/gsm23003.h
M include/osmocom/gsm/protocol/gsm_23_003.h
M src/gsm/Makefile.am
A src/gsm/gsm23003.c
M src/gsm/libosmogsm.map
M tests/Makefile.am
A tests/gsm23003/gsm23003_test.c
A tests/gsm23003/gsm23003_test.ok
M tests/testsuite.at
9 files changed, 252 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/44/4144/1

diff --git a/include/osmocom/gsm/gsm23003.h b/include/osmocom/gsm/gsm23003.h
index 2bc7583..dd41bc5 100644
--- a/include/osmocom/gsm/gsm23003.h
+++ b/include/osmocom/gsm/gsm23003.h
@@ -3,6 +3,7 @@
 #pragma once
 
 #include <stdint.h>
+#include <stdbool.h>
 
 /* 23.003 Chapter 12.1 */
 struct osmo_plmn_id {
@@ -81,3 +82,6 @@
 	struct osmo_gummei gummei;
 	uint32_t mtmsi;
 };
+
+bool osmo_imsi_str_valid(const char *imsi);
+bool osmo_msisdn_str_valid(const char *msisdn);
diff --git a/include/osmocom/gsm/protocol/gsm_23_003.h b/include/osmocom/gsm/protocol/gsm_23_003.h
index 94243fe..0e66939 100644
--- a/include/osmocom/gsm/protocol/gsm_23_003.h
+++ b/include/osmocom/gsm/protocol/gsm_23_003.h
@@ -4,6 +4,7 @@
 
 /* Chapter 2.2 */
 #define GSM23003_IMSI_MAX_DIGITS	15
+#define GSM23003_IMSI_MIN_DIGITS	6
 /* Chapter 2.4 */
 #define GSM23003_TMSI_NUM_BYTES		4
 /* Chapter 2.5 */
diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am
index 08cd5e6..48b8b2c 100644
--- a/src/gsm/Makefile.am
+++ b/src/gsm/Makefile.am
@@ -29,7 +29,8 @@
 			auth_milenage.c milenage/aes-encblock.c gea.c \
 			milenage/aes-internal.c milenage/aes-internal-enc.c \
 			milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \
-			gsup.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c
+			gsup.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \
+			gsm23003.c
 libgsmint_la_LDFLAGS = -no-undefined
 libgsmint_la_LIBADD = $(top_builddir)/src/libosmocore.la
 
diff --git a/src/gsm/gsm23003.c b/src/gsm/gsm23003.c
new file mode 100644
index 0000000..073d2e4
--- /dev/null
+++ b/src/gsm/gsm23003.c
@@ -0,0 +1,62 @@
+/*! \file gsm23003.c
+ * Utility function implementations related to 3GPP TS 23.003 */
+/*
+ * (C) 2017 sysmocom s.f.m.c. GmbH <info at sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr at sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <ctype.h>
+
+#include <osmocom/gsm/gsm23003.h>
+#include <osmocom/gsm/protocol/gsm_23_003.h>
+
+static bool is_n_digits(const char *str, int min_digits, int max_digits)
+{
+	int len;
+	for (len = 0; *str && len < max_digits; len++, str++)
+		if (!isdigit(*str))
+			return false;
+	if (len < min_digits)
+		return false;
+	/* With not too many digits, we should have reached *str == nul */
+	if (*str)
+		return false;
+	return true;
+}
+
+/*! Determine whether the given IMSI is valid according to 3GPP TS 23.003.
+ * \param imsi  IMSI digits in ASCII string representation.
+ * \returns true when the IMSI is valid, false for invalid characters or number
+ *          of digits.
+ */
+bool osmo_imsi_str_valid(const char *imsi)
+{
+	return is_n_digits(imsi, GSM23003_IMSI_MIN_DIGITS, GSM23003_IMSI_MAX_DIGITS);
+}
+
+/*! Determine whether the given MSISDN is valid according to 3GPP TS 23.003.
+ * \param msisdn  MSISDN digits in ASCII string representation.
+ * \returns true when the MSISDN is valid, false for invalid characters or number
+ *          of digits.
+ */
+bool osmo_msisdn_str_valid(const char *msisdn)
+{
+	return is_n_digits(msisdn, 1, 15);
+}
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 066f410..95b2ca9 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -418,5 +418,8 @@
 osmo_oap_encode;
 osmo_oap_decode;
 
+osmo_imsi_str_valid;
+osmo_msisdn_str_valid;
+
 local: *;
 };
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b138717..dbe349f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -15,7 +15,7 @@
 		 write_queue/wqueue_test socket/socket_test		\
 		 coding/coding_test conv/conv_gsm0503_test		\
 		 abis/abis_test endian/endian_test sercomm/sercomm_test	\
-		 stats/stats_test prbs/prbs_test
+		 stats/stats_test prbs/prbs_test gsm23003/gsm23003_test
 
 if ENABLE_MSGFILE
 check_PROGRAMS += msgfile/msgfile_test
@@ -186,6 +186,9 @@
 prbs_prbs_test_SOURCES = prbs/prbs_test.c
 prbs_prbs_test_LDADD = $(top_builddir)/src/libosmocore.la
 
+gsm23003_gsm23003_test_SOURCES = gsm23003/gsm23003_test.c
+gsm23003_gsm23003_test_LDADD = $(top_builddir)/src/gsm/libosmogsm.la $(top_builddir)/src/libosmocore.la
+
 # The `:;' works around a Bash 3.2 bug when the output is not writeable.
 $(srcdir)/package.m4: $(top_srcdir)/configure.ac
 	:;{ \
@@ -241,7 +244,8 @@
 	     osmo-auc-gen/osmo-auc-gen_test.ok				\
 	     osmo-auc-gen/osmo-auc-gen_test.err				\
 	     conv/conv_gsm0503_test.ok endian/endian_test.ok 		\
-	     sercomm/sercomm_test.ok prbs/prbs_test.ok
+	     sercomm/sercomm_test.ok prbs/prbs_test.ok			\
+	     gsm23003/gsm23003_test.ok
 
 DISTCLEANFILES = atconfig atlocal conv/gsm0503_test_vectors.c
 BUILT_SOURCES = conv/gsm0503_test_vectors.c
diff --git a/tests/gsm23003/gsm23003_test.c b/tests/gsm23003/gsm23003_test.c
new file mode 100644
index 0000000..f1f80f5
--- /dev/null
+++ b/tests/gsm23003/gsm23003_test.c
@@ -0,0 +1,126 @@
+/*
+ * (C) 2017 by sysmocom s.f.m.c. GmbH <info at sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr at sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdio.h>
+
+#include <osmocom/gsm/gsm23003.h>
+#include <osmocom/core/utils.h>
+
+#define BOOL_STR(b) ((b)? "true" : "false")
+
+static struct {
+	const char *imsi;
+	bool expect_ok;
+} test_imsis[] = {
+	{ "", false },
+	{ " ", false },
+	{ "1", false },
+	{ "123", false },
+	{ "12345", false },
+	{ "123456", true },
+	{ "1234567", true },
+	{ "1234567890123", true },
+	{ "123456789012345", true },
+	{ "000000000000000", true },
+	{ "999999999999999", true },
+	{ "1234567890123456", false },
+	{ "a23456789012345", false },
+	{ "1234567b9012345", false },
+	{ "12345678901234c", false },
+	{ "123456789 01234", false },
+	{ "1234567\n123456", false },
+	{ "123456\t123456", false },
+	{ "123456\r123456", false },
+};
+
+bool test_valid_imsi()
+{
+	int i;
+	bool pass = true;
+	bool ok = true;
+	printf("----- %s\n", __func__);
+
+	for (i = 0; i < ARRAY_SIZE(test_imsis); i++) {
+		ok = osmo_imsi_str_valid(test_imsis[i].imsi);
+		pass = pass && (ok == test_imsis[i].expect_ok);
+		printf("%2d: expect=%s result=%s imsi='%s'\n",
+		       i, BOOL_STR(test_imsis[i].expect_ok), BOOL_STR(ok),
+		       test_imsis[i].imsi);
+	}
+	return pass;
+}
+
+static struct {
+	const char *msisdn;
+	bool expect_ok;
+} test_msisdns[] = {
+	{ "", false },
+	{ " ", false },
+	{ "1", true },
+	{ "123", true },
+	{ "12345", true },
+	{ "123456", true },
+	{ "1234567", true },
+	{ "1234567890123", true },
+	{ "123456789012345", true },
+	{ "000000000000000", true },
+	{ "999999999999999", true },
+	{ "1234567890123456", false },
+	{ "a23456789012345", false },
+	{ "1234567b9012345", false },
+	{ "12345678901234c", false },
+	{ "123456789 01234", false },
+	{ "1234567\n123456", false },
+	{ "123456\t123456", false },
+	{ "123456\r123456", false },
+};
+
+bool test_valid_msisdn()
+{
+	int i;
+	bool pass = true;
+	bool ok = true;
+	printf("----- %s\n", __func__);
+
+	for (i = 0; i < ARRAY_SIZE(test_msisdns); i++) {
+		ok = osmo_msisdn_str_valid(test_msisdns[i].msisdn);
+		pass = pass && (ok == test_msisdns[i].expect_ok);
+		printf("%2d: expect=%s result=%s msisdn='%s'\n",
+		       i, BOOL_STR(test_msisdns[i].expect_ok), BOOL_STR(ok),
+		       test_msisdns[i].msisdn);
+	}
+	return pass;
+}
+
+int main(int argc, char **argv)
+{
+	bool pass = true;
+
+	msgb_talloc_ctx_init(NULL, 0);
+
+	pass = pass && test_valid_imsi();
+	pass = pass && test_valid_msisdn();
+
+	OSMO_ASSERT(pass);
+
+	return EXIT_SUCCESS;
+}
diff --git a/tests/gsm23003/gsm23003_test.ok b/tests/gsm23003/gsm23003_test.ok
new file mode 100644
index 0000000..777451a
--- /dev/null
+++ b/tests/gsm23003/gsm23003_test.ok
@@ -0,0 +1,42 @@
+----- test_valid_imsi
+ 0: expect=false result=false imsi=''
+ 1: expect=false result=false imsi=' '
+ 2: expect=false result=false imsi='1'
+ 3: expect=false result=false imsi='123'
+ 4: expect=false result=false imsi='12345'
+ 5: expect=true result=true imsi='123456'
+ 6: expect=true result=true imsi='1234567'
+ 7: expect=true result=true imsi='1234567890123'
+ 8: expect=true result=true imsi='123456789012345'
+ 9: expect=true result=true imsi='000000000000000'
+10: expect=true result=true imsi='999999999999999'
+11: expect=false result=false imsi='1234567890123456'
+12: expect=false result=false imsi='a23456789012345'
+13: expect=false result=false imsi='1234567b9012345'
+14: expect=false result=false imsi='12345678901234c'
+15: expect=false result=false imsi='123456789 01234'
+16: expect=false result=false imsi='1234567
+123456'
+17: expect=false result=false imsi='123456	123456'
+18: expect=false result=false imsi='123456
123456'
+----- test_valid_msisdn
+ 0: expect=false result=false msisdn=''
+ 1: expect=false result=false msisdn=' '
+ 2: expect=true result=true msisdn='1'
+ 3: expect=true result=true msisdn='123'
+ 4: expect=true result=true msisdn='12345'
+ 5: expect=true result=true msisdn='123456'
+ 6: expect=true result=true msisdn='1234567'
+ 7: expect=true result=true msisdn='1234567890123'
+ 8: expect=true result=true msisdn='123456789012345'
+ 9: expect=true result=true msisdn='000000000000000'
+10: expect=true result=true msisdn='999999999999999'
+11: expect=false result=false msisdn='1234567890123456'
+12: expect=false result=false msisdn='a23456789012345'
+13: expect=false result=false msisdn='1234567b9012345'
+14: expect=false result=false msisdn='12345678901234c'
+15: expect=false result=false msisdn='123456789 01234'
+16: expect=false result=false msisdn='1234567
+123456'
+17: expect=false result=false msisdn='123456	123456'
+18: expect=false result=false msisdn='123456
123456'
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 1954e66..483860f 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -287,3 +287,9 @@
 cat $abs_srcdir/prbs/prbs_test.ok > expout
 AT_CHECK([$abs_top_builddir/tests/prbs/prbs_test], [0], [expout], [ignore])
 AT_CLEANUP
+
+AT_SETUP([gsm23003])
+AT_KEYWORDS([gsm23003])
+cat $abs_srcdir/gsm23003/gsm23003_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/gsm23003/gsm23003_test], [0], [expout], [ignore])
+AT_CLEANUP

-- 
To view, visit https://gerrit.osmocom.org/4144
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I1e94f5b0717b947d2a7a7d36bacdf04a75cb3522
Gerrit-PatchSet: 1
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>


More information about the gerrit-log mailing list