blob: e1fd2e713644044de1c79db45177cf1e3d18c051 [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>
Neels Hofmeyreaaee922016-12-08 21:22:58 +010028#include <openbsc/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>
Neels Hofmeyr59504dc2017-01-13 03:10:54 +010039#include <osmocom/core/utils.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020040
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020041#include <stdio.h>
42
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020043void *tall_bsc_ctx;
44static struct sgsn_instance sgsn_inst = {
45 .config_file = "osmo_sgsn.cfg",
46 .cfg = {
47 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010048 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020049 },
50};
51struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010052unsigned sgsn_tx_counter = 0;
Jacob Erlbeck133e8622015-10-12 19:36:32 +020053struct msgb *last_msg = NULL;
54struct gprs_gb_parse_context last_dl_parse_ctx;
55
56static void reset_last_msg()
57{
58 if (last_msg)
59 msgb_free(last_msg);
60
61 last_msg = NULL;
62 memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx));
63}
Jacob Erlbeck189999d2014-10-27 14:34:13 +010064
Jacob Erlbeckcf151872015-10-12 19:36:31 +020065static void cleanup_test()
66{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020067 reset_last_msg();
68}
69
70static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
71{
72 uint32_t new_ptmsi = GSM_RESERVED_TMSI;
73
74 if (parse_ctx->new_ptmsi_enc)
75 gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
76
77 return new_ptmsi;
Jacob Erlbeckcf151872015-10-12 19:36:31 +020078}
79
Jacob Erlbeck189999d2014-10-27 14:34:13 +010080/* override */
81int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
82 struct bssgp_dl_ud_par *dup)
83{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020084 int rc;
85
86 reset_last_msg();
87
88 last_msg = msg;
89 OSMO_ASSERT(msgb_data(last_msg) != NULL);
90
91 rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg),
92 &last_dl_parse_ctx);
93
94 fprintf(stderr, "Got DL LLC message: %s\n",
95 gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN"));
96
97 OSMO_ASSERT(rc > 0);
98
Jacob Erlbeck189999d2014-10-27 14:34:13 +010099 sgsn_tx_counter += 1;
100 return 0;
101}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200102
Max4011e722016-07-05 15:19:12 +0200103/* override, requires '-Wl,--wrap=RAND_bytes' */
104int __real_RAND_bytes(unsigned char *buf, int num);
105int mock_RAND_bytes(unsigned char *buf, int num);
106int (*RAND_bytes_cb)(unsigned char *, int) =
107 &mock_RAND_bytes;
108
109int __wrap_RAND_bytes(unsigned char *buf, int num)
110{
111 return (*RAND_bytes_cb)(buf, num);
112}
113/* make results of A&C ref predictable */
114int mock_RAND_bytes(unsigned char *buf, int num)
115{
116 if (num > 1)
117 return __real_RAND_bytes(buf, num);
118 buf[0] = 0;
119 return 1;
120}
121
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100122/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100123void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
124void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100125 &__real_sgsn_update_subscriber_data;
126
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100127void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100128{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100129 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100130}
131
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100132/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
133int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
134int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
135 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100136
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100137int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
138 return (*subscr_request_update_location_cb)(mmctx);
139};
140
141/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
142int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
143int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
144 &__real_gprs_subscr_request_auth_info;
145
146int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
147 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100148};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100149
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100150/* override, requires '-Wl,--wrap=gsup_client_send' */
151int __real_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg);
152int (*gsup_client_send_cb)(struct gsup_client *gsupc, struct msgb *msg) =
153 &__real_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100154
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100155int __wrap_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100156{
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100157 return (*gsup_client_send_cb)(gsupc, msg);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100158};
159
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200160static int count(struct llist_head *head)
161{
162 struct llist_head *cur;
163 int count = 0;
164
165 llist_for_each(cur, head)
166 count += 1;
167
168 return count;
169}
170
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200171static struct msgb *create_msg(const uint8_t *data, size_t len)
172{
173 struct msgb *msg = msgb_alloc(len + 8, "test message");
174 msg->l1h = msgb_put(msg, 8);
175 msg->l2h = msgb_put(msg, len);
176 memcpy(msg->l2h, data, len);
177
178 msgb_bcid(msg) = msg->l1h;
179 msgb_gmmh(msg) = msg->l2h;
180 return msg;
181}
182
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100183/*
184 * Create a context and search for it
185 */
186static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
187{
188 struct sgsn_mm_ctx *ctx, *ictx;
189 struct gprs_llc_lle *lle;
190 int old_count = count(gprs_llme_list());
191
192 lle = gprs_lle_get_or_create(tlli, 3);
193 ctx = sgsn_mm_ctx_alloc(tlli, raid);
194 ctx->mm_state = GMM_REGISTERED_NORMAL;
Harald Weltef97ee042015-12-25 19:12:21 +0100195 ctx->gb.llme = lle->llme;
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100196
197 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
198 OSMO_ASSERT(ictx == ctx);
199
200 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
201
202 return ctx;
203}
204
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100205static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck91580892016-01-04 18:43:33 +0100206 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100207 const uint8_t *data, size_t data_len)
208{
209 struct msgb *msg;
210
Jacob Erlbeck133e8622015-10-12 19:36:32 +0200211 reset_last_msg();
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100212 sgsn_tx_counter = 0;
213
214 msg = create_msg(data, data_len);
215 msgb_tlli(msg) = tlli;
Jacob Erlbeck91580892016-01-04 18:43:33 +0100216 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Max82040102016-07-06 11:59:18 +0200217 gsm0408_gprs_rcvmsg_gb(msg, llme, false);
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100218 msgb_free(msg);
219}
220
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200221static void test_llme(void)
222{
223 struct gprs_llc_lle *lle, *lle_copy;
224 uint32_t local_tlli;
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200225
226 printf("Testing LLME allocations\n");
227 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200228
229 /* initial state */
230 OSMO_ASSERT(count(gprs_llme_list()) == 0);
231
232 /* Create a new entry */
233 lle = gprs_lle_get_or_create(local_tlli, 3);
234 OSMO_ASSERT(lle);
235 OSMO_ASSERT(count(gprs_llme_list()) == 1);
236
237 /* No new entry is created */
238 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
239 OSMO_ASSERT(lle == lle_copy);
240 OSMO_ASSERT(count(gprs_llme_list()) == 1);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200241
242 /* unassign which should delete it*/
Max39550252016-06-28 17:39:20 +0200243 gprs_llgmm_unassign(lle->llme);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200244
245 /* Check that everything was cleaned up */
246 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200247
248 cleanup_test();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200249}
250
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100251struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100252void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100253{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100254 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100255 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100256 __func__, mmctx, mmctx->subscr);
257 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100258}
259
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100260static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
261{
262 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100263 OSMO_ASSERT(subscr);
264 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100265
266 sfound = gprs_subscr_get_by_imsi(imsi);
267 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100268
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100269 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100270}
271
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100272static void show_subscrs(FILE *out)
273{
274 struct gsm_subscriber *subscr;
275
276 llist_for_each_entry(subscr, &active_subscribers, entry) {
277 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100278 "use count: %d\n",
279 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100280 }
281}
282
283static void assert_no_subscrs()
284{
285 show_subscrs(stdout);
286 fflush(stdout);
287 OSMO_ASSERT(llist_empty(&active_subscribers));
288}
289
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100290static void test_subscriber(void)
291{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100292 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100293 const char *imsi1 = "1234567890";
294 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100295 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100296
297 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
298
299 printf("Testing core subscriber data API\n");
300
301 /* Check for emptiness */
302 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
303 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100304 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100305
306 /* Allocate entry 1 */
307 s1 = gprs_subscr_get_or_create(imsi1);
308 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100309 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100310 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100311
312 /* Allocate entry 2 */
313 s2 = gprs_subscr_get_or_create(imsi2);
314 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100315
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100316 /* Allocate entry 3 */
317 s3 = gprs_subscr_get_or_create(imsi3);
318
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100319 /* Check entries */
320 assert_subscr(s1, imsi1);
321 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100322 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100323
324 /* Update entry 1 */
325 last_updated_subscr = NULL;
326 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100327 OSMO_ASSERT(last_updated_subscr == NULL);
328 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
329 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100330
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100331 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100332 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100333 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100334 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100335 sfound = gprs_subscr_get_by_imsi(imsi1);
336 OSMO_ASSERT(sfound == NULL);
337
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100338 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100339 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100340
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100341 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100342 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100343 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100344 s2 = NULL;
345 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
346 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100347 assert_subscr(s3, imsi3);
348
349 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100350 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100351 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100352 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100353 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100354
355 OSMO_ASSERT(llist_empty(&active_subscribers));
356
357 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200358
359 cleanup_test();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100360}
361
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100362static void test_auth_triplets(void)
363{
364 struct gsm_subscriber *s1, *s1found;
365 const char *imsi1 = "1234567890";
366 struct gsm_auth_tuple *at;
367 struct sgsn_mm_ctx *ctx;
368 struct gprs_ra_id raid = { 0, };
369 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100370
371 printf("Testing authentication triplet handling\n");
372
373 /* Check for emptiness */
374 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
375
376 /* Allocate entry 1 */
377 s1 = gprs_subscr_get_or_create(imsi1);
378 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
379 s1found = gprs_subscr_get_by_imsi(imsi1);
380 OSMO_ASSERT(s1found == s1);
381 subscr_put(s1found);
382
383 /* Create a context */
384 OSMO_ASSERT(count(gprs_llme_list()) == 0);
385 ctx = alloc_mm_ctx(local_tlli, &raid);
386
387 /* Attach s1 to ctx */
388 ctx->subscr = subscr_get(s1);
389 ctx->subscr->sgsn_data->mm = ctx;
390
391 /* Try to get auth tuple */
392 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
393 OSMO_ASSERT(at == NULL);
394
395 /* Add triplets */
396 s1->sgsn_data->auth_triplets[0].key_seq = 0;
397 s1->sgsn_data->auth_triplets[1].key_seq = 1;
398 s1->sgsn_data->auth_triplets[2].key_seq = 2;
399
400 /* Try to get auth tuple */
401 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
402 OSMO_ASSERT(at != NULL);
403 OSMO_ASSERT(at->key_seq == 0);
404 OSMO_ASSERT(at->use_count == 1);
405 at = sgsn_auth_get_tuple(ctx, at->key_seq);
406 OSMO_ASSERT(at != NULL);
407 OSMO_ASSERT(at->key_seq == 1);
408 OSMO_ASSERT(at->use_count == 1);
409 at = sgsn_auth_get_tuple(ctx, at->key_seq);
410 OSMO_ASSERT(at != NULL);
411 OSMO_ASSERT(at->key_seq == 2);
412 OSMO_ASSERT(at->use_count == 1);
413 at = sgsn_auth_get_tuple(ctx, at->key_seq);
414 OSMO_ASSERT(at == NULL);
415
416 /* Free MM context and subscriber */
417 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100418 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100419 s1found = gprs_subscr_get_by_imsi(imsi1);
420 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200421
422 cleanup_test();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100423}
424
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100425#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
426
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100427static int rx_gsup_message(const uint8_t *data, size_t data_len)
428{
429 struct msgb *msg;
430 int rc;
431
432 msg = msgb_alloc(1024, __func__);
433 msg->l2h = msgb_put(msg, data_len);
434 OSMO_ASSERT(msg->l2h != NULL);
435 memcpy(msg->l2h, data, data_len);
436 rc = gprs_subscr_rx_gsup_message(msg);
437 msgb_free(msg);
438
439 return rc;
440}
441
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100442static void test_subscriber_gsup(void)
443{
444 struct gsm_subscriber *s1, *s1found;
445 const char *imsi1 = "1234567890";
446 struct sgsn_mm_ctx *ctx;
447 struct gprs_ra_id raid = { 0, };
448 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100449 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100450 int rc;
451
452 static const uint8_t send_auth_info_res[] = {
453 0x0a,
454 TEST_GSUP_IMSI1_IE,
455 0x03, 0x22, /* Auth tuple */
456 0x20, 0x10,
457 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
458 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
459 0x21, 0x04,
460 0x21, 0x22, 0x23, 0x24,
461 0x22, 0x08,
462 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
463 0x03, 0x22, /* Auth tuple */
464 0x20, 0x10,
465 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
466 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
467 0x21, 0x04,
468 0xa1, 0xa2, 0xa3, 0xa4,
469 0x22, 0x08,
470 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
471 };
472
473 static const uint8_t send_auth_info_err[] = {
474 0x09,
475 TEST_GSUP_IMSI1_IE,
476 0x02, 0x01, 0x07 /* GPRS not allowed */
477 };
478
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400479#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
480
481 static const uint8_t s1_msisdn[] = { MSISDN };
482
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100483 static const uint8_t update_location_res[] = {
484 0x06,
485 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400486 0x08, 0x09, MSISDN,
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100487 0x04, 0x00, /* PDP info complete */
488 0x05, 0x12,
489 0x10, 0x01, 0x01,
490 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
491 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
492 0x05, 0x11,
493 0x10, 0x01, 0x02,
494 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
495 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
496 };
497
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400498#undef MSISDN
499
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100500 static const uint8_t update_location_err[] = {
501 0x05,
502 TEST_GSUP_IMSI1_IE,
503 0x02, 0x01, 0x07 /* GPRS not allowed */
504 };
505
506 static const uint8_t location_cancellation_req[] = {
507 0x1c,
508 TEST_GSUP_IMSI1_IE,
509 0x06, 0x01, 0x00,
510 };
511
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200512 static const uint8_t location_cancellation_req_withdraw[] = {
513 0x1c,
514 TEST_GSUP_IMSI1_IE,
515 0x06, 0x01, 0x01,
516 };
517
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100518 static const uint8_t location_cancellation_req_other[] = {
519 0x1c,
520 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
521 0x06, 0x01, 0x00,
522 };
523
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100524 static const uint8_t purge_ms_err[] = {
525 0x0d,
526 TEST_GSUP_IMSI1_IE,
527 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
528 };
529
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100530 static const uint8_t purge_ms_err_no_cause[] = {
531 0x0d,
532 TEST_GSUP_IMSI1_IE,
533 };
534
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100535 static const uint8_t purge_ms_res[] = {
536 0x0e,
537 TEST_GSUP_IMSI1_IE,
538 0x07, 0x00,
539 };
540
541
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100542 static const uint8_t insert_data_req[] = {
543 0x10,
544 TEST_GSUP_IMSI1_IE,
545 0x05, 0x11,
546 0x10, 0x01, 0x03,
547 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
548 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
549 };
550
551 static const uint8_t delete_data_req[] = {
552 0x14,
553 TEST_GSUP_IMSI1_IE,
554 0x10, 0x01, 0x03,
555 };
556
Neels Hofmeyr241bda02016-06-20 18:26:15 +0200557 printf("Testing subscriber GSUP handling\n");
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100558
559 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
560
561 /* Check for emptiness */
562 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
563
564 /* Allocate entry 1 */
565 s1 = gprs_subscr_get_or_create(imsi1);
566 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
567 s1found = gprs_subscr_get_by_imsi(imsi1);
568 OSMO_ASSERT(s1found == s1);
569 subscr_put(s1found);
570
571 /* Create a context */
572 OSMO_ASSERT(count(gprs_llme_list()) == 0);
573 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100574
575 /* Attach s1 to ctx */
576 ctx->subscr = subscr_get(s1);
577 ctx->subscr->sgsn_data->mm = ctx;
578
579 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100580 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100581 OSMO_ASSERT(rc >= 0);
582 OSMO_ASSERT(last_updated_subscr == s1);
583
584 /* Check triplets */
585 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
586 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
587 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
588
589 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100590 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100591 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100592 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100593 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100594
595 /* Check triplets */
596 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
597 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
598 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
599
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100600 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100601 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100602 OSMO_ASSERT(rc >= 0);
603 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100604 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100605 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400606 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
607 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100608 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
609 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
610 struct sgsn_subscriber_pdp_data, list);
611 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
612 pdpd = llist_entry(pdpd->list.next,
613 struct sgsn_subscriber_pdp_data, list);
614 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100615
616 /* Check authorization */
617 OSMO_ASSERT(s1->authorized == 1);
618
619 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100620 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100621 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100622 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100623 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100624
625 /* Check authorization */
626 OSMO_ASSERT(s1->authorized == 0);
627
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100628 /* Inject InsertSubscrData GSUP message */
629 last_updated_subscr = NULL;
630 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Harald Weltec346f872016-11-26 14:58:36 +0100631 OSMO_ASSERT(rc == -ENOTSUP); /* not connected */
Harald Weltecd5e5262016-05-06 13:46:21 +0200632 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100633
634 /* Inject DeleteSubscrData GSUP message */
635 last_updated_subscr = NULL;
636 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
637 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
638 OSMO_ASSERT(last_updated_subscr == NULL);
639
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100640 /* Inject wrong LocCancelReq GSUP message */
641 last_updated_subscr = NULL;
642 rc = rx_gsup_message(location_cancellation_req_other,
643 sizeof(location_cancellation_req_other));
644 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
645 OSMO_ASSERT(last_updated_subscr == NULL);
646
647 /* Check cancellation result */
648 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
649 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
650
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100651 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100652 rc = rx_gsup_message(location_cancellation_req,
653 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100654 OSMO_ASSERT(rc >= 0);
655 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100656 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100657
658 /* Check cancellation result */
659 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
660 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
661
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200662 /* Inject LocCancelReq(withdraw) GSUP message */
663 rc = rx_gsup_message(location_cancellation_req_withdraw,
664 sizeof(location_cancellation_req_withdraw));
665 OSMO_ASSERT(rc >= 0);
666 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
667
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100668 /* Inject PurgeMsRes GSUP message */
669 rc = rx_gsup_message(purge_ms_res,
670 sizeof(purge_ms_res));
671 OSMO_ASSERT(rc >= 0);
672 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
673
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100674 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100675 OSMO_ASSERT(ctx->subscr == NULL);
676 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100677 subscr_put(s1);
678 s1found = gprs_subscr_get_by_imsi(imsi1);
679 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100680
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100681 /* Inject PurgeMsRes GSUP message */
682 rc = rx_gsup_message(purge_ms_res,
683 sizeof(purge_ms_res));
684 OSMO_ASSERT(rc >= 0);
685
686 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
687 rc = rx_gsup_message(purge_ms_err,
688 sizeof(purge_ms_err));
689 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
690
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100691 /* Inject PurgeMsErr() GSUP message */
692 rc = rx_gsup_message(purge_ms_err_no_cause,
693 sizeof(purge_ms_err_no_cause));
694 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
695
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100696 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
697 last_updated_subscr = NULL;
698 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100699 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100700 OSMO_ASSERT(last_updated_subscr == NULL);
701
702 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
703 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
704 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
705 OSMO_ASSERT(last_updated_subscr == NULL);
706
707 /* Inject LocCancelReq GSUP message (unknown IMSI) */
708 rc = rx_gsup_message(location_cancellation_req,
709 sizeof(location_cancellation_req));
710 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
711 OSMO_ASSERT(last_updated_subscr == NULL);
712
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100713 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200714
715 cleanup_test();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100716}
717
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100718int my_gsup_client_send_dummy(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100719{
720 msgb_free(msg);
721 return 0;
722};
723
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200724/*
725 * Test that a GMM Detach will remove the MMCTX and the
726 * associated LLME.
727 */
728static void test_gmm_detach(void)
729{
730 struct gprs_ra_id raid = { 0, };
731 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200732 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200733
734 printf("Testing GMM detach\n");
735
736 /* DTAP - Detach Request (MO) */
737 /* normal detach, power_off = 0 */
738 static const unsigned char detach_req[] = {
739 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
740 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
741 };
742
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200743 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200744
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100745 /* Create a context */
746 OSMO_ASSERT(count(gprs_llme_list()) == 0);
747 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200748
749 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +0100750 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100751 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200752
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100753 /* verify that a single message (hopefully the Detach Accept) has been
754 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100755 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100756
757 /* verify that things are gone */
758 OSMO_ASSERT(count(gprs_llme_list()) == 0);
759 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
760 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200761
762 cleanup_test();
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100763}
764
765/*
766 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
767 * will not sent a Detach Accept message (power_off = 1)
768 */
769static void test_gmm_detach_power_off(void)
770{
771 struct gprs_ra_id raid = { 0, };
772 struct sgsn_mm_ctx *ctx, *ictx;
773 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100774
775 printf("Testing GMM detach (power off)\n");
776
777 /* DTAP - Detach Request (MO) */
778 /* normal detach, power_off = 1 */
779 static const unsigned char detach_req[] = {
780 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
781 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
782 };
783
784 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
785
786 /* Create a context */
787 OSMO_ASSERT(count(gprs_llme_list()) == 0);
788 ctx = alloc_mm_ctx(local_tlli, &raid);
789
790 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +0100791 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100792 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100793
794 /* verify that no message (and therefore no Detach Accept) has been
795 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100796 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100797
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200798 /* verify that things are gone */
799 OSMO_ASSERT(count(gprs_llme_list()) == 0);
800 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200801 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200802
803 cleanup_test();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200804}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200805
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200806/*
807 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
808 */
809static void test_gmm_detach_no_mmctx(void)
810{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100811 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200812 struct gprs_llc_lle *lle;
813 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200814
815 printf("Testing GMM detach (no MMCTX)\n");
816
817 /* DTAP - Detach Request (MO) */
818 /* normal detach, power_off = 0 */
819 static const unsigned char detach_req[] = {
820 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
821 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
822 };
823
824 /* Create an LLME */
825 OSMO_ASSERT(count(gprs_llme_list()) == 0);
826 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
827 lle = gprs_lle_get_or_create(local_tlli, 3);
828
829 OSMO_ASSERT(count(gprs_llme_list()) == 1);
830
831 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100832 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100833 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200834
835 /* verify that the LLME is gone */
836 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200837
838 cleanup_test();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200839}
840
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100841/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100842 * Test that a single GMM Detach Accept message will not cause the SGSN to send
843 * any message or leave an MM context at the SGSN.
844 */
845static void test_gmm_detach_accept_unexpected(void)
846{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100847 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100848 struct gprs_llc_lle *lle;
849 uint32_t local_tlli;
850
851 printf("Testing GMM detach accept (unexpected)\n");
852
853 /* DTAP - Detach Accept (MT) */
854 /* normal detach */
855 static const unsigned char detach_acc[] = {
856 0x08, 0x06
857 };
858
859 /* Create an LLME */
860 OSMO_ASSERT(count(gprs_llme_list()) == 0);
861 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
862 lle = gprs_lle_get_or_create(local_tlli, 3);
863
864 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100865 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100866 detach_acc, ARRAY_SIZE(detach_acc));
867
868 /* verify that no message (and therefore no Status or XID reset) has been
869 * sent by the SGSN */
870 OSMO_ASSERT(sgsn_tx_counter == 0);
871
872 /* verify that things are gone */
873 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200874
875 cleanup_test();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100876}
877
878/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100879 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
880 */
881static void test_gmm_status_no_mmctx(void)
882{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100883 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100884 struct gprs_llc_lle *lle;
885 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100886
887 printf("Testing GMM Status (no MMCTX)\n");
888
889 /* DTAP - GMM Status, protocol error */
890 static const unsigned char gmm_status[] = {
891 0x08, 0x20, 0x6f
892 };
893
894 /* Create an LLME */
895 OSMO_ASSERT(count(gprs_llme_list()) == 0);
896 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
897 lle = gprs_lle_get_or_create(local_tlli, 3);
898
899 OSMO_ASSERT(count(gprs_llme_list()) == 1);
900
901 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100902 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100903 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100904
905 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100906 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100907
908 /* verify that the LLME is gone */
909 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200910
911 cleanup_test();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100912}
913
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100914/*
915 * Test the GMM Attach procedure
916 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100917static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100918{
919 struct gprs_ra_id raid = { 0, };
920 struct sgsn_mm_ctx *ctx = NULL;
921 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100922 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100923 uint32_t foreign_tlli;
924 uint32_t local_tlli = 0;
925 struct gprs_llc_lle *lle;
926
927 /* DTAP - Attach Request */
928 /* The P-TMSI is not known by the SGSN */
929 static const unsigned char attach_req[] = {
930 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
931 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
932 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
933 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
934 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
935 };
936
937 /* DTAP - Identity Response IMEI */
938 static const unsigned char ident_resp_imei[] = {
939 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
940 0x56
941 };
942
943 /* DTAP - Identity Response IMSI */
944 static const unsigned char ident_resp_imsi[] = {
945 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
946 0x54
947 };
948
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100949 /* DTAP - Authentication and Ciphering Resp */
950 static const unsigned char auth_ciph_resp[] = {
951 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
952 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
953 };
954
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100955 /* DTAP - Attach Complete */
956 static const unsigned char attach_compl[] = {
957 0x08, 0x03
958 };
959
960 /* DTAP - Detach Request (MO) */
961 /* normal detach, power_off = 0 */
962 static const unsigned char detach_req[] = {
963 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
964 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
965 };
966
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100967 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100968
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100969 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
970
971 /* Create a LLE/LLME */
972 OSMO_ASSERT(count(gprs_llme_list()) == 0);
973 lle = gprs_lle_get_or_create(foreign_tlli, 3);
974 OSMO_ASSERT(count(gprs_llme_list()) == 1);
975
976 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100977 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100978 attach_req, ARRAY_SIZE(attach_req));
979
980 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
981 OSMO_ASSERT(ctx != NULL);
982 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
983
984 /* we expect an identity request (IMEI) */
985 OSMO_ASSERT(sgsn_tx_counter == 1);
986
987 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +0100988 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100989 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
990
991 /* we expect an identity request (IMSI) */
992 OSMO_ASSERT(sgsn_tx_counter == 1);
993
994 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +0100995 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100996 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
997
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100998 /* check that the MM context has not been removed due to a failed
999 * authorization */
1000 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1001
Jacob Erlbeck0074a772014-10-28 16:23:46 +01001002 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001003
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001004retry_attach_req:
1005
1006 if (retry && sgsn_tx_counter == 0) {
1007 fprintf(stderr, "Retrying attach request\n");
1008 /* re-inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001009 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001010 attach_req, ARRAY_SIZE(attach_req));
1011 }
1012
1013 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
1014 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001015
1016 /* inject the auth & ciph response */
Harald Weltef97ee042015-12-25 19:12:21 +01001017 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001018 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1019
1020 /* check that the MM context has not been removed due to a
1021 * failed authorization */
1022 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001023 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1024 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001025 }
1026
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001027 if (retry && sgsn_tx_counter == 0)
1028 goto retry_attach_req;
1029
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001030 /* we expect an attach accept/reject */
1031 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001032 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1033 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001034
1035 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001036 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001037
1038 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001039 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001040 attach_compl, ARRAY_SIZE(attach_compl));
1041
1042 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1043
1044 /* we don't expect a response */
1045 OSMO_ASSERT(sgsn_tx_counter == 0);
1046
1047 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001048 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001049 detach_req, ARRAY_SIZE(detach_req));
1050
1051 /* verify that things are gone */
1052 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1053 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1054 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001055
1056 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001057}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001058
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001059static void test_gmm_attach_acl(void)
1060{
1061 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1062
1063 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1064 sgsn_acl_add("123456789012345", &sgsn->cfg);
1065 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001066 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001067 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001068
1069 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001070
1071 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001072}
1073
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001074int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001075 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001076 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001077 if (rc == -ENOTSUP) {
1078 OSMO_ASSERT(mmctx->subscr);
1079 gprs_subscr_update(mmctx->subscr);
1080 }
1081 return rc;
1082};
1083
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001084int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1085 gprs_subscr_update(mmctx->subscr);
1086 return 0;
1087};
1088
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001089static void test_gmm_attach_subscr(void)
1090{
1091 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1092 struct gsm_subscriber *subscr;
1093
1094 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001095 subscr_request_update_location_cb = my_subscr_request_update_location;
1096 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001097
1098 subscr = gprs_subscr_get_or_create("123456789012345");
1099 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001100
1101 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001102 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001103 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001104 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001105
1106 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001107 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1108 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001109
1110 cleanup_test();
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001111}
1112
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001113int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1114{
1115 /* Fake an authentication */
1116 OSMO_ASSERT(mmctx->subscr);
1117 mmctx->is_authenticated = 1;
1118 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001119
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001120 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001121};
1122
1123static void test_gmm_attach_subscr_fake_auth(void)
1124{
1125 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1126 struct gsm_subscriber *subscr;
1127
1128 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001129 subscr_request_update_location_cb = my_subscr_request_update_location;
1130 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001131
1132 subscr = gprs_subscr_get_or_create("123456789012345");
1133 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001134 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001135 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001136
1137 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001138 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001139 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001140 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001141
1142 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001143 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1144 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001145
1146 cleanup_test();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001147}
1148
1149int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1150{
1151 struct gsm_auth_tuple at = {
Harald Welte121e9a42016-04-20 13:13:19 +02001152 .vec.sres = {0x51, 0xe5, 0x51, 0xe5},
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001153 .key_seq = 0
1154 };
1155
1156 /* Fake an authentication */
1157 OSMO_ASSERT(mmctx->subscr);
1158 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1159
1160 gprs_subscr_update_auth_info(mmctx->subscr);
1161
1162 return 0;
1163};
1164
1165static void test_gmm_attach_subscr_real_auth(void)
1166{
1167 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1168 struct gsm_subscriber *subscr;
1169
1170 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1171 subscr_request_update_location_cb = my_subscr_request_update_location;
1172 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1173
1174 subscr = gprs_subscr_get_or_create("123456789012345");
1175 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001176 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001177 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001178
1179 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001180
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001181 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001182 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001183 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001184
1185 sgsn->cfg.auth_policy = saved_auth_policy;
1186 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1187 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001188
1189 cleanup_test();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001190}
1191
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001192#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1193 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1194
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001195static int auth_info_skip = 0;
1196static int upd_loc_skip = 0;
1197
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001198int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1199{
1200 static const uint8_t send_auth_info_res[] = {
1201 0x0a,
1202 TEST_GSUP_IMSI_LONG_IE,
1203 0x03, 0x22, /* Auth tuple */
1204 0x20, 0x10,
1205 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1206 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1207 0x21, 0x04,
1208 0x51, 0xe5, 0x51, 0xe5,
1209 0x22, 0x08,
1210 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1211 };
1212
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001213 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001214
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001215 if (auth_info_skip > 0) {
1216 auth_info_skip -= 1;
1217 return -EAGAIN;
1218 }
1219
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001220 /* Fake an SendAuthInfoRes */
1221 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1222
1223 return 0;
1224};
1225
1226int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1227 static const uint8_t update_location_res[] = {
1228 0x06,
1229 TEST_GSUP_IMSI_LONG_IE,
1230 0x04, 0x00, /* PDP info complete */
1231 0x05, 0x12,
1232 0x10, 0x01, 0x01,
1233 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1234 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001235 0x08, 0x07, /* MSISDN 49166213323 encoded */
1236 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freyther10c0f562015-05-17 20:58:40 +02001237 0x09, 0x07, /* MSISDN 38166213323 encoded */
1238 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001239 };
1240
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001241 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001242
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001243 if (upd_loc_skip > 0) {
1244 upd_loc_skip -= 1;
1245 return -EAGAIN;
1246 }
1247
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001248 /* Fake an UpdateLocRes */
1249 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1250};
1251
1252
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001253static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001254{
1255 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1256 struct gsm_subscriber *subscr;
1257
1258 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1259 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1260 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001261 if (retry) {
1262 upd_loc_skip = 3;
1263 auth_info_skip = 3;
1264 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001265
1266 subscr = gprs_subscr_get_or_create("123456789012345");
1267 subscr->authorized = 1;
1268 sgsn->cfg.require_authentication = 1;
1269 sgsn->cfg.require_update_location = 1;
1270 subscr_put(subscr);
1271
1272 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001273 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001274 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001275
1276 sgsn->cfg.auth_policy = saved_auth_policy;
1277 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1278 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001279 upd_loc_skip = 0;
1280 auth_info_skip = 0;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001281
1282 cleanup_test();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001283}
1284
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001285int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001286{
Harald Welte23d77d52016-04-25 19:07:34 +02001287 struct osmo_gsup_message to_peer = {0};
1288 struct osmo_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001289 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001290 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001291
1292 /* Simulate the GSUP peer */
Harald Welte23d77d52016-04-25 19:07:34 +02001293 rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001294 OSMO_ASSERT(rc >= 0);
1295 OSMO_ASSERT(to_peer.imsi[0] != 0);
Neels Hofmeyr59504dc2017-01-13 03:10:54 +01001296 osmo_strlcpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001297
1298 /* This invalidates the pointers in to_peer */
1299 msgb_free(msg);
1300
1301 switch (to_peer.message_type) {
Harald Welte23d77d52016-04-25 19:07:34 +02001302 case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001303 /* Send UPDATE_LOCATION_RESULT */
1304 return my_subscr_request_update_gsup_auth(NULL);
1305
Harald Welte23d77d52016-04-25 19:07:34 +02001306 case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001307 /* Send SEND_AUTH_INFO_RESULT */
1308 return my_subscr_request_auth_info_gsup_auth(NULL);
1309
Harald Welte23d77d52016-04-25 19:07:34 +02001310 case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
1311 from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001312 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001313
1314 default:
1315 if ((to_peer.message_type & 0b00000011) == 0) {
1316 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001317 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001318 from_peer.message_type = to_peer.message_type + 1;
1319 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1320 break;
1321 }
1322
1323 /* Ignore it */
1324 return 0;
1325 }
1326
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001327 reply_msg = gsup_client_msgb_alloc();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001328 reply_msg->l2h = reply_msg->data;
Harald Welte23d77d52016-04-25 19:07:34 +02001329 osmo_gsup_encode(reply_msg, &from_peer);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001330 gprs_subscr_rx_gsup_message(reply_msg);
1331 msgb_free(reply_msg);
1332
1333 return 0;
1334};
1335
1336static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1337{
1338 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1339 struct gsm_subscriber *subscr;
1340
1341 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001342 gsup_client_send_cb = my_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001343
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001344 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gsup_client);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001345
1346 if (retry) {
1347 upd_loc_skip = 3;
1348 auth_info_skip = 3;
1349 }
1350
1351 printf("Auth policy 'remote', real GSUP based auth: ");
1352 test_gmm_attach(retry);
1353
1354 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001355 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001356 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001357
1358 sgsn->cfg.auth_policy = saved_auth_policy;
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001359 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001360 upd_loc_skip = 0;
1361 auth_info_skip = 0;
1362 talloc_free(sgsn->gsup_client);
1363 sgsn->gsup_client = NULL;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001364
1365 cleanup_test();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001366}
1367
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001368/*
1369 * Test the GMM Rejects
1370 */
1371static void test_gmm_reject(void)
1372{
1373 struct gprs_ra_id raid = { 0, };
1374 struct sgsn_mm_ctx *ctx = NULL;
1375 uint32_t foreign_tlli;
1376 struct gprs_llc_lle *lle;
1377 int idx;
1378
1379 /* DTAP - Attach Request */
1380 /* Invalid MI length */
1381 static const unsigned char attach_req_inv_mi_len[] = {
1382 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1383 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1384 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1385 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1386 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1387 };
1388
1389 /* DTAP - Attach Request */
1390 /* Invalid MI type (IMEI) */
1391 static const unsigned char attach_req_inv_mi_type[] = {
1392 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1393 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1394 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1395 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1396 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1397 };
1398
1399 /* DTAP - Routing Area Update Request */
1400 static const unsigned char dtap_ra_upd_req[] = {
1401 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1402 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1403 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1404 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1405 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1406 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1407 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1408 };
1409
1410 /* DTAP - Routing Area Update Request */
1411 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1412 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1413 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1414 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1415 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1416 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1417 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1418 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1419 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1420 };
1421
1422 /* DTAP - Routing Area Update Request */
1423 /* Invalid cap length */
1424 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1425 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1426 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1427 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1428 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1429 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1430 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1431 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1432 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1433 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1434 };
1435
1436 struct test {
1437 const char *title;
1438 const unsigned char *msg;
1439 unsigned msg_len;
1440 unsigned num_resp;
1441
1442 };
1443 static struct test tests[] = {
1444 {
1445 .title = "Attach Request (invalid MI length)",
1446 .msg = attach_req_inv_mi_len,
1447 .msg_len = sizeof(attach_req_inv_mi_len),
1448 .num_resp = 1 /* Reject */
1449
1450 },
1451 {
1452 .title = "Attach Request (invalid MI type)",
1453 .msg = attach_req_inv_mi_type,
1454 .msg_len = sizeof(attach_req_inv_mi_type),
1455 .num_resp = 1 /* Reject */
1456 },
1457 {
1458 .title = "Routing Area Update Request (valid)",
1459 .msg = dtap_ra_upd_req,
1460 .msg_len = sizeof(dtap_ra_upd_req),
1461 .num_resp = 2 /* XID Reset + Reject */
1462 },
1463 {
1464 .title = "Routing Area Update Request (invalid type)",
1465 .msg = dtap_ra_upd_req_inv_type,
1466 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1467 .num_resp = 1 /* Reject */
1468 },
1469 {
1470 .title = "Routing Area Update Request (invalid CAP length)",
1471 .msg = dtap_ra_upd_req_inv_cap_len,
1472 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1473 .num_resp = 1 /* Reject */
1474 },
1475 };
1476
1477 printf("Testing GMM reject\n");
1478
1479 /* reset the PRNG used by sgsn_alloc_ptmsi */
1480 srand(1);
1481
1482 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1483
1484 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1485
1486 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1487 const struct test *test = &tests[idx];
1488 printf(" - %s\n", test->title);
1489
1490 /* Create a LLE/LLME */
1491 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1492 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1493
1494 /* Inject the Request message */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001495 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001496 test->msg, test->msg_len);
1497
1498 /* We expect a Reject message */
1499 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1500 sgsn_tx_counter, test->num_resp);
1501 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1502
1503 /* verify that LLME/MM are removed */
1504 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1505 OSMO_ASSERT(ctx == NULL);
1506 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1507 }
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001508
1509 cleanup_test();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001510}
1511
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001512/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001513 * Test cancellation of attached MM contexts
1514 */
1515static void test_gmm_cancel(void)
1516{
1517 struct gprs_ra_id raid = { 0, };
1518 struct sgsn_mm_ctx *ctx = NULL;
1519 struct sgsn_mm_ctx *ictx;
1520 uint32_t ptmsi1;
1521 uint32_t foreign_tlli;
1522 uint32_t local_tlli = 0;
1523 struct gprs_llc_lle *lle;
1524 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1525
1526 /* DTAP - Attach Request */
1527 /* The P-TMSI is not known by the SGSN */
1528 static const unsigned char attach_req[] = {
1529 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1530 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1531 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1532 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1533 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1534 };
1535
1536 /* DTAP - Identity Response IMEI */
1537 static const unsigned char ident_resp_imei[] = {
1538 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1539 0x56
1540 };
1541
1542 /* DTAP - Identity Response IMSI */
1543 static const unsigned char ident_resp_imsi[] = {
1544 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1545 0x54
1546 };
1547
1548 /* DTAP - Attach Complete */
1549 static const unsigned char attach_compl[] = {
1550 0x08, 0x03
1551 };
1552
1553 printf("Testing cancellation\n");
1554
1555 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1556
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001557 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1558
1559 /* Create a LLE/LLME */
1560 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1561 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1562 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1563
1564 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001565 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001566 attach_req, ARRAY_SIZE(attach_req));
1567
1568 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1569 OSMO_ASSERT(ctx != NULL);
1570 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1571
1572 /* we expect an identity request (IMEI) */
1573 OSMO_ASSERT(sgsn_tx_counter == 1);
1574
1575 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001576 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001577 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1578
1579 /* we expect an identity request (IMSI) */
1580 OSMO_ASSERT(sgsn_tx_counter == 1);
1581
1582 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001583 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001584 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1585
1586 /* check that the MM context has not been removed due to a failed
1587 * authorization */
1588 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1589
1590 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1591
1592 /* we expect an attach accept/reject */
1593 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001594 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1595 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001596
1597 /* this has been randomly assigned by the SGSN */
1598 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1599
1600 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001601 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001602 attach_compl, ARRAY_SIZE(attach_compl));
1603
1604 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1605
1606 /* we don't expect a response */
1607 OSMO_ASSERT(sgsn_tx_counter == 0);
1608
1609 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001610 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001611
1612 /* verify that things are gone */
1613 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1614 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1615 OSMO_ASSERT(!ictx);
1616
1617 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001618
1619 cleanup_test();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001620}
1621
1622/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001623 * Test the dynamic allocation of P-TMSIs
1624 */
1625static void test_gmm_ptmsi_allocation(void)
1626{
Jacob Erlbeckd58c0332016-01-04 18:43:35 +01001627 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001628 struct sgsn_mm_ctx *ctx = NULL;
1629 struct sgsn_mm_ctx *ictx;
1630 uint32_t foreign_tlli;
1631 uint32_t ptmsi1;
1632 uint32_t ptmsi2;
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001633 uint32_t received_ptmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001634 uint32_t old_ptmsi;
1635 uint32_t local_tlli = 0;
1636 struct gprs_llc_lle *lle;
1637 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1638
1639 /* DTAP - Attach Request (IMSI 12131415161718) */
1640 static const unsigned char attach_req[] = {
1641 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1642 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1643 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1644 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1645 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1646 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1647 0x00,
1648 };
1649
1650 /* DTAP - Identity Response IMEI */
1651 static const unsigned char ident_resp_imei[] = {
1652 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1653 0x56
1654 };
1655
1656 /* DTAP - Attach Complete */
1657 static const unsigned char attach_compl[] = {
1658 0x08, 0x03
1659 };
1660
1661 /* DTAP - Routing Area Update Request */
1662 static const unsigned char ra_upd_req[] = {
1663 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1664 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1665 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1666 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1667 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1668 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1669 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1670 };
1671
1672 /* DTAP - Routing Area Update Complete */
1673 static const unsigned char ra_upd_complete[] = {
1674 0x08, 0x0a
1675 };
1676
1677 /* DTAP - Detach Request (MO) */
1678 /* normal detach, power_off = 1 */
1679 static const unsigned char detach_req[] = {
1680 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1681 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1682 };
1683
1684 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1685
1686 printf("Testing P-TMSI allocation\n");
1687
1688 printf(" - sgsn_alloc_ptmsi\n");
1689
1690 /* reset the PRNG used by sgsn_alloc_ptmsi */
1691 srand(1);
1692
1693 ptmsi1 = sgsn_alloc_ptmsi();
1694 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1695
1696 ptmsi2 = sgsn_alloc_ptmsi();
1697 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1698
1699 OSMO_ASSERT(ptmsi1 != ptmsi2);
1700
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001701 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001702
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001703 printf(" - Repeated Attach Request\n");
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001704
1705 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1706
1707 /* Create a LLE/LLME */
1708 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1709 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1710 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1711
1712 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001713 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001714 attach_req, ARRAY_SIZE(attach_req));
1715
1716 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1717 OSMO_ASSERT(ctx != NULL);
1718 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001719 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1720 ptmsi1 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001721
1722 old_ptmsi = ctx->p_tmsi_old;
1723
1724 /* we expect an identity request (IMEI) */
1725 OSMO_ASSERT(sgsn_tx_counter == 1);
1726
1727 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001728 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001729 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1730
1731 /* check that the MM context has not been removed due to a failed
1732 * authorization */
1733 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1734
1735 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1736 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1737
1738 /* we expect an attach accept */
1739 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001740 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1741 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001742
1743 /* we ignore this and send the attach again */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001744 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001745 attach_req, ARRAY_SIZE(attach_req));
1746
1747 /* the allocated P-TMSI should be the same */
1748 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1749 OSMO_ASSERT(ctx != NULL);
1750 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1751 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1752 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1753
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001754 /* we expect an attach accept */
1755 OSMO_ASSERT(sgsn_tx_counter == 1);
1756 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1757 OSMO_ASSERT(received_ptmsi == ptmsi1);
1758
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001759 /* inject the attach complete */
1760 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001761 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001762 attach_compl, ARRAY_SIZE(attach_compl));
1763
1764 /* we don't expect a response */
1765 OSMO_ASSERT(sgsn_tx_counter == 0);
1766
1767 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1768 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1769 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1770
1771 printf(" - Repeated RA Update Request\n");
1772
1773 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001774 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001775 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1776
1777 /* we expect an RA update accept */
1778 OSMO_ASSERT(sgsn_tx_counter == 1);
1779
1780 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1781 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001782 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1783 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1784 ptmsi2 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001785
1786 /* repeat the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001787 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001788 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1789
1790 /* we expect an RA update accept */
1791 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001792 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1793 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001794
1795 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1796 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1797 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1798
1799 /* inject the RA update complete */
1800 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001801 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001802 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1803
1804 /* we don't expect a response */
1805 OSMO_ASSERT(sgsn_tx_counter == 0);
1806
1807 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1808 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1809 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1810
1811 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001812 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001813 detach_req, ARRAY_SIZE(detach_req));
1814
1815 /* verify that things are gone */
1816 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1817 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1818 OSMO_ASSERT(!ictx);
1819
1820 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001821
1822 cleanup_test();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001823}
1824
Jacob Erlbeck13304782016-01-04 18:43:37 +01001825/*
1826 * Test changing of routing areas
1827 */
1828static void test_gmm_routing_areas(void)
1829{
1830 struct gprs_ra_id raid1 = {332, 112, 16464, 96};
1831 struct gprs_ra_id raid2 = {332, 112, 16464, 97};
1832 struct sgsn_mm_ctx *ctx = NULL;
1833 struct sgsn_mm_ctx *ictx;
1834 uint32_t ptmsi1;
1835 uint32_t received_ptmsi;
1836 uint32_t ms_tlli = 0;
1837 struct gprs_llc_lle *lle;
1838 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1839
1840 /* DTAP - Attach Request (IMSI 12131415161718) */
1841 static const unsigned char attach_req[] = {
1842 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1843 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1844 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1845 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1846 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1847 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1848 0x00,
1849 };
1850
1851 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1852 static const unsigned char attach_req2[] = {
1853 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1854 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1855 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1856 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1857 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1858 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1859 0x00,
1860 };
1861
1862 /* DTAP - Identity Response IMEI */
1863 static const unsigned char ident_resp_imei[] = {
1864 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1865 0x56
1866 };
1867
1868 /* DTAP - Attach Complete */
1869 static const unsigned char attach_compl[] = {
1870 0x08, 0x03
1871 };
1872
1873 /* DTAP - Routing Area Update Request (coming from RA 1) */
1874 static const unsigned char ra_upd_req1[] = {
1875 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1876 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1877 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1878 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1879 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1880 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1881 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1882 };
1883
1884 /* DTAP - Routing Area Update Request (coming from RA 2) */
1885 static const unsigned char ra_upd_req2[] = {
1886 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1887 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1888 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1889 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1890 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1891 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1892 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1893 };
1894
1895 /* DTAP - Routing Area Update Request (coming from RA other) */
1896 /* raid_other = {443, 223, 16464, 98}; */
1897 static const unsigned char ra_upd_req_other[] = {
1898 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1899 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1900 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1901 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1902 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1903 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1904 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1905 };
1906
1907 /* DTAP - Routing Area Update Complete */
1908 static const unsigned char ra_upd_complete[] = {
1909 0x08, 0x0a
1910 };
1911
1912 /* DTAP - Detach Request (MO) */
1913 /* normal detach, power_off = 1 */
1914 static const unsigned char detach_req[] = {
1915 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1916 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1917 };
1918
1919 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1920
1921 printf("Testing routing area changes\n");
1922
1923 /* reset the PRNG used by sgsn_alloc_ptmsi */
1924 srand(1);
1925
1926 ptmsi1 = GSM_RESERVED_TMSI;
1927
1928 printf(" - Attach Request (RA 1)\n");
1929
1930 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1931
1932 /* Create a LLE/LLME */
1933 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1934 lle = gprs_lle_get_or_create(ms_tlli, 3);
1935 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1936
1937 /* inject the attach request */
1938 send_0408_message(lle->llme, ms_tlli, &raid1,
1939 attach_req, ARRAY_SIZE(attach_req));
1940
1941 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1942 OSMO_ASSERT(ctx != NULL);
1943 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1944 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1945
1946 /* we expect an identity request (IMEI) */
1947 OSMO_ASSERT(sgsn_tx_counter == 1);
1948 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1949 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1950
1951 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001952 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001953 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1954
1955 /* check that the MM context has not been removed due to a failed
1956 * authorization */
1957 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1958
1959 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1960
1961 /* we expect an attach accept */
1962 OSMO_ASSERT(sgsn_tx_counter == 1);
1963 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1964 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1965
1966 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1967 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1968 ptmsi1 = received_ptmsi;
1969
1970 /* inject the attach complete */
1971 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001972 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001973 attach_compl, ARRAY_SIZE(attach_compl));
1974
1975 /* we don't expect a response */
1976 OSMO_ASSERT(sgsn_tx_counter == 0);
1977
1978 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1979 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1980 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1981
1982 printf(" - RA Update Request (RA 1 -> RA 1)\n");
1983
1984 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001985 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001986 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
1987
1988 /* we expect an RA update accept */
1989 OSMO_ASSERT(sgsn_tx_counter == 1);
1990 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
1991 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1992
1993 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1994 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1995 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1996 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1997
1998 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1999 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2000 ptmsi1 = received_ptmsi;
2001
2002 /* inject the RA update complete */
2003 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002004 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002005 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2006
2007 /* we don't expect a response */
2008 OSMO_ASSERT(sgsn_tx_counter == 0);
2009
2010 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2011 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2012 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002013 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002014
Jacob Erlbeck13304782016-01-04 18:43:37 +01002015 printf(" - RA Update Request (RA 1 -> RA 2)\n");
2016
2017 /* inject the RA update request */
2018 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2019
2020 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002021 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002022 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2023
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002024 /* we expect an RA update accept */
Jacob Erlbeck13304782016-01-04 18:43:37 +01002025 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002026 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002027
2028 printf(" - RA Update Request (RA other -> RA 2)\n");
2029
2030 /* inject the RA update request */
2031 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2032
2033 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002034 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002035 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2036
2037 /* we expect an RA update reject (and a LLC XID RESET) */
2038 OSMO_ASSERT(sgsn_tx_counter == 2);
2039 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2040 /* this has killed the LLE/LLME */
2041
2042 printf(" - Attach Request (RA 2)\n");
2043
2044 /* Create a LLE/LLME */
2045 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2046 lle = gprs_lle_get_or_create(ms_tlli, 3);
2047 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2048
2049 /* inject the attach request */
2050 send_0408_message(lle->llme, ms_tlli, &raid2,
2051 attach_req2, ARRAY_SIZE(attach_req2));
2052
2053 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2054 OSMO_ASSERT(ctx != NULL);
2055 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2056 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2057
2058 /* we expect an attach accept */
2059 OSMO_ASSERT(sgsn_tx_counter == 1);
2060 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2061
2062 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2063 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2064 ptmsi1 = received_ptmsi;
2065
2066 /* inject the attach complete */
2067 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2068 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2069 OSMO_ASSERT(ictx != NULL);
2070 OSMO_ASSERT(ictx == ctx);
2071
Harald Weltef97ee042015-12-25 19:12:21 +01002072 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002073 attach_compl, ARRAY_SIZE(attach_compl));
2074
2075 /* we don't expect a response */
2076 OSMO_ASSERT(sgsn_tx_counter == 0);
2077
2078 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2079 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2080 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2081
2082 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2083
2084 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01002085 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002086 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2087
2088 /* we expect an RA update accept */
2089 OSMO_ASSERT(sgsn_tx_counter == 1);
2090 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2091
2092 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2093 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2094 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2095 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2096
2097 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2098 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2099 ptmsi1 = received_ptmsi;
2100
2101 /* inject the RA update complete */
2102 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002103 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002104 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2105
2106 /* we don't expect a response */
2107 OSMO_ASSERT(sgsn_tx_counter == 0);
2108
2109 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2110 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2111 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002112 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002113
2114
2115 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01002116 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002117 detach_req, ARRAY_SIZE(detach_req));
2118
2119 /* verify that things are gone */
2120 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2121 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2122 OSMO_ASSERT(!ictx);
2123
2124 sgsn->cfg.auth_policy = saved_auth_policy;
2125
2126 cleanup_test();
2127}
2128
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002129static void test_apn_matching(void)
2130{
2131 struct apn_ctx *actx, *actxs[9];
2132
2133 printf("Testing APN matching\n");
2134
2135 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2136 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2137 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2138 actxs[3] = NULL;
2139
2140 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2141 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2142 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2143 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2144
2145 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2146
2147 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2148 OSMO_ASSERT(actx == actxs[2]);
2149 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2150 OSMO_ASSERT(actx == actxs[2]);
2151 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2152 OSMO_ASSERT(actx == actxs[1]);
2153 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2154 OSMO_ASSERT(actx == actxs[1]);
2155 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2156 OSMO_ASSERT(actx == actxs[0]);
2157 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2158 OSMO_ASSERT(actx == NULL);
2159
2160 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2161 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2162 OSMO_ASSERT(actx == actxs[3]);
2163
2164 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2165 OSMO_ASSERT(actx == actxs[4]);
2166
2167 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2168 OSMO_ASSERT(actx == actxs[6]);
2169
2170 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2171 OSMO_ASSERT(actx == actxs[5]);
2172
2173 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2174 OSMO_ASSERT(actx == actxs[7]);
2175
2176 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2177 OSMO_ASSERT(actx == actxs[8]);
2178
2179 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2180 OSMO_ASSERT(actx == actxs[7]);
2181
2182 /* Free APN contexts and check how the matching changes */
2183
2184 sgsn_apn_ctx_free(actxs[7]);
2185 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2186 OSMO_ASSERT(actx == actxs[8]);
2187
2188 sgsn_apn_ctx_free(actxs[8]);
2189 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2190 OSMO_ASSERT(actx == actxs[6]);
2191
2192 sgsn_apn_ctx_free(actxs[6]);
2193 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2194 OSMO_ASSERT(actx == actxs[1]);
2195
2196 sgsn_apn_ctx_free(actxs[5]);
2197 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2198 OSMO_ASSERT(actx == actxs[4]);
2199
2200 sgsn_apn_ctx_free(actxs[4]);
2201 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2202 OSMO_ASSERT(actx == actxs[2]);
2203
2204 sgsn_apn_ctx_free(actxs[2]);
2205 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2206 OSMO_ASSERT(actx == actxs[1]);
2207
2208 sgsn_apn_ctx_free(actxs[1]);
2209 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2210 OSMO_ASSERT(actx == actxs[0]);
2211
2212 sgsn_apn_ctx_free(actxs[0]);
2213 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2214 OSMO_ASSERT(actx == actxs[3]);
2215
2216 sgsn_apn_ctx_free(actxs[3]);
2217 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2218 OSMO_ASSERT(actx == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002219
2220 cleanup_test();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002221}
2222
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002223struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2224 struct sgsn_subscriber_data *sdata);
2225
2226static void test_ggsn_selection(void)
2227{
2228 struct apn_ctx *actxs[4];
2229 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
2230 struct gsm_subscriber *s1;
2231 const char *imsi1 = "1234567890";
2232 struct sgsn_mm_ctx *ctx;
2233 struct gprs_ra_id raid = { 0, };
2234 uint32_t local_tlli = 0xffeeddcc;
2235 enum gsm48_gsm_cause gsm_cause;
2236 struct tlv_parsed tp;
2237 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2238 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002239 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002240
2241 printf("Testing GGSN selection\n");
2242
Neels Hofmeyr814fef02016-12-08 21:19:57 +01002243 gsup_client_send_cb = my_gsup_client_send_dummy;
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002244
2245 /* Check for emptiness */
2246 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2247
2248 /* Create a context */
2249 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2250 ctx = alloc_mm_ctx(local_tlli, &raid);
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002251 osmo_strlcpy(ctx->imsi, imsi1, sizeof(ctx->imsi));
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002252
2253 /* Allocate and attach a subscriber */
2254 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2255 assert_subscr(s1, imsi1);
2256
2257 tp.lv[GSM48_IE_GSM_APN].len = 0;
2258 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2259
2260 /* TODO: Add PDP info entries to s1 */
2261
2262 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2263 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2264 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2265
2266 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2267 actxs[0]->ggsn = ggcs[0];
2268 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2269 actxs[1]->ggsn = ggcs[1];
2270 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2271 actxs[2]->ggsn = ggcs[2];
2272
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002273 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2274 pdp_data->context_id = 1;
2275 pdp_data->pdp_type = 0x0121;
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002276 osmo_strlcpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str));
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002277
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002278 /* Resolve GGSNs */
2279
2280 tp.lv[GSM48_IE_GSM_APN].len =
2281 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2282
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002283 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002284 OSMO_ASSERT(ggc != NULL);
2285 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002286 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002287
2288 tp.lv[GSM48_IE_GSM_APN].len =
2289 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2290
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002291 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002292 OSMO_ASSERT(ggc != NULL);
2293 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002294 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002295
2296 tp.lv[GSM48_IE_GSM_APN].len = 0;
2297 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2298
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002299 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002300 OSMO_ASSERT(ggc != NULL);
2301 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002302 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002303
2304 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2305 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002306 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002307 OSMO_ASSERT(ggc != NULL);
2308 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002309 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002310
2311 sgsn_apn_ctx_free(actxs[3]);
2312 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2313
2314 tp.lv[GSM48_IE_GSM_APN].len =
2315 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2316
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002317 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002318 OSMO_ASSERT(ggc == NULL);
2319 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002320 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002321
2322 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002323 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002324 OSMO_ASSERT(ggc == NULL);
2325 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2326
2327 /* Add PDP data entry to subscriber */
2328
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002329 osmo_strlcpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str));
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002330
2331 tp.lv[GSM48_IE_GSM_APN].len =
2332 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2333
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002334 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002335 OSMO_ASSERT(ggc != NULL);
2336 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002337 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002338
2339 tp.lv[GSM48_IE_GSM_APN].len =
2340 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2341
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002342 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002343 OSMO_ASSERT(ggc == NULL);
2344 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002345 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002346
2347 /* Cleanup */
2348
2349 subscr_put(s1);
2350 sgsn_mm_ctx_cleanup_free(ctx);
2351
2352 assert_no_subscrs();
2353
2354 sgsn_apn_ctx_free(actxs[0]);
2355 sgsn_apn_ctx_free(actxs[1]);
2356 sgsn_apn_ctx_free(actxs[2]);
2357
2358 sgsn_ggsn_ctx_free(ggcs[0]);
2359 sgsn_ggsn_ctx_free(ggcs[1]);
2360 sgsn_ggsn_ctx_free(ggcs[2]);
2361
Neels Hofmeyr814fef02016-12-08 21:19:57 +01002362 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002363
2364 cleanup_test();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002365}
2366
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002367static struct log_info_cat gprs_categories[] = {
2368 [DMM] = {
2369 .name = "DMM",
2370 .description = "Layer3 Mobility Management (MM)",
2371 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002372 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002373 },
2374 [DPAG] = {
2375 .name = "DPAG",
2376 .description = "Paging Subsystem",
2377 .color = "\033[1;38m",
2378 .enabled = 1, .loglevel = LOGL_NOTICE,
2379 },
2380 [DMEAS] = {
2381 .name = "DMEAS",
2382 .description = "Radio Measurement Processing",
2383 .enabled = 0, .loglevel = LOGL_NOTICE,
2384 },
2385 [DREF] = {
2386 .name = "DREF",
2387 .description = "Reference Counting",
2388 .enabled = 0, .loglevel = LOGL_NOTICE,
2389 },
2390 [DGPRS] = {
2391 .name = "DGPRS",
2392 .description = "GPRS Packet Service",
2393 .enabled = 1, .loglevel = LOGL_DEBUG,
2394 },
2395 [DNS] = {
2396 .name = "DNS",
2397 .description = "GPRS Network Service (NS)",
2398 .enabled = 1, .loglevel = LOGL_INFO,
2399 },
2400 [DBSSGP] = {
2401 .name = "DBSSGP",
2402 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2403 .enabled = 1, .loglevel = LOGL_DEBUG,
2404 },
2405 [DLLC] = {
2406 .name = "DLLC",
2407 .description = "GPRS Logical Link Control Protocol (LLC)",
2408 .enabled = 1, .loglevel = LOGL_DEBUG,
2409 },
2410 [DSNDCP] = {
2411 .name = "DSNDCP",
2412 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2413 .enabled = 1, .loglevel = LOGL_DEBUG,
2414 },
2415};
2416
2417static struct log_info info = {
2418 .cat = gprs_categories,
2419 .num_cat = ARRAY_SIZE(gprs_categories),
2420};
2421
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002422int main(int argc, char **argv)
2423{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002424 void *osmo_sgsn_ctx;
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002425 void *msgb_ctx;
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002426
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");
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002430 msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0);
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);
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002461 OSMO_ASSERT(talloc_total_blocks(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}