blob: 5743fce9d55b6b6d1ddfae5a5f0b41e5425a494e [file] [log] [blame]
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Neels Hofmeyr396f2e62017-09-04 15:13:25 +020022#include <osmocom/sgsn/gprs_llc.h>
23#include <osmocom/sgsn/sgsn.h>
24#include <osmocom/sgsn/gprs_gmm.h>
25#include <osmocom/sgsn/debug.h>
26#include <osmocom/sgsn/gprs_subscriber.h>
Harald Welte23d77d52016-04-25 19:07:34 +020027#include <osmocom/gsm/gsup.h>
Neels Hofmeyr396f2e62017-09-04 15:13:25 +020028#include <osmocom/sgsn/gsup_client.h>
29#include <osmocom/sgsn/gprs_utils.h>
30#include <osmocom/sgsn/gprs_gb_parse.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020031
Jacob Erlbeck189999d2014-10-27 14:34:13 +010032#include <osmocom/gprs/gprs_bssgp.h>
33
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020034#include <osmocom/gsm/gsm_utils.h>
35
36#include <osmocom/core/application.h>
37#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010038#include <osmocom/core/rate_ctr.h>
Neels Hofmeyr59504dc2017-01-13 03:10:54 +010039#include <osmocom/core/utils.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020040
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020041#include <stdio.h>
42
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020043void *tall_bsc_ctx;
44static struct sgsn_instance sgsn_inst = {
45 .config_file = "osmo_sgsn.cfg",
46 .cfg = {
47 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010048 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020049 },
50};
51struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010052unsigned sgsn_tx_counter = 0;
Jacob Erlbeck133e8622015-10-12 19:36:32 +020053struct msgb *last_msg = NULL;
54struct gprs_gb_parse_context last_dl_parse_ctx;
55
56static void reset_last_msg()
57{
58 if (last_msg)
59 msgb_free(last_msg);
60
61 last_msg = NULL;
62 memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx));
63}
Jacob Erlbeck189999d2014-10-27 14:34:13 +010064
Jacob Erlbeckcf151872015-10-12 19:36:31 +020065static void cleanup_test()
66{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020067 reset_last_msg();
68}
69
70static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
71{
72 uint32_t new_ptmsi = GSM_RESERVED_TMSI;
73
74 if (parse_ctx->new_ptmsi_enc)
75 gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
76
77 return new_ptmsi;
Jacob Erlbeckcf151872015-10-12 19:36:31 +020078}
79
Jacob Erlbeck189999d2014-10-27 14:34:13 +010080/* override */
81int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
82 struct bssgp_dl_ud_par *dup)
83{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020084 int rc;
85
86 reset_last_msg();
87
88 last_msg = msg;
89 OSMO_ASSERT(msgb_data(last_msg) != NULL);
90
91 rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg),
92 &last_dl_parse_ctx);
93
94 fprintf(stderr, "Got DL LLC message: %s\n",
95 gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN"));
96
97 OSMO_ASSERT(rc > 0);
98
Jacob Erlbeck189999d2014-10-27 14:34:13 +010099 sgsn_tx_counter += 1;
100 return 0;
101}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200102
Max3b6332f2017-11-01 13:28:38 +0100103/* override, requires '-Wl,--wrap=osmo_get_rand_id' */
104int __real_osmo_get_rand_id(uint8_t *data, size_t len);
105int mock_osmo_get_rand_id(uint8_t *data, size_t len);
106int (*osmo_get_rand_id_cb)(uint8_t *, size_t) =
107 &mock_osmo_get_rand_id;
Max4011e722016-07-05 15:19:12 +0200108
Max3b6332f2017-11-01 13:28:38 +0100109int __wrap_osmo_get_rand_id(uint8_t *buf, size_t num)
Max4011e722016-07-05 15:19:12 +0200110{
Max3b6332f2017-11-01 13:28:38 +0100111 return (*osmo_get_rand_id_cb)(buf, num);
Max4011e722016-07-05 15:19:12 +0200112}
113/* make results of A&C ref predictable */
Max3b6332f2017-11-01 13:28:38 +0100114int mock_osmo_get_rand_id(uint8_t *buf, size_t num)
Max4011e722016-07-05 15:19:12 +0200115{
116 if (num > 1)
Max3b6332f2017-11-01 13:28:38 +0100117 return __real_osmo_get_rand_id(buf, num);
Max4011e722016-07-05 15:19:12 +0200118 buf[0] = 0;
119 return 1;
120}
121
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100122/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100123void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
124void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100125 &__real_sgsn_update_subscriber_data;
126
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100127void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100128{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100129 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100130}
131
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100132/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
133int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
134int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
135 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100136
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100137int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
138 return (*subscr_request_update_location_cb)(mmctx);
139};
140
141/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
Pau Espin Pedrol93fd4622017-08-16 11:30:01 +0200142int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand);
143int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand) =
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100144 &__real_gprs_subscr_request_auth_info;
145
Pau Espin Pedrol93fd4622017-08-16 11:30:01 +0200146int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand) {
147 return (*subscr_request_auth_info_cb)(mmctx, auts, auts_rand);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100148};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100149
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100150/* override, requires '-Wl,--wrap=gsup_client_send' */
151int __real_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg);
152int (*gsup_client_send_cb)(struct gsup_client *gsupc, struct msgb *msg) =
153 &__real_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100154
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100155int __wrap_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100156{
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100157 return (*gsup_client_send_cb)(gsupc, msg);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100158};
159
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200160static int count(struct llist_head *head)
161{
162 struct llist_head *cur;
163 int count = 0;
164
165 llist_for_each(cur, head)
166 count += 1;
167
168 return count;
169}
170
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200171static struct msgb *create_msg(const uint8_t *data, size_t len)
172{
173 struct msgb *msg = msgb_alloc(len + 8, "test message");
174 msg->l1h = msgb_put(msg, 8);
175 msg->l2h = msgb_put(msg, len);
176 memcpy(msg->l2h, data, len);
177
178 msgb_bcid(msg) = msg->l1h;
179 msgb_gmmh(msg) = msg->l2h;
180 return msg;
181}
182
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100183/*
184 * Create a context and search for it
185 */
186static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
187{
188 struct sgsn_mm_ctx *ctx, *ictx;
189 struct gprs_llc_lle *lle;
190 int old_count = count(gprs_llme_list());
191
192 lle = gprs_lle_get_or_create(tlli, 3);
Alexander Couzens2b5fb8e2017-02-04 06:01:00 +0100193 ctx = sgsn_mm_ctx_alloc_gb(tlli, raid);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +0100194 ctx->gmm_state = GMM_REGISTERED_NORMAL;
Harald Weltef97ee042015-12-25 19:12:21 +0100195 ctx->gb.llme = lle->llme;
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100196
197 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
198 OSMO_ASSERT(ictx == ctx);
199
200 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
201
202 return ctx;
203}
204
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100205static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck91580892016-01-04 18:43:33 +0100206 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100207 const uint8_t *data, size_t data_len)
208{
209 struct msgb *msg;
210
Jacob Erlbeck133e8622015-10-12 19:36:32 +0200211 reset_last_msg();
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100212 sgsn_tx_counter = 0;
213
214 msg = create_msg(data, data_len);
215 msgb_tlli(msg) = tlli;
Jacob Erlbeck91580892016-01-04 18:43:33 +0100216 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Max82040102016-07-06 11:59:18 +0200217 gsm0408_gprs_rcvmsg_gb(msg, llme, false);
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100218 msgb_free(msg);
219}
220
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200221static void test_llme(void)
222{
223 struct gprs_llc_lle *lle, *lle_copy;
224 uint32_t local_tlli;
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200225
226 printf("Testing LLME allocations\n");
227 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200228
229 /* initial state */
230 OSMO_ASSERT(count(gprs_llme_list()) == 0);
231
232 /* Create a new entry */
233 lle = gprs_lle_get_or_create(local_tlli, 3);
234 OSMO_ASSERT(lle);
235 OSMO_ASSERT(count(gprs_llme_list()) == 1);
236
237 /* No new entry is created */
238 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
239 OSMO_ASSERT(lle == lle_copy);
240 OSMO_ASSERT(count(gprs_llme_list()) == 1);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200241
242 /* unassign which should delete it*/
Max39550252016-06-28 17:39:20 +0200243 gprs_llgmm_unassign(lle->llme);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200244
245 /* Check that everything was cleaned up */
246 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200247
248 cleanup_test();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200249}
250
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100251struct gprs_subscr *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100252void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100253{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100254 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100255 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100256 __func__, mmctx, mmctx->subscr);
257 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100258}
259
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100260static void assert_subscr(const struct gprs_subscr *subscr, const char *imsi)
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100261{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100262 struct gprs_subscr *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100263 OSMO_ASSERT(subscr);
264 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100265
266 sfound = gprs_subscr_get_by_imsi(imsi);
267 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100268
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100269 gprs_subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100270}
271
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100272static void show_subscrs(FILE *out)
273{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100274 struct gprs_subscr *subscr;
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100275
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100276 llist_for_each_entry(subscr, gprs_subscribers, entry) {
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100277 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100278 "use count: %d\n",
279 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100280 }
281}
282
283static void assert_no_subscrs()
284{
285 show_subscrs(stdout);
286 fflush(stdout);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100287 OSMO_ASSERT(llist_empty(gprs_subscribers));
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100288}
289
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100290#define VERBOSE_ASSERT(val, expect_op, fmt) \
291 do { \
292 printf(#val " == " fmt "\n", (val)); \
293 OSMO_ASSERT((val) expect_op); \
294 } while (0);
295
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100296static void test_subscriber(void)
297{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100298 struct gprs_subscr *s1, *s2, *s3;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100299 const char *imsi1 = "1234567890";
300 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100301 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100302
303 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
304
305 printf("Testing core subscriber data API\n");
306
307 /* Check for emptiness */
308 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
309 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100310 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100311 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d");
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100312
313 /* Allocate entry 1 */
314 s1 = gprs_subscr_get_or_create(imsi1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100315 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
316 s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100317 assert_subscr(s1, imsi1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100318 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100319 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100320
321 /* Allocate entry 2 */
322 s2 = gprs_subscr_get_or_create(imsi2);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100323 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d");
324 s2->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100325
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100326 /* Allocate entry 3 */
327 s3 = gprs_subscr_get_or_create(imsi3);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100328 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 3, "%d");
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100329
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100330 /* Check entries */
331 assert_subscr(s1, imsi1);
332 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100333 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100334
335 /* Update entry 1 */
336 last_updated_subscr = NULL;
337 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100338 OSMO_ASSERT(last_updated_subscr == NULL);
339 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100340 OSMO_ASSERT((s1->flags & GPRS_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100341
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100342 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100343 gprs_subscr_cleanup(s1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100344 gprs_subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100345 s1 = NULL;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100346 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d");
347 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100348
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100349 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100350 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100351
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100352 /* Free entry 2 (GPRS_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100353 gprs_subscr_cleanup(s2);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100354 gprs_subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100355 s2 = NULL;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100356 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100357 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
358 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100359 assert_subscr(s3, imsi3);
360
361 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100362 gprs_subscr_cleanup(s3);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100363 gprs_subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100364 s3 = NULL;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100365 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d");
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100366 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100367
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100368 OSMO_ASSERT(llist_empty(gprs_subscribers));
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100369
370 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200371
372 cleanup_test();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100373}
374
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100375static void test_auth_triplets(void)
376{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100377 struct gprs_subscr *s1, *s1found;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100378 const char *imsi1 = "1234567890";
379 struct gsm_auth_tuple *at;
380 struct sgsn_mm_ctx *ctx;
381 struct gprs_ra_id raid = { 0, };
382 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100383
384 printf("Testing authentication triplet handling\n");
385
386 /* Check for emptiness */
387 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
388
389 /* Allocate entry 1 */
390 s1 = gprs_subscr_get_or_create(imsi1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100391 s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100392 s1found = gprs_subscr_get_by_imsi(imsi1);
393 OSMO_ASSERT(s1found == s1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100394 gprs_subscr_put(s1found);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100395
396 /* Create a context */
397 OSMO_ASSERT(count(gprs_llme_list()) == 0);
398 ctx = alloc_mm_ctx(local_tlli, &raid);
399
400 /* Attach s1 to ctx */
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100401 ctx->subscr = gprs_subscr_get(s1);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100402 ctx->subscr->sgsn_data->mm = ctx;
403
404 /* Try to get auth tuple */
405 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
406 OSMO_ASSERT(at == NULL);
407
408 /* Add triplets */
409 s1->sgsn_data->auth_triplets[0].key_seq = 0;
410 s1->sgsn_data->auth_triplets[1].key_seq = 1;
411 s1->sgsn_data->auth_triplets[2].key_seq = 2;
412
413 /* Try to get auth tuple */
414 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
415 OSMO_ASSERT(at != NULL);
416 OSMO_ASSERT(at->key_seq == 0);
417 OSMO_ASSERT(at->use_count == 1);
418 at = sgsn_auth_get_tuple(ctx, at->key_seq);
419 OSMO_ASSERT(at != NULL);
420 OSMO_ASSERT(at->key_seq == 1);
421 OSMO_ASSERT(at->use_count == 1);
422 at = sgsn_auth_get_tuple(ctx, at->key_seq);
423 OSMO_ASSERT(at != NULL);
424 OSMO_ASSERT(at->key_seq == 2);
425 OSMO_ASSERT(at->use_count == 1);
426 at = sgsn_auth_get_tuple(ctx, at->key_seq);
427 OSMO_ASSERT(at == NULL);
428
429 /* Free MM context and subscriber */
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100430 gprs_subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100431 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100432 s1found = gprs_subscr_get_by_imsi(imsi1);
433 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200434
435 cleanup_test();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100436}
437
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100438#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
439
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100440static int rx_gsup_message(const uint8_t *data, size_t data_len)
441{
442 struct msgb *msg;
443 int rc;
444
445 msg = msgb_alloc(1024, __func__);
446 msg->l2h = msgb_put(msg, data_len);
447 OSMO_ASSERT(msg->l2h != NULL);
448 memcpy(msg->l2h, data, data_len);
449 rc = gprs_subscr_rx_gsup_message(msg);
450 msgb_free(msg);
451
452 return rc;
453}
454
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100455static void test_subscriber_gsup(void)
456{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100457 struct gprs_subscr *s1, *s1found;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100458 const char *imsi1 = "1234567890";
459 struct sgsn_mm_ctx *ctx;
460 struct gprs_ra_id raid = { 0, };
461 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100462 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100463 int rc;
464
465 static const uint8_t send_auth_info_res[] = {
466 0x0a,
467 TEST_GSUP_IMSI1_IE,
468 0x03, 0x22, /* Auth tuple */
469 0x20, 0x10,
470 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
471 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
472 0x21, 0x04,
473 0x21, 0x22, 0x23, 0x24,
474 0x22, 0x08,
475 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
476 0x03, 0x22, /* Auth tuple */
477 0x20, 0x10,
478 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
479 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
480 0x21, 0x04,
481 0xa1, 0xa2, 0xa3, 0xa4,
482 0x22, 0x08,
483 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
484 };
485
486 static const uint8_t send_auth_info_err[] = {
487 0x09,
488 TEST_GSUP_IMSI1_IE,
489 0x02, 0x01, 0x07 /* GPRS not allowed */
490 };
491
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400492#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
493
494 static const uint8_t s1_msisdn[] = { MSISDN };
495
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100496 static const uint8_t update_location_res[] = {
497 0x06,
498 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400499 0x08, 0x09, MSISDN,
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100500 0x04, 0x00, /* PDP info complete */
501 0x05, 0x12,
502 0x10, 0x01, 0x01,
503 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
504 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
505 0x05, 0x11,
506 0x10, 0x01, 0x02,
507 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
508 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
509 };
510
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400511#undef MSISDN
512
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100513 static const uint8_t update_location_err[] = {
514 0x05,
515 TEST_GSUP_IMSI1_IE,
516 0x02, 0x01, 0x07 /* GPRS not allowed */
517 };
518
519 static const uint8_t location_cancellation_req[] = {
520 0x1c,
521 TEST_GSUP_IMSI1_IE,
522 0x06, 0x01, 0x00,
523 };
524
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200525 static const uint8_t location_cancellation_req_withdraw[] = {
526 0x1c,
527 TEST_GSUP_IMSI1_IE,
528 0x06, 0x01, 0x01,
529 };
530
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100531 static const uint8_t location_cancellation_req_other[] = {
532 0x1c,
533 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
534 0x06, 0x01, 0x00,
535 };
536
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100537 static const uint8_t purge_ms_err[] = {
538 0x0d,
539 TEST_GSUP_IMSI1_IE,
540 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
541 };
542
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100543 static const uint8_t purge_ms_err_no_cause[] = {
544 0x0d,
545 TEST_GSUP_IMSI1_IE,
546 };
547
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100548 static const uint8_t purge_ms_res[] = {
549 0x0e,
550 TEST_GSUP_IMSI1_IE,
551 0x07, 0x00,
552 };
553
554
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100555 static const uint8_t insert_data_req[] = {
556 0x10,
557 TEST_GSUP_IMSI1_IE,
558 0x05, 0x11,
559 0x10, 0x01, 0x03,
560 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
561 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
562 };
563
564 static const uint8_t delete_data_req[] = {
565 0x14,
566 TEST_GSUP_IMSI1_IE,
567 0x10, 0x01, 0x03,
568 };
569
Neels Hofmeyr241bda02016-06-20 18:26:15 +0200570 printf("Testing subscriber GSUP handling\n");
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100571
572 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
573
574 /* Check for emptiness */
575 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
576
577 /* Allocate entry 1 */
578 s1 = gprs_subscr_get_or_create(imsi1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100579 s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100580 s1found = gprs_subscr_get_by_imsi(imsi1);
581 OSMO_ASSERT(s1found == s1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100582 gprs_subscr_put(s1found);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100583
584 /* Create a context */
585 OSMO_ASSERT(count(gprs_llme_list()) == 0);
586 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100587
588 /* Attach s1 to ctx */
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100589 ctx->subscr = gprs_subscr_get(s1);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100590 ctx->subscr->sgsn_data->mm = ctx;
591
592 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100593 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100594 OSMO_ASSERT(rc >= 0);
595 OSMO_ASSERT(last_updated_subscr == s1);
596
597 /* Check triplets */
598 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
599 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
600 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
601
602 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100603 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100604 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100605 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100606 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100607
608 /* Check triplets */
609 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
610 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
611 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
612
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100613 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100614 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100615 OSMO_ASSERT(rc >= 0);
616 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100617 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100618 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400619 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
620 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100621 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
622 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
623 struct sgsn_subscriber_pdp_data, list);
624 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
625 pdpd = llist_entry(pdpd->list.next,
626 struct sgsn_subscriber_pdp_data, list);
627 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100628
629 /* Check authorization */
630 OSMO_ASSERT(s1->authorized == 1);
631
632 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100633 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100634 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100635 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100636 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100637
638 /* Check authorization */
639 OSMO_ASSERT(s1->authorized == 0);
640
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100641 /* Inject InsertSubscrData GSUP message */
642 last_updated_subscr = NULL;
643 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Harald Weltec346f872016-11-26 14:58:36 +0100644 OSMO_ASSERT(rc == -ENOTSUP); /* not connected */
Harald Weltecd5e5262016-05-06 13:46:21 +0200645 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100646
647 /* Inject DeleteSubscrData GSUP message */
648 last_updated_subscr = NULL;
649 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
Maxa66d8cf2017-02-15 11:43:59 +0100650 if (rc != -GMM_CAUSE_SEM_INCORR_MSG)
651 printf("Unexpected response to DSD: %d\n", rc);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100652 OSMO_ASSERT(last_updated_subscr == NULL);
653
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100654 /* Inject wrong LocCancelReq GSUP message */
655 last_updated_subscr = NULL;
656 rc = rx_gsup_message(location_cancellation_req_other,
657 sizeof(location_cancellation_req_other));
658 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
659 OSMO_ASSERT(last_updated_subscr == NULL);
660
661 /* Check cancellation result */
662 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
663 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
664
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100665 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100666 rc = rx_gsup_message(location_cancellation_req,
667 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100668 OSMO_ASSERT(rc >= 0);
669 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100670 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100671
672 /* Check cancellation result */
673 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
674 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
675
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200676 /* Inject LocCancelReq(withdraw) GSUP message */
677 rc = rx_gsup_message(location_cancellation_req_withdraw,
678 sizeof(location_cancellation_req_withdraw));
679 OSMO_ASSERT(rc >= 0);
680 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
681
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100682 /* Inject PurgeMsRes GSUP message */
683 rc = rx_gsup_message(purge_ms_res,
684 sizeof(purge_ms_res));
685 OSMO_ASSERT(rc >= 0);
686 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
687
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100688 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100689 OSMO_ASSERT(ctx->subscr == NULL);
690 sgsn_mm_ctx_cleanup_free(ctx);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100691 gprs_subscr_put(s1);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100692 s1found = gprs_subscr_get_by_imsi(imsi1);
693 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100694
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100695 /* Inject PurgeMsRes GSUP message */
696 rc = rx_gsup_message(purge_ms_res,
697 sizeof(purge_ms_res));
698 OSMO_ASSERT(rc >= 0);
699
700 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
701 rc = rx_gsup_message(purge_ms_err,
702 sizeof(purge_ms_err));
703 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
704
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100705 /* Inject PurgeMsErr() GSUP message */
706 rc = rx_gsup_message(purge_ms_err_no_cause,
707 sizeof(purge_ms_err_no_cause));
708 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
709
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100710 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
711 last_updated_subscr = NULL;
712 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100713 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100714 OSMO_ASSERT(last_updated_subscr == NULL);
715
716 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
717 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
718 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
719 OSMO_ASSERT(last_updated_subscr == NULL);
720
721 /* Inject LocCancelReq GSUP message (unknown IMSI) */
722 rc = rx_gsup_message(location_cancellation_req,
723 sizeof(location_cancellation_req));
724 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
725 OSMO_ASSERT(last_updated_subscr == NULL);
726
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100727 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200728
729 cleanup_test();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100730}
731
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100732int my_gsup_client_send_dummy(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100733{
734 msgb_free(msg);
735 return 0;
736};
737
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200738/*
739 * Test that a GMM Detach will remove the MMCTX and the
740 * associated LLME.
741 */
742static void test_gmm_detach(void)
743{
744 struct gprs_ra_id raid = { 0, };
745 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200746 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200747
748 printf("Testing GMM detach\n");
749
750 /* DTAP - Detach Request (MO) */
751 /* normal detach, power_off = 0 */
752 static const unsigned char detach_req[] = {
753 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
754 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
755 };
756
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200757 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200758
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100759 /* Create a context */
760 OSMO_ASSERT(count(gprs_llme_list()) == 0);
761 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200762
763 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +0100764 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100765 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200766
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100767 /* verify that a single message (hopefully the Detach Accept) has been
768 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100769 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100770
771 /* verify that things are gone */
772 OSMO_ASSERT(count(gprs_llme_list()) == 0);
773 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
774 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200775
776 cleanup_test();
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100777}
778
779/*
780 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
781 * will not sent a Detach Accept message (power_off = 1)
782 */
783static void test_gmm_detach_power_off(void)
784{
785 struct gprs_ra_id raid = { 0, };
786 struct sgsn_mm_ctx *ctx, *ictx;
787 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100788
789 printf("Testing GMM detach (power off)\n");
790
791 /* DTAP - Detach Request (MO) */
792 /* normal detach, power_off = 1 */
793 static const unsigned char detach_req[] = {
794 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
795 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
796 };
797
798 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
799
800 /* Create a context */
801 OSMO_ASSERT(count(gprs_llme_list()) == 0);
802 ctx = alloc_mm_ctx(local_tlli, &raid);
803
804 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +0100805 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100806 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100807
808 /* verify that no message (and therefore no Detach Accept) has been
809 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100810 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100811
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200812 /* verify that things are gone */
813 OSMO_ASSERT(count(gprs_llme_list()) == 0);
814 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200815 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200816
817 cleanup_test();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200818}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200819
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200820/*
821 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
822 */
823static void test_gmm_detach_no_mmctx(void)
824{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100825 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200826 struct gprs_llc_lle *lle;
827 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200828
829 printf("Testing GMM detach (no MMCTX)\n");
830
831 /* DTAP - Detach Request (MO) */
832 /* normal detach, power_off = 0 */
833 static const unsigned char detach_req[] = {
834 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
835 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
836 };
837
838 /* Create an LLME */
839 OSMO_ASSERT(count(gprs_llme_list()) == 0);
840 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
841 lle = gprs_lle_get_or_create(local_tlli, 3);
842
843 OSMO_ASSERT(count(gprs_llme_list()) == 1);
844
845 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100846 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100847 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200848
849 /* verify that the LLME is gone */
850 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200851
852 cleanup_test();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200853}
854
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100855/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100856 * Test that a single GMM Detach Accept message will not cause the SGSN to send
857 * any message or leave an MM context at the SGSN.
858 */
859static void test_gmm_detach_accept_unexpected(void)
860{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100861 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100862 struct gprs_llc_lle *lle;
863 uint32_t local_tlli;
864
865 printf("Testing GMM detach accept (unexpected)\n");
866
867 /* DTAP - Detach Accept (MT) */
868 /* normal detach */
869 static const unsigned char detach_acc[] = {
870 0x08, 0x06
871 };
872
873 /* Create an LLME */
874 OSMO_ASSERT(count(gprs_llme_list()) == 0);
875 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
876 lle = gprs_lle_get_or_create(local_tlli, 3);
877
878 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100879 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100880 detach_acc, ARRAY_SIZE(detach_acc));
881
882 /* verify that no message (and therefore no Status or XID reset) has been
883 * sent by the SGSN */
884 OSMO_ASSERT(sgsn_tx_counter == 0);
885
886 /* verify that things are gone */
887 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200888
889 cleanup_test();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100890}
891
892/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100893 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
894 */
895static void test_gmm_status_no_mmctx(void)
896{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100897 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100898 struct gprs_llc_lle *lle;
899 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100900
901 printf("Testing GMM Status (no MMCTX)\n");
902
903 /* DTAP - GMM Status, protocol error */
904 static const unsigned char gmm_status[] = {
905 0x08, 0x20, 0x6f
906 };
907
908 /* Create an LLME */
909 OSMO_ASSERT(count(gprs_llme_list()) == 0);
910 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
911 lle = gprs_lle_get_or_create(local_tlli, 3);
912
913 OSMO_ASSERT(count(gprs_llme_list()) == 1);
914
915 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100916 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100917 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100918
919 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100920 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100921
922 /* verify that the LLME is gone */
923 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200924
925 cleanup_test();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100926}
927
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100928/*
929 * Test the GMM Attach procedure
930 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100931static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100932{
933 struct gprs_ra_id raid = { 0, };
934 struct sgsn_mm_ctx *ctx = NULL;
935 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100936 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100937 uint32_t foreign_tlli;
938 uint32_t local_tlli = 0;
939 struct gprs_llc_lle *lle;
940
941 /* DTAP - Attach Request */
942 /* The P-TMSI is not known by the SGSN */
943 static const unsigned char attach_req[] = {
944 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
945 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
946 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
947 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
948 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
949 };
950
951 /* DTAP - Identity Response IMEI */
952 static const unsigned char ident_resp_imei[] = {
953 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
954 0x56
955 };
956
957 /* DTAP - Identity Response IMSI */
958 static const unsigned char ident_resp_imsi[] = {
959 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
960 0x54
961 };
962
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100963 /* DTAP - Authentication and Ciphering Resp */
964 static const unsigned char auth_ciph_resp[] = {
965 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
966 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
967 };
968
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100969 /* DTAP - Attach Complete */
970 static const unsigned char attach_compl[] = {
971 0x08, 0x03
972 };
973
974 /* DTAP - Detach Request (MO) */
975 /* normal detach, power_off = 0 */
976 static const unsigned char detach_req[] = {
977 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
978 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
979 };
980
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100981 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100982
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100983 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
984
985 /* Create a LLE/LLME */
986 OSMO_ASSERT(count(gprs_llme_list()) == 0);
987 lle = gprs_lle_get_or_create(foreign_tlli, 3);
988 OSMO_ASSERT(count(gprs_llme_list()) == 1);
989
990 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100991 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100992 attach_req, ARRAY_SIZE(attach_req));
993
994 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
995 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +0100996 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100997
998 /* we expect an identity request (IMEI) */
999 OSMO_ASSERT(sgsn_tx_counter == 1);
1000
1001 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001002 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001003 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1004
1005 /* we expect an identity request (IMSI) */
1006 OSMO_ASSERT(sgsn_tx_counter == 1);
1007
1008 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001009 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001010 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1011
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001012 /* check that the MM context has not been removed due to a failed
1013 * authorization */
1014 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1015
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001016 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001017
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001018retry_attach_req:
1019
1020 if (retry && sgsn_tx_counter == 0) {
1021 fprintf(stderr, "Retrying attach request\n");
1022 /* re-inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001023 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001024 attach_req, ARRAY_SIZE(attach_req));
1025 }
1026
1027 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
1028 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001029
1030 /* inject the auth & ciph response */
Harald Weltef97ee042015-12-25 19:12:21 +01001031 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001032 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1033
1034 /* check that the MM context has not been removed due to a
1035 * failed authorization */
1036 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001037 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1038 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001039 }
1040
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001041 if (retry && sgsn_tx_counter == 0)
1042 goto retry_attach_req;
1043
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001044 /* we expect an attach accept/reject */
1045 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001046 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1047 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001048
1049 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001050 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001051
1052 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001053 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001054 attach_compl, ARRAY_SIZE(attach_compl));
1055
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001056 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001057
1058 /* we don't expect a response */
1059 OSMO_ASSERT(sgsn_tx_counter == 0);
1060
1061 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001062 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001063 detach_req, ARRAY_SIZE(detach_req));
1064
1065 /* verify that things are gone */
1066 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1067 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1068 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001069
1070 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001071}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001072
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001073static void test_gmm_attach_acl(void)
1074{
1075 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1076
1077 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1078 sgsn_acl_add("123456789012345", &sgsn->cfg);
1079 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001080 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001081 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001082
1083 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001084
1085 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001086}
1087
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001088int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001089 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001090 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001091 if (rc == -ENOTSUP) {
1092 OSMO_ASSERT(mmctx->subscr);
1093 gprs_subscr_update(mmctx->subscr);
1094 }
1095 return rc;
1096};
1097
Pau Espin Pedrol0b050392018-01-07 18:05:22 +01001098int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_t *auts,
1099 const uint8_t *auts_rand)
1100{
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001101 gprs_subscr_update(mmctx->subscr);
1102 return 0;
1103};
1104
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001105static void test_gmm_attach_subscr(void)
1106{
1107 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001108 struct gprs_subscr *subscr;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001109
1110 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001111 subscr_request_update_location_cb = my_subscr_request_update_location;
1112 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001113
1114 subscr = gprs_subscr_get_or_create("123456789012345");
1115 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001116
1117 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001118 test_gmm_attach(0);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001119 gprs_subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001120 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001121
1122 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001123 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1124 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001125
1126 cleanup_test();
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001127}
1128
Pau Espin Pedrol0b050392018-01-07 18:05:22 +01001129int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts,
1130 const uint8_t *auts_rand)
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001131{
1132 /* Fake an authentication */
1133 OSMO_ASSERT(mmctx->subscr);
1134 mmctx->is_authenticated = 1;
1135 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001136
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001137 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001138};
1139
1140static void test_gmm_attach_subscr_fake_auth(void)
1141{
1142 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001143 struct gprs_subscr *subscr;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001144
1145 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001146 subscr_request_update_location_cb = my_subscr_request_update_location;
1147 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001148
1149 subscr = gprs_subscr_get_or_create("123456789012345");
1150 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001151 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001152 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001153
1154 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001155 test_gmm_attach(0);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001156 gprs_subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001157 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001158
1159 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001160 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1161 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001162
1163 cleanup_test();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001164}
1165
Pau Espin Pedrol93fd4622017-08-16 11:30:01 +02001166int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand)
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001167{
1168 struct gsm_auth_tuple at = {
Harald Welte121e9a42016-04-20 13:13:19 +02001169 .vec.sres = {0x51, 0xe5, 0x51, 0xe5},
Neels Hofmeyr058cd572017-02-24 06:24:45 +01001170 .vec.auth_types = OSMO_AUTH_TYPE_GSM,
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001171 .key_seq = 0
1172 };
1173
1174 /* Fake an authentication */
1175 OSMO_ASSERT(mmctx->subscr);
1176 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1177
1178 gprs_subscr_update_auth_info(mmctx->subscr);
1179
1180 return 0;
1181};
1182
1183static void test_gmm_attach_subscr_real_auth(void)
1184{
1185 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001186 struct gprs_subscr *subscr;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001187
1188 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1189 subscr_request_update_location_cb = my_subscr_request_update_location;
1190 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1191
1192 subscr = gprs_subscr_get_or_create("123456789012345");
1193 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001194 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001195 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001196
1197 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001198
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001199 test_gmm_attach(0);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001200 gprs_subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001201 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001202
1203 sgsn->cfg.auth_policy = saved_auth_policy;
1204 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1205 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001206
1207 cleanup_test();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001208}
1209
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001210#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1211 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1212
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001213static int auth_info_skip = 0;
1214static int upd_loc_skip = 0;
1215
Pau Espin Pedrol0b050392018-01-07 18:05:22 +01001216int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts,
1217 const uint8_t *auts_rand)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001218{
1219 static const uint8_t send_auth_info_res[] = {
1220 0x0a,
1221 TEST_GSUP_IMSI_LONG_IE,
1222 0x03, 0x22, /* Auth tuple */
1223 0x20, 0x10,
1224 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1225 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1226 0x21, 0x04,
1227 0x51, 0xe5, 0x51, 0xe5,
1228 0x22, 0x08,
1229 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1230 };
1231
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001232 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001233
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001234 if (auth_info_skip > 0) {
1235 auth_info_skip -= 1;
1236 return -EAGAIN;
1237 }
1238
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001239 /* Fake an SendAuthInfoRes */
1240 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1241
1242 return 0;
1243};
1244
1245int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1246 static const uint8_t update_location_res[] = {
1247 0x06,
1248 TEST_GSUP_IMSI_LONG_IE,
1249 0x04, 0x00, /* PDP info complete */
1250 0x05, 0x12,
1251 0x10, 0x01, 0x01,
1252 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1253 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001254 0x08, 0x07, /* MSISDN 49166213323 encoded */
1255 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freyther10c0f562015-05-17 20:58:40 +02001256 0x09, 0x07, /* MSISDN 38166213323 encoded */
1257 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001258 };
1259
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001260 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001261
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001262 if (upd_loc_skip > 0) {
1263 upd_loc_skip -= 1;
1264 return -EAGAIN;
1265 }
1266
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001267 /* Fake an UpdateLocRes */
1268 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1269};
1270
1271
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001272static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001273{
1274 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001275 struct gprs_subscr *subscr;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001276
1277 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1278 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1279 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001280 if (retry) {
1281 upd_loc_skip = 3;
1282 auth_info_skip = 3;
1283 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001284
1285 subscr = gprs_subscr_get_or_create("123456789012345");
1286 subscr->authorized = 1;
1287 sgsn->cfg.require_authentication = 1;
1288 sgsn->cfg.require_update_location = 1;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001289 gprs_subscr_put(subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001290
1291 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001292 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001293 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001294
1295 sgsn->cfg.auth_policy = saved_auth_policy;
1296 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1297 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001298 upd_loc_skip = 0;
1299 auth_info_skip = 0;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001300
1301 cleanup_test();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001302}
1303
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001304int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001305{
Harald Welte23d77d52016-04-25 19:07:34 +02001306 struct osmo_gsup_message to_peer = {0};
1307 struct osmo_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001308 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001309 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001310
1311 /* Simulate the GSUP peer */
Harald Welte23d77d52016-04-25 19:07:34 +02001312 rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001313 OSMO_ASSERT(rc >= 0);
1314 OSMO_ASSERT(to_peer.imsi[0] != 0);
Neels Hofmeyr59504dc2017-01-13 03:10:54 +01001315 osmo_strlcpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001316
1317 /* This invalidates the pointers in to_peer */
1318 msgb_free(msg);
1319
1320 switch (to_peer.message_type) {
Harald Welte23d77d52016-04-25 19:07:34 +02001321 case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001322 /* Send UPDATE_LOCATION_RESULT */
1323 return my_subscr_request_update_gsup_auth(NULL);
1324
Harald Welte23d77d52016-04-25 19:07:34 +02001325 case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001326 /* Send SEND_AUTH_INFO_RESULT */
Pau Espin Pedrol0b050392018-01-07 18:05:22 +01001327 return my_subscr_request_auth_info_gsup_auth(NULL, NULL, NULL);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001328
Harald Welte23d77d52016-04-25 19:07:34 +02001329 case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
1330 from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001331 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001332
1333 default:
1334 if ((to_peer.message_type & 0b00000011) == 0) {
1335 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001336 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001337 from_peer.message_type = to_peer.message_type + 1;
1338 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1339 break;
1340 }
1341
1342 /* Ignore it */
1343 return 0;
1344 }
1345
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001346 reply_msg = gsup_client_msgb_alloc();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001347 reply_msg->l2h = reply_msg->data;
Harald Welte23d77d52016-04-25 19:07:34 +02001348 osmo_gsup_encode(reply_msg, &from_peer);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001349 gprs_subscr_rx_gsup_message(reply_msg);
1350 msgb_free(reply_msg);
1351
1352 return 0;
1353};
1354
1355static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1356{
1357 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001358 struct gprs_subscr *subscr;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001359
1360 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001361 gsup_client_send_cb = my_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001362
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001363 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gsup_client);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001364
1365 if (retry) {
1366 upd_loc_skip = 3;
1367 auth_info_skip = 3;
1368 }
1369
1370 printf("Auth policy 'remote', real GSUP based auth: ");
1371 test_gmm_attach(retry);
1372
1373 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001374 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001375 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001376
1377 sgsn->cfg.auth_policy = saved_auth_policy;
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001378 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001379 upd_loc_skip = 0;
1380 auth_info_skip = 0;
1381 talloc_free(sgsn->gsup_client);
1382 sgsn->gsup_client = NULL;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001383
1384 cleanup_test();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001385}
1386
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001387/*
1388 * Test the GMM Rejects
1389 */
1390static void test_gmm_reject(void)
1391{
1392 struct gprs_ra_id raid = { 0, };
1393 struct sgsn_mm_ctx *ctx = NULL;
1394 uint32_t foreign_tlli;
1395 struct gprs_llc_lle *lle;
1396 int idx;
1397
1398 /* DTAP - Attach Request */
1399 /* Invalid MI length */
1400 static const unsigned char attach_req_inv_mi_len[] = {
1401 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1402 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1403 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1404 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1405 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1406 };
1407
1408 /* DTAP - Attach Request */
1409 /* Invalid MI type (IMEI) */
1410 static const unsigned char attach_req_inv_mi_type[] = {
1411 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1412 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1413 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1414 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1415 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1416 };
1417
1418 /* DTAP - Routing Area Update Request */
1419 static const unsigned char dtap_ra_upd_req[] = {
1420 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1421 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1422 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1423 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1424 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1425 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1426 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1427 };
1428
1429 /* DTAP - Routing Area Update Request */
1430 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1431 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1432 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1433 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1434 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1435 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1436 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1437 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1438 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1439 };
1440
1441 /* DTAP - Routing Area Update Request */
1442 /* Invalid cap length */
1443 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1444 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1445 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1446 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1447 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1448 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1449 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1450 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1451 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1452 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1453 };
1454
1455 struct test {
1456 const char *title;
1457 const unsigned char *msg;
1458 unsigned msg_len;
1459 unsigned num_resp;
1460
1461 };
1462 static struct test tests[] = {
1463 {
1464 .title = "Attach Request (invalid MI length)",
1465 .msg = attach_req_inv_mi_len,
1466 .msg_len = sizeof(attach_req_inv_mi_len),
1467 .num_resp = 1 /* Reject */
1468
1469 },
1470 {
1471 .title = "Attach Request (invalid MI type)",
1472 .msg = attach_req_inv_mi_type,
1473 .msg_len = sizeof(attach_req_inv_mi_type),
1474 .num_resp = 1 /* Reject */
1475 },
1476 {
1477 .title = "Routing Area Update Request (valid)",
1478 .msg = dtap_ra_upd_req,
1479 .msg_len = sizeof(dtap_ra_upd_req),
1480 .num_resp = 2 /* XID Reset + Reject */
1481 },
1482 {
1483 .title = "Routing Area Update Request (invalid type)",
1484 .msg = dtap_ra_upd_req_inv_type,
1485 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1486 .num_resp = 1 /* Reject */
1487 },
1488 {
1489 .title = "Routing Area Update Request (invalid CAP length)",
1490 .msg = dtap_ra_upd_req_inv_cap_len,
1491 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1492 .num_resp = 1 /* Reject */
1493 },
1494 };
1495
1496 printf("Testing GMM reject\n");
1497
1498 /* reset the PRNG used by sgsn_alloc_ptmsi */
1499 srand(1);
1500
1501 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1502
1503 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1504
1505 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1506 const struct test *test = &tests[idx];
1507 printf(" - %s\n", test->title);
1508
1509 /* Create a LLE/LLME */
1510 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1511 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1512
1513 /* Inject the Request message */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001514 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001515 test->msg, test->msg_len);
1516
1517 /* We expect a Reject message */
1518 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1519 sgsn_tx_counter, test->num_resp);
1520 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1521
1522 /* verify that LLME/MM are removed */
1523 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1524 OSMO_ASSERT(ctx == NULL);
1525 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1526 }
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001527
1528 cleanup_test();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001529}
1530
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001531/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001532 * Test cancellation of attached MM contexts
1533 */
1534static void test_gmm_cancel(void)
1535{
1536 struct gprs_ra_id raid = { 0, };
1537 struct sgsn_mm_ctx *ctx = NULL;
1538 struct sgsn_mm_ctx *ictx;
1539 uint32_t ptmsi1;
1540 uint32_t foreign_tlli;
1541 uint32_t local_tlli = 0;
1542 struct gprs_llc_lle *lle;
1543 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1544
1545 /* DTAP - Attach Request */
1546 /* The P-TMSI is not known by the SGSN */
1547 static const unsigned char attach_req[] = {
1548 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1549 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1550 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1551 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1552 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1553 };
1554
1555 /* DTAP - Identity Response IMEI */
1556 static const unsigned char ident_resp_imei[] = {
1557 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1558 0x56
1559 };
1560
1561 /* DTAP - Identity Response IMSI */
1562 static const unsigned char ident_resp_imsi[] = {
1563 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1564 0x54
1565 };
1566
1567 /* DTAP - Attach Complete */
1568 static const unsigned char attach_compl[] = {
1569 0x08, 0x03
1570 };
1571
1572 printf("Testing cancellation\n");
1573
1574 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1575
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001576 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1577
1578 /* Create a LLE/LLME */
1579 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1580 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1581 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1582
1583 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001584 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001585 attach_req, ARRAY_SIZE(attach_req));
1586
1587 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1588 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001589 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001590
1591 /* we expect an identity request (IMEI) */
1592 OSMO_ASSERT(sgsn_tx_counter == 1);
1593
1594 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001595 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001596 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1597
1598 /* we expect an identity request (IMSI) */
1599 OSMO_ASSERT(sgsn_tx_counter == 1);
1600
1601 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001602 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001603 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1604
1605 /* check that the MM context has not been removed due to a failed
1606 * authorization */
1607 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1608
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001609 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001610
1611 /* we expect an attach accept/reject */
1612 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001613 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1614 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001615
1616 /* this has been randomly assigned by the SGSN */
1617 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1618
1619 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001620 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001621 attach_compl, ARRAY_SIZE(attach_compl));
1622
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001623 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001624
1625 /* we don't expect a response */
1626 OSMO_ASSERT(sgsn_tx_counter == 0);
1627
1628 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001629 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001630
1631 /* verify that things are gone */
1632 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1633 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1634 OSMO_ASSERT(!ictx);
1635
1636 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001637
1638 cleanup_test();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001639}
1640
1641/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001642 * Test the dynamic allocation of P-TMSIs
1643 */
1644static void test_gmm_ptmsi_allocation(void)
1645{
Jacob Erlbeckd58c0332016-01-04 18:43:35 +01001646 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001647 struct sgsn_mm_ctx *ctx = NULL;
1648 struct sgsn_mm_ctx *ictx;
1649 uint32_t foreign_tlli;
1650 uint32_t ptmsi1;
1651 uint32_t ptmsi2;
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001652 uint32_t received_ptmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001653 uint32_t old_ptmsi;
1654 uint32_t local_tlli = 0;
1655 struct gprs_llc_lle *lle;
1656 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1657
1658 /* DTAP - Attach Request (IMSI 12131415161718) */
1659 static const unsigned char attach_req[] = {
1660 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1661 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1662 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1663 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1664 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1665 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1666 0x00,
1667 };
1668
1669 /* DTAP - Identity Response IMEI */
1670 static const unsigned char ident_resp_imei[] = {
1671 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1672 0x56
1673 };
1674
1675 /* DTAP - Attach Complete */
1676 static const unsigned char attach_compl[] = {
1677 0x08, 0x03
1678 };
1679
1680 /* DTAP - Routing Area Update Request */
1681 static const unsigned char ra_upd_req[] = {
1682 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1683 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1684 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1685 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1686 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1687 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1688 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1689 };
1690
1691 /* DTAP - Routing Area Update Complete */
1692 static const unsigned char ra_upd_complete[] = {
1693 0x08, 0x0a
1694 };
1695
1696 /* DTAP - Detach Request (MO) */
1697 /* normal detach, power_off = 1 */
1698 static const unsigned char detach_req[] = {
1699 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1700 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1701 };
1702
1703 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1704
1705 printf("Testing P-TMSI allocation\n");
1706
1707 printf(" - sgsn_alloc_ptmsi\n");
1708
1709 /* reset the PRNG used by sgsn_alloc_ptmsi */
1710 srand(1);
1711
1712 ptmsi1 = sgsn_alloc_ptmsi();
1713 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1714
1715 ptmsi2 = sgsn_alloc_ptmsi();
1716 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1717
1718 OSMO_ASSERT(ptmsi1 != ptmsi2);
1719
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001720 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001721
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001722 printf(" - Repeated Attach Request\n");
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001723
1724 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1725
1726 /* Create a LLE/LLME */
1727 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1728 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1729 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1730
1731 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001732 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001733 attach_req, ARRAY_SIZE(attach_req));
1734
1735 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1736 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001737 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001738 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1739 ptmsi1 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001740
1741 old_ptmsi = ctx->p_tmsi_old;
1742
1743 /* we expect an identity request (IMEI) */
1744 OSMO_ASSERT(sgsn_tx_counter == 1);
1745
1746 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001747 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001748 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1749
1750 /* check that the MM context has not been removed due to a failed
1751 * authorization */
1752 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1753
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001754 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001755 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1756
1757 /* we expect an attach accept */
1758 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001759 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1760 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001761
1762 /* we ignore this and send the attach again */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001763 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001764 attach_req, ARRAY_SIZE(attach_req));
1765
1766 /* the allocated P-TMSI should be the same */
1767 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1768 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001769 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001770 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1771 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1772
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001773 /* we expect an attach accept */
1774 OSMO_ASSERT(sgsn_tx_counter == 1);
1775 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1776 OSMO_ASSERT(received_ptmsi == ptmsi1);
1777
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001778 /* inject the attach complete */
1779 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001780 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001781 attach_compl, ARRAY_SIZE(attach_compl));
1782
1783 /* we don't expect a response */
1784 OSMO_ASSERT(sgsn_tx_counter == 0);
1785
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001786 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001787 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1788 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1789
1790 printf(" - Repeated RA Update Request\n");
1791
1792 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001793 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001794 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1795
1796 /* we expect an RA update accept */
1797 OSMO_ASSERT(sgsn_tx_counter == 1);
1798
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001799 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001800 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001801 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1802 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1803 ptmsi2 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001804
1805 /* repeat the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001806 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001807 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1808
1809 /* we expect an RA update accept */
1810 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001811 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1812 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001813
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001814 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001815 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1816 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1817
1818 /* inject the RA update complete */
1819 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001820 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001821 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1822
1823 /* we don't expect a response */
1824 OSMO_ASSERT(sgsn_tx_counter == 0);
1825
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001826 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001827 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1828 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1829
1830 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001831 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001832 detach_req, ARRAY_SIZE(detach_req));
1833
1834 /* verify that things are gone */
1835 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1836 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1837 OSMO_ASSERT(!ictx);
1838
1839 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001840
1841 cleanup_test();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001842}
1843
Jacob Erlbeck13304782016-01-04 18:43:37 +01001844/*
1845 * Test changing of routing areas
1846 */
1847static void test_gmm_routing_areas(void)
1848{
1849 struct gprs_ra_id raid1 = {332, 112, 16464, 96};
1850 struct gprs_ra_id raid2 = {332, 112, 16464, 97};
1851 struct sgsn_mm_ctx *ctx = NULL;
1852 struct sgsn_mm_ctx *ictx;
1853 uint32_t ptmsi1;
1854 uint32_t received_ptmsi;
1855 uint32_t ms_tlli = 0;
1856 struct gprs_llc_lle *lle;
1857 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1858
1859 /* DTAP - Attach Request (IMSI 12131415161718) */
1860 static const unsigned char attach_req[] = {
1861 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1862 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1863 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1864 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1865 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1866 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1867 0x00,
1868 };
1869
1870 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1871 static const unsigned char attach_req2[] = {
1872 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1873 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1874 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1875 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1876 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1877 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1878 0x00,
1879 };
1880
1881 /* DTAP - Identity Response IMEI */
1882 static const unsigned char ident_resp_imei[] = {
1883 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1884 0x56
1885 };
1886
1887 /* DTAP - Attach Complete */
1888 static const unsigned char attach_compl[] = {
1889 0x08, 0x03
1890 };
1891
1892 /* DTAP - Routing Area Update Request (coming from RA 1) */
1893 static const unsigned char ra_upd_req1[] = {
1894 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1895 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1896 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1897 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1898 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1899 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1900 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1901 };
1902
1903 /* DTAP - Routing Area Update Request (coming from RA 2) */
1904 static const unsigned char ra_upd_req2[] = {
1905 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1906 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1907 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1908 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1909 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1910 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1911 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1912 };
1913
1914 /* DTAP - Routing Area Update Request (coming from RA other) */
1915 /* raid_other = {443, 223, 16464, 98}; */
1916 static const unsigned char ra_upd_req_other[] = {
1917 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1918 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1919 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1920 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1921 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1922 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1923 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1924 };
1925
1926 /* DTAP - Routing Area Update Complete */
1927 static const unsigned char ra_upd_complete[] = {
1928 0x08, 0x0a
1929 };
1930
1931 /* DTAP - Detach Request (MO) */
1932 /* normal detach, power_off = 1 */
1933 static const unsigned char detach_req[] = {
1934 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1935 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1936 };
1937
1938 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1939
1940 printf("Testing routing area changes\n");
1941
1942 /* reset the PRNG used by sgsn_alloc_ptmsi */
1943 srand(1);
1944
1945 ptmsi1 = GSM_RESERVED_TMSI;
1946
1947 printf(" - Attach Request (RA 1)\n");
1948
1949 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1950
1951 /* Create a LLE/LLME */
1952 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1953 lle = gprs_lle_get_or_create(ms_tlli, 3);
1954 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1955
1956 /* inject the attach request */
1957 send_0408_message(lle->llme, ms_tlli, &raid1,
1958 attach_req, ARRAY_SIZE(attach_req));
1959
1960 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1961 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001962 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01001963 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1964
1965 /* we expect an identity request (IMEI) */
1966 OSMO_ASSERT(sgsn_tx_counter == 1);
1967 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1968 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1969
1970 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001971 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001972 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1973
1974 /* check that the MM context has not been removed due to a failed
1975 * authorization */
1976 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1977
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001978 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01001979
1980 /* we expect an attach accept */
1981 OSMO_ASSERT(sgsn_tx_counter == 1);
1982 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1983 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1984
1985 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1986 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1987 ptmsi1 = received_ptmsi;
1988
1989 /* inject the attach complete */
1990 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001991 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001992 attach_compl, ARRAY_SIZE(attach_compl));
1993
1994 /* we don't expect a response */
1995 OSMO_ASSERT(sgsn_tx_counter == 0);
1996
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001997 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01001998 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1999 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2000
2001 printf(" - RA Update Request (RA 1 -> RA 1)\n");
2002
2003 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01002004 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002005 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2006
2007 /* we expect an RA update accept */
2008 OSMO_ASSERT(sgsn_tx_counter == 1);
2009 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2010 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
2011
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002012 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002013 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2014 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2015 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2016
2017 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2018 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2019 ptmsi1 = received_ptmsi;
2020
2021 /* inject the RA update complete */
2022 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002023 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002024 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2025
2026 /* we don't expect a response */
2027 OSMO_ASSERT(sgsn_tx_counter == 0);
2028
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002029 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002030 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2031 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002032 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002033
Jacob Erlbeck13304782016-01-04 18:43:37 +01002034 printf(" - RA Update Request (RA 1 -> RA 2)\n");
2035
2036 /* inject the RA update request */
2037 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2038
2039 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002040 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002041 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2042
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002043 /* we expect an RA update accept */
Jacob Erlbeck13304782016-01-04 18:43:37 +01002044 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002045 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002046
2047 printf(" - RA Update Request (RA other -> RA 2)\n");
2048
2049 /* inject the RA update request */
2050 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2051
2052 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002053 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002054 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2055
2056 /* we expect an RA update reject (and a LLC XID RESET) */
2057 OSMO_ASSERT(sgsn_tx_counter == 2);
2058 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2059 /* this has killed the LLE/LLME */
2060
2061 printf(" - Attach Request (RA 2)\n");
2062
2063 /* Create a LLE/LLME */
2064 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2065 lle = gprs_lle_get_or_create(ms_tlli, 3);
2066 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2067
2068 /* inject the attach request */
2069 send_0408_message(lle->llme, ms_tlli, &raid2,
2070 attach_req2, ARRAY_SIZE(attach_req2));
2071
2072 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2073 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002074 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002075 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2076
2077 /* we expect an attach accept */
2078 OSMO_ASSERT(sgsn_tx_counter == 1);
2079 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2080
2081 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2082 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2083 ptmsi1 = received_ptmsi;
2084
2085 /* inject the attach complete */
2086 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2087 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2088 OSMO_ASSERT(ictx != NULL);
2089 OSMO_ASSERT(ictx == ctx);
2090
Harald Weltef97ee042015-12-25 19:12:21 +01002091 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002092 attach_compl, ARRAY_SIZE(attach_compl));
2093
2094 /* we don't expect a response */
2095 OSMO_ASSERT(sgsn_tx_counter == 0);
2096
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002097 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002098 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2099 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2100
2101 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2102
2103 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01002104 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002105 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2106
2107 /* we expect an RA update accept */
2108 OSMO_ASSERT(sgsn_tx_counter == 1);
2109 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2110
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002111 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002112 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2113 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2114 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2115
2116 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2117 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2118 ptmsi1 = received_ptmsi;
2119
2120 /* inject the RA update complete */
2121 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002122 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002123 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2124
2125 /* we don't expect a response */
2126 OSMO_ASSERT(sgsn_tx_counter == 0);
2127
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002128 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002129 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2130 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002131 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002132
2133
2134 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01002135 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002136 detach_req, ARRAY_SIZE(detach_req));
2137
2138 /* verify that things are gone */
2139 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2140 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2141 OSMO_ASSERT(!ictx);
2142
2143 sgsn->cfg.auth_policy = saved_auth_policy;
2144
2145 cleanup_test();
2146}
2147
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002148static void test_apn_matching(void)
2149{
2150 struct apn_ctx *actx, *actxs[9];
2151
2152 printf("Testing APN matching\n");
2153
2154 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2155 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2156 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2157 actxs[3] = NULL;
2158
2159 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2160 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2161 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2162 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2163
2164 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2165
2166 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2167 OSMO_ASSERT(actx == actxs[2]);
2168 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2169 OSMO_ASSERT(actx == actxs[2]);
2170 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2171 OSMO_ASSERT(actx == actxs[1]);
2172 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2173 OSMO_ASSERT(actx == actxs[1]);
2174 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2175 OSMO_ASSERT(actx == actxs[0]);
2176 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2177 OSMO_ASSERT(actx == NULL);
2178
2179 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2180 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2181 OSMO_ASSERT(actx == actxs[3]);
2182
2183 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2184 OSMO_ASSERT(actx == actxs[4]);
2185
2186 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2187 OSMO_ASSERT(actx == actxs[6]);
2188
2189 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2190 OSMO_ASSERT(actx == actxs[5]);
2191
2192 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2193 OSMO_ASSERT(actx == actxs[7]);
2194
2195 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2196 OSMO_ASSERT(actx == actxs[8]);
2197
2198 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2199 OSMO_ASSERT(actx == actxs[7]);
2200
2201 /* Free APN contexts and check how the matching changes */
2202
2203 sgsn_apn_ctx_free(actxs[7]);
2204 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2205 OSMO_ASSERT(actx == actxs[8]);
2206
2207 sgsn_apn_ctx_free(actxs[8]);
2208 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2209 OSMO_ASSERT(actx == actxs[6]);
2210
2211 sgsn_apn_ctx_free(actxs[6]);
2212 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2213 OSMO_ASSERT(actx == actxs[1]);
2214
2215 sgsn_apn_ctx_free(actxs[5]);
2216 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2217 OSMO_ASSERT(actx == actxs[4]);
2218
2219 sgsn_apn_ctx_free(actxs[4]);
2220 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2221 OSMO_ASSERT(actx == actxs[2]);
2222
2223 sgsn_apn_ctx_free(actxs[2]);
2224 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2225 OSMO_ASSERT(actx == actxs[1]);
2226
2227 sgsn_apn_ctx_free(actxs[1]);
2228 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2229 OSMO_ASSERT(actx == actxs[0]);
2230
2231 sgsn_apn_ctx_free(actxs[0]);
2232 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2233 OSMO_ASSERT(actx == actxs[3]);
2234
2235 sgsn_apn_ctx_free(actxs[3]);
2236 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2237 OSMO_ASSERT(actx == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002238
2239 cleanup_test();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002240}
2241
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002242struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2243 struct sgsn_subscriber_data *sdata);
2244
2245static void test_ggsn_selection(void)
2246{
2247 struct apn_ctx *actxs[4];
2248 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01002249 struct gprs_subscr *s1;
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002250 const char *imsi1 = "1234567890";
2251 struct sgsn_mm_ctx *ctx;
2252 struct gprs_ra_id raid = { 0, };
2253 uint32_t local_tlli = 0xffeeddcc;
2254 enum gsm48_gsm_cause gsm_cause;
2255 struct tlv_parsed tp;
2256 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2257 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002258 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002259
2260 printf("Testing GGSN selection\n");
2261
Neels Hofmeyr814fef02016-12-08 21:19:57 +01002262 gsup_client_send_cb = my_gsup_client_send_dummy;
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002263
2264 /* Check for emptiness */
2265 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2266
2267 /* Create a context */
2268 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2269 ctx = alloc_mm_ctx(local_tlli, &raid);
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002270 osmo_strlcpy(ctx->imsi, imsi1, sizeof(ctx->imsi));
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002271
2272 /* Allocate and attach a subscriber */
2273 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2274 assert_subscr(s1, imsi1);
2275
2276 tp.lv[GSM48_IE_GSM_APN].len = 0;
2277 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2278
2279 /* TODO: Add PDP info entries to s1 */
2280
2281 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2282 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2283 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2284
2285 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2286 actxs[0]->ggsn = ggcs[0];
2287 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2288 actxs[1]->ggsn = ggcs[1];
2289 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2290 actxs[2]->ggsn = ggcs[2];
2291
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002292 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2293 pdp_data->context_id = 1;
2294 pdp_data->pdp_type = 0x0121;
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002295 osmo_strlcpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str));
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002296
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002297 /* Resolve GGSNs */
2298
2299 tp.lv[GSM48_IE_GSM_APN].len =
2300 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2301
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002302 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002303 OSMO_ASSERT(ggc != NULL);
2304 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002305 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002306
2307 tp.lv[GSM48_IE_GSM_APN].len =
2308 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2309
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002310 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002311 OSMO_ASSERT(ggc != NULL);
2312 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002313 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002314
2315 tp.lv[GSM48_IE_GSM_APN].len = 0;
2316 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2317
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002318 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002319 OSMO_ASSERT(ggc != NULL);
2320 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002321 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002322
2323 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2324 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002325 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002326 OSMO_ASSERT(ggc != NULL);
2327 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002328 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002329
2330 sgsn_apn_ctx_free(actxs[3]);
2331 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2332
2333 tp.lv[GSM48_IE_GSM_APN].len =
2334 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2335
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002336 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002337 OSMO_ASSERT(ggc == NULL);
2338 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002339 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002340
2341 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002342 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002343 OSMO_ASSERT(ggc == NULL);
2344 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2345
2346 /* Add PDP data entry to subscriber */
2347
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002348 osmo_strlcpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str));
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002349
2350 tp.lv[GSM48_IE_GSM_APN].len =
2351 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2352
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002353 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002354 OSMO_ASSERT(ggc != NULL);
2355 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002356 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002357
2358 tp.lv[GSM48_IE_GSM_APN].len =
2359 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2360
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002361 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002362 OSMO_ASSERT(ggc == NULL);
2363 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002364 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002365
2366 /* Cleanup */
2367
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01002368 gprs_subscr_put(s1);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002369 sgsn_mm_ctx_cleanup_free(ctx);
2370
2371 assert_no_subscrs();
2372
2373 sgsn_apn_ctx_free(actxs[0]);
2374 sgsn_apn_ctx_free(actxs[1]);
2375 sgsn_apn_ctx_free(actxs[2]);
2376
2377 sgsn_ggsn_ctx_free(ggcs[0]);
2378 sgsn_ggsn_ctx_free(ggcs[1]);
2379 sgsn_ggsn_ctx_free(ggcs[2]);
2380
Neels Hofmeyr814fef02016-12-08 21:19:57 +01002381 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002382
2383 cleanup_test();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002384}
2385
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002386static struct log_info_cat gprs_categories[] = {
2387 [DMM] = {
2388 .name = "DMM",
2389 .description = "Layer3 Mobility Management (MM)",
2390 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002391 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002392 },
2393 [DPAG] = {
2394 .name = "DPAG",
2395 .description = "Paging Subsystem",
2396 .color = "\033[1;38m",
2397 .enabled = 1, .loglevel = LOGL_NOTICE,
2398 },
2399 [DMEAS] = {
2400 .name = "DMEAS",
2401 .description = "Radio Measurement Processing",
2402 .enabled = 0, .loglevel = LOGL_NOTICE,
2403 },
2404 [DREF] = {
2405 .name = "DREF",
2406 .description = "Reference Counting",
2407 .enabled = 0, .loglevel = LOGL_NOTICE,
2408 },
2409 [DGPRS] = {
2410 .name = "DGPRS",
2411 .description = "GPRS Packet Service",
2412 .enabled = 1, .loglevel = LOGL_DEBUG,
2413 },
2414 [DNS] = {
2415 .name = "DNS",
2416 .description = "GPRS Network Service (NS)",
2417 .enabled = 1, .loglevel = LOGL_INFO,
2418 },
2419 [DBSSGP] = {
2420 .name = "DBSSGP",
2421 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2422 .enabled = 1, .loglevel = LOGL_DEBUG,
2423 },
2424 [DLLC] = {
2425 .name = "DLLC",
2426 .description = "GPRS Logical Link Control Protocol (LLC)",
2427 .enabled = 1, .loglevel = LOGL_DEBUG,
2428 },
2429 [DSNDCP] = {
2430 .name = "DSNDCP",
2431 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2432 .enabled = 1, .loglevel = LOGL_DEBUG,
2433 },
2434};
2435
2436static struct log_info info = {
2437 .cat = gprs_categories,
2438 .num_cat = ARRAY_SIZE(gprs_categories),
2439};
2440
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002441int main(int argc, char **argv)
2442{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002443 void *osmo_sgsn_ctx;
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002444 void *msgb_ctx;
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002445
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002446 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002447 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2448 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002449 msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002450
Alexander Couzens14314bd2016-07-05 09:52:52 +02002451 sgsn_rate_ctr_init();
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01002452 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002453 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002454
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002455 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002456 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002457 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002458 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002459 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002460 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002461 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002462 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002463 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002464 test_gmm_attach_acl();
2465 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002466 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002467 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002468 test_gmm_attach_subscr_gsup_auth(0);
2469 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002470 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002471 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002472 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002473 test_gmm_ptmsi_allocation();
Jacob Erlbeck13304782016-01-04 18:43:37 +01002474 test_gmm_routing_areas();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002475 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002476 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002477 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002478
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002479 talloc_report_full(osmo_sgsn_ctx, stderr);
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002480 OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);
Alexander Couzens14314bd2016-07-05 09:52:52 +02002481 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 2);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002482 return 0;
2483}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002484
2485
2486/* stubs */
2487struct osmo_prim_hdr;
2488int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2489{
2490 abort();
2491}