blob: 5ee5fa47bf18ad0e33a835f4eda3246699971e95 [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
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Harald Welte23d77d52016-04-25 19:07:34 +020027#include <osmocom/gsm/gsup.h>
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010028#include <openbsc/gprs_gsup_client.h>
Jacob Erlbeck277b71e2015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Jacob Erlbeck133e8622015-10-12 19:36:32 +020030#include <openbsc/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>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020039
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020040#include <stdio.h>
41
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020042extern void *tall_msgb_ctx;
43
44void *tall_bsc_ctx;
45static struct sgsn_instance sgsn_inst = {
46 .config_file = "osmo_sgsn.cfg",
47 .cfg = {
48 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010049 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020050 },
51};
52struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010053unsigned sgsn_tx_counter = 0;
Jacob Erlbeck133e8622015-10-12 19:36:32 +020054struct msgb *last_msg = NULL;
55struct gprs_gb_parse_context last_dl_parse_ctx;
56
57static void reset_last_msg()
58{
59 if (last_msg)
60 msgb_free(last_msg);
61
62 last_msg = NULL;
63 memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx));
64}
Jacob Erlbeck189999d2014-10-27 14:34:13 +010065
Jacob Erlbeckcf151872015-10-12 19:36:31 +020066static void cleanup_test()
67{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020068 reset_last_msg();
69}
70
71static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
72{
73 uint32_t new_ptmsi = GSM_RESERVED_TMSI;
74
75 if (parse_ctx->new_ptmsi_enc)
76 gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
77
78 return new_ptmsi;
Jacob Erlbeckcf151872015-10-12 19:36:31 +020079}
80
Jacob Erlbeck189999d2014-10-27 14:34:13 +010081/* override */
82int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
83 struct bssgp_dl_ud_par *dup)
84{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020085 int rc;
86
87 reset_last_msg();
88
89 last_msg = msg;
90 OSMO_ASSERT(msgb_data(last_msg) != NULL);
91
92 rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg),
93 &last_dl_parse_ctx);
94
95 fprintf(stderr, "Got DL LLC message: %s\n",
96 gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN"));
97
98 OSMO_ASSERT(rc > 0);
99
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100100 sgsn_tx_counter += 1;
101 return 0;
102}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200103
Max4011e722016-07-05 15:19:12 +0200104/* override, requires '-Wl,--wrap=RAND_bytes' */
105int __real_RAND_bytes(unsigned char *buf, int num);
106int mock_RAND_bytes(unsigned char *buf, int num);
107int (*RAND_bytes_cb)(unsigned char *, int) =
108 &mock_RAND_bytes;
109
110int __wrap_RAND_bytes(unsigned char *buf, int num)
111{
112 return (*RAND_bytes_cb)(buf, num);
113}
114/* make results of A&C ref predictable */
115int mock_RAND_bytes(unsigned char *buf, int num)
116{
117 if (num > 1)
118 return __real_RAND_bytes(buf, num);
119 buf[0] = 0;
120 return 1;
121}
122
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100123/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100124void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
125void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100126 &__real_sgsn_update_subscriber_data;
127
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100128void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100129{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100130 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100131}
132
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100133/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
134int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
135int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
136 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100137
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100138int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
139 return (*subscr_request_update_location_cb)(mmctx);
140};
141
142/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
143int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
144int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
145 &__real_gprs_subscr_request_auth_info;
146
147int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
148 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100149};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100150
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100151/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
152int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
153int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
154 &__real_gprs_gsup_client_send;
155
156int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
157{
158 return (*gprs_gsup_client_send_cb)(gsupc, msg);
159};
160
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200161static int count(struct llist_head *head)
162{
163 struct llist_head *cur;
164 int count = 0;
165
166 llist_for_each(cur, head)
167 count += 1;
168
169 return count;
170}
171
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200172static struct msgb *create_msg(const uint8_t *data, size_t len)
173{
174 struct msgb *msg = msgb_alloc(len + 8, "test message");
175 msg->l1h = msgb_put(msg, 8);
176 msg->l2h = msgb_put(msg, len);
177 memcpy(msg->l2h, data, len);
178
179 msgb_bcid(msg) = msg->l1h;
180 msgb_gmmh(msg) = msg->l2h;
181 return msg;
182}
183
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100184/*
185 * Create a context and search for it
186 */
187static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
188{
189 struct sgsn_mm_ctx *ctx, *ictx;
190 struct gprs_llc_lle *lle;
191 int old_count = count(gprs_llme_list());
192
193 lle = gprs_lle_get_or_create(tlli, 3);
194 ctx = sgsn_mm_ctx_alloc(tlli, raid);
195 ctx->mm_state = GMM_REGISTERED_NORMAL;
Harald Weltef97ee042015-12-25 19:12:21 +0100196 ctx->gb.llme = lle->llme;
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100197
198 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
199 OSMO_ASSERT(ictx == ctx);
200
201 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
202
203 return ctx;
204}
205
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100206static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck91580892016-01-04 18:43:33 +0100207 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100208 const uint8_t *data, size_t data_len)
209{
210 struct msgb *msg;
211
Jacob Erlbeck133e8622015-10-12 19:36:32 +0200212 reset_last_msg();
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100213 sgsn_tx_counter = 0;
214
215 msg = create_msg(data, data_len);
216 msgb_tlli(msg) = tlli;
Jacob Erlbeck91580892016-01-04 18:43:33 +0100217 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Max82040102016-07-06 11:59:18 +0200218 gsm0408_gprs_rcvmsg_gb(msg, llme, false);
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100219 msgb_free(msg);
220}
221
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200222static void test_llme(void)
223{
224 struct gprs_llc_lle *lle, *lle_copy;
225 uint32_t local_tlli;
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200226
227 printf("Testing LLME allocations\n");
228 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200229
230 /* initial state */
231 OSMO_ASSERT(count(gprs_llme_list()) == 0);
232
233 /* Create a new entry */
234 lle = gprs_lle_get_or_create(local_tlli, 3);
235 OSMO_ASSERT(lle);
236 OSMO_ASSERT(count(gprs_llme_list()) == 1);
237
238 /* No new entry is created */
239 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
240 OSMO_ASSERT(lle == lle_copy);
241 OSMO_ASSERT(count(gprs_llme_list()) == 1);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200242
243 /* unassign which should delete it*/
Max39550252016-06-28 17:39:20 +0200244 gprs_llgmm_unassign(lle->llme);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200245
246 /* Check that everything was cleaned up */
247 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200248
249 cleanup_test();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200250}
251
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100252struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100253void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100254{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100255 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100256 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100257 __func__, mmctx, mmctx->subscr);
258 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100259}
260
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100261static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
262{
263 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100264 OSMO_ASSERT(subscr);
265 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100266
267 sfound = gprs_subscr_get_by_imsi(imsi);
268 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100269
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100270 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100271}
272
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100273static void show_subscrs(FILE *out)
274{
275 struct gsm_subscriber *subscr;
276
277 llist_for_each_entry(subscr, &active_subscribers, entry) {
278 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100279 "use count: %d\n",
280 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100281 }
282}
283
284static void assert_no_subscrs()
285{
286 show_subscrs(stdout);
287 fflush(stdout);
288 OSMO_ASSERT(llist_empty(&active_subscribers));
289}
290
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100291static void test_subscriber(void)
292{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100293 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100294 const char *imsi1 = "1234567890";
295 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100296 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100297
298 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
299
300 printf("Testing core subscriber data API\n");
301
302 /* Check for emptiness */
303 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
304 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100305 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100306
307 /* Allocate entry 1 */
308 s1 = gprs_subscr_get_or_create(imsi1);
309 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100310 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100311 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100312
313 /* Allocate entry 2 */
314 s2 = gprs_subscr_get_or_create(imsi2);
315 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100316
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100317 /* Allocate entry 3 */
318 s3 = gprs_subscr_get_or_create(imsi3);
319
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100320 /* Check entries */
321 assert_subscr(s1, imsi1);
322 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100323 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100324
325 /* Update entry 1 */
326 last_updated_subscr = NULL;
327 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100328 OSMO_ASSERT(last_updated_subscr == NULL);
329 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
330 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100331
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100332 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100333 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100334 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100335 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100336 sfound = gprs_subscr_get_by_imsi(imsi1);
337 OSMO_ASSERT(sfound == NULL);
338
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100339 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100340 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100341
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100342 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100343 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100344 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100345 s2 = NULL;
346 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
347 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100348 assert_subscr(s3, imsi3);
349
350 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100351 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100352 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100353 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100354 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100355
356 OSMO_ASSERT(llist_empty(&active_subscribers));
357
358 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200359
360 cleanup_test();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100361}
362
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100363static void test_auth_triplets(void)
364{
365 struct gsm_subscriber *s1, *s1found;
366 const char *imsi1 = "1234567890";
367 struct gsm_auth_tuple *at;
368 struct sgsn_mm_ctx *ctx;
369 struct gprs_ra_id raid = { 0, };
370 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100371
372 printf("Testing authentication triplet handling\n");
373
374 /* Check for emptiness */
375 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
376
377 /* Allocate entry 1 */
378 s1 = gprs_subscr_get_or_create(imsi1);
379 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
380 s1found = gprs_subscr_get_by_imsi(imsi1);
381 OSMO_ASSERT(s1found == s1);
382 subscr_put(s1found);
383
384 /* Create a context */
385 OSMO_ASSERT(count(gprs_llme_list()) == 0);
386 ctx = alloc_mm_ctx(local_tlli, &raid);
387
388 /* Attach s1 to ctx */
389 ctx->subscr = subscr_get(s1);
390 ctx->subscr->sgsn_data->mm = ctx;
391
392 /* Try to get auth tuple */
393 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
394 OSMO_ASSERT(at == NULL);
395
396 /* Add triplets */
397 s1->sgsn_data->auth_triplets[0].key_seq = 0;
398 s1->sgsn_data->auth_triplets[1].key_seq = 1;
399 s1->sgsn_data->auth_triplets[2].key_seq = 2;
400
401 /* Try to get auth tuple */
402 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
403 OSMO_ASSERT(at != NULL);
404 OSMO_ASSERT(at->key_seq == 0);
405 OSMO_ASSERT(at->use_count == 1);
406 at = sgsn_auth_get_tuple(ctx, at->key_seq);
407 OSMO_ASSERT(at != NULL);
408 OSMO_ASSERT(at->key_seq == 1);
409 OSMO_ASSERT(at->use_count == 1);
410 at = sgsn_auth_get_tuple(ctx, at->key_seq);
411 OSMO_ASSERT(at != NULL);
412 OSMO_ASSERT(at->key_seq == 2);
413 OSMO_ASSERT(at->use_count == 1);
414 at = sgsn_auth_get_tuple(ctx, at->key_seq);
415 OSMO_ASSERT(at == NULL);
416
417 /* Free MM context and subscriber */
418 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100419 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100420 s1found = gprs_subscr_get_by_imsi(imsi1);
421 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200422
423 cleanup_test();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100424}
425
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100426#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
427
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100428static int rx_gsup_message(const uint8_t *data, size_t data_len)
429{
430 struct msgb *msg;
431 int rc;
432
433 msg = msgb_alloc(1024, __func__);
434 msg->l2h = msgb_put(msg, data_len);
435 OSMO_ASSERT(msg->l2h != NULL);
436 memcpy(msg->l2h, data, data_len);
437 rc = gprs_subscr_rx_gsup_message(msg);
438 msgb_free(msg);
439
440 return rc;
441}
442
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100443static void test_subscriber_gsup(void)
444{
445 struct gsm_subscriber *s1, *s1found;
446 const char *imsi1 = "1234567890";
447 struct sgsn_mm_ctx *ctx;
448 struct gprs_ra_id raid = { 0, };
449 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100450 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100451 int rc;
452
453 static const uint8_t send_auth_info_res[] = {
454 0x0a,
455 TEST_GSUP_IMSI1_IE,
456 0x03, 0x22, /* Auth tuple */
457 0x20, 0x10,
458 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
459 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
460 0x21, 0x04,
461 0x21, 0x22, 0x23, 0x24,
462 0x22, 0x08,
463 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
464 0x03, 0x22, /* Auth tuple */
465 0x20, 0x10,
466 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
467 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
468 0x21, 0x04,
469 0xa1, 0xa2, 0xa3, 0xa4,
470 0x22, 0x08,
471 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
472 };
473
474 static const uint8_t send_auth_info_err[] = {
475 0x09,
476 TEST_GSUP_IMSI1_IE,
477 0x02, 0x01, 0x07 /* GPRS not allowed */
478 };
479
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400480#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
481
482 static const uint8_t s1_msisdn[] = { MSISDN };
483
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100484 static const uint8_t update_location_res[] = {
485 0x06,
486 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400487 0x08, 0x09, MSISDN,
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100488 0x04, 0x00, /* PDP info complete */
489 0x05, 0x12,
490 0x10, 0x01, 0x01,
491 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
492 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
493 0x05, 0x11,
494 0x10, 0x01, 0x02,
495 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
496 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
497 };
498
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400499#undef MSISDN
500
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100501 static const uint8_t update_location_err[] = {
502 0x05,
503 TEST_GSUP_IMSI1_IE,
504 0x02, 0x01, 0x07 /* GPRS not allowed */
505 };
506
507 static const uint8_t location_cancellation_req[] = {
508 0x1c,
509 TEST_GSUP_IMSI1_IE,
510 0x06, 0x01, 0x00,
511 };
512
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200513 static const uint8_t location_cancellation_req_withdraw[] = {
514 0x1c,
515 TEST_GSUP_IMSI1_IE,
516 0x06, 0x01, 0x01,
517 };
518
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100519 static const uint8_t location_cancellation_req_other[] = {
520 0x1c,
521 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
522 0x06, 0x01, 0x00,
523 };
524
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100525 static const uint8_t purge_ms_err[] = {
526 0x0d,
527 TEST_GSUP_IMSI1_IE,
528 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
529 };
530
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100531 static const uint8_t purge_ms_err_no_cause[] = {
532 0x0d,
533 TEST_GSUP_IMSI1_IE,
534 };
535
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100536 static const uint8_t purge_ms_res[] = {
537 0x0e,
538 TEST_GSUP_IMSI1_IE,
539 0x07, 0x00,
540 };
541
542
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100543 static const uint8_t insert_data_req[] = {
544 0x10,
545 TEST_GSUP_IMSI1_IE,
546 0x05, 0x11,
547 0x10, 0x01, 0x03,
548 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
549 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
550 };
551
552 static const uint8_t delete_data_req[] = {
553 0x14,
554 TEST_GSUP_IMSI1_IE,
555 0x10, 0x01, 0x03,
556 };
557
Neels Hofmeyr241bda02016-06-20 18:26:15 +0200558 printf("Testing subscriber GSUP handling\n");
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100559
560 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
561
562 /* Check for emptiness */
563 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
564
565 /* Allocate entry 1 */
566 s1 = gprs_subscr_get_or_create(imsi1);
567 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
568 s1found = gprs_subscr_get_by_imsi(imsi1);
569 OSMO_ASSERT(s1found == s1);
570 subscr_put(s1found);
571
572 /* Create a context */
573 OSMO_ASSERT(count(gprs_llme_list()) == 0);
574 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100575
576 /* Attach s1 to ctx */
577 ctx->subscr = subscr_get(s1);
578 ctx->subscr->sgsn_data->mm = ctx;
579
580 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100581 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100582 OSMO_ASSERT(rc >= 0);
583 OSMO_ASSERT(last_updated_subscr == s1);
584
585 /* Check triplets */
586 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
587 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
588 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
589
590 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100591 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100592 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100593 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100594 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100595
596 /* Check triplets */
597 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
598 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
599 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
600
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100601 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100602 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100603 OSMO_ASSERT(rc >= 0);
604 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100605 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100606 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400607 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
608 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100609 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
610 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
611 struct sgsn_subscriber_pdp_data, list);
612 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
613 pdpd = llist_entry(pdpd->list.next,
614 struct sgsn_subscriber_pdp_data, list);
615 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100616
617 /* Check authorization */
618 OSMO_ASSERT(s1->authorized == 1);
619
620 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100621 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100622 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100623 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100624 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100625
626 /* Check authorization */
627 OSMO_ASSERT(s1->authorized == 0);
628
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100629 /* Inject InsertSubscrData GSUP message */
630 last_updated_subscr = NULL;
631 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Harald Weltecd5e5262016-05-06 13:46:21 +0200632 OSMO_ASSERT(rc = -ENOTSUP); /* not connected */
633 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100634
635 /* Inject DeleteSubscrData GSUP message */
636 last_updated_subscr = NULL;
637 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
638 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
639 OSMO_ASSERT(last_updated_subscr == NULL);
640
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100641 /* Inject wrong LocCancelReq GSUP message */
642 last_updated_subscr = NULL;
643 rc = rx_gsup_message(location_cancellation_req_other,
644 sizeof(location_cancellation_req_other));
645 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
646 OSMO_ASSERT(last_updated_subscr == NULL);
647
648 /* Check cancellation result */
649 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
650 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
651
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100652 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100653 rc = rx_gsup_message(location_cancellation_req,
654 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100655 OSMO_ASSERT(rc >= 0);
656 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100657 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100658
659 /* Check cancellation result */
660 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
661 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
662
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200663 /* Inject LocCancelReq(withdraw) GSUP message */
664 rc = rx_gsup_message(location_cancellation_req_withdraw,
665 sizeof(location_cancellation_req_withdraw));
666 OSMO_ASSERT(rc >= 0);
667 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
668
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100669 /* Inject PurgeMsRes GSUP message */
670 rc = rx_gsup_message(purge_ms_res,
671 sizeof(purge_ms_res));
672 OSMO_ASSERT(rc >= 0);
673 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
674
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100675 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100676 OSMO_ASSERT(ctx->subscr == NULL);
677 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100678 subscr_put(s1);
679 s1found = gprs_subscr_get_by_imsi(imsi1);
680 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100681
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
687 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
688 rc = rx_gsup_message(purge_ms_err,
689 sizeof(purge_ms_err));
690 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
691
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100692 /* Inject PurgeMsErr() GSUP message */
693 rc = rx_gsup_message(purge_ms_err_no_cause,
694 sizeof(purge_ms_err_no_cause));
695 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
696
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100697 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
698 last_updated_subscr = NULL;
699 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100700 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100701 OSMO_ASSERT(last_updated_subscr == NULL);
702
703 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
704 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
705 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
706 OSMO_ASSERT(last_updated_subscr == NULL);
707
708 /* Inject LocCancelReq GSUP message (unknown IMSI) */
709 rc = rx_gsup_message(location_cancellation_req,
710 sizeof(location_cancellation_req));
711 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
712 OSMO_ASSERT(last_updated_subscr == NULL);
713
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100714 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200715
716 cleanup_test();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100717}
718
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100719int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
720{
721 msgb_free(msg);
722 return 0;
723};
724
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200725/*
726 * Test that a GMM Detach will remove the MMCTX and the
727 * associated LLME.
728 */
729static void test_gmm_detach(void)
730{
731 struct gprs_ra_id raid = { 0, };
732 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200733 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200734
735 printf("Testing GMM detach\n");
736
737 /* DTAP - Detach Request (MO) */
738 /* normal detach, power_off = 0 */
739 static const unsigned char detach_req[] = {
740 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
741 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
742 };
743
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200744 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200745
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100746 /* Create a context */
747 OSMO_ASSERT(count(gprs_llme_list()) == 0);
748 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200749
750 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +0100751 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100752 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200753
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100754 /* verify that a single message (hopefully the Detach Accept) has been
755 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100756 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100757
758 /* verify that things are gone */
759 OSMO_ASSERT(count(gprs_llme_list()) == 0);
760 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
761 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200762
763 cleanup_test();
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100764}
765
766/*
767 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
768 * will not sent a Detach Accept message (power_off = 1)
769 */
770static void test_gmm_detach_power_off(void)
771{
772 struct gprs_ra_id raid = { 0, };
773 struct sgsn_mm_ctx *ctx, *ictx;
774 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100775
776 printf("Testing GMM detach (power off)\n");
777
778 /* DTAP - Detach Request (MO) */
779 /* normal detach, power_off = 1 */
780 static const unsigned char detach_req[] = {
781 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
782 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
783 };
784
785 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
786
787 /* Create a context */
788 OSMO_ASSERT(count(gprs_llme_list()) == 0);
789 ctx = alloc_mm_ctx(local_tlli, &raid);
790
791 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +0100792 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100793 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100794
795 /* verify that no message (and therefore no Detach Accept) has been
796 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100797 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100798
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200799 /* verify that things are gone */
800 OSMO_ASSERT(count(gprs_llme_list()) == 0);
801 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200802 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200803
804 cleanup_test();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200805}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200806
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200807/*
808 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
809 */
810static void test_gmm_detach_no_mmctx(void)
811{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100812 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200813 struct gprs_llc_lle *lle;
814 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200815
816 printf("Testing GMM detach (no MMCTX)\n");
817
818 /* DTAP - Detach Request (MO) */
819 /* normal detach, power_off = 0 */
820 static const unsigned char detach_req[] = {
821 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
822 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
823 };
824
825 /* Create an LLME */
826 OSMO_ASSERT(count(gprs_llme_list()) == 0);
827 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
828 lle = gprs_lle_get_or_create(local_tlli, 3);
829
830 OSMO_ASSERT(count(gprs_llme_list()) == 1);
831
832 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100833 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100834 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200835
836 /* verify that the LLME is gone */
837 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200838
839 cleanup_test();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200840}
841
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100842/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100843 * Test that a single GMM Detach Accept message will not cause the SGSN to send
844 * any message or leave an MM context at the SGSN.
845 */
846static void test_gmm_detach_accept_unexpected(void)
847{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100848 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100849 struct gprs_llc_lle *lle;
850 uint32_t local_tlli;
851
852 printf("Testing GMM detach accept (unexpected)\n");
853
854 /* DTAP - Detach Accept (MT) */
855 /* normal detach */
856 static const unsigned char detach_acc[] = {
857 0x08, 0x06
858 };
859
860 /* Create an LLME */
861 OSMO_ASSERT(count(gprs_llme_list()) == 0);
862 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
863 lle = gprs_lle_get_or_create(local_tlli, 3);
864
865 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100866 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100867 detach_acc, ARRAY_SIZE(detach_acc));
868
869 /* verify that no message (and therefore no Status or XID reset) has been
870 * sent by the SGSN */
871 OSMO_ASSERT(sgsn_tx_counter == 0);
872
873 /* verify that things are gone */
874 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200875
876 cleanup_test();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100877}
878
879/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100880 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
881 */
882static void test_gmm_status_no_mmctx(void)
883{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100884 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100885 struct gprs_llc_lle *lle;
886 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100887
888 printf("Testing GMM Status (no MMCTX)\n");
889
890 /* DTAP - GMM Status, protocol error */
891 static const unsigned char gmm_status[] = {
892 0x08, 0x20, 0x6f
893 };
894
895 /* Create an LLME */
896 OSMO_ASSERT(count(gprs_llme_list()) == 0);
897 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
898 lle = gprs_lle_get_or_create(local_tlli, 3);
899
900 OSMO_ASSERT(count(gprs_llme_list()) == 1);
901
902 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100903 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100904 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100905
906 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100907 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100908
909 /* verify that the LLME is gone */
910 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200911
912 cleanup_test();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100913}
914
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100915/*
916 * Test the GMM Attach procedure
917 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100918static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100919{
920 struct gprs_ra_id raid = { 0, };
921 struct sgsn_mm_ctx *ctx = NULL;
922 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100923 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100924 uint32_t foreign_tlli;
925 uint32_t local_tlli = 0;
926 struct gprs_llc_lle *lle;
927
928 /* DTAP - Attach Request */
929 /* The P-TMSI is not known by the SGSN */
930 static const unsigned char attach_req[] = {
931 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
932 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
933 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
934 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
935 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
936 };
937
938 /* DTAP - Identity Response IMEI */
939 static const unsigned char ident_resp_imei[] = {
940 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
941 0x56
942 };
943
944 /* DTAP - Identity Response IMSI */
945 static const unsigned char ident_resp_imsi[] = {
946 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
947 0x54
948 };
949
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100950 /* DTAP - Authentication and Ciphering Resp */
951 static const unsigned char auth_ciph_resp[] = {
952 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
953 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
954 };
955
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100956 /* DTAP - Attach Complete */
957 static const unsigned char attach_compl[] = {
958 0x08, 0x03
959 };
960
961 /* DTAP - Detach Request (MO) */
962 /* normal detach, power_off = 0 */
963 static const unsigned char detach_req[] = {
964 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
965 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
966 };
967
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100968 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100969
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100970 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
971
972 /* Create a LLE/LLME */
973 OSMO_ASSERT(count(gprs_llme_list()) == 0);
974 lle = gprs_lle_get_or_create(foreign_tlli, 3);
975 OSMO_ASSERT(count(gprs_llme_list()) == 1);
976
977 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100978 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100979 attach_req, ARRAY_SIZE(attach_req));
980
981 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
982 OSMO_ASSERT(ctx != NULL);
983 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
984
985 /* we expect an identity request (IMEI) */
986 OSMO_ASSERT(sgsn_tx_counter == 1);
987
988 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +0100989 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100990 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
991
992 /* we expect an identity request (IMSI) */
993 OSMO_ASSERT(sgsn_tx_counter == 1);
994
995 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +0100996 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100997 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
998
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100999 /* check that the MM context has not been removed due to a failed
1000 * authorization */
1001 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1002
Jacob Erlbeck0074a772014-10-28 16:23:46 +01001003 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001004
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001005retry_attach_req:
1006
1007 if (retry && sgsn_tx_counter == 0) {
1008 fprintf(stderr, "Retrying attach request\n");
1009 /* re-inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001010 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001011 attach_req, ARRAY_SIZE(attach_req));
1012 }
1013
1014 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
1015 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001016
1017 /* inject the auth & ciph response */
Harald Weltef97ee042015-12-25 19:12:21 +01001018 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001019 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1020
1021 /* check that the MM context has not been removed due to a
1022 * failed authorization */
1023 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001024 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1025 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001026 }
1027
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001028 if (retry && sgsn_tx_counter == 0)
1029 goto retry_attach_req;
1030
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001031 /* we expect an attach accept/reject */
1032 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001033 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1034 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001035
1036 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001037 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001038
1039 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001040 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001041 attach_compl, ARRAY_SIZE(attach_compl));
1042
1043 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1044
1045 /* we don't expect a response */
1046 OSMO_ASSERT(sgsn_tx_counter == 0);
1047
1048 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001049 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001050 detach_req, ARRAY_SIZE(detach_req));
1051
1052 /* verify that things are gone */
1053 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1054 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1055 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001056
1057 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001058}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001059
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001060static void test_gmm_attach_acl(void)
1061{
1062 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1063
1064 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1065 sgsn_acl_add("123456789012345", &sgsn->cfg);
1066 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001067 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001068 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001069
1070 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001071
1072 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001073}
1074
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001075int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001076 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001077 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001078 if (rc == -ENOTSUP) {
1079 OSMO_ASSERT(mmctx->subscr);
1080 gprs_subscr_update(mmctx->subscr);
1081 }
1082 return rc;
1083};
1084
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001085int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1086 gprs_subscr_update(mmctx->subscr);
1087 return 0;
1088};
1089
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001090static void test_gmm_attach_subscr(void)
1091{
1092 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1093 struct gsm_subscriber *subscr;
1094
1095 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001096 subscr_request_update_location_cb = my_subscr_request_update_location;
1097 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001098
1099 subscr = gprs_subscr_get_or_create("123456789012345");
1100 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001101
1102 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001103 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001104 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001105 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001106
1107 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001108 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1109 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001110
1111 cleanup_test();
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001112}
1113
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001114int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1115{
1116 /* Fake an authentication */
1117 OSMO_ASSERT(mmctx->subscr);
1118 mmctx->is_authenticated = 1;
1119 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001120
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001121 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001122};
1123
1124static void test_gmm_attach_subscr_fake_auth(void)
1125{
1126 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1127 struct gsm_subscriber *subscr;
1128
1129 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001130 subscr_request_update_location_cb = my_subscr_request_update_location;
1131 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001132
1133 subscr = gprs_subscr_get_or_create("123456789012345");
1134 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001135 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001136 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001137
1138 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001139 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001140 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001141 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001142
1143 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001144 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1145 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001146
1147 cleanup_test();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001148}
1149
1150int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1151{
1152 struct gsm_auth_tuple at = {
Harald Welte121e9a42016-04-20 13:13:19 +02001153 .vec.sres = {0x51, 0xe5, 0x51, 0xe5},
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001154 .key_seq = 0
1155 };
1156
1157 /* Fake an authentication */
1158 OSMO_ASSERT(mmctx->subscr);
1159 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1160
1161 gprs_subscr_update_auth_info(mmctx->subscr);
1162
1163 return 0;
1164};
1165
1166static void test_gmm_attach_subscr_real_auth(void)
1167{
1168 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1169 struct gsm_subscriber *subscr;
1170
1171 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1172 subscr_request_update_location_cb = my_subscr_request_update_location;
1173 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1174
1175 subscr = gprs_subscr_get_or_create("123456789012345");
1176 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001177 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001178 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001179
1180 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001181
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001182 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001183 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001184 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001185
1186 sgsn->cfg.auth_policy = saved_auth_policy;
1187 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1188 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001189
1190 cleanup_test();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001191}
1192
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001193#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1194 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1195
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001196static int auth_info_skip = 0;
1197static int upd_loc_skip = 0;
1198
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001199int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1200{
1201 static const uint8_t send_auth_info_res[] = {
1202 0x0a,
1203 TEST_GSUP_IMSI_LONG_IE,
1204 0x03, 0x22, /* Auth tuple */
1205 0x20, 0x10,
1206 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1207 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1208 0x21, 0x04,
1209 0x51, 0xe5, 0x51, 0xe5,
1210 0x22, 0x08,
1211 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1212 };
1213
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001214 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001215
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001216 if (auth_info_skip > 0) {
1217 auth_info_skip -= 1;
1218 return -EAGAIN;
1219 }
1220
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001221 /* Fake an SendAuthInfoRes */
1222 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1223
1224 return 0;
1225};
1226
1227int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1228 static const uint8_t update_location_res[] = {
1229 0x06,
1230 TEST_GSUP_IMSI_LONG_IE,
1231 0x04, 0x00, /* PDP info complete */
1232 0x05, 0x12,
1233 0x10, 0x01, 0x01,
1234 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1235 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001236 0x08, 0x07, /* MSISDN 49166213323 encoded */
1237 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freyther10c0f562015-05-17 20:58:40 +02001238 0x09, 0x07, /* MSISDN 38166213323 encoded */
1239 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001240 };
1241
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001242 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001243
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001244 if (upd_loc_skip > 0) {
1245 upd_loc_skip -= 1;
1246 return -EAGAIN;
1247 }
1248
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001249 /* Fake an UpdateLocRes */
1250 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1251};
1252
1253
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001254static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001255{
1256 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1257 struct gsm_subscriber *subscr;
1258
1259 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1260 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1261 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001262 if (retry) {
1263 upd_loc_skip = 3;
1264 auth_info_skip = 3;
1265 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001266
1267 subscr = gprs_subscr_get_or_create("123456789012345");
1268 subscr->authorized = 1;
1269 sgsn->cfg.require_authentication = 1;
1270 sgsn->cfg.require_update_location = 1;
1271 subscr_put(subscr);
1272
1273 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001274 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001275 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001276
1277 sgsn->cfg.auth_policy = saved_auth_policy;
1278 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1279 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001280 upd_loc_skip = 0;
1281 auth_info_skip = 0;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001282
1283 cleanup_test();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001284}
1285
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001286int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1287{
Harald Welte23d77d52016-04-25 19:07:34 +02001288 struct osmo_gsup_message to_peer = {0};
1289 struct osmo_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001290 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001291 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001292
1293 /* Simulate the GSUP peer */
Harald Welte23d77d52016-04-25 19:07:34 +02001294 rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001295 OSMO_ASSERT(rc >= 0);
1296 OSMO_ASSERT(to_peer.imsi[0] != 0);
1297 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001298
1299 /* This invalidates the pointers in to_peer */
1300 msgb_free(msg);
1301
1302 switch (to_peer.message_type) {
Harald Welte23d77d52016-04-25 19:07:34 +02001303 case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001304 /* Send UPDATE_LOCATION_RESULT */
1305 return my_subscr_request_update_gsup_auth(NULL);
1306
Harald Welte23d77d52016-04-25 19:07:34 +02001307 case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001308 /* Send SEND_AUTH_INFO_RESULT */
1309 return my_subscr_request_auth_info_gsup_auth(NULL);
1310
Harald Welte23d77d52016-04-25 19:07:34 +02001311 case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
1312 from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001313 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001314
1315 default:
1316 if ((to_peer.message_type & 0b00000011) == 0) {
1317 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001318 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001319 from_peer.message_type = to_peer.message_type + 1;
1320 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1321 break;
1322 }
1323
1324 /* Ignore it */
1325 return 0;
1326 }
1327
1328 reply_msg = gprs_gsup_msgb_alloc();
1329 reply_msg->l2h = reply_msg->data;
Harald Welte23d77d52016-04-25 19:07:34 +02001330 osmo_gsup_encode(reply_msg, &from_peer);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001331 gprs_subscr_rx_gsup_message(reply_msg);
1332 msgb_free(reply_msg);
1333
1334 return 0;
1335};
1336
1337static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1338{
1339 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1340 struct gsm_subscriber *subscr;
1341
1342 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001343 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1344
1345 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1346
1347 if (retry) {
1348 upd_loc_skip = 3;
1349 auth_info_skip = 3;
1350 }
1351
1352 printf("Auth policy 'remote', real GSUP based auth: ");
1353 test_gmm_attach(retry);
1354
1355 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001356 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001357 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001358
1359 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001360 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1361 upd_loc_skip = 0;
1362 auth_info_skip = 0;
1363 talloc_free(sgsn->gsup_client);
1364 sgsn->gsup_client = NULL;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001365
1366 cleanup_test();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001367}
1368
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001369/*
1370 * Test the GMM Rejects
1371 */
1372static void test_gmm_reject(void)
1373{
1374 struct gprs_ra_id raid = { 0, };
1375 struct sgsn_mm_ctx *ctx = NULL;
1376 uint32_t foreign_tlli;
1377 struct gprs_llc_lle *lle;
1378 int idx;
1379
1380 /* DTAP - Attach Request */
1381 /* Invalid MI length */
1382 static const unsigned char attach_req_inv_mi_len[] = {
1383 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1384 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1385 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1386 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1387 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1388 };
1389
1390 /* DTAP - Attach Request */
1391 /* Invalid MI type (IMEI) */
1392 static const unsigned char attach_req_inv_mi_type[] = {
1393 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1394 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1395 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1396 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1397 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1398 };
1399
1400 /* DTAP - Routing Area Update Request */
1401 static const unsigned char dtap_ra_upd_req[] = {
1402 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1403 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1404 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1405 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1406 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1407 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1408 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1409 };
1410
1411 /* DTAP - Routing Area Update Request */
1412 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1413 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1414 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1415 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1416 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1417 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1418 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1419 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1420 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1421 };
1422
1423 /* DTAP - Routing Area Update Request */
1424 /* Invalid cap length */
1425 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1426 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1427 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1428 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1429 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1430 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1431 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1432 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1433 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1434 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1435 };
1436
1437 struct test {
1438 const char *title;
1439 const unsigned char *msg;
1440 unsigned msg_len;
1441 unsigned num_resp;
1442
1443 };
1444 static struct test tests[] = {
1445 {
1446 .title = "Attach Request (invalid MI length)",
1447 .msg = attach_req_inv_mi_len,
1448 .msg_len = sizeof(attach_req_inv_mi_len),
1449 .num_resp = 1 /* Reject */
1450
1451 },
1452 {
1453 .title = "Attach Request (invalid MI type)",
1454 .msg = attach_req_inv_mi_type,
1455 .msg_len = sizeof(attach_req_inv_mi_type),
1456 .num_resp = 1 /* Reject */
1457 },
1458 {
1459 .title = "Routing Area Update Request (valid)",
1460 .msg = dtap_ra_upd_req,
1461 .msg_len = sizeof(dtap_ra_upd_req),
1462 .num_resp = 2 /* XID Reset + Reject */
1463 },
1464 {
1465 .title = "Routing Area Update Request (invalid type)",
1466 .msg = dtap_ra_upd_req_inv_type,
1467 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1468 .num_resp = 1 /* Reject */
1469 },
1470 {
1471 .title = "Routing Area Update Request (invalid CAP length)",
1472 .msg = dtap_ra_upd_req_inv_cap_len,
1473 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1474 .num_resp = 1 /* Reject */
1475 },
1476 };
1477
1478 printf("Testing GMM reject\n");
1479
1480 /* reset the PRNG used by sgsn_alloc_ptmsi */
1481 srand(1);
1482
1483 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1484
1485 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1486
1487 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1488 const struct test *test = &tests[idx];
1489 printf(" - %s\n", test->title);
1490
1491 /* Create a LLE/LLME */
1492 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1493 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1494
1495 /* Inject the Request message */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001496 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001497 test->msg, test->msg_len);
1498
1499 /* We expect a Reject message */
1500 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1501 sgsn_tx_counter, test->num_resp);
1502 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1503
1504 /* verify that LLME/MM are removed */
1505 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1506 OSMO_ASSERT(ctx == NULL);
1507 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1508 }
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001509
1510 cleanup_test();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001511}
1512
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001513/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001514 * Test cancellation of attached MM contexts
1515 */
1516static void test_gmm_cancel(void)
1517{
1518 struct gprs_ra_id raid = { 0, };
1519 struct sgsn_mm_ctx *ctx = NULL;
1520 struct sgsn_mm_ctx *ictx;
1521 uint32_t ptmsi1;
1522 uint32_t foreign_tlli;
1523 uint32_t local_tlli = 0;
1524 struct gprs_llc_lle *lle;
1525 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1526
1527 /* DTAP - Attach Request */
1528 /* The P-TMSI is not known by the SGSN */
1529 static const unsigned char attach_req[] = {
1530 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1531 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1532 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1533 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1534 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1535 };
1536
1537 /* DTAP - Identity Response IMEI */
1538 static const unsigned char ident_resp_imei[] = {
1539 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1540 0x56
1541 };
1542
1543 /* DTAP - Identity Response IMSI */
1544 static const unsigned char ident_resp_imsi[] = {
1545 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1546 0x54
1547 };
1548
1549 /* DTAP - Attach Complete */
1550 static const unsigned char attach_compl[] = {
1551 0x08, 0x03
1552 };
1553
1554 printf("Testing cancellation\n");
1555
1556 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1557
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001558 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1559
1560 /* Create a LLE/LLME */
1561 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1562 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1563 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1564
1565 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001566 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001567 attach_req, ARRAY_SIZE(attach_req));
1568
1569 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1570 OSMO_ASSERT(ctx != NULL);
1571 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1572
1573 /* we expect an identity request (IMEI) */
1574 OSMO_ASSERT(sgsn_tx_counter == 1);
1575
1576 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001577 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001578 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1579
1580 /* we expect an identity request (IMSI) */
1581 OSMO_ASSERT(sgsn_tx_counter == 1);
1582
1583 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001584 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001585 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1586
1587 /* check that the MM context has not been removed due to a failed
1588 * authorization */
1589 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1590
1591 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1592
1593 /* we expect an attach accept/reject */
1594 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001595 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1596 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001597
1598 /* this has been randomly assigned by the SGSN */
1599 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1600
1601 /* inject the attach complete */
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 attach_compl, ARRAY_SIZE(attach_compl));
1604
1605 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1606
1607 /* we don't expect a response */
1608 OSMO_ASSERT(sgsn_tx_counter == 0);
1609
1610 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001611 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001612
1613 /* verify that things are gone */
1614 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1615 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1616 OSMO_ASSERT(!ictx);
1617
1618 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001619
1620 cleanup_test();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001621}
1622
1623/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001624 * Test the dynamic allocation of P-TMSIs
1625 */
1626static void test_gmm_ptmsi_allocation(void)
1627{
Jacob Erlbeckd58c0332016-01-04 18:43:35 +01001628 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001629 struct sgsn_mm_ctx *ctx = NULL;
1630 struct sgsn_mm_ctx *ictx;
1631 uint32_t foreign_tlli;
1632 uint32_t ptmsi1;
1633 uint32_t ptmsi2;
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001634 uint32_t received_ptmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001635 uint32_t old_ptmsi;
1636 uint32_t local_tlli = 0;
1637 struct gprs_llc_lle *lle;
1638 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1639
1640 /* DTAP - Attach Request (IMSI 12131415161718) */
1641 static const unsigned char attach_req[] = {
1642 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1643 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1644 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1645 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1646 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1647 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1648 0x00,
1649 };
1650
1651 /* DTAP - Identity Response IMEI */
1652 static const unsigned char ident_resp_imei[] = {
1653 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1654 0x56
1655 };
1656
1657 /* DTAP - Attach Complete */
1658 static const unsigned char attach_compl[] = {
1659 0x08, 0x03
1660 };
1661
1662 /* DTAP - Routing Area Update Request */
1663 static const unsigned char ra_upd_req[] = {
1664 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1665 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1666 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1667 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1668 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1669 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1670 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1671 };
1672
1673 /* DTAP - Routing Area Update Complete */
1674 static const unsigned char ra_upd_complete[] = {
1675 0x08, 0x0a
1676 };
1677
1678 /* DTAP - Detach Request (MO) */
1679 /* normal detach, power_off = 1 */
1680 static const unsigned char detach_req[] = {
1681 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1682 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1683 };
1684
1685 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1686
1687 printf("Testing P-TMSI allocation\n");
1688
1689 printf(" - sgsn_alloc_ptmsi\n");
1690
1691 /* reset the PRNG used by sgsn_alloc_ptmsi */
1692 srand(1);
1693
1694 ptmsi1 = sgsn_alloc_ptmsi();
1695 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1696
1697 ptmsi2 = sgsn_alloc_ptmsi();
1698 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1699
1700 OSMO_ASSERT(ptmsi1 != ptmsi2);
1701
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001702 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001703
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001704 printf(" - Repeated Attach Request\n");
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001705
1706 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1707
1708 /* Create a LLE/LLME */
1709 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1710 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1711 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1712
1713 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001714 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001715 attach_req, ARRAY_SIZE(attach_req));
1716
1717 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1718 OSMO_ASSERT(ctx != NULL);
1719 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001720 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1721 ptmsi1 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001722
1723 old_ptmsi = ctx->p_tmsi_old;
1724
1725 /* we expect an identity request (IMEI) */
1726 OSMO_ASSERT(sgsn_tx_counter == 1);
1727
1728 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001729 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001730 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1731
1732 /* check that the MM context has not been removed due to a failed
1733 * authorization */
1734 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1735
1736 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1737 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1738
1739 /* we expect an attach accept */
1740 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001741 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1742 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001743
1744 /* we ignore this and send the attach again */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001745 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001746 attach_req, ARRAY_SIZE(attach_req));
1747
1748 /* the allocated P-TMSI should be the same */
1749 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1750 OSMO_ASSERT(ctx != NULL);
1751 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1752 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1753 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1754
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001755 /* we expect an attach accept */
1756 OSMO_ASSERT(sgsn_tx_counter == 1);
1757 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1758 OSMO_ASSERT(received_ptmsi == ptmsi1);
1759
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001760 /* inject the attach complete */
1761 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001762 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001763 attach_compl, ARRAY_SIZE(attach_compl));
1764
1765 /* we don't expect a response */
1766 OSMO_ASSERT(sgsn_tx_counter == 0);
1767
1768 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1769 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1770 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1771
1772 printf(" - Repeated RA Update Request\n");
1773
1774 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001775 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001776 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1777
1778 /* we expect an RA update accept */
1779 OSMO_ASSERT(sgsn_tx_counter == 1);
1780
1781 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1782 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001783 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1784 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1785 ptmsi2 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001786
1787 /* repeat the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001788 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001789 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1790
1791 /* we expect an RA update accept */
1792 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001793 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1794 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001795
1796 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1797 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1798 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1799
1800 /* inject the RA update complete */
1801 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001802 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001803 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1804
1805 /* we don't expect a response */
1806 OSMO_ASSERT(sgsn_tx_counter == 0);
1807
1808 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1809 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1810 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1811
1812 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001813 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001814 detach_req, ARRAY_SIZE(detach_req));
1815
1816 /* verify that things are gone */
1817 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1818 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1819 OSMO_ASSERT(!ictx);
1820
1821 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001822
1823 cleanup_test();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001824}
1825
Jacob Erlbeck13304782016-01-04 18:43:37 +01001826/*
1827 * Test changing of routing areas
1828 */
1829static void test_gmm_routing_areas(void)
1830{
1831 struct gprs_ra_id raid1 = {332, 112, 16464, 96};
1832 struct gprs_ra_id raid2 = {332, 112, 16464, 97};
1833 struct sgsn_mm_ctx *ctx = NULL;
1834 struct sgsn_mm_ctx *ictx;
1835 uint32_t ptmsi1;
1836 uint32_t received_ptmsi;
1837 uint32_t ms_tlli = 0;
1838 struct gprs_llc_lle *lle;
1839 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1840
1841 /* DTAP - Attach Request (IMSI 12131415161718) */
1842 static const unsigned char attach_req[] = {
1843 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1844 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1845 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1846 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1847 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1848 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1849 0x00,
1850 };
1851
1852 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1853 static const unsigned char attach_req2[] = {
1854 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1855 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1856 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1857 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1858 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1859 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1860 0x00,
1861 };
1862
1863 /* DTAP - Identity Response IMEI */
1864 static const unsigned char ident_resp_imei[] = {
1865 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1866 0x56
1867 };
1868
1869 /* DTAP - Attach Complete */
1870 static const unsigned char attach_compl[] = {
1871 0x08, 0x03
1872 };
1873
1874 /* DTAP - Routing Area Update Request (coming from RA 1) */
1875 static const unsigned char ra_upd_req1[] = {
1876 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1877 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1878 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1879 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1880 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1881 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1882 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1883 };
1884
1885 /* DTAP - Routing Area Update Request (coming from RA 2) */
1886 static const unsigned char ra_upd_req2[] = {
1887 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1888 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1889 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1890 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1891 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1892 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1893 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1894 };
1895
1896 /* DTAP - Routing Area Update Request (coming from RA other) */
1897 /* raid_other = {443, 223, 16464, 98}; */
1898 static const unsigned char ra_upd_req_other[] = {
1899 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1900 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1901 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1902 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1903 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1904 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1905 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1906 };
1907
1908 /* DTAP - Routing Area Update Complete */
1909 static const unsigned char ra_upd_complete[] = {
1910 0x08, 0x0a
1911 };
1912
1913 /* DTAP - Detach Request (MO) */
1914 /* normal detach, power_off = 1 */
1915 static const unsigned char detach_req[] = {
1916 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1917 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1918 };
1919
1920 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1921
1922 printf("Testing routing area changes\n");
1923
1924 /* reset the PRNG used by sgsn_alloc_ptmsi */
1925 srand(1);
1926
1927 ptmsi1 = GSM_RESERVED_TMSI;
1928
1929 printf(" - Attach Request (RA 1)\n");
1930
1931 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1932
1933 /* Create a LLE/LLME */
1934 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1935 lle = gprs_lle_get_or_create(ms_tlli, 3);
1936 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1937
1938 /* inject the attach request */
1939 send_0408_message(lle->llme, ms_tlli, &raid1,
1940 attach_req, ARRAY_SIZE(attach_req));
1941
1942 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1943 OSMO_ASSERT(ctx != NULL);
1944 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1945 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1946
1947 /* we expect an identity request (IMEI) */
1948 OSMO_ASSERT(sgsn_tx_counter == 1);
1949 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1950 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1951
1952 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001953 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001954 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1955
1956 /* check that the MM context has not been removed due to a failed
1957 * authorization */
1958 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1959
1960 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1961
1962 /* we expect an attach accept */
1963 OSMO_ASSERT(sgsn_tx_counter == 1);
1964 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1965 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1966
1967 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1968 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1969 ptmsi1 = received_ptmsi;
1970
1971 /* inject the attach complete */
1972 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001973 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001974 attach_compl, ARRAY_SIZE(attach_compl));
1975
1976 /* we don't expect a response */
1977 OSMO_ASSERT(sgsn_tx_counter == 0);
1978
1979 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1980 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1981 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1982
1983 printf(" - RA Update Request (RA 1 -> RA 1)\n");
1984
1985 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001986 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001987 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
1988
1989 /* we expect an RA update accept */
1990 OSMO_ASSERT(sgsn_tx_counter == 1);
1991 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
1992 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1993
1994 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1995 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1996 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1997 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1998
1999 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2000 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2001 ptmsi1 = received_ptmsi;
2002
2003 /* inject the RA update complete */
2004 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002005 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002006 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2007
2008 /* we don't expect a response */
2009 OSMO_ASSERT(sgsn_tx_counter == 0);
2010
2011 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2012 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2013 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002014 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002015
Jacob Erlbeck13304782016-01-04 18:43:37 +01002016 printf(" - RA Update Request (RA 1 -> RA 2)\n");
2017
2018 /* inject the RA update request */
2019 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2020
2021 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002022 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002023 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2024
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002025 /* we expect an RA update accept */
Jacob Erlbeck13304782016-01-04 18:43:37 +01002026 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002027 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002028
2029 printf(" - RA Update Request (RA other -> RA 2)\n");
2030
2031 /* inject the RA update request */
2032 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2033
2034 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002035 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002036 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2037
2038 /* we expect an RA update reject (and a LLC XID RESET) */
2039 OSMO_ASSERT(sgsn_tx_counter == 2);
2040 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2041 /* this has killed the LLE/LLME */
2042
2043 printf(" - Attach Request (RA 2)\n");
2044
2045 /* Create a LLE/LLME */
2046 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2047 lle = gprs_lle_get_or_create(ms_tlli, 3);
2048 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2049
2050 /* inject the attach request */
2051 send_0408_message(lle->llme, ms_tlli, &raid2,
2052 attach_req2, ARRAY_SIZE(attach_req2));
2053
2054 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2055 OSMO_ASSERT(ctx != NULL);
2056 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2057 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2058
2059 /* we expect an attach accept */
2060 OSMO_ASSERT(sgsn_tx_counter == 1);
2061 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2062
2063 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2064 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2065 ptmsi1 = received_ptmsi;
2066
2067 /* inject the attach complete */
2068 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2069 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2070 OSMO_ASSERT(ictx != NULL);
2071 OSMO_ASSERT(ictx == ctx);
2072
Harald Weltef97ee042015-12-25 19:12:21 +01002073 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002074 attach_compl, ARRAY_SIZE(attach_compl));
2075
2076 /* we don't expect a response */
2077 OSMO_ASSERT(sgsn_tx_counter == 0);
2078
2079 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2080 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2081 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2082
2083 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2084
2085 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01002086 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002087 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2088
2089 /* we expect an RA update accept */
2090 OSMO_ASSERT(sgsn_tx_counter == 1);
2091 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2092
2093 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2094 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2095 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2096 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2097
2098 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2099 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2100 ptmsi1 = received_ptmsi;
2101
2102 /* inject the RA update complete */
2103 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
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_complete, ARRAY_SIZE(ra_upd_complete));
2106
2107 /* we don't expect a response */
2108 OSMO_ASSERT(sgsn_tx_counter == 0);
2109
2110 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2111 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2112 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002113 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002114
2115
2116 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01002117 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002118 detach_req, ARRAY_SIZE(detach_req));
2119
2120 /* verify that things are gone */
2121 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2122 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2123 OSMO_ASSERT(!ictx);
2124
2125 sgsn->cfg.auth_policy = saved_auth_policy;
2126
2127 cleanup_test();
2128}
2129
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002130static void test_apn_matching(void)
2131{
2132 struct apn_ctx *actx, *actxs[9];
2133
2134 printf("Testing APN matching\n");
2135
2136 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2137 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2138 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2139 actxs[3] = NULL;
2140
2141 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2142 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2143 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2144 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2145
2146 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2147
2148 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2149 OSMO_ASSERT(actx == actxs[2]);
2150 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2151 OSMO_ASSERT(actx == actxs[2]);
2152 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2153 OSMO_ASSERT(actx == actxs[1]);
2154 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2155 OSMO_ASSERT(actx == actxs[1]);
2156 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2157 OSMO_ASSERT(actx == actxs[0]);
2158 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2159 OSMO_ASSERT(actx == NULL);
2160
2161 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2162 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2163 OSMO_ASSERT(actx == actxs[3]);
2164
2165 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2166 OSMO_ASSERT(actx == actxs[4]);
2167
2168 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2169 OSMO_ASSERT(actx == actxs[6]);
2170
2171 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2172 OSMO_ASSERT(actx == actxs[5]);
2173
2174 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2175 OSMO_ASSERT(actx == actxs[7]);
2176
2177 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2178 OSMO_ASSERT(actx == actxs[8]);
2179
2180 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2181 OSMO_ASSERT(actx == actxs[7]);
2182
2183 /* Free APN contexts and check how the matching changes */
2184
2185 sgsn_apn_ctx_free(actxs[7]);
2186 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2187 OSMO_ASSERT(actx == actxs[8]);
2188
2189 sgsn_apn_ctx_free(actxs[8]);
2190 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2191 OSMO_ASSERT(actx == actxs[6]);
2192
2193 sgsn_apn_ctx_free(actxs[6]);
2194 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2195 OSMO_ASSERT(actx == actxs[1]);
2196
2197 sgsn_apn_ctx_free(actxs[5]);
2198 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2199 OSMO_ASSERT(actx == actxs[4]);
2200
2201 sgsn_apn_ctx_free(actxs[4]);
2202 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2203 OSMO_ASSERT(actx == actxs[2]);
2204
2205 sgsn_apn_ctx_free(actxs[2]);
2206 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2207 OSMO_ASSERT(actx == actxs[1]);
2208
2209 sgsn_apn_ctx_free(actxs[1]);
2210 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2211 OSMO_ASSERT(actx == actxs[0]);
2212
2213 sgsn_apn_ctx_free(actxs[0]);
2214 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2215 OSMO_ASSERT(actx == actxs[3]);
2216
2217 sgsn_apn_ctx_free(actxs[3]);
2218 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2219 OSMO_ASSERT(actx == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002220
2221 cleanup_test();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002222}
2223
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002224struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2225 struct sgsn_subscriber_data *sdata);
2226
2227static void test_ggsn_selection(void)
2228{
2229 struct apn_ctx *actxs[4];
2230 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
2231 struct gsm_subscriber *s1;
2232 const char *imsi1 = "1234567890";
2233 struct sgsn_mm_ctx *ctx;
2234 struct gprs_ra_id raid = { 0, };
2235 uint32_t local_tlli = 0xffeeddcc;
2236 enum gsm48_gsm_cause gsm_cause;
2237 struct tlv_parsed tp;
2238 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2239 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002240 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002241
2242 printf("Testing GGSN selection\n");
2243
2244 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
2245
2246 /* Check for emptiness */
2247 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2248
2249 /* Create a context */
2250 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2251 ctx = alloc_mm_ctx(local_tlli, &raid);
2252 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
2253
2254 /* Allocate and attach a subscriber */
2255 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2256 assert_subscr(s1, imsi1);
2257
2258 tp.lv[GSM48_IE_GSM_APN].len = 0;
2259 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2260
2261 /* TODO: Add PDP info entries to s1 */
2262
2263 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2264 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2265 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2266
2267 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2268 actxs[0]->ggsn = ggcs[0];
2269 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2270 actxs[1]->ggsn = ggcs[1];
2271 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2272 actxs[2]->ggsn = ggcs[2];
2273
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002274 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2275 pdp_data->context_id = 1;
2276 pdp_data->pdp_type = 0x0121;
2277 strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
2278
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002279 /* Resolve GGSNs */
2280
2281 tp.lv[GSM48_IE_GSM_APN].len =
2282 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2283
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002284 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002285 OSMO_ASSERT(ggc != NULL);
2286 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002287 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002288
2289 tp.lv[GSM48_IE_GSM_APN].len =
2290 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2291
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002292 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002293 OSMO_ASSERT(ggc != NULL);
2294 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002295 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002296
2297 tp.lv[GSM48_IE_GSM_APN].len = 0;
2298 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2299
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002300 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002301 OSMO_ASSERT(ggc != NULL);
2302 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002303 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002304
2305 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2306 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002307 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002308 OSMO_ASSERT(ggc != NULL);
2309 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002310 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002311
2312 sgsn_apn_ctx_free(actxs[3]);
2313 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2314
2315 tp.lv[GSM48_IE_GSM_APN].len =
2316 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
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(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002321 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002322
2323 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002324 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002325 OSMO_ASSERT(ggc == NULL);
2326 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2327
2328 /* Add PDP data entry to subscriber */
2329
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002330 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
2331
2332 tp.lv[GSM48_IE_GSM_APN].len =
2333 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2334
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002335 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002336 OSMO_ASSERT(ggc != NULL);
2337 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002338 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002339
2340 tp.lv[GSM48_IE_GSM_APN].len =
2341 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2342
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002343 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002344 OSMO_ASSERT(ggc == NULL);
2345 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002346 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002347
2348 /* Cleanup */
2349
2350 subscr_put(s1);
2351 sgsn_mm_ctx_cleanup_free(ctx);
2352
2353 assert_no_subscrs();
2354
2355 sgsn_apn_ctx_free(actxs[0]);
2356 sgsn_apn_ctx_free(actxs[1]);
2357 sgsn_apn_ctx_free(actxs[2]);
2358
2359 sgsn_ggsn_ctx_free(ggcs[0]);
2360 sgsn_ggsn_ctx_free(ggcs[1]);
2361 sgsn_ggsn_ctx_free(ggcs[2]);
2362
2363 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002364
2365 cleanup_test();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002366}
2367
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002368static struct log_info_cat gprs_categories[] = {
2369 [DMM] = {
2370 .name = "DMM",
2371 .description = "Layer3 Mobility Management (MM)",
2372 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002373 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002374 },
2375 [DPAG] = {
2376 .name = "DPAG",
2377 .description = "Paging Subsystem",
2378 .color = "\033[1;38m",
2379 .enabled = 1, .loglevel = LOGL_NOTICE,
2380 },
2381 [DMEAS] = {
2382 .name = "DMEAS",
2383 .description = "Radio Measurement Processing",
2384 .enabled = 0, .loglevel = LOGL_NOTICE,
2385 },
2386 [DREF] = {
2387 .name = "DREF",
2388 .description = "Reference Counting",
2389 .enabled = 0, .loglevel = LOGL_NOTICE,
2390 },
2391 [DGPRS] = {
2392 .name = "DGPRS",
2393 .description = "GPRS Packet Service",
2394 .enabled = 1, .loglevel = LOGL_DEBUG,
2395 },
2396 [DNS] = {
2397 .name = "DNS",
2398 .description = "GPRS Network Service (NS)",
2399 .enabled = 1, .loglevel = LOGL_INFO,
2400 },
2401 [DBSSGP] = {
2402 .name = "DBSSGP",
2403 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2404 .enabled = 1, .loglevel = LOGL_DEBUG,
2405 },
2406 [DLLC] = {
2407 .name = "DLLC",
2408 .description = "GPRS Logical Link Control Protocol (LLC)",
2409 .enabled = 1, .loglevel = LOGL_DEBUG,
2410 },
2411 [DSNDCP] = {
2412 .name = "DSNDCP",
2413 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2414 .enabled = 1, .loglevel = LOGL_DEBUG,
2415 },
2416};
2417
2418static struct log_info info = {
2419 .cat = gprs_categories,
2420 .num_cat = ARRAY_SIZE(gprs_categories),
2421};
2422
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002423int main(int argc, char **argv)
2424{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002425 void *osmo_sgsn_ctx;
2426
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002427 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002428 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2429 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
2430 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002431
Alexander Couzens14314bd2016-07-05 09:52:52 +02002432 sgsn_rate_ctr_init();
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01002433 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002434 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002435
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002436 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002437 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002438 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002439 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002440 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002441 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002442 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002443 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002444 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002445 test_gmm_attach_acl();
2446 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002447 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002448 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002449 test_gmm_attach_subscr_gsup_auth(0);
2450 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002451 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002452 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002453 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002454 test_gmm_ptmsi_allocation();
Jacob Erlbeck13304782016-01-04 18:43:37 +01002455 test_gmm_routing_areas();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002456 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002457 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002458 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002459
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002460 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01002461 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Alexander Couzens14314bd2016-07-05 09:52:52 +02002462 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 2);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002463 return 0;
2464}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002465
2466
2467/* stubs */
2468struct osmo_prim_hdr;
2469int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2470{
2471 abort();
2472}