diff options
Diffstat (limited to 'tests/db')
-rw-r--r-- | tests/db/Makefile.am | 22 | ||||
-rw-r--r-- | tests/db/db_test.c | 231 | ||||
-rw-r--r-- | tests/db/db_test.err | 363 |
3 files changed, 457 insertions, 159 deletions
diff --git a/tests/db/Makefile.am b/tests/db/Makefile.am index afda5be..b07460e 100644 --- a/tests/db/Makefile.am +++ b/tests/db/Makefile.am @@ -1,7 +1,10 @@ -AM_CFLAGS = \ +AM_CPPFLAGS = \ $(all_includes) \ - -I$(top_srcdir)/src \ - -I$(top_builddir)/src \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + $(NULL) + +AM_CFLAGS = \ -Wall \ -ggdb3 \ $(LIBOSMOCORE_CFLAGS) \ @@ -26,16 +29,21 @@ db_test_SOURCES = \ $(NULL) db_test_LDADD = \ - $(top_srcdir)/src/db.c \ - $(top_srcdir)/src/db_hlr.c \ - $(top_srcdir)/src/db_auc.c \ - $(top_srcdir)/src/logging.c \ + $(top_builddir)/src/logging.o \ + $(top_builddir)/src/db_auc.o \ + $(top_builddir)/src/db_hlr.o \ + $(top_builddir)/src/db.o \ + $(top_builddir)/src/cni_peer_id.o \ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(LIBOSMOABIS_LIBS) \ $(SQLITE3_LIBS) \ $(NULL) +if DB_SQLITE_DEBUG +db_test_LDADD += $(top_builddir)/src/db_debug.o +endif + .PHONY: db_test.db update_exp manual manual-nonverbose manual-gdb db_test.db: rm -f db_test.db diff --git a/tests/db/db_test.c b/tests/db/db_test.c index fdd62c5..bdf1393 100644 --- a/tests/db/db_test.c +++ b/tests/db/db_test.c @@ -27,8 +27,9 @@ #include <osmocom/core/utils.h> #include <osmocom/core/logging.h> -#include "db.h" -#include "logging.h" +#include <osmocom/gsupclient/cni_peer_id.h> +#include <osmocom/hlr/db.h> +#include <osmocom/hlr/logging.h> #define comment_start() fprintf(stderr, "\n===== %s\n", __func__); #define comment(fmt, args...) fprintf(stderr, "\n--- " fmt "\n\n", ## args); @@ -51,7 +52,12 @@ static void _fill_invalid(void *dest, size_t size) * The return code is then available in g_rc. */ #define ASSERT_RC(call, expect_rc) \ do { \ - fprintf(stderr, #call " --> " #expect_rc "\n"); \ + if ((expect_rc) == -ENOKEY) \ + fprintf(stderr, #call " --> -ENOKEY\n"); \ + else if ((expect_rc) == -ENOTSUP) \ + fprintf(stderr, #call " --> -ENOTSUP\n"); \ + else \ + fprintf(stderr, #call " --> " #expect_rc "\n"); \ g_rc = call; \ if (g_rc != (expect_rc)) \ fprintf(stderr, " MISMATCH: got rc = %d, expected: " \ @@ -67,7 +73,12 @@ static void _fill_invalid(void *dest, size_t size) do { \ int rc; \ fill_invalid(g_subscr); \ - fprintf(stderr, "db_subscr_get_by_" #by "(dbc, " #val ", &g_subscr) --> " \ + if ((expect_rc) == -ENOKEY) \ + fprintf(stderr, "db_subscr_get_by_" #by "(dbc, " #val ", &g_subscr) --> -ENOKEY \n"); \ + else if ((expect_rc) == -ENOTSUP) \ + fprintf(stderr, "db_subscr_get_by_" #by "(dbc, " #val ", &g_subscr) --> -ENOTSUP \n"); \ + else \ + fprintf(stderr, "db_subscr_get_by_" #by "(dbc, " #val ", &g_subscr) --> " \ #expect_rc "\n"); \ rc = db_subscr_get_by_##by(dbc, val, &g_subscr); \ if (rc != (expect_rc)) \ @@ -105,22 +116,22 @@ static void _fill_invalid(void *dest, size_t size) #define ASSERT_DB_GET_AUC(imsi, expect_rc) \ do { \ struct osmo_auth_vector vec[N_VECTORS]; \ - ASSERT_RC(db_get_auc(dbc, imsi, 3, vec, N_VECTORS, NULL, NULL), expect_rc); \ + ASSERT_RC(db_get_auc(dbc, imsi, 3, vec, N_VECTORS, NULL, NULL, false), expect_rc); \ } while (0) /* Not linking the real auc_compute_vectors(), just returning num_vec. * This gets called by db_get_auc(), but we're only interested in its rc. */ int auc_compute_vectors(struct osmo_auth_vector *vec, unsigned int num_vec, - struct osmo_sub_auth_data *aud2g, - struct osmo_sub_auth_data *aud3g, + struct osmo_sub_auth_data2 *aud2g, + struct osmo_sub_auth_data2 *aud3g, const uint8_t *rand_auts, const uint8_t *auts) { return num_vec; } static struct db_context *dbc = NULL; static void *ctx = NULL; static struct hlr_subscriber g_subscr; -static struct osmo_sub_auth_data g_aud2g; -static struct osmo_sub_auth_data g_aud3g; +static struct osmo_sub_auth_data2 g_aud2g; +static struct osmo_sub_auth_data2 g_aud3g; static int g_rc; static int64_t g_id; @@ -135,6 +146,8 @@ void dump_subscr(struct hlr_subscriber *subscr) #define Ps(name) \ if (*subscr->name) \ Pfo(name, "'%s'", subscr) +#define Pgt(name) \ + Pfv(name, "%s", osmo_ipa_name_to_str(&subscr->name)) #define Pd(name) \ Pfv(name, "%"PRId64, (int64_t)subscr->name) #define Pd_nonzero(name) \ @@ -167,18 +180,21 @@ void dump_subscr(struct hlr_subscriber *subscr) #undef Pb } -void dump_aud(const char *label, struct osmo_sub_auth_data *aud) +void dump_aud(const char *label, struct osmo_sub_auth_data2 *aud) { if (aud->type == OSMO_AUTH_TYPE_NONE) { fprintf(stderr, "%s: none\n", label); return; } - fprintf(stderr, "%s: struct osmo_sub_auth_data {\n", label); + fprintf(stderr, "%s: struct osmo_sub_auth_data2 {\n", label); #define Pf(name, fmt) \ Pfo(name, fmt, aud) #define Phex(name) \ Pfv(name, "'%s'", osmo_hexdump_nospc(aud->name, sizeof(aud->name))) +#define Phexl(name, len) \ + Pfv(name, "'%s'", osmo_hexdump_nospc(aud->name, aud->len)) + Pfv(type, "%s", osmo_sub_auth_type_name(aud->type)); Pfv(algo, "%s", osmo_auth_alg_name(aud->algo)); @@ -187,9 +203,9 @@ void dump_aud(const char *label, struct osmo_sub_auth_data *aud) Phex(u.gsm.ki); break; case OSMO_AUTH_TYPE_UMTS: - Phex(u.umts.opc); + Phexl(u.umts.opc, u.umts.opc_len); Pf(u.umts.opc_is_op, "%u"); - Phex(u.umts.k); + Phexl(u.umts.k, u.umts.k_len); Phex(u.umts.amf); if (aud->u.umts.sqn) { Pf(u.umts.sqn, "%"PRIu64); @@ -206,6 +222,18 @@ void dump_aud(const char *label, struct osmo_sub_auth_data *aud) #undef Pf #undef Phex +#undef Phexl +} + +void db_raw_sql(struct db_context *dbc, const char *sql) +{ + sqlite3_stmt *stmt; + + fprintf(stderr, "raw SQL: %s\n", sql); + ASSERT_RC(sqlite3_prepare_v2(dbc->db, sql, -1, &stmt, NULL), SQLITE_OK); + ASSERT_RC(sqlite3_step(stmt), SQLITE_DONE); + db_remove_reset(stmt); + sqlite3_finalize(stmt); } static const char *imsi0 = "123456789000000"; @@ -214,7 +242,15 @@ static const char *imsi2 = "123456789000002"; static const char *short_imsi = "123456"; static const char *unknown_imsi = "999999999"; -static void test_subscr_create_update_sel_delete() +static int db_subscr_lu_str(struct db_context *dbc, int64_t subscr_id, + const char *vlr_or_sgsn_number, bool is_ps) +{ + struct osmo_ipa_name vlr_nr; + osmo_ipa_name_set_str(&vlr_nr, vlr_or_sgsn_number); + return db_subscr_lu(dbc, subscr_id, &vlr_nr, is_ps, NULL); +} + +static void test_subscr_create_update_sel_delete(void) { int64_t id0, id1, id2, id_short; comment_start(); @@ -230,13 +266,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); @@ -365,39 +401,39 @@ static void test_subscr_create_update_sel_delete() comment("Record LU for PS and CS (SGSN and VLR names)"); - ASSERT_RC(db_subscr_lu(dbc, id0, "5952", true), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "5952", true), 0); ASSERT_SEL(id, id0, 0); - ASSERT_RC(db_subscr_lu(dbc, id0, "712", false), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "712", false), 0); ASSERT_SEL(id, id0, 0); comment("Record LU for PS and CS (SGSN and VLR names) *again*"); - ASSERT_RC(db_subscr_lu(dbc, id0, "111", true), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "111", true), 0); ASSERT_SEL(id, id0, 0); - ASSERT_RC(db_subscr_lu(dbc, id0, "111", true), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "111", true), 0); ASSERT_SEL(id, id0, 0); - ASSERT_RC(db_subscr_lu(dbc, id0, "222", false), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "222", false), 0); ASSERT_SEL(id, id0, 0); - ASSERT_RC(db_subscr_lu(dbc, id0, "222", false), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "222", false), 0); ASSERT_SEL(id, id0, 0); comment("Unset LU info for PS and CS (SGSN and VLR names)"); - ASSERT_RC(db_subscr_lu(dbc, id0, "", true), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "", true), 0); ASSERT_SEL(id, id0, 0); - ASSERT_RC(db_subscr_lu(dbc, id0, "", false), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "", false), 0); ASSERT_SEL(id, id0, 0); - ASSERT_RC(db_subscr_lu(dbc, id0, "111", true), 0); - ASSERT_RC(db_subscr_lu(dbc, id0, "222", false), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "111", true), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, "222", false), 0); ASSERT_SEL(id, id0, 0); - ASSERT_RC(db_subscr_lu(dbc, id0, NULL, true), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, NULL, true), 0); ASSERT_SEL(id, id0, 0); - ASSERT_RC(db_subscr_lu(dbc, id0, NULL, false), 0); + ASSERT_RC(db_subscr_lu_str(dbc, id0, NULL, false), 0); ASSERT_SEL(id, id0, 0); comment("Record LU for non-existent ID"); - ASSERT_RC(db_subscr_lu(dbc, 99999, "5952", true), -ENOENT); - ASSERT_RC(db_subscr_lu(dbc, 99999, "712", false), -ENOENT); + ASSERT_RC(db_subscr_lu_str(dbc, 99999, "5952", true), -ENOENT); + ASSERT_RC(db_subscr_lu_str(dbc, 99999, "712", false), -ENOENT); ASSERT_SEL(id, 99999, -ENOENT); comment("Purge and un-purge PS and CS"); @@ -509,7 +545,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; @@ -554,7 +590,7 @@ static void test_subscr_aud() ASSERT_SEL_AUD(imsi0, 0, id); ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, - mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")), + mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "CededEffacedAceFacedBadFadedBeef")), 0); ASSERT_SEL_AUD(imsi0, 0, id); @@ -572,7 +608,7 @@ static void test_subscr_aud() -ENOENT); ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, - mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")), + mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "CededEffacedAceFacedBadFadedBeef")), 0); ASSERT_SEL_AUD(imsi0, 0, id); @@ -675,12 +711,12 @@ static void test_subscr_aud() ASSERT_SEL_AUD(imsi0, 0, id); ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, - mk_aud_2g(OSMO_AUTH_ALG_XOR, "f000000000000f00000000000f000000f00000000")), + mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "f000000000000f00000000000f000000f00000000")), -EINVAL); ASSERT_SEL_AUD(imsi0, 0, id); ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, - mk_aud_2g(OSMO_AUTH_ALG_XOR, "f00")), + mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "f00")), -EINVAL); ASSERT_SEL_AUD(imsi0, 0, id); @@ -749,7 +785,71 @@ static void test_subscr_aud() comment_end(); } -static void test_subscr_sqn() +/* 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(void) +{ + int64_t id; + + comment_start(); + comment("Create subscriber"); + ASSERT_RC(db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS), 0); + ASSERT_SEL(imsi, imsi0, 0); + id = g_subscr.id; + + + /* Invalid Ki length */ + comment("Set auth data, 2G only, with invalid Ki length"); + ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, + mk_aud_2g(OSMO_AUTH_ALG_COMP128v1, "0123456789abcdef0123456789abcdef")), + 0); + /* Use raw SQL to avoid length check in db_subscr_update_aud_by_id(). This changes all rows in the table, which + * is fine for this test (implicit WHERE 1). */ + db_raw_sql(dbc, "UPDATE auc_2g SET ki = '0123456789abcdef0123456789abcde'"); + ASSERT_SEL_AUD(imsi0, -ENOKEY, id); + + comment("Remove 2G auth data"); + ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, + mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)), + 0); + + /* Invalid K length */ + comment("Set auth data, 3G only, with invalid K length"); + ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, + mk_aud_3g(OSMO_AUTH_ALG_MILENAGE, + "BeefedCafeFaceAcedAddedDecadeFee", true, + "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)), + 0); + db_raw_sql(dbc, "UPDATE auc_3g SET k = 'C01ffedC1cadaeAc1d1f1edAcac1aB0'"); + ASSERT_SEL_AUD(imsi0, -EIO, id); + + /* Invalid OP length */ + comment("Set auth data, 3G only, with invalid OP length"); + ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, + mk_aud_3g(OSMO_AUTH_ALG_MILENAGE, + "BeefedCafeFaceAcedAddedDecadeFee", true, + "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)), + 0); + db_raw_sql(dbc, "UPDATE auc_3g SET op = 'BeefedCafeFaceAcedAddedDecadeFe'"); + ASSERT_SEL_AUD(imsi0, -EIO, id); + + /* Invalid OPC length */ + comment("Set auth data, 3G only, with invalid OPC length"); + ASSERT_RC(db_subscr_update_aud_by_id(dbc, id, + mk_aud_3g(OSMO_AUTH_ALG_MILENAGE, + "BeefedCafeFaceAcedAddedDecadeFee", false, + "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)), + 0); + db_raw_sql(dbc, "UPDATE auc_3g SET opc = 'BeefedCafeFaceAcedAddedDecadeFe'"); + ASSERT_SEL_AUD(imsi0, -EIO, id); + + + comment("Delete subscriber"); + ASSERT_RC(db_subscr_delete_by_id(dbc, id), 0); + comment_end(); +} + +static void test_subscr_sqn(void) { int64_t id; @@ -822,6 +922,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 = { @@ -884,9 +1028,13 @@ int main(int argc, char **argv) handle_options(argc, argv); osmo_init_logging2(ctx, &hlr_log_info); - log_set_print_filename(osmo_stderr_target, cmdline_opts.verbose); + log_set_print_filename2(osmo_stderr_target, + cmdline_opts.verbose ? + LOG_FILENAME_BASENAME : + LOG_FILENAME_NONE); log_set_print_timestamp(osmo_stderr_target, 0); log_set_use_color(osmo_stderr_target, 0); + log_set_print_category_hex(osmo_stderr_target, 0); log_set_print_category(osmo_stderr_target, 1); log_parse_category_mask(osmo_stderr_target, "DMAIN,1:DDB,1:DAUC,1"); @@ -900,9 +1048,12 @@ int main(int argc, char **argv) test_subscr_create_update_sel_delete(); test_subscr_aud(); + test_subscr_aud_invalid_len(); test_subscr_sqn(); + test_ind(); printf("Done\n"); + db_close(dbc); return 0; } diff --git a/tests/db/db_test.err b/tests/db/db_test.err index 4dc77e8..dee85e0 100644 --- a/tests/db/db_test.err +++ b/tests/db/db_test.err @@ -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 @@ -64,25 +64,21 @@ db_subscr_create(dbc, "123456789 000003", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG DAUC Cannot create subscriber: invalid IMSI: '123456789 000003' db_subscr_get_by_imsi(dbc, "123456789000003", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123456789000003': No such subscriber db_subscr_create(dbc, "123456789000002123456", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EINVAL DAUC Cannot create subscriber: invalid IMSI: '123456789000002123456' db_subscr_get_by_imsi(dbc, "123456789000002123456", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123456789000002123456': No such subscriber db_subscr_create(dbc, "foobar123", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EINVAL DAUC Cannot create subscriber: invalid IMSI: 'foobar123' db_subscr_get_by_imsi(dbc, "foobar123", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='foobar123': No such subscriber db_subscr_create(dbc, "123", DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> -EINVAL DAUC Cannot create subscriber: invalid IMSI: '123' db_subscr_get_by_imsi(dbc, "123", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123': No such subscriber db_subscr_create(dbc, short_imsi, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> 0 @@ -142,7 +138,6 @@ struct hlr_subscriber { } db_subscr_get_by_msisdn(dbc, "54321012345678912345678", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: MSISDN='54321012345678912345678': No such subscriber db_subscr_update_msisdn_by_imsi(dbc, imsi0, "543 21") --> -EINVAL DAUC IMSI='123456789000000': Cannot update subscriber: invalid MSISDN: '543 21' @@ -155,7 +150,6 @@ struct hlr_subscriber { } db_subscr_get_by_msisdn(dbc, "543 21", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: MSISDN='543 21': No such subscriber db_subscr_update_msisdn_by_imsi(dbc, imsi0, "foobar123") --> -EINVAL DAUC IMSI='123456789000000': Cannot update subscriber: invalid MSISDN: 'foobar123' @@ -168,7 +162,6 @@ struct hlr_subscriber { } db_subscr_get_by_msisdn(dbc, "foobar123", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: MSISDN='foobar123': No such subscriber db_subscr_update_msisdn_by_imsi(dbc, imsi0, "5") --> 0 @@ -187,7 +180,6 @@ struct hlr_subscriber { } db_subscr_get_by_msisdn(dbc, "54321", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: MSISDN='54321': No such subscriber db_subscr_update_msisdn_by_imsi(dbc, imsi0, "543210123456789") --> 0 @@ -216,7 +208,6 @@ struct hlr_subscriber { } db_subscr_get_by_msisdn(dbc, "5432101234567891", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: MSISDN='5432101234567891': No such subscriber --- Check if subscriber exists (by MSISDN) @@ -232,13 +223,11 @@ db_subscr_update_msisdn_by_imsi(dbc, unknown_imsi, "99") --> -ENOENT DAUC Cannot update MSISDN: no such subscriber: IMSI='999999999' db_subscr_get_by_msisdn(dbc, "99", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: MSISDN='99': No such subscriber db_subscr_update_msisdn_by_imsi(dbc, "foobar", "99") --> -ENOENT DAUC Cannot update MSISDN: no such subscriber: IMSI='foobar' db_subscr_get_by_msisdn(dbc, "99", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: MSISDN='99': No such subscriber --- Set valid / invalid IMEI @@ -265,7 +254,6 @@ struct hlr_subscriber { } db_subscr_get_by_imei(dbc, "123456789012345", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMEI=123456789012345: No such subscriber --- Set the same IMEI again @@ -286,7 +274,6 @@ struct hlr_subscriber { db_subscr_update_imei_by_imsi(dbc, imsi0, NULL) --> 0 db_subscr_get_by_imei(dbc, "12345678901234", &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMEI=12345678901234: No such subscriber --- Set / unset nam_cs and nam_ps @@ -424,7 +411,6 @@ db_subscr_nam(dbc, unknown_imsi, false, false) --> -ENOENT DAUC Cannot disable CS: no such subscriber: IMSI='999999999' db_subscr_get_by_imsi(dbc, unknown_imsi, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='999999999': No such subscriber db_subscr_nam(dbc, "foobar", false, true) --> -ENOENT DAUC Cannot disable PS: no such subscriber: IMSI='foobar' @@ -435,7 +421,7 @@ DAUC Cannot disable CS: no such subscriber: IMSI='foobar' --- Record LU for PS and CS (SGSN and VLR names) -db_subscr_lu(dbc, id0, "5952", true) --> 0 +db_subscr_lu_str(dbc, id0, "5952", true) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -445,7 +431,7 @@ struct hlr_subscriber { .sgsn_number = '5952', } -db_subscr_lu(dbc, id0, "712", false) --> 0 +db_subscr_lu_str(dbc, id0, "712", false) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -459,7 +445,7 @@ struct hlr_subscriber { --- Record LU for PS and CS (SGSN and VLR names) *again* -db_subscr_lu(dbc, id0, "111", true) --> 0 +db_subscr_lu_str(dbc, id0, "111", true) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -470,7 +456,7 @@ struct hlr_subscriber { .sgsn_number = '111', } -db_subscr_lu(dbc, id0, "111", true) --> 0 +db_subscr_lu_str(dbc, id0, "111", true) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -481,7 +467,7 @@ struct hlr_subscriber { .sgsn_number = '111', } -db_subscr_lu(dbc, id0, "222", false) --> 0 +db_subscr_lu_str(dbc, id0, "222", false) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -492,7 +478,7 @@ struct hlr_subscriber { .sgsn_number = '111', } -db_subscr_lu(dbc, id0, "222", false) --> 0 +db_subscr_lu_str(dbc, id0, "222", false) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -506,7 +492,7 @@ struct hlr_subscriber { --- Unset LU info for PS and CS (SGSN and VLR names) -db_subscr_lu(dbc, id0, "", true) --> 0 +db_subscr_lu_str(dbc, id0, "", true) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -516,7 +502,7 @@ struct hlr_subscriber { .vlr_number = '222', } -db_subscr_lu(dbc, id0, "", false) --> 0 +db_subscr_lu_str(dbc, id0, "", false) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -525,9 +511,9 @@ struct hlr_subscriber { .msisdn = '543210123456789', } -db_subscr_lu(dbc, id0, "111", true) --> 0 +db_subscr_lu_str(dbc, id0, "111", true) --> 0 -db_subscr_lu(dbc, id0, "222", false) --> 0 +db_subscr_lu_str(dbc, id0, "222", false) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -538,7 +524,7 @@ struct hlr_subscriber { .sgsn_number = '111', } -db_subscr_lu(dbc, id0, NULL, true) --> 0 +db_subscr_lu_str(dbc, id0, NULL, true) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -548,7 +534,7 @@ struct hlr_subscriber { .vlr_number = '222', } -db_subscr_lu(dbc, id0, NULL, false) --> 0 +db_subscr_lu_str(dbc, id0, NULL, false) --> 0 db_subscr_get_by_id(dbc, id0, &g_subscr) --> 0 struct hlr_subscriber { @@ -560,14 +546,13 @@ struct hlr_subscriber { --- Record LU for non-existent ID -db_subscr_lu(dbc, 99999, "5952", true) --> -ENOENT +db_subscr_lu_str(dbc, 99999, "5952", true) --> -ENOENT DAUC Cannot update SGSN number for subscriber ID=99999: no such subscriber -db_subscr_lu(dbc, 99999, "712", false) --> -ENOENT +db_subscr_lu_str(dbc, 99999, "712", false) --> -ENOENT DAUC Cannot update VLR number for subscriber ID=99999: no such subscriber db_subscr_get_by_id(dbc, 99999, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: ID=99999: No such subscriber --- Purge and un-purge PS and CS @@ -698,13 +683,11 @@ db_subscr_purge(dbc, unknown_imsi, true, true) --> -ENOENT DAUC Cannot purge PS: no such subscriber: IMSI='999999999' db_subscr_get_by_imsi(dbc, unknown_imsi, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='999999999': No such subscriber db_subscr_purge(dbc, unknown_imsi, true, false) --> -ENOENT DAUC Cannot purge CS: no such subscriber: IMSI='999999999' db_subscr_get_by_imsi(dbc, unknown_imsi, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='999999999': No such subscriber --- Delete non-existent / invalid IDs @@ -728,7 +711,6 @@ struct hlr_subscriber { db_subscr_delete_by_id(dbc, id0) --> 0 db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123456789000000': No such subscriber db_subscr_delete_by_id(dbc, id0) --> -ENOENT DAUC Cannot delete: no such subscriber: ID=1 @@ -742,7 +724,6 @@ struct hlr_subscriber { db_subscr_delete_by_id(dbc, id1) --> 0 db_subscr_get_by_imsi(dbc, imsi1, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123456789000001': No such subscriber db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> 0 struct hlr_subscriber { @@ -753,7 +734,6 @@ struct hlr_subscriber { db_subscr_delete_by_id(dbc, id2) --> 0 db_subscr_get_by_imsi(dbc, imsi2, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123456789000002': No such subscriber db_subscr_get_by_imsi(dbc, short_imsi, &g_subscr) --> 0 struct hlr_subscriber { @@ -764,7 +744,6 @@ struct hlr_subscriber { db_subscr_delete_by_id(dbc, id_short) --> 0 db_subscr_get_by_imsi(dbc, short_imsi, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123456': No such subscriber --- Create and delete subscribers with non-default nam_cs and nam_ps @@ -814,7 +793,7 @@ db_get_auth_data(dbc, unknown_imsi, &g_aud2g, &g_aud3g, &g_id) --> -2 DAUC IMSI='999999999': No such subscriber -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -2 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> -2 DAUC IMSI='123456789000000': No such subscriber @@ -828,12 +807,12 @@ struct hlr_subscriber { .imsi = '123456789000000', } -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data @@ -845,14 +824,14 @@ db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_COMP128v1, "01234567 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 3G Auth Data -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v1, .u.gsm.ki = '0123456789abcdef0123456789abcdef', } 3G: none -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> 3 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> 3 DAUC IMSI='123456789000000': No 3G Auth Data DAUC IMSI='123456789000000': Calling to generate 3 vectors DAUC IMSI='123456789000000': Generated 3 vectors @@ -862,7 +841,7 @@ db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_COMP128v1, "01234567 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 3G Auth Data -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v1, .u.gsm.ki = '0123456789abcdef0123456789abcdef', @@ -874,7 +853,7 @@ db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_COMP128v2, "BeadedBe db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 3G Auth Data -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v2, .u.gsm.ki = 'beadedbeeaced1ebbeddefacedfacade', @@ -886,21 +865,21 @@ db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_COMP128v3, "DeafBedd db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 3G Auth Data -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'deafbeddedbabeacceededfadeddecaf', } 3G: none -db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")) --> 0 +db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "CededEffacedAceFacedBadFadedBeef")) --> 0 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 3G Auth Data -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, - .algo = XOR, + .algo = XOR-2G, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } 3G: none @@ -910,37 +889,37 @@ DAUC IMSI='123456789000000': No 3G Auth Data db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)) --> 0 -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)) --> -ENOENT -db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR, "CededEffacedAceFacedBadFadedBeef")) --> 0 +db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "CededEffacedAceFacedBadFadedBeef")) --> 0 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 3G Auth Data -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, - .algo = XOR, + .algo = XOR-2G, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } 3G: none db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, "f000000000000f00000000000f000000")) --> 0 -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data @@ -953,7 +932,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -963,7 +942,7 @@ DAUC IMSI='123456789000000': No 2G Auth Data .u.umts.ind_bitlen = 5, } -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> 3 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> 3 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': Calling to generate 3 vectors DAUC IMSI='123456789000000': Generated 3 vectors @@ -975,7 +954,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -991,7 +970,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'deaf0ff1ced0d0dabbedd1ced1cef00d', @@ -1006,7 +985,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1022,7 +1001,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'cededeffacedacefacedbadfadedbeef', @@ -1037,12 +1016,12 @@ DAUC IMSI='123456789000000': No 2G Auth Data db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_NONE, NULL, false, NULL, 0)) --> 0 -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data @@ -1054,7 +1033,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'cededeffacedacefacedbadfadedbeef', @@ -1064,7 +1043,7 @@ DAUC IMSI='123456789000000': No 2G Auth Data .u.umts.ind_bitlen = 5, } -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> 3 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> 3 DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': Calling to generate 3 vectors DAUC IMSI='123456789000000': Generated 3 vectors @@ -1072,12 +1051,12 @@ DAUC IMSI='123456789000000': Updating SQN=0 in DB db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_NONE, "asdfasdfasd", false, "asdfasdfasdf", 99999)) --> 0 -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data @@ -1090,12 +1069,12 @@ db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_MILENAGE, "BeefedCaf db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1105,7 +1084,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 .u.umts.ind_bitlen = 5, } -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> 3 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> 3 DAUC IMSI='123456789000000': Calling to generate 3 vectors DAUC IMSI='123456789000000': Generated 3 vectors DAUC IMSI='123456789000000': Updating SQN=0 in DB @@ -1118,12 +1097,12 @@ DAUC Cannot update auth tokens: Unknown auth algo: 99999 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1133,17 +1112,17 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 .u.umts.ind_bitlen = 5, } -db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR, "f000000000000f00000000000f000000f00000000")) --> -EINVAL +db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "f000000000000f00000000000f000000f00000000")) --> -EINVAL DAUC Cannot update auth tokens: Invalid KI: 'f000000000000f00000000000f000000f00000000' db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1153,17 +1132,17 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 .u.umts.ind_bitlen = 5, } -db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR, "f00")) --> -EINVAL +db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_XOR_2G, "f00")) --> -EINVAL DAUC Cannot update auth tokens: Invalid KI: 'f00' db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1178,12 +1157,12 @@ DAUC Cannot update auth tokens: auth algo not suited for 2G: MILENAGE db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1198,12 +1177,12 @@ DAUC Cannot update auth tokens: Invalid OP/OPC: '0f000000000000f00000000000f0000 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1218,12 +1197,12 @@ DAUC Cannot update auth tokens: Invalid K: '000000000000f00000000000f000000' db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1238,12 +1217,12 @@ DAUC Cannot update auth tokens: Invalid ind_bitlen: 29 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1258,12 +1237,12 @@ DAUC Cannot update auth tokens: Invalid OP/OPC: 'X000000000000f00000000000f00000 db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1278,12 +1257,12 @@ DAUC Cannot update auth tokens: Invalid K: 'f000000000000 f00000000000 f000000' db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 -2G: struct osmo_sub_auth_data { +2G: struct osmo_sub_auth_data2 { .type = GSM, .algo = COMP128v3, .u.gsm.ki = 'cededeffacedacefacedbadfadedbeef', } -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1305,7 +1284,6 @@ struct hlr_subscriber { db_subscr_delete_by_id(dbc, id) --> 0 db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123456789000000': No such subscriber --- Re-add subscriber and verify auth data didn't come back @@ -1318,26 +1296,110 @@ struct hlr_subscriber { .imsi = '123456789000000', } -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -126 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data db_subscr_delete_by_id(dbc, id) --> 0 db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123456789000000': No such subscriber -db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL) --> -2 +db_get_auc(dbc, imsi0, 3, vec, N_VECTORS, NULL, NULL, false) --> -2 DAUC IMSI='123456789000000': No such subscriber ===== test_subscr_aud: SUCCESS +===== test_subscr_aud_invalid_len + +--- Create subscriber + +db_subscr_create(dbc, imsi0, DB_SUBSCR_FLAG_NAM_CS | DB_SUBSCR_FLAG_NAM_PS) --> 0 + +db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> 0 +struct hlr_subscriber { + .id = 1, + .imsi = '123456789000000', +} + + +--- Set auth data, 2G only, with invalid Ki length + +db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_COMP128v1, "0123456789abcdef0123456789abcdef")) --> 0 + +raw SQL: UPDATE auc_2g SET ki = '0123456789abcdef0123456789abcde' +sqlite3_prepare_v2(dbc->db, sql, -1, &stmt, NULL) --> SQLITE_OK + +sqlite3_step(stmt) --> SQLITE_DONE + +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY +DAUC IMSI='123456789000000': Error reading Ki, expected min length 16 but has length 15 +DAUC IMSI='123456789000000': No 3G Auth Data + + + +--- Remove 2G auth data + +db_subscr_update_aud_by_id(dbc, id, mk_aud_2g(OSMO_AUTH_ALG_NONE, NULL)) --> 0 + + +--- Set auth data, 3G only, with invalid K length + +db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_MILENAGE, "BeefedCafeFaceAcedAddedDecadeFee", true, "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)) --> 0 + +raw SQL: UPDATE auc_3g SET k = 'C01ffedC1cadaeAc1d1f1edAcac1aB0' +sqlite3_prepare_v2(dbc->db, sql, -1, &stmt, NULL) --> SQLITE_OK + +sqlite3_step(stmt) --> SQLITE_DONE + +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -5 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': Error reading K, expected min length 16 but has length 15 + + + +--- Set auth data, 3G only, with invalid OP length + +db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_MILENAGE, "BeefedCafeFaceAcedAddedDecadeFee", true, "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)) --> 0 + +raw SQL: UPDATE auc_3g SET op = 'BeefedCafeFaceAcedAddedDecadeFe' +sqlite3_prepare_v2(dbc->db, sql, -1, &stmt, NULL) --> SQLITE_OK + +sqlite3_step(stmt) --> SQLITE_DONE + +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -5 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': Error reading OP, expected min length 16 but has length 15 + + + +--- Set auth data, 3G only, with invalid OPC length + +db_subscr_update_aud_by_id(dbc, id, mk_aud_3g(OSMO_AUTH_ALG_MILENAGE, "BeefedCafeFaceAcedAddedDecadeFee", false, "C01ffedC1cadaeAc1d1f1edAcac1aB0a", 5)) --> 0 + +raw SQL: UPDATE auc_3g SET opc = 'BeefedCafeFaceAcedAddedDecadeFe' +sqlite3_prepare_v2(dbc->db, sql, -1, &stmt, NULL) --> SQLITE_OK + +sqlite3_step(stmt) --> SQLITE_DONE + +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -5 +DAUC IMSI='123456789000000': No 2G Auth Data +DAUC IMSI='123456789000000': Error reading OPC, expected min length 16 but has length 15 + + + +--- Delete subscriber + +db_subscr_delete_by_id(dbc, id) --> 0 + +===== test_subscr_aud_invalid_len: SUCCESS + + ===== test_subscr_sqn --- Set SQN for unknown subscriber @@ -1346,13 +1408,11 @@ db_update_sqn(dbc, 99, 999) --> -ENOENT DAUC Cannot update SQN for subscriber ID=99: no auc_3g entry for such subscriber db_subscr_get_by_id(dbc, 99, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: ID=99: No such subscriber db_update_sqn(dbc, 9999, 99) --> -ENOENT DAUC Cannot update SQN for subscriber ID=9999: no auc_3g entry for such subscriber db_subscr_get_by_id(dbc, 9999, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: ID=9999: No such subscriber --- Create subscriber @@ -1365,7 +1425,7 @@ struct hlr_subscriber { .imsi = '123456789000000', } -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data @@ -1376,7 +1436,7 @@ DAUC IMSI='123456789000000': No 3G Auth Data db_update_sqn(dbc, id, 123) --> -ENOENT DAUC Cannot update SQN for subscriber ID=1: no auc_3g entry for such subscriber -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data @@ -1384,7 +1444,7 @@ DAUC IMSI='123456789000000': No 3G Auth Data db_update_sqn(dbc, id, 543) --> -ENOENT DAUC Cannot update SQN for subscriber ID=1: no auc_3g entry for such subscriber -db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -126 +db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> -ENOKEY DAUC IMSI='123456789000000': No 2G Auth Data DAUC IMSI='123456789000000': No 3G Auth Data @@ -1398,7 +1458,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1417,7 +1477,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1435,7 +1495,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1453,7 +1513,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1474,7 +1534,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1490,7 +1550,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1508,7 +1568,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1526,7 +1586,7 @@ db_get_auth_data(dbc, imsi0, &g_aud2g, &g_aud3g, &g_id) --> 0 DAUC IMSI='123456789000000': No 2G Auth Data 2G: none -3G: struct osmo_sub_auth_data { +3G: struct osmo_sub_auth_data2 { .type = UMTS, .algo = MILENAGE, .u.umts.opc = 'beefedcafefaceacedaddeddecadefee', @@ -1550,7 +1610,86 @@ struct hlr_subscriber { db_subscr_delete_by_id(dbc, id) --> 0 db_subscr_get_by_imsi(dbc, imsi0, &g_subscr) --> -ENOENT -DAUC Cannot read subscriber from db: IMSI='123456789000000': No such subscriber ===== 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 + |