blob: ff07978c047c37ce73416d38356cdc96efd387ce [file] [log] [blame]
Holger Hans Peter Freyther232f6212014-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 Freyther49dbcd92014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbecke8b69682014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Harald Welte4e349d62016-04-25 19:07:34 +020027#include <osmocom/gsm/gsup.h>
Neels Hofmeyrdb1d8012016-12-08 21:22:58 +010028#include <openbsc/gsup_client.h>
Jacob Erlbeck3400f112015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Jacob Erlbeck28c28f92015-10-12 19:36:32 +020030#include <openbsc/gprs_gb_parse.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020031
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010032#include <osmocom/gprs/gprs_bssgp.h>
33
Holger Hans Peter Freyther49dbcd92014-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 Erlbeck0b2da872014-10-27 14:34:13 +010038#include <osmocom/core/rate_ctr.h>
Neels Hofmeyr64a40bf2017-01-13 03:10:54 +010039#include <osmocom/core/utils.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020040
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +020041#include <stdio.h>
42
Holger Hans Peter Freyther49dbcd92014-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 Erlbeckd7b77732014-11-04 10:08:37 +010048 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020049 },
50};
51struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010052unsigned sgsn_tx_counter = 0;
Jacob Erlbeck28c28f92015-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 Erlbeck0b2da872014-10-27 14:34:13 +010064
Jacob Erlbeck515fc332015-10-12 19:36:31 +020065static void cleanup_test()
66{
Jacob Erlbeck28c28f92015-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 Erlbeck515fc332015-10-12 19:36:31 +020078}
79
Jacob Erlbeck0b2da872014-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 Erlbeck28c28f92015-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 Erlbeck0b2da872014-10-27 14:34:13 +010099 sgsn_tx_counter += 1;
100 return 0;
101}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200102
Max9943d7a2016-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 Erlbecke8b69682014-11-12 10:12:11 +0100122/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck428f1ec2015-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 Erlbecke8b69682014-11-12 10:12:11 +0100125 &__real_sgsn_update_subscriber_data;
126
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100127void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100128{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100129 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100130}
131
Jacob Erlbeck828059f2014-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 Erlbeckd04f7cc2014-11-12 10:18:09 +0100136
Jacob Erlbeck828059f2014-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 Erlbeckd04f7cc2014-11-12 10:18:09 +0100148};
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100149
Neels Hofmeyr0e5c1e12016-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 Erlbeck0d2cf602015-01-09 15:07:16 +0100154
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +0100155int __wrap_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +0100156{
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +0100157 return (*gsup_client_send_cb)(gsupc, msg);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +0100158};
159
Holger Hans Peter Freyther49dbcd92014-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 Freyther94246842014-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 Erlbeckf43a2992014-10-27 13:23:49 +0100183/*
184 * Create a context and search for it
185 */
186static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
187{
188 struct sgsn_mm_ctx *ctx, *ictx;
189 struct gprs_llc_lle *lle;
190 int old_count = count(gprs_llme_list());
191
192 lle = gprs_lle_get_or_create(tlli, 3);
Alexander Couzens1c7869e2017-02-04 06:01:00 +0100193 ctx = sgsn_mm_ctx_alloc_gb(tlli, raid);
Alexander Couzens5e33f442017-01-31 15:34:26 +0100194 ctx->gmm_state = GMM_REGISTERED_NORMAL;
Harald Weltec28dc2f2015-12-25 19:12:21 +0100195 ctx->gb.llme = lle->llme;
Jacob Erlbeckf43a2992014-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 Erlbeck75488292014-10-29 10:31:18 +0100205static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100206 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100207 const uint8_t *data, size_t data_len)
208{
209 struct msgb *msg;
210
Jacob Erlbeck28c28f92015-10-12 19:36:32 +0200211 reset_last_msg();
Jacob Erlbeck75488292014-10-29 10:31:18 +0100212 sgsn_tx_counter = 0;
213
214 msg = create_msg(data, data_len);
215 msgb_tlli(msg) = tlli;
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100216 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Max4bc28212016-07-06 11:59:18 +0200217 gsm0408_gprs_rcvmsg_gb(msg, llme, false);
Jacob Erlbeck75488292014-10-29 10:31:18 +0100218 msgb_free(msg);
219}
220
Holger Hans Peter Freyther49dbcd92014-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 Freyther49dbcd92014-10-02 21:27:24 +0200225
226 printf("Testing LLME allocations\n");
227 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther49dbcd92014-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 Freyther49dbcd92014-10-02 21:27:24 +0200241
242 /* unassign which should delete it*/
Maxa86f5c02016-06-28 17:39:20 +0200243 gprs_llgmm_unassign(lle->llme);
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200244
245 /* Check that everything was cleaned up */
246 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200247
248 cleanup_test();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200249}
250
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100251struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100252void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100253{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100254 OSMO_ASSERT(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100255 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100256 __func__, mmctx, mmctx->subscr);
257 last_updated_subscr = mmctx->subscr;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100258}
259
Jacob Erlbecka695d242015-01-09 11:59:50 +0100260static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
261{
262 struct gsm_subscriber *sfound;
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100263 OSMO_ASSERT(subscr);
264 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100265
266 sfound = gprs_subscr_get_by_imsi(imsi);
267 OSMO_ASSERT(sfound == subscr);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100268
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100269 subscr_put(sfound);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100270}
271
Jacob Erlbeck8768f2b2015-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 Freytherd95cb732015-01-20 21:14:03 +0100278 "use count: %d\n",
279 subscr->imsi, subscr->use_count);
Jacob Erlbeck8768f2b2015-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 Erlbecke8b69682014-11-12 10:12:11 +0100290static void test_subscriber(void)
291{
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100292 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100293 const char *imsi1 = "1234567890";
294 const char *imsi2 = "9876543210";
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100295 const char *imsi3 = "5656565656";
Jacob Erlbecke8b69682014-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 Erlbeck9bf4be92015-01-06 16:32:41 +0100304 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-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 Erlbecka695d242015-01-09 11:59:50 +0100309 assert_subscr(s1, imsi1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100310 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbecke8b69682014-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 Erlbecka695d242015-01-09 11:59:50 +0100315
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100316 /* Allocate entry 3 */
317 s3 = gprs_subscr_get_or_create(imsi3);
318
Jacob Erlbecka695d242015-01-09 11:59:50 +0100319 /* Check entries */
320 assert_subscr(s1, imsi1);
321 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100322 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100323
324 /* Update entry 1 */
325 last_updated_subscr = NULL;
326 gprs_subscr_update(s1);
Jacob Erlbeck428f1ec2015-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 Erlbecke8b69682014-11-12 10:12:11 +0100330
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100331 /* There is no subscriber cache. Verify it */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100332 gprs_subscr_cleanup(s1);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100333 subscr_put(s1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100334 s1 = NULL;
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100335 sfound = gprs_subscr_get_by_imsi(imsi1);
336 OSMO_ASSERT(sfound == NULL);
337
Jacob Erlbecka695d242015-01-09 11:59:50 +0100338 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100339 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100340
Jacob Erlbecka695d242015-01-09 11:59:50 +0100341 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100342 gprs_subscr_cleanup(s2);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100343 subscr_put(s2);
Jacob Erlbecke8b69682014-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 Erlbeck9bf4be92015-01-06 16:32:41 +0100347 assert_subscr(s3, imsi3);
348
349 /* Try to delete entry 3 */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100350 gprs_subscr_cleanup(s3);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100351 subscr_put(s3);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100352 s3 = NULL;
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100353 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-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 Erlbeck515fc332015-10-12 19:36:31 +0200358
359 cleanup_test();
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100360}
361
Jacob Erlbeckb1332b62014-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 Erlbeckb1332b62014-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 Erlbeck70c177a2015-01-26 14:43:07 +0100418 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100419 s1found = gprs_subscr_get_by_imsi(imsi1);
420 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200421
422 cleanup_test();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100423}
424
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100425#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
426
Jacob Erlbeckb5c51432014-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 Erlbeck5641cfc2014-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 Erlbeck94a346a2014-12-17 14:03:35 +0100449 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbeck5641cfc2014-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 Freyther786cfee2015-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 Erlbeck5641cfc2014-12-12 15:01:37 +0100483 static const uint8_t update_location_res[] = {
484 0x06,
485 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400486 0x08, 0x09, MSISDN,
Jacob Erlbeck5641cfc2014-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 Freyther786cfee2015-04-23 09:53:53 -0400498#undef MSISDN
499
Jacob Erlbeck5641cfc2014-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 Erlbecke7fea452015-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 Erlbeck00b8b912015-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 Erlbeck86bc8702015-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 Erlbeck9ca3ace2015-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 Erlbeck86bc8702015-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 Erlbeck4f414862015-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 Hofmeyr2b91ce22016-06-20 18:26:15 +0200557 printf("Testing subscriber GSUP handling\n");
Jacob Erlbeck5641cfc2014-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 Erlbeck5641cfc2014-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 Erlbeckb5c51432014-12-19 18:19:50 +0100580 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbeck5641cfc2014-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 Erlbeckb5c51432014-12-19 18:19:50 +0100590 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100591 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100592 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100593 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-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 Erlbeck94a346a2014-12-17 14:03:35 +0100600 /* Inject UpdateLocRes GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100601 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100602 OSMO_ASSERT(rc >= 0);
603 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100604 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100605 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther786cfee2015-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 Erlbeck94a346a2014-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 Erlbeck5641cfc2014-12-12 15:01:37 +0100615
616 /* Check authorization */
617 OSMO_ASSERT(s1->authorized == 1);
618
619 /* Inject UpdateLocErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100620 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100621 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100622 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100623 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100624
625 /* Check authorization */
626 OSMO_ASSERT(s1->authorized == 0);
627
Jacob Erlbeck4f414862015-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 Weltee7e3f272016-11-26 14:58:36 +0100631 OSMO_ASSERT(rc == -ENOTSUP); /* not connected */
Harald Welted3356e72016-05-06 13:46:21 +0200632 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck4f414862015-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));
Maxe405f152017-02-15 11:43:59 +0100637 if (rc != -GMM_CAUSE_SEM_INCORR_MSG)
638 printf("Unexpected response to DSD: %d\n", rc);
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100639 OSMO_ASSERT(last_updated_subscr == NULL);
640
Jacob Erlbeck00b8b912015-01-08 15:29:01 +0100641 /* Inject wrong LocCancelReq GSUP message */
642 last_updated_subscr = NULL;
643 rc = rx_gsup_message(location_cancellation_req_other,
644 sizeof(location_cancellation_req_other));
645 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
646 OSMO_ASSERT(last_updated_subscr == NULL);
647
648 /* Check cancellation result */
649 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
650 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
651
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100652 /* Inject LocCancelReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100653 rc = rx_gsup_message(location_cancellation_req,
654 sizeof(location_cancellation_req));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100655 OSMO_ASSERT(rc >= 0);
656 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100657 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100658
659 /* Check cancellation result */
660 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
661 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
662
Jacob Erlbecke7fea452015-04-07 17:49:48 +0200663 /* Inject LocCancelReq(withdraw) GSUP message */
664 rc = rx_gsup_message(location_cancellation_req_withdraw,
665 sizeof(location_cancellation_req_withdraw));
666 OSMO_ASSERT(rc >= 0);
667 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
668
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100669 /* Inject PurgeMsRes GSUP message */
670 rc = rx_gsup_message(purge_ms_res,
671 sizeof(purge_ms_res));
672 OSMO_ASSERT(rc >= 0);
673 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
674
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100675 /* Free MM context and subscriber */
Jacob Erlbeck265e7352015-01-30 11:57:25 +0100676 OSMO_ASSERT(ctx->subscr == NULL);
677 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100678 subscr_put(s1);
679 s1found = gprs_subscr_get_by_imsi(imsi1);
680 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100681
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100682 /* Inject PurgeMsRes GSUP message */
683 rc = rx_gsup_message(purge_ms_res,
684 sizeof(purge_ms_res));
685 OSMO_ASSERT(rc >= 0);
686
687 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
688 rc = rx_gsup_message(purge_ms_err,
689 sizeof(purge_ms_err));
690 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
691
Jacob Erlbeck9ca3ace2015-01-29 14:17:51 +0100692 /* Inject PurgeMsErr() GSUP message */
693 rc = rx_gsup_message(purge_ms_err_no_cause,
694 sizeof(purge_ms_err_no_cause));
695 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
696
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100697 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
698 last_updated_subscr = NULL;
699 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck629dacc2015-01-15 17:50:16 +0100700 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100701 OSMO_ASSERT(last_updated_subscr == NULL);
702
703 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
704 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
705 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
706 OSMO_ASSERT(last_updated_subscr == NULL);
707
708 /* Inject LocCancelReq GSUP message (unknown IMSI) */
709 rc = rx_gsup_message(location_cancellation_req,
710 sizeof(location_cancellation_req));
711 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
712 OSMO_ASSERT(last_updated_subscr == NULL);
713
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100714 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200715
716 cleanup_test();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100717}
718
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +0100719int my_gsup_client_send_dummy(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +0100720{
721 msgb_free(msg);
722 return 0;
723};
724
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200725/*
726 * Test that a GMM Detach will remove the MMCTX and the
727 * associated LLME.
728 */
729static void test_gmm_detach(void)
730{
731 struct gprs_ra_id raid = { 0, };
732 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200733 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200734
735 printf("Testing GMM detach\n");
736
737 /* DTAP - Detach Request (MO) */
738 /* normal detach, power_off = 0 */
739 static const unsigned char detach_req[] = {
740 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
741 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
742 };
743
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200744 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200745
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100746 /* Create a context */
747 OSMO_ASSERT(count(gprs_llme_list()) == 0);
748 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200749
750 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +0100751 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100752 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200753
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100754 /* verify that a single message (hopefully the Detach Accept) has been
755 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100756 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100757
758 /* verify that things are gone */
759 OSMO_ASSERT(count(gprs_llme_list()) == 0);
760 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
761 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200762
763 cleanup_test();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100764}
765
766/*
767 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
768 * will not sent a Detach Accept message (power_off = 1)
769 */
770static void test_gmm_detach_power_off(void)
771{
772 struct gprs_ra_id raid = { 0, };
773 struct sgsn_mm_ctx *ctx, *ictx;
774 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100775
776 printf("Testing GMM detach (power off)\n");
777
778 /* DTAP - Detach Request (MO) */
779 /* normal detach, power_off = 1 */
780 static const unsigned char detach_req[] = {
781 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
782 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
783 };
784
785 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
786
787 /* Create a context */
788 OSMO_ASSERT(count(gprs_llme_list()) == 0);
789 ctx = alloc_mm_ctx(local_tlli, &raid);
790
791 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +0100792 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100793 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100794
795 /* verify that no message (and therefore no Detach Accept) has been
796 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100797 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100798
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200799 /* verify that things are gone */
800 OSMO_ASSERT(count(gprs_llme_list()) == 0);
801 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200802 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200803
804 cleanup_test();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200805}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200806
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200807/*
808 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
809 */
810static void test_gmm_detach_no_mmctx(void)
811{
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100812 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200813 struct gprs_llc_lle *lle;
814 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200815
816 printf("Testing GMM detach (no MMCTX)\n");
817
818 /* DTAP - Detach Request (MO) */
819 /* normal detach, power_off = 0 */
820 static const unsigned char detach_req[] = {
821 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
822 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
823 };
824
825 /* Create an LLME */
826 OSMO_ASSERT(count(gprs_llme_list()) == 0);
827 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
828 lle = gprs_lle_get_or_create(local_tlli, 3);
829
830 OSMO_ASSERT(count(gprs_llme_list()) == 1);
831
832 /* inject the detach */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100833 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100834 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200835
836 /* verify that the LLME is gone */
837 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200838
839 cleanup_test();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200840}
841
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100842/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100843 * Test that a single GMM Detach Accept message will not cause the SGSN to send
844 * any message or leave an MM context at the SGSN.
845 */
846static void test_gmm_detach_accept_unexpected(void)
847{
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100848 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100849 struct gprs_llc_lle *lle;
850 uint32_t local_tlli;
851
852 printf("Testing GMM detach accept (unexpected)\n");
853
854 /* DTAP - Detach Accept (MT) */
855 /* normal detach */
856 static const unsigned char detach_acc[] = {
857 0x08, 0x06
858 };
859
860 /* Create an LLME */
861 OSMO_ASSERT(count(gprs_llme_list()) == 0);
862 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
863 lle = gprs_lle_get_or_create(local_tlli, 3);
864
865 /* inject the detach */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100866 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100867 detach_acc, ARRAY_SIZE(detach_acc));
868
869 /* verify that no message (and therefore no Status or XID reset) has been
870 * sent by the SGSN */
871 OSMO_ASSERT(sgsn_tx_counter == 0);
872
873 /* verify that things are gone */
874 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200875
876 cleanup_test();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100877}
878
879/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100880 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
881 */
882static void test_gmm_status_no_mmctx(void)
883{
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100884 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100885 struct gprs_llc_lle *lle;
886 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100887
888 printf("Testing GMM Status (no MMCTX)\n");
889
890 /* DTAP - GMM Status, protocol error */
891 static const unsigned char gmm_status[] = {
892 0x08, 0x20, 0x6f
893 };
894
895 /* Create an LLME */
896 OSMO_ASSERT(count(gprs_llme_list()) == 0);
897 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
898 lle = gprs_lle_get_or_create(local_tlli, 3);
899
900 OSMO_ASSERT(count(gprs_llme_list()) == 1);
901
902 /* inject the detach */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100903 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100904 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100905
906 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100907 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100908
909 /* verify that the LLME is gone */
910 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200911
912 cleanup_test();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100913}
914
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100915/*
916 * Test the GMM Attach procedure
917 */
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100918static void test_gmm_attach(int retry)
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100919{
920 struct gprs_ra_id raid = { 0, };
921 struct sgsn_mm_ctx *ctx = NULL;
922 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100923 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100924 uint32_t foreign_tlli;
925 uint32_t local_tlli = 0;
926 struct gprs_llc_lle *lle;
927
928 /* DTAP - Attach Request */
929 /* The P-TMSI is not known by the SGSN */
930 static const unsigned char attach_req[] = {
931 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
932 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
933 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
934 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
935 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
936 };
937
938 /* DTAP - Identity Response IMEI */
939 static const unsigned char ident_resp_imei[] = {
940 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
941 0x56
942 };
943
944 /* DTAP - Identity Response IMSI */
945 static const unsigned char ident_resp_imsi[] = {
946 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
947 0x54
948 };
949
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100950 /* DTAP - Authentication and Ciphering Resp */
951 static const unsigned char auth_ciph_resp[] = {
952 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
953 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
954 };
955
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100956 /* DTAP - Attach Complete */
957 static const unsigned char attach_compl[] = {
958 0x08, 0x03
959 };
960
961 /* DTAP - Detach Request (MO) */
962 /* normal detach, power_off = 0 */
963 static const unsigned char detach_req[] = {
964 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
965 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
966 };
967
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100968 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100969
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100970 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
971
972 /* Create a LLE/LLME */
973 OSMO_ASSERT(count(gprs_llme_list()) == 0);
974 lle = gprs_lle_get_or_create(foreign_tlli, 3);
975 OSMO_ASSERT(count(gprs_llme_list()) == 1);
976
977 /* inject the attach request */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100978 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100979 attach_req, ARRAY_SIZE(attach_req));
980
981 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
982 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +0100983 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100984
985 /* we expect an identity request (IMEI) */
986 OSMO_ASSERT(sgsn_tx_counter == 1);
987
988 /* inject the identity response (IMEI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +0100989 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100990 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
991
992 /* we expect an identity request (IMSI) */
993 OSMO_ASSERT(sgsn_tx_counter == 1);
994
995 /* inject the identity response (IMSI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +0100996 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100997 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
998
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100999 /* check that the MM context has not been removed due to a failed
1000 * authorization */
1001 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1002
Alexander Couzens5e33f442017-01-31 15:34:26 +01001003 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001004
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001005retry_attach_req:
1006
1007 if (retry && sgsn_tx_counter == 0) {
1008 fprintf(stderr, "Retrying attach request\n");
1009 /* re-inject the attach request */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001010 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001011 attach_req, ARRAY_SIZE(attach_req));
1012 }
1013
1014 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
1015 /* we got an auth & ciph request */
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001016
1017 /* inject the auth & ciph response */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001018 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001019 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1020
1021 /* check that the MM context has not been removed due to a
1022 * failed authorization */
1023 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freythera9f671c2015-05-05 22:52:40 +02001024 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1025 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001026 }
1027
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001028 if (retry && sgsn_tx_counter == 0)
1029 goto retry_attach_req;
1030
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001031 /* we expect an attach accept/reject */
1032 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001033 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1034 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001035
1036 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +01001037 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001038
1039 /* inject the attach complete */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001040 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001041 attach_compl, ARRAY_SIZE(attach_compl));
1042
Alexander Couzens5e33f442017-01-31 15:34:26 +01001043 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001044
1045 /* we don't expect a response */
1046 OSMO_ASSERT(sgsn_tx_counter == 0);
1047
1048 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001049 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001050 detach_req, ARRAY_SIZE(detach_req));
1051
1052 /* verify that things are gone */
1053 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1054 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1055 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001056
1057 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001058}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001059
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001060static void test_gmm_attach_acl(void)
1061{
1062 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1063
1064 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1065 sgsn_acl_add("123456789012345", &sgsn->cfg);
1066 printf("Auth policy 'closed': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001067 test_gmm_attach(0);
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001068 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001069
1070 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001071
1072 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001073}
1074
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001075int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001076 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001077 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001078 if (rc == -ENOTSUP) {
1079 OSMO_ASSERT(mmctx->subscr);
1080 gprs_subscr_update(mmctx->subscr);
1081 }
1082 return rc;
1083};
1084
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001085int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1086 gprs_subscr_update(mmctx->subscr);
1087 return 0;
1088};
1089
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001090static void test_gmm_attach_subscr(void)
1091{
1092 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1093 struct gsm_subscriber *subscr;
1094
1095 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001096 subscr_request_update_location_cb = my_subscr_request_update_location;
1097 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001098
1099 subscr = gprs_subscr_get_or_create("123456789012345");
1100 subscr->authorized = 1;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001101
1102 printf("Auth policy 'remote': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001103 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001104 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001105 assert_no_subscrs();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001106
1107 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001108 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1109 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001110
1111 cleanup_test();
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001112}
1113
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001114int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1115{
1116 /* Fake an authentication */
1117 OSMO_ASSERT(mmctx->subscr);
1118 mmctx->is_authenticated = 1;
1119 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001120
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001121 return 0;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001122};
1123
1124static void test_gmm_attach_subscr_fake_auth(void)
1125{
1126 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1127 struct gsm_subscriber *subscr;
1128
1129 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001130 subscr_request_update_location_cb = my_subscr_request_update_location;
1131 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001132
1133 subscr = gprs_subscr_get_or_create("123456789012345");
1134 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001135 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001136 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001137
1138 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001139 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001140 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001141 assert_no_subscrs();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001142
1143 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001144 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1145 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001146
1147 cleanup_test();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001148}
1149
1150int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1151{
1152 struct gsm_auth_tuple at = {
Harald Welte34ef4c52016-04-20 13:13:19 +02001153 .vec.sres = {0x51, 0xe5, 0x51, 0xe5},
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001154 .key_seq = 0
1155 };
1156
1157 /* Fake an authentication */
1158 OSMO_ASSERT(mmctx->subscr);
1159 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1160
1161 gprs_subscr_update_auth_info(mmctx->subscr);
1162
1163 return 0;
1164};
1165
1166static void test_gmm_attach_subscr_real_auth(void)
1167{
1168 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1169 struct gsm_subscriber *subscr;
1170
1171 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1172 subscr_request_update_location_cb = my_subscr_request_update_location;
1173 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1174
1175 subscr = gprs_subscr_get_or_create("123456789012345");
1176 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001177 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001178 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001179
1180 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001181
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001182 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001183 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001184 assert_no_subscrs();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001185
1186 sgsn->cfg.auth_policy = saved_auth_policy;
1187 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1188 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001189
1190 cleanup_test();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001191}
1192
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001193#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1194 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1195
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001196static int auth_info_skip = 0;
1197static int upd_loc_skip = 0;
1198
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001199int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1200{
1201 static const uint8_t send_auth_info_res[] = {
1202 0x0a,
1203 TEST_GSUP_IMSI_LONG_IE,
1204 0x03, 0x22, /* Auth tuple */
1205 0x20, 0x10,
1206 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1207 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1208 0x21, 0x04,
1209 0x51, 0xe5, 0x51, 0xe5,
1210 0x22, 0x08,
1211 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1212 };
1213
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001214 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001215
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001216 if (auth_info_skip > 0) {
1217 auth_info_skip -= 1;
1218 return -EAGAIN;
1219 }
1220
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001221 /* Fake an SendAuthInfoRes */
1222 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1223
1224 return 0;
1225};
1226
1227int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1228 static const uint8_t update_location_res[] = {
1229 0x06,
1230 TEST_GSUP_IMSI_LONG_IE,
1231 0x04, 0x00, /* PDP info complete */
1232 0x05, 0x12,
1233 0x10, 0x01, 0x01,
1234 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1235 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freythera9f671c2015-05-05 22:52:40 +02001236 0x08, 0x07, /* MSISDN 49166213323 encoded */
1237 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freytherfe4a9f62015-05-17 20:58:40 +02001238 0x09, 0x07, /* MSISDN 38166213323 encoded */
1239 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001240 };
1241
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001242 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001243
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001244 if (upd_loc_skip > 0) {
1245 upd_loc_skip -= 1;
1246 return -EAGAIN;
1247 }
1248
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001249 /* Fake an UpdateLocRes */
1250 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1251};
1252
1253
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001254static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001255{
1256 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1257 struct gsm_subscriber *subscr;
1258
1259 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1260 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1261 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001262 if (retry) {
1263 upd_loc_skip = 3;
1264 auth_info_skip = 3;
1265 }
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001266
1267 subscr = gprs_subscr_get_or_create("123456789012345");
1268 subscr->authorized = 1;
1269 sgsn->cfg.require_authentication = 1;
1270 sgsn->cfg.require_update_location = 1;
1271 subscr_put(subscr);
1272
1273 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001274 test_gmm_attach(retry);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001275 assert_no_subscrs();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001276
1277 sgsn->cfg.auth_policy = saved_auth_policy;
1278 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1279 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001280 upd_loc_skip = 0;
1281 auth_info_skip = 0;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001282
1283 cleanup_test();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001284}
1285
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001286int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001287{
Harald Welte4e349d62016-04-25 19:07:34 +02001288 struct osmo_gsup_message to_peer = {0};
1289 struct osmo_gsup_message from_peer = {0};
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001290 struct msgb *reply_msg;
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001291 int rc;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001292
1293 /* Simulate the GSUP peer */
Harald Welte4e349d62016-04-25 19:07:34 +02001294 rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001295 OSMO_ASSERT(rc >= 0);
1296 OSMO_ASSERT(to_peer.imsi[0] != 0);
Neels Hofmeyr64a40bf2017-01-13 03:10:54 +01001297 osmo_strlcpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001298
1299 /* This invalidates the pointers in to_peer */
1300 msgb_free(msg);
1301
1302 switch (to_peer.message_type) {
Harald Welte4e349d62016-04-25 19:07:34 +02001303 case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001304 /* Send UPDATE_LOCATION_RESULT */
1305 return my_subscr_request_update_gsup_auth(NULL);
1306
Harald Welte4e349d62016-04-25 19:07:34 +02001307 case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001308 /* Send SEND_AUTH_INFO_RESULT */
1309 return my_subscr_request_auth_info_gsup_auth(NULL);
1310
Harald Welte4e349d62016-04-25 19:07:34 +02001311 case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
1312 from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001313 break;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001314
1315 default:
1316 if ((to_peer.message_type & 0b00000011) == 0) {
1317 /* Unhandled request */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001318 /* Send error(NOT_IMPL) */
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001319 from_peer.message_type = to_peer.message_type + 1;
1320 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1321 break;
1322 }
1323
1324 /* Ignore it */
1325 return 0;
1326 }
1327
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001328 reply_msg = gsup_client_msgb_alloc();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001329 reply_msg->l2h = reply_msg->data;
Harald Welte4e349d62016-04-25 19:07:34 +02001330 osmo_gsup_encode(reply_msg, &from_peer);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001331 gprs_subscr_rx_gsup_message(reply_msg);
1332 msgb_free(reply_msg);
1333
1334 return 0;
1335};
1336
1337static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1338{
1339 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1340 struct gsm_subscriber *subscr;
1341
1342 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001343 gsup_client_send_cb = my_gsup_client_send;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001344
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001345 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gsup_client);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001346
1347 if (retry) {
1348 upd_loc_skip = 3;
1349 auth_info_skip = 3;
1350 }
1351
1352 printf("Auth policy 'remote', real GSUP based auth: ");
1353 test_gmm_attach(retry);
1354
1355 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001356 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001357 assert_no_subscrs();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001358
1359 sgsn->cfg.auth_policy = saved_auth_policy;
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001360 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001361 upd_loc_skip = 0;
1362 auth_info_skip = 0;
1363 talloc_free(sgsn->gsup_client);
1364 sgsn->gsup_client = NULL;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001365
1366 cleanup_test();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001367}
1368
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001369/*
1370 * Test the GMM Rejects
1371 */
1372static void test_gmm_reject(void)
1373{
1374 struct gprs_ra_id raid = { 0, };
1375 struct sgsn_mm_ctx *ctx = NULL;
1376 uint32_t foreign_tlli;
1377 struct gprs_llc_lle *lle;
1378 int idx;
1379
1380 /* DTAP - Attach Request */
1381 /* Invalid MI length */
1382 static const unsigned char attach_req_inv_mi_len[] = {
1383 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1384 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1385 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1386 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1387 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1388 };
1389
1390 /* DTAP - Attach Request */
1391 /* Invalid MI type (IMEI) */
1392 static const unsigned char attach_req_inv_mi_type[] = {
1393 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1394 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1395 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1396 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1397 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1398 };
1399
1400 /* DTAP - Routing Area Update Request */
1401 static const unsigned char dtap_ra_upd_req[] = {
1402 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1403 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1404 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1405 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1406 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1407 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1408 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1409 };
1410
1411 /* DTAP - Routing Area Update Request */
1412 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1413 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1414 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1415 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1416 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1417 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1418 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1419 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1420 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1421 };
1422
1423 /* DTAP - Routing Area Update Request */
1424 /* Invalid cap length */
1425 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1426 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1427 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1428 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1429 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1430 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1431 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1432 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1433 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1434 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1435 };
1436
1437 struct test {
1438 const char *title;
1439 const unsigned char *msg;
1440 unsigned msg_len;
1441 unsigned num_resp;
1442
1443 };
1444 static struct test tests[] = {
1445 {
1446 .title = "Attach Request (invalid MI length)",
1447 .msg = attach_req_inv_mi_len,
1448 .msg_len = sizeof(attach_req_inv_mi_len),
1449 .num_resp = 1 /* Reject */
1450
1451 },
1452 {
1453 .title = "Attach Request (invalid MI type)",
1454 .msg = attach_req_inv_mi_type,
1455 .msg_len = sizeof(attach_req_inv_mi_type),
1456 .num_resp = 1 /* Reject */
1457 },
1458 {
1459 .title = "Routing Area Update Request (valid)",
1460 .msg = dtap_ra_upd_req,
1461 .msg_len = sizeof(dtap_ra_upd_req),
1462 .num_resp = 2 /* XID Reset + Reject */
1463 },
1464 {
1465 .title = "Routing Area Update Request (invalid type)",
1466 .msg = dtap_ra_upd_req_inv_type,
1467 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1468 .num_resp = 1 /* Reject */
1469 },
1470 {
1471 .title = "Routing Area Update Request (invalid CAP length)",
1472 .msg = dtap_ra_upd_req_inv_cap_len,
1473 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1474 .num_resp = 1 /* Reject */
1475 },
1476 };
1477
1478 printf("Testing GMM reject\n");
1479
1480 /* reset the PRNG used by sgsn_alloc_ptmsi */
1481 srand(1);
1482
1483 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1484
1485 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1486
1487 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1488 const struct test *test = &tests[idx];
1489 printf(" - %s\n", test->title);
1490
1491 /* Create a LLE/LLME */
1492 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1493 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1494
1495 /* Inject the Request message */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001496 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001497 test->msg, test->msg_len);
1498
1499 /* We expect a Reject message */
1500 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1501 sgsn_tx_counter, test->num_resp);
1502 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1503
1504 /* verify that LLME/MM are removed */
1505 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1506 OSMO_ASSERT(ctx == NULL);
1507 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1508 }
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001509
1510 cleanup_test();
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001511}
1512
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001513/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001514 * Test cancellation of attached MM contexts
1515 */
1516static void test_gmm_cancel(void)
1517{
1518 struct gprs_ra_id raid = { 0, };
1519 struct sgsn_mm_ctx *ctx = NULL;
1520 struct sgsn_mm_ctx *ictx;
1521 uint32_t ptmsi1;
1522 uint32_t foreign_tlli;
1523 uint32_t local_tlli = 0;
1524 struct gprs_llc_lle *lle;
1525 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1526
1527 /* DTAP - Attach Request */
1528 /* The P-TMSI is not known by the SGSN */
1529 static const unsigned char attach_req[] = {
1530 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1531 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1532 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1533 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1534 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1535 };
1536
1537 /* DTAP - Identity Response IMEI */
1538 static const unsigned char ident_resp_imei[] = {
1539 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1540 0x56
1541 };
1542
1543 /* DTAP - Identity Response IMSI */
1544 static const unsigned char ident_resp_imsi[] = {
1545 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1546 0x54
1547 };
1548
1549 /* DTAP - Attach Complete */
1550 static const unsigned char attach_compl[] = {
1551 0x08, 0x03
1552 };
1553
1554 printf("Testing cancellation\n");
1555
1556 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1557
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001558 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1559
1560 /* Create a LLE/LLME */
1561 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1562 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1563 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1564
1565 /* inject the attach request */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001566 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001567 attach_req, ARRAY_SIZE(attach_req));
1568
1569 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1570 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01001571 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001572
1573 /* we expect an identity request (IMEI) */
1574 OSMO_ASSERT(sgsn_tx_counter == 1);
1575
1576 /* inject the identity response (IMEI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001577 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001578 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1579
1580 /* we expect an identity request (IMSI) */
1581 OSMO_ASSERT(sgsn_tx_counter == 1);
1582
1583 /* inject the identity response (IMSI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001584 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001585 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1586
1587 /* check that the MM context has not been removed due to a failed
1588 * authorization */
1589 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1590
Alexander Couzens5e33f442017-01-31 15:34:26 +01001591 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001592
1593 /* we expect an attach accept/reject */
1594 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001595 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1596 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001597
1598 /* this has been randomly assigned by the SGSN */
1599 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1600
1601 /* inject the attach complete */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001602 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001603 attach_compl, ARRAY_SIZE(attach_compl));
1604
Alexander Couzens5e33f442017-01-31 15:34:26 +01001605 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001606
1607 /* we don't expect a response */
1608 OSMO_ASSERT(sgsn_tx_counter == 0);
1609
1610 /* cancel */
Jacob Erlbeck41010082015-01-05 17:51:17 +01001611 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001612
1613 /* verify that things are gone */
1614 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1615 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1616 OSMO_ASSERT(!ictx);
1617
1618 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001619
1620 cleanup_test();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001621}
1622
1623/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001624 * Test the dynamic allocation of P-TMSIs
1625 */
1626static void test_gmm_ptmsi_allocation(void)
1627{
Jacob Erlbeckf963e7e2016-01-04 18:43:35 +01001628 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001629 struct sgsn_mm_ctx *ctx = NULL;
1630 struct sgsn_mm_ctx *ictx;
1631 uint32_t foreign_tlli;
1632 uint32_t ptmsi1;
1633 uint32_t ptmsi2;
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001634 uint32_t received_ptmsi;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001635 uint32_t old_ptmsi;
1636 uint32_t local_tlli = 0;
1637 struct gprs_llc_lle *lle;
1638 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1639
1640 /* DTAP - Attach Request (IMSI 12131415161718) */
1641 static const unsigned char attach_req[] = {
1642 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1643 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1644 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1645 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1646 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1647 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1648 0x00,
1649 };
1650
1651 /* DTAP - Identity Response IMEI */
1652 static const unsigned char ident_resp_imei[] = {
1653 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1654 0x56
1655 };
1656
1657 /* DTAP - Attach Complete */
1658 static const unsigned char attach_compl[] = {
1659 0x08, 0x03
1660 };
1661
1662 /* DTAP - Routing Area Update Request */
1663 static const unsigned char ra_upd_req[] = {
1664 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1665 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1666 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1667 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1668 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1669 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1670 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1671 };
1672
1673 /* DTAP - Routing Area Update Complete */
1674 static const unsigned char ra_upd_complete[] = {
1675 0x08, 0x0a
1676 };
1677
1678 /* DTAP - Detach Request (MO) */
1679 /* normal detach, power_off = 1 */
1680 static const unsigned char detach_req[] = {
1681 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1682 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1683 };
1684
1685 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1686
1687 printf("Testing P-TMSI allocation\n");
1688
1689 printf(" - sgsn_alloc_ptmsi\n");
1690
1691 /* reset the PRNG used by sgsn_alloc_ptmsi */
1692 srand(1);
1693
1694 ptmsi1 = sgsn_alloc_ptmsi();
1695 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1696
1697 ptmsi2 = sgsn_alloc_ptmsi();
1698 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1699
1700 OSMO_ASSERT(ptmsi1 != ptmsi2);
1701
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001702 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001703
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001704 printf(" - Repeated Attach Request\n");
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001705
1706 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1707
1708 /* Create a LLE/LLME */
1709 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1710 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1711 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1712
1713 /* inject the attach request */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001714 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001715 attach_req, ARRAY_SIZE(attach_req));
1716
1717 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1718 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01001719 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001720 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1721 ptmsi1 = ctx->p_tmsi;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001722
1723 old_ptmsi = ctx->p_tmsi_old;
1724
1725 /* we expect an identity request (IMEI) */
1726 OSMO_ASSERT(sgsn_tx_counter == 1);
1727
1728 /* inject the identity response (IMEI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001729 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001730 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1731
1732 /* check that the MM context has not been removed due to a failed
1733 * authorization */
1734 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1735
Alexander Couzens5e33f442017-01-31 15:34:26 +01001736 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001737 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1738
1739 /* we expect an attach accept */
1740 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001741 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1742 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001743
1744 /* we ignore this and send the attach again */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001745 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001746 attach_req, ARRAY_SIZE(attach_req));
1747
1748 /* the allocated P-TMSI should be the same */
1749 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1750 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01001751 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001752 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1753 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1754
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001755 /* we expect an attach accept */
1756 OSMO_ASSERT(sgsn_tx_counter == 1);
1757 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1758 OSMO_ASSERT(received_ptmsi == ptmsi1);
1759
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001760 /* inject the attach complete */
1761 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01001762 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001763 attach_compl, ARRAY_SIZE(attach_compl));
1764
1765 /* we don't expect a response */
1766 OSMO_ASSERT(sgsn_tx_counter == 0);
1767
Alexander Couzens5e33f442017-01-31 15:34:26 +01001768 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001769 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1770 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1771
1772 printf(" - Repeated RA Update Request\n");
1773
1774 /* inject the RA update request */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001775 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001776 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1777
1778 /* we expect an RA update accept */
1779 OSMO_ASSERT(sgsn_tx_counter == 1);
1780
Alexander Couzens5e33f442017-01-31 15:34:26 +01001781 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001782 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001783 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1784 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1785 ptmsi2 = ctx->p_tmsi;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001786
1787 /* repeat the RA update request */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001788 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001789 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1790
1791 /* we expect an RA update accept */
1792 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001793 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1794 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001795
Alexander Couzens5e33f442017-01-31 15:34:26 +01001796 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001797 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1798 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1799
1800 /* inject the RA update complete */
1801 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01001802 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001803 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1804
1805 /* we don't expect a response */
1806 OSMO_ASSERT(sgsn_tx_counter == 0);
1807
Alexander Couzens5e33f442017-01-31 15:34:26 +01001808 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001809 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1810 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1811
1812 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001813 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001814 detach_req, ARRAY_SIZE(detach_req));
1815
1816 /* verify that things are gone */
1817 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1818 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1819 OSMO_ASSERT(!ictx);
1820
1821 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001822
1823 cleanup_test();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001824}
1825
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001826/*
1827 * Test changing of routing areas
1828 */
1829static void test_gmm_routing_areas(void)
1830{
1831 struct gprs_ra_id raid1 = {332, 112, 16464, 96};
1832 struct gprs_ra_id raid2 = {332, 112, 16464, 97};
1833 struct sgsn_mm_ctx *ctx = NULL;
1834 struct sgsn_mm_ctx *ictx;
1835 uint32_t ptmsi1;
1836 uint32_t received_ptmsi;
1837 uint32_t ms_tlli = 0;
1838 struct gprs_llc_lle *lle;
1839 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1840
1841 /* DTAP - Attach Request (IMSI 12131415161718) */
1842 static const unsigned char attach_req[] = {
1843 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1844 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1845 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1846 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1847 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1848 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1849 0x00,
1850 };
1851
1852 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1853 static const unsigned char attach_req2[] = {
1854 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1855 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1856 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1857 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1858 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1859 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1860 0x00,
1861 };
1862
1863 /* DTAP - Identity Response IMEI */
1864 static const unsigned char ident_resp_imei[] = {
1865 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1866 0x56
1867 };
1868
1869 /* DTAP - Attach Complete */
1870 static const unsigned char attach_compl[] = {
1871 0x08, 0x03
1872 };
1873
1874 /* DTAP - Routing Area Update Request (coming from RA 1) */
1875 static const unsigned char ra_upd_req1[] = {
1876 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1877 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1878 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1879 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1880 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1881 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1882 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1883 };
1884
1885 /* DTAP - Routing Area Update Request (coming from RA 2) */
1886 static const unsigned char ra_upd_req2[] = {
1887 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1888 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1889 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1890 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1891 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1892 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1893 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1894 };
1895
1896 /* DTAP - Routing Area Update Request (coming from RA other) */
1897 /* raid_other = {443, 223, 16464, 98}; */
1898 static const unsigned char ra_upd_req_other[] = {
1899 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1900 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1901 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1902 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1903 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1904 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1905 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1906 };
1907
1908 /* DTAP - Routing Area Update Complete */
1909 static const unsigned char ra_upd_complete[] = {
1910 0x08, 0x0a
1911 };
1912
1913 /* DTAP - Detach Request (MO) */
1914 /* normal detach, power_off = 1 */
1915 static const unsigned char detach_req[] = {
1916 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1917 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1918 };
1919
1920 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1921
1922 printf("Testing routing area changes\n");
1923
1924 /* reset the PRNG used by sgsn_alloc_ptmsi */
1925 srand(1);
1926
1927 ptmsi1 = GSM_RESERVED_TMSI;
1928
1929 printf(" - Attach Request (RA 1)\n");
1930
1931 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1932
1933 /* Create a LLE/LLME */
1934 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1935 lle = gprs_lle_get_or_create(ms_tlli, 3);
1936 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1937
1938 /* inject the attach request */
1939 send_0408_message(lle->llme, ms_tlli, &raid1,
1940 attach_req, ARRAY_SIZE(attach_req));
1941
1942 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1943 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01001944 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001945 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1946
1947 /* we expect an identity request (IMEI) */
1948 OSMO_ASSERT(sgsn_tx_counter == 1);
1949 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1950 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1951
1952 /* inject the identity response (IMEI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001953 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001954 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1955
1956 /* check that the MM context has not been removed due to a failed
1957 * authorization */
1958 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1959
Alexander Couzens5e33f442017-01-31 15:34:26 +01001960 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001961
1962 /* we expect an attach accept */
1963 OSMO_ASSERT(sgsn_tx_counter == 1);
1964 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1965 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1966
1967 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1968 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1969 ptmsi1 = received_ptmsi;
1970
1971 /* inject the attach complete */
1972 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01001973 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001974 attach_compl, ARRAY_SIZE(attach_compl));
1975
1976 /* we don't expect a response */
1977 OSMO_ASSERT(sgsn_tx_counter == 0);
1978
Alexander Couzens5e33f442017-01-31 15:34:26 +01001979 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001980 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1981 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1982
1983 printf(" - RA Update Request (RA 1 -> RA 1)\n");
1984
1985 /* inject the RA update request */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001986 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001987 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
1988
1989 /* we expect an RA update accept */
1990 OSMO_ASSERT(sgsn_tx_counter == 1);
1991 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
1992 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1993
Alexander Couzens5e33f442017-01-31 15:34:26 +01001994 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001995 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1996 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1997 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1998
1999 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2000 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2001 ptmsi1 = received_ptmsi;
2002
2003 /* inject the RA update complete */
2004 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01002005 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002006 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2007
2008 /* we don't expect a response */
2009 OSMO_ASSERT(sgsn_tx_counter == 0);
2010
Alexander Couzens5e33f442017-01-31 15:34:26 +01002011 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002012 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2013 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltec28dc2f2015-12-25 19:12:21 +01002014 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002015
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002016 printf(" - RA Update Request (RA 1 -> RA 2)\n");
2017
2018 /* inject the RA update request */
2019 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2020
2021 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltec28dc2f2015-12-25 19:12:21 +01002022 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002023 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2024
Jacob Erlbeck556aa912016-01-04 18:43:38 +01002025 /* we expect an RA update accept */
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002026 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck556aa912016-01-04 18:43:38 +01002027 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002028
2029 printf(" - RA Update Request (RA other -> RA 2)\n");
2030
2031 /* inject the RA update request */
2032 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2033
2034 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltec28dc2f2015-12-25 19:12:21 +01002035 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002036 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2037
2038 /* we expect an RA update reject (and a LLC XID RESET) */
2039 OSMO_ASSERT(sgsn_tx_counter == 2);
2040 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2041 /* this has killed the LLE/LLME */
2042
2043 printf(" - Attach Request (RA 2)\n");
2044
2045 /* Create a LLE/LLME */
2046 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2047 lle = gprs_lle_get_or_create(ms_tlli, 3);
2048 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2049
2050 /* inject the attach request */
2051 send_0408_message(lle->llme, ms_tlli, &raid2,
2052 attach_req2, ARRAY_SIZE(attach_req2));
2053
2054 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2055 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01002056 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002057 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2058
2059 /* we expect an attach accept */
2060 OSMO_ASSERT(sgsn_tx_counter == 1);
2061 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2062
2063 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2064 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2065 ptmsi1 = received_ptmsi;
2066
2067 /* inject the attach complete */
2068 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2069 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2070 OSMO_ASSERT(ictx != NULL);
2071 OSMO_ASSERT(ictx == ctx);
2072
Harald Weltec28dc2f2015-12-25 19:12:21 +01002073 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002074 attach_compl, ARRAY_SIZE(attach_compl));
2075
2076 /* we don't expect a response */
2077 OSMO_ASSERT(sgsn_tx_counter == 0);
2078
Alexander Couzens5e33f442017-01-31 15:34:26 +01002079 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002080 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2081 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2082
2083 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2084
2085 /* inject the RA update request */
Harald Weltec28dc2f2015-12-25 19:12:21 +01002086 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002087 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2088
2089 /* we expect an RA update accept */
2090 OSMO_ASSERT(sgsn_tx_counter == 1);
2091 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2092
Alexander Couzens5e33f442017-01-31 15:34:26 +01002093 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002094 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2095 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2096 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2097
2098 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2099 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2100 ptmsi1 = received_ptmsi;
2101
2102 /* inject the RA update complete */
2103 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01002104 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002105 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2106
2107 /* we don't expect a response */
2108 OSMO_ASSERT(sgsn_tx_counter == 0);
2109
Alexander Couzens5e33f442017-01-31 15:34:26 +01002110 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002111 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2112 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltec28dc2f2015-12-25 19:12:21 +01002113 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002114
2115
2116 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +01002117 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002118 detach_req, ARRAY_SIZE(detach_req));
2119
2120 /* verify that things are gone */
2121 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2122 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2123 OSMO_ASSERT(!ictx);
2124
2125 sgsn->cfg.auth_policy = saved_auth_policy;
2126
2127 cleanup_test();
2128}
2129
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002130static void test_apn_matching(void)
2131{
2132 struct apn_ctx *actx, *actxs[9];
2133
2134 printf("Testing APN matching\n");
2135
2136 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2137 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2138 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2139 actxs[3] = NULL;
2140
2141 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2142 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2143 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2144 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2145
2146 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2147
2148 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2149 OSMO_ASSERT(actx == actxs[2]);
2150 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2151 OSMO_ASSERT(actx == actxs[2]);
2152 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2153 OSMO_ASSERT(actx == actxs[1]);
2154 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2155 OSMO_ASSERT(actx == actxs[1]);
2156 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2157 OSMO_ASSERT(actx == actxs[0]);
2158 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2159 OSMO_ASSERT(actx == NULL);
2160
2161 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2162 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2163 OSMO_ASSERT(actx == actxs[3]);
2164
2165 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2166 OSMO_ASSERT(actx == actxs[4]);
2167
2168 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2169 OSMO_ASSERT(actx == actxs[6]);
2170
2171 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2172 OSMO_ASSERT(actx == actxs[5]);
2173
2174 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2175 OSMO_ASSERT(actx == actxs[7]);
2176
2177 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2178 OSMO_ASSERT(actx == actxs[8]);
2179
2180 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2181 OSMO_ASSERT(actx == actxs[7]);
2182
2183 /* Free APN contexts and check how the matching changes */
2184
2185 sgsn_apn_ctx_free(actxs[7]);
2186 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2187 OSMO_ASSERT(actx == actxs[8]);
2188
2189 sgsn_apn_ctx_free(actxs[8]);
2190 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2191 OSMO_ASSERT(actx == actxs[6]);
2192
2193 sgsn_apn_ctx_free(actxs[6]);
2194 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2195 OSMO_ASSERT(actx == actxs[1]);
2196
2197 sgsn_apn_ctx_free(actxs[5]);
2198 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2199 OSMO_ASSERT(actx == actxs[4]);
2200
2201 sgsn_apn_ctx_free(actxs[4]);
2202 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2203 OSMO_ASSERT(actx == actxs[2]);
2204
2205 sgsn_apn_ctx_free(actxs[2]);
2206 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2207 OSMO_ASSERT(actx == actxs[1]);
2208
2209 sgsn_apn_ctx_free(actxs[1]);
2210 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2211 OSMO_ASSERT(actx == actxs[0]);
2212
2213 sgsn_apn_ctx_free(actxs[0]);
2214 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2215 OSMO_ASSERT(actx == actxs[3]);
2216
2217 sgsn_apn_ctx_free(actxs[3]);
2218 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2219 OSMO_ASSERT(actx == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02002220
2221 cleanup_test();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002222}
2223
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002224struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2225 struct sgsn_subscriber_data *sdata);
2226
2227static void test_ggsn_selection(void)
2228{
2229 struct apn_ctx *actxs[4];
2230 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
2231 struct gsm_subscriber *s1;
2232 const char *imsi1 = "1234567890";
2233 struct sgsn_mm_ctx *ctx;
2234 struct gprs_ra_id raid = { 0, };
2235 uint32_t local_tlli = 0xffeeddcc;
2236 enum gsm48_gsm_cause gsm_cause;
2237 struct tlv_parsed tp;
2238 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2239 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002240 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002241
2242 printf("Testing GGSN selection\n");
2243
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01002244 gsup_client_send_cb = my_gsup_client_send_dummy;
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002245
2246 /* Check for emptiness */
2247 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2248
2249 /* Create a context */
2250 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2251 ctx = alloc_mm_ctx(local_tlli, &raid);
Neels Hofmeyr5644c2b2017-01-13 03:12:08 +01002252 osmo_strlcpy(ctx->imsi, imsi1, sizeof(ctx->imsi));
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002253
2254 /* Allocate and attach a subscriber */
2255 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2256 assert_subscr(s1, imsi1);
2257
2258 tp.lv[GSM48_IE_GSM_APN].len = 0;
2259 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2260
2261 /* TODO: Add PDP info entries to s1 */
2262
2263 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2264 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2265 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2266
2267 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2268 actxs[0]->ggsn = ggcs[0];
2269 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2270 actxs[1]->ggsn = ggcs[1];
2271 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2272 actxs[2]->ggsn = ggcs[2];
2273
Holger Hans Peter Freytherab9422e2015-05-24 20:51:17 +08002274 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2275 pdp_data->context_id = 1;
2276 pdp_data->pdp_type = 0x0121;
Neels Hofmeyr5644c2b2017-01-13 03:12:08 +01002277 osmo_strlcpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str));
Holger Hans Peter Freytherab9422e2015-05-24 20:51:17 +08002278
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002279 /* Resolve GGSNs */
2280
2281 tp.lv[GSM48_IE_GSM_APN].len =
2282 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2283
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002284 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002285 OSMO_ASSERT(ggc != NULL);
2286 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002287 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002288
2289 tp.lv[GSM48_IE_GSM_APN].len =
2290 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2291
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002292 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002293 OSMO_ASSERT(ggc != NULL);
2294 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002295 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002296
2297 tp.lv[GSM48_IE_GSM_APN].len = 0;
2298 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2299
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002300 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002301 OSMO_ASSERT(ggc != NULL);
2302 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002303 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002304
2305 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2306 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002307 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002308 OSMO_ASSERT(ggc != NULL);
2309 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002310 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002311
2312 sgsn_apn_ctx_free(actxs[3]);
2313 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2314
2315 tp.lv[GSM48_IE_GSM_APN].len =
2316 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2317
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002318 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002319 OSMO_ASSERT(ggc == NULL);
2320 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002321 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002322
2323 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002324 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002325 OSMO_ASSERT(ggc == NULL);
2326 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2327
2328 /* Add PDP data entry to subscriber */
2329
Neels Hofmeyr5644c2b2017-01-13 03:12:08 +01002330 osmo_strlcpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str));
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002331
2332 tp.lv[GSM48_IE_GSM_APN].len =
2333 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2334
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002335 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002336 OSMO_ASSERT(ggc != NULL);
2337 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002338 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002339
2340 tp.lv[GSM48_IE_GSM_APN].len =
2341 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2342
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002343 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002344 OSMO_ASSERT(ggc == NULL);
2345 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002346 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002347
2348 /* Cleanup */
2349
2350 subscr_put(s1);
2351 sgsn_mm_ctx_cleanup_free(ctx);
2352
2353 assert_no_subscrs();
2354
2355 sgsn_apn_ctx_free(actxs[0]);
2356 sgsn_apn_ctx_free(actxs[1]);
2357 sgsn_apn_ctx_free(actxs[2]);
2358
2359 sgsn_ggsn_ctx_free(ggcs[0]);
2360 sgsn_ggsn_ctx_free(ggcs[1]);
2361 sgsn_ggsn_ctx_free(ggcs[2]);
2362
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01002363 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02002364
2365 cleanup_test();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002366}
2367
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002368static struct log_info_cat gprs_categories[] = {
2369 [DMM] = {
2370 .name = "DMM",
2371 .description = "Layer3 Mobility Management (MM)",
2372 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002373 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002374 },
2375 [DPAG] = {
2376 .name = "DPAG",
2377 .description = "Paging Subsystem",
2378 .color = "\033[1;38m",
2379 .enabled = 1, .loglevel = LOGL_NOTICE,
2380 },
2381 [DMEAS] = {
2382 .name = "DMEAS",
2383 .description = "Radio Measurement Processing",
2384 .enabled = 0, .loglevel = LOGL_NOTICE,
2385 },
2386 [DREF] = {
2387 .name = "DREF",
2388 .description = "Reference Counting",
2389 .enabled = 0, .loglevel = LOGL_NOTICE,
2390 },
2391 [DGPRS] = {
2392 .name = "DGPRS",
2393 .description = "GPRS Packet Service",
2394 .enabled = 1, .loglevel = LOGL_DEBUG,
2395 },
2396 [DNS] = {
2397 .name = "DNS",
2398 .description = "GPRS Network Service (NS)",
2399 .enabled = 1, .loglevel = LOGL_INFO,
2400 },
2401 [DBSSGP] = {
2402 .name = "DBSSGP",
2403 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2404 .enabled = 1, .loglevel = LOGL_DEBUG,
2405 },
2406 [DLLC] = {
2407 .name = "DLLC",
2408 .description = "GPRS Logical Link Control Protocol (LLC)",
2409 .enabled = 1, .loglevel = LOGL_DEBUG,
2410 },
2411 [DSNDCP] = {
2412 .name = "DSNDCP",
2413 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2414 .enabled = 1, .loglevel = LOGL_DEBUG,
2415 },
2416};
2417
2418static struct log_info info = {
2419 .cat = gprs_categories,
2420 .num_cat = ARRAY_SIZE(gprs_categories),
2421};
2422
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002423int main(int argc, char **argv)
2424{
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002425 void *osmo_sgsn_ctx;
Neels Hofmeyra73e5f12016-09-16 01:49:08 +02002426 void *msgb_ctx;
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002427
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002428 osmo_init_logging(&info);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002429 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2430 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
Neels Hofmeyra73e5f12016-09-16 01:49:08 +02002431 msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0);
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002432
Alexander Couzens32fdba02016-07-05 09:52:52 +02002433 sgsn_rate_ctr_init();
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01002434 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002435 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002436
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002437 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002438 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01002439 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01002440 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02002441 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01002442 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02002443 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01002444 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01002445 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01002446 test_gmm_attach_acl();
2447 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01002448 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01002449 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01002450 test_gmm_attach_subscr_gsup_auth(0);
2451 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01002452 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01002453 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01002454 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01002455 test_gmm_ptmsi_allocation();
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002456 test_gmm_routing_areas();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002457 test_apn_matching();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002458 test_ggsn_selection();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002459 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01002460
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002461 talloc_report_full(osmo_sgsn_ctx, stderr);
Neels Hofmeyra73e5f12016-09-16 01:49:08 +02002462 OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);
Alexander Couzens32fdba02016-07-05 09:52:52 +02002463 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 2);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002464 return 0;
2465}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002466
2467
2468/* stubs */
2469struct osmo_prim_hdr;
2470int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2471{
2472 abort();
2473}