blob: 58d3a4f86c5a390d4956d2b5d6d8c8d22e6920b4 [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>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020027
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010028#include <osmocom/gprs/gprs_bssgp.h>
29
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020030#include <osmocom/gsm/gsm_utils.h>
31
32#include <osmocom/core/application.h>
33#include <osmocom/core/msgb.h>
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010034#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020035
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +020036#include <stdio.h>
37
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020038extern void *tall_msgb_ctx;
39
40void *tall_bsc_ctx;
41static struct sgsn_instance sgsn_inst = {
42 .config_file = "osmo_sgsn.cfg",
43 .cfg = {
44 .gtp_statedir = "./",
Jacob Erlbeckd7b77732014-11-04 10:08:37 +010045 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020046 },
47};
48struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010049unsigned sgsn_tx_counter = 0;
50
51/* override */
52int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
53 struct bssgp_dl_ud_par *dup)
54{
55 sgsn_tx_counter += 1;
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +010056 msgb_free(msg);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010057 return 0;
58}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020059
Jacob Erlbecke8b69682014-11-12 10:12:11 +010060/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
61void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *, struct gsm_subscriber *);
62void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *, struct gsm_subscriber *) =
63 &__real_sgsn_update_subscriber_data;
64
65void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
66 struct gsm_subscriber *subscr)
67{
68 (*update_subscriber_data_cb)(mmctx, subscr);
69}
70
Jacob Erlbeck828059f2014-11-28 14:55:25 +010071/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
72int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
73int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
74 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +010075
Jacob Erlbeck828059f2014-11-28 14:55:25 +010076int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
77 return (*subscr_request_update_location_cb)(mmctx);
78};
79
80/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
81int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
82int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
83 &__real_gprs_subscr_request_auth_info;
84
85int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
86 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +010087};
Jacob Erlbecke8b69682014-11-12 10:12:11 +010088
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020089static int count(struct llist_head *head)
90{
91 struct llist_head *cur;
92 int count = 0;
93
94 llist_for_each(cur, head)
95 count += 1;
96
97 return count;
98}
99
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200100static struct msgb *create_msg(const uint8_t *data, size_t len)
101{
102 struct msgb *msg = msgb_alloc(len + 8, "test message");
103 msg->l1h = msgb_put(msg, 8);
104 msg->l2h = msgb_put(msg, len);
105 memcpy(msg->l2h, data, len);
106
107 msgb_bcid(msg) = msg->l1h;
108 msgb_gmmh(msg) = msg->l2h;
109 return msg;
110}
111
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100112/*
113 * Create a context and search for it
114 */
115static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
116{
117 struct sgsn_mm_ctx *ctx, *ictx;
118 struct gprs_llc_lle *lle;
119 int old_count = count(gprs_llme_list());
120
121 lle = gprs_lle_get_or_create(tlli, 3);
122 ctx = sgsn_mm_ctx_alloc(tlli, raid);
123 ctx->mm_state = GMM_REGISTERED_NORMAL;
124 ctx->llme = lle->llme;
125
126 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
127 OSMO_ASSERT(ictx == ctx);
128
129 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
130
131 return ctx;
132}
133
Jacob Erlbeck75488292014-10-29 10:31:18 +0100134static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
135 const uint8_t *data, size_t data_len)
136{
137 struct msgb *msg;
138
139 sgsn_tx_counter = 0;
140
141 msg = create_msg(data, data_len);
142 msgb_tlli(msg) = tlli;
143 gsm0408_gprs_rcvmsg(msg, llme);
144 msgb_free(msg);
145}
146
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200147static void test_llme(void)
148{
149 struct gprs_llc_lle *lle, *lle_copy;
150 uint32_t local_tlli;
151 uint32_t foreign_tlli;
152
153 printf("Testing LLME allocations\n");
154 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
155 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
156
157 /* initial state */
158 OSMO_ASSERT(count(gprs_llme_list()) == 0);
159
160 /* Create a new entry */
161 lle = gprs_lle_get_or_create(local_tlli, 3);
162 OSMO_ASSERT(lle);
163 OSMO_ASSERT(count(gprs_llme_list()) == 1);
164
165 /* No new entry is created */
166 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
167 OSMO_ASSERT(lle == lle_copy);
168 OSMO_ASSERT(count(gprs_llme_list()) == 1);
169 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
170 OSMO_ASSERT(lle == lle_copy);
171 OSMO_ASSERT(count(gprs_llme_list()) == 1);
172
173 /* unassign which should delete it*/
174 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
175
176 /* Check that everything was cleaned up */
177 OSMO_ASSERT(count(gprs_llme_list()) == 0);
178}
179
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100180struct gsm_subscriber *last_updated_subscr = NULL;
181void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
182 struct gsm_subscriber *subscr)
183{
184 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
185 __func__, mmctx, subscr);
186 last_updated_subscr = subscr;
187}
188
189static void test_subscriber(void)
190{
191 struct gsm_subscriber *s1, *s2, *s1found, *s2found;
192 const char *imsi1 = "1234567890";
193 const char *imsi2 = "9876543210";
194
195 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
196
197 printf("Testing core subscriber data API\n");
198
199 /* Check for emptiness */
200 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
201 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
202
203 /* Allocate entry 1 */
204 s1 = gprs_subscr_get_or_create(imsi1);
205 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
206 s1found = gprs_subscr_get_by_imsi(imsi1);
207 OSMO_ASSERT(s1found == s1);
208 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
209 subscr_put(s1found);
210
211 /* Allocate entry 2 */
212 s2 = gprs_subscr_get_or_create(imsi2);
213 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
214 s1found = gprs_subscr_get_by_imsi(imsi1);
215 s2found = gprs_subscr_get_by_imsi(imsi2);
216 OSMO_ASSERT(s1found == s1);
217 OSMO_ASSERT(s2found == s2);
218 subscr_put(s1found);
219 subscr_put(s2found);
220
221 /* Update entry 1 */
222 last_updated_subscr = NULL;
223 gprs_subscr_update(s1);
224 OSMO_ASSERT(last_updated_subscr == s1);
225
226 /* Because of the update, it won't be freed on delete now */
227 gprs_subscr_delete(s1);
228 s1found = gprs_subscr_get_by_imsi(imsi1);
229 OSMO_ASSERT(s1found != NULL);
230 s1 = s1found;
231
232 /* Cancel it, so that delete will free it.
233 * Refcount it to make sure s1 won't be freed here */
234 last_updated_subscr = NULL;
235 gprs_subscr_put_and_cancel(subscr_get(s1));
236 OSMO_ASSERT(last_updated_subscr == s1);
237
238 /* Cancelled entries are still being found */
239 s1found = gprs_subscr_get_by_imsi(imsi1);
240 OSMO_ASSERT(s1found != NULL);
241 subscr_put(s1found);
242
243 /* Free entry 1 */
244 gprs_subscr_delete(s1);
245 s1 = NULL;
246 s2found = gprs_subscr_get_by_imsi(imsi2);
247 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
248 OSMO_ASSERT(s2found == s2);
249 subscr_put(s2found);
250
251 /* Free entry 2 */
252 gprs_subscr_delete(s2);
253 s2 = NULL;
254 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
255 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
256
257 OSMO_ASSERT(llist_empty(&active_subscribers));
258
259 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
260}
261
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100262static void test_auth_triplets(void)
263{
264 struct gsm_subscriber *s1, *s1found;
265 const char *imsi1 = "1234567890";
266 struct gsm_auth_tuple *at;
267 struct sgsn_mm_ctx *ctx;
268 struct gprs_ra_id raid = { 0, };
269 uint32_t local_tlli = 0xffeeddcc;
270 struct gprs_llc_llme *llme;
271
272 printf("Testing authentication triplet handling\n");
273
274 /* Check for emptiness */
275 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
276
277 /* Allocate entry 1 */
278 s1 = gprs_subscr_get_or_create(imsi1);
279 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
280 s1found = gprs_subscr_get_by_imsi(imsi1);
281 OSMO_ASSERT(s1found == s1);
282 subscr_put(s1found);
283
284 /* Create a context */
285 OSMO_ASSERT(count(gprs_llme_list()) == 0);
286 ctx = alloc_mm_ctx(local_tlli, &raid);
287
288 /* Attach s1 to ctx */
289 ctx->subscr = subscr_get(s1);
290 ctx->subscr->sgsn_data->mm = ctx;
291
292 /* Try to get auth tuple */
293 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
294 OSMO_ASSERT(at == NULL);
295
296 /* Add triplets */
297 s1->sgsn_data->auth_triplets[0].key_seq = 0;
298 s1->sgsn_data->auth_triplets[1].key_seq = 1;
299 s1->sgsn_data->auth_triplets[2].key_seq = 2;
300
301 /* Try to get auth tuple */
302 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
303 OSMO_ASSERT(at != NULL);
304 OSMO_ASSERT(at->key_seq == 0);
305 OSMO_ASSERT(at->use_count == 1);
306 at = sgsn_auth_get_tuple(ctx, at->key_seq);
307 OSMO_ASSERT(at != NULL);
308 OSMO_ASSERT(at->key_seq == 1);
309 OSMO_ASSERT(at->use_count == 1);
310 at = sgsn_auth_get_tuple(ctx, at->key_seq);
311 OSMO_ASSERT(at != NULL);
312 OSMO_ASSERT(at->key_seq == 2);
313 OSMO_ASSERT(at->use_count == 1);
314 at = sgsn_auth_get_tuple(ctx, at->key_seq);
315 OSMO_ASSERT(at == NULL);
316
317 /* Free MM context and subscriber */
318 subscr_put(s1);
319 llme = ctx->llme;
320 sgsn_mm_ctx_free(ctx);
321 s1found = gprs_subscr_get_by_imsi(imsi1);
322 OSMO_ASSERT(s1found == NULL);
323 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
324}
325
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100326#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
327
328static void test_subscriber_gsup(void)
329{
330 struct gsm_subscriber *s1, *s1found;
331 const char *imsi1 = "1234567890";
332 struct sgsn_mm_ctx *ctx;
333 struct gprs_ra_id raid = { 0, };
334 uint32_t local_tlli = 0xffeeddcc;
335 struct gprs_llc_llme *llme;
336 struct msgb *msg;
337 int rc;
338
339 static const uint8_t send_auth_info_res[] = {
340 0x0a,
341 TEST_GSUP_IMSI1_IE,
342 0x03, 0x22, /* Auth tuple */
343 0x20, 0x10,
344 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
345 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
346 0x21, 0x04,
347 0x21, 0x22, 0x23, 0x24,
348 0x22, 0x08,
349 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
350 0x03, 0x22, /* Auth tuple */
351 0x20, 0x10,
352 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
353 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
354 0x21, 0x04,
355 0xa1, 0xa2, 0xa3, 0xa4,
356 0x22, 0x08,
357 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
358 };
359
360 static const uint8_t send_auth_info_err[] = {
361 0x09,
362 TEST_GSUP_IMSI1_IE,
363 0x02, 0x01, 0x07 /* GPRS not allowed */
364 };
365
366 static const uint8_t update_location_res[] = {
367 0x06,
368 TEST_GSUP_IMSI1_IE,
369 0x04, 0x00, /* PDP info complete */
370 0x05, 0x12,
371 0x10, 0x01, 0x01,
372 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
373 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
374 0x05, 0x11,
375 0x10, 0x01, 0x02,
376 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
377 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
378 };
379
380 static const uint8_t update_location_err[] = {
381 0x05,
382 TEST_GSUP_IMSI1_IE,
383 0x02, 0x01, 0x07 /* GPRS not allowed */
384 };
385
386 static const uint8_t location_cancellation_req[] = {
387 0x1c,
388 TEST_GSUP_IMSI1_IE,
389 0x06, 0x01, 0x00,
390 };
391
392 printf("Testing subcriber GSUP handling\n");
393
394 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
395
396 /* Check for emptiness */
397 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
398
399 /* Allocate entry 1 */
400 s1 = gprs_subscr_get_or_create(imsi1);
401 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
402 s1found = gprs_subscr_get_by_imsi(imsi1);
403 OSMO_ASSERT(s1found == s1);
404 subscr_put(s1found);
405
406 /* Create a context */
407 OSMO_ASSERT(count(gprs_llme_list()) == 0);
408 ctx = alloc_mm_ctx(local_tlli, &raid);
409 llme = ctx->llme;
410
411 /* Attach s1 to ctx */
412 ctx->subscr = subscr_get(s1);
413 ctx->subscr->sgsn_data->mm = ctx;
414
415 /* Inject SendAuthInfoReq GSUP message */
416 msg = msgb_alloc(1024, __func__);
417 msg->l2h = msgb_put(msg, sizeof(send_auth_info_res));
418 memcpy(msg->l2h, send_auth_info_res, sizeof(send_auth_info_res));
419 rc = gprs_subscr_rx_gsup_message(msg);
420 msgb_free(msg);
421 OSMO_ASSERT(rc >= 0);
422 OSMO_ASSERT(last_updated_subscr == s1);
423
424 /* Check triplets */
425 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
426 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
427 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
428
429 /* Inject SendAuthInfoErr GSUP message */
430 msg = msgb_alloc(1024, __func__);
431 msg->l2h = msgb_put(msg, sizeof(send_auth_info_err));
432 memcpy(msg->l2h, send_auth_info_err, sizeof(send_auth_info_err));
433 rc = gprs_subscr_rx_gsup_message(msg);
434 msgb_free(msg);
435 OSMO_ASSERT(rc >= 0);
436 OSMO_ASSERT(last_updated_subscr == s1);
437
438 /* Check triplets */
439 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
440 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
441 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
442
443 /* Inject UpdateLocReq GSUP message */
444 msg = msgb_alloc(1024, __func__);
445 msg->l2h = msgb_put(msg, sizeof(update_location_res));
446 memcpy(msg->l2h, update_location_res, sizeof(update_location_res));
447 rc = gprs_subscr_rx_gsup_message(msg);
448 msgb_free(msg);
449 OSMO_ASSERT(rc >= 0);
450 OSMO_ASSERT(last_updated_subscr == s1);
451
452 /* Check authorization */
453 OSMO_ASSERT(s1->authorized == 1);
454
455 /* Inject UpdateLocErr GSUP message */
456 msg = msgb_alloc(1024, __func__);
457 msg->l2h = msgb_put(msg, sizeof(update_location_err));
458 memcpy(msg->l2h, update_location_err, sizeof(update_location_err));
459 rc = gprs_subscr_rx_gsup_message(msg);
460 msgb_free(msg);
461 OSMO_ASSERT(rc >= 0);
462 OSMO_ASSERT(last_updated_subscr == s1);
463
464 /* Check authorization */
465 OSMO_ASSERT(s1->authorized == 0);
466
467 /* Inject UpdateLocReq GSUP message */
468 msg = msgb_alloc(1024, __func__);
469 msg->l2h = msgb_put(msg, sizeof(location_cancellation_req));
470 memcpy(msg->l2h,
471 location_cancellation_req, sizeof(location_cancellation_req));
472 rc = gprs_subscr_rx_gsup_message(msg);
473 msgb_free(msg);
474 OSMO_ASSERT(rc >= 0);
475 OSMO_ASSERT(last_updated_subscr == s1);
476
477 /* Check cancellation result */
478 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
479 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
480
481 /* Free MM context and subscriber */
482 subscr_put(s1);
483 s1found = gprs_subscr_get_by_imsi(imsi1);
484 OSMO_ASSERT(s1found == NULL);
485 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
486
487 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
488}
489
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200490/*
491 * Test that a GMM Detach will remove the MMCTX and the
492 * associated LLME.
493 */
494static void test_gmm_detach(void)
495{
496 struct gprs_ra_id raid = { 0, };
497 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200498 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200499
500 printf("Testing GMM detach\n");
501
502 /* DTAP - Detach Request (MO) */
503 /* normal detach, power_off = 0 */
504 static const unsigned char detach_req[] = {
505 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
506 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
507 };
508
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200509 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200510
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100511 /* Create a context */
512 OSMO_ASSERT(count(gprs_llme_list()) == 0);
513 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200514
515 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100516 send_0408_message(ctx->llme, local_tlli,
517 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200518
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100519 /* verify that a single message (hopefully the Detach Accept) has been
520 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100521 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100522
523 /* verify that things are gone */
524 OSMO_ASSERT(count(gprs_llme_list()) == 0);
525 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
526 OSMO_ASSERT(!ictx);
527}
528
529/*
530 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
531 * will not sent a Detach Accept message (power_off = 1)
532 */
533static void test_gmm_detach_power_off(void)
534{
535 struct gprs_ra_id raid = { 0, };
536 struct sgsn_mm_ctx *ctx, *ictx;
537 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100538
539 printf("Testing GMM detach (power off)\n");
540
541 /* DTAP - Detach Request (MO) */
542 /* normal detach, power_off = 1 */
543 static const unsigned char detach_req[] = {
544 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
545 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
546 };
547
548 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
549
550 /* Create a context */
551 OSMO_ASSERT(count(gprs_llme_list()) == 0);
552 ctx = alloc_mm_ctx(local_tlli, &raid);
553
554 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100555 send_0408_message(ctx->llme, local_tlli,
556 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100557
558 /* verify that no message (and therefore no Detach Accept) has been
559 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100560 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100561
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200562 /* verify that things are gone */
563 OSMO_ASSERT(count(gprs_llme_list()) == 0);
564 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200565 OSMO_ASSERT(!ictx);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200566}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200567
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200568/*
569 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
570 */
571static void test_gmm_detach_no_mmctx(void)
572{
573 struct gprs_llc_lle *lle;
574 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200575
576 printf("Testing GMM detach (no MMCTX)\n");
577
578 /* DTAP - Detach Request (MO) */
579 /* normal detach, power_off = 0 */
580 static const unsigned char detach_req[] = {
581 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
582 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
583 };
584
585 /* Create an LLME */
586 OSMO_ASSERT(count(gprs_llme_list()) == 0);
587 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
588 lle = gprs_lle_get_or_create(local_tlli, 3);
589
590 OSMO_ASSERT(count(gprs_llme_list()) == 1);
591
592 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100593 send_0408_message(lle->llme, local_tlli,
594 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200595
596 /* verify that the LLME is gone */
597 OSMO_ASSERT(count(gprs_llme_list()) == 0);
598}
599
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100600/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100601 * Test that a single GMM Detach Accept message will not cause the SGSN to send
602 * any message or leave an MM context at the SGSN.
603 */
604static void test_gmm_detach_accept_unexpected(void)
605{
606 struct gprs_llc_lle *lle;
607 uint32_t local_tlli;
608
609 printf("Testing GMM detach accept (unexpected)\n");
610
611 /* DTAP - Detach Accept (MT) */
612 /* normal detach */
613 static const unsigned char detach_acc[] = {
614 0x08, 0x06
615 };
616
617 /* Create an LLME */
618 OSMO_ASSERT(count(gprs_llme_list()) == 0);
619 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
620 lle = gprs_lle_get_or_create(local_tlli, 3);
621
622 /* inject the detach */
623 send_0408_message(lle->llme, local_tlli,
624 detach_acc, ARRAY_SIZE(detach_acc));
625
626 /* verify that no message (and therefore no Status or XID reset) has been
627 * sent by the SGSN */
628 OSMO_ASSERT(sgsn_tx_counter == 0);
629
630 /* verify that things are gone */
631 OSMO_ASSERT(count(gprs_llme_list()) == 0);
632}
633
634/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100635 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
636 */
637static void test_gmm_status_no_mmctx(void)
638{
639 struct gprs_llc_lle *lle;
640 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100641
642 printf("Testing GMM Status (no MMCTX)\n");
643
644 /* DTAP - GMM Status, protocol error */
645 static const unsigned char gmm_status[] = {
646 0x08, 0x20, 0x6f
647 };
648
649 /* Create an LLME */
650 OSMO_ASSERT(count(gprs_llme_list()) == 0);
651 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
652 lle = gprs_lle_get_or_create(local_tlli, 3);
653
654 OSMO_ASSERT(count(gprs_llme_list()) == 1);
655
656 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100657 send_0408_message(lle->llme, local_tlli,
658 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100659
660 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100661 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100662
663 /* verify that the LLME is gone */
664 OSMO_ASSERT(count(gprs_llme_list()) == 0);
665}
666
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100667/*
668 * Test the GMM Attach procedure
669 */
670static void test_gmm_attach(void)
671{
672 struct gprs_ra_id raid = { 0, };
673 struct sgsn_mm_ctx *ctx = NULL;
674 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100675 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100676 uint32_t foreign_tlli;
677 uint32_t local_tlli = 0;
678 struct gprs_llc_lle *lle;
679
680 /* DTAP - Attach Request */
681 /* The P-TMSI is not known by the SGSN */
682 static const unsigned char attach_req[] = {
683 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
684 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
685 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
686 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
687 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
688 };
689
690 /* DTAP - Identity Response IMEI */
691 static const unsigned char ident_resp_imei[] = {
692 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
693 0x56
694 };
695
696 /* DTAP - Identity Response IMSI */
697 static const unsigned char ident_resp_imsi[] = {
698 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
699 0x54
700 };
701
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100702 /* DTAP - Authentication and Ciphering Resp */
703 static const unsigned char auth_ciph_resp[] = {
704 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
705 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
706 };
707
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100708 /* DTAP - Attach Complete */
709 static const unsigned char attach_compl[] = {
710 0x08, 0x03
711 };
712
713 /* DTAP - Detach Request (MO) */
714 /* normal detach, power_off = 0 */
715 static const unsigned char detach_req[] = {
716 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
717 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
718 };
719
720 printf("Testing GMM attach\n");
721
722 /* reset the PRNG used by sgsn_alloc_ptmsi */
723 srand(1);
724
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100725 ptmsi1 = sgsn_alloc_ptmsi();
726 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
727
728 /* reset the PRNG, so that the same P-TMSI sequence will be generated
729 * again */
730 srand(1);
731
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100732 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
733
734 /* Create a LLE/LLME */
735 OSMO_ASSERT(count(gprs_llme_list()) == 0);
736 lle = gprs_lle_get_or_create(foreign_tlli, 3);
737 OSMO_ASSERT(count(gprs_llme_list()) == 1);
738
739 /* inject the attach request */
740 send_0408_message(lle->llme, foreign_tlli,
741 attach_req, ARRAY_SIZE(attach_req));
742
743 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
744 OSMO_ASSERT(ctx != NULL);
745 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
746
747 /* we expect an identity request (IMEI) */
748 OSMO_ASSERT(sgsn_tx_counter == 1);
749
750 /* inject the identity response (IMEI) */
751 send_0408_message(ctx->llme, foreign_tlli,
752 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
753
754 /* we expect an identity request (IMSI) */
755 OSMO_ASSERT(sgsn_tx_counter == 1);
756
757 /* inject the identity response (IMSI) */
758 send_0408_message(ctx->llme, foreign_tlli,
759 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
760
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100761 /* check that the MM context has not been removed due to a failed
762 * authorization */
763 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
764
Jacob Erlbeck67318ef2014-10-28 16:23:46 +0100765 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100766
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100767 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE) {
768 /* we expect an auth & ciph request */
769 OSMO_ASSERT(sgsn_tx_counter == 1);
770
771 /* inject the auth & ciph response */
772 send_0408_message(ctx->llme, foreign_tlli,
773 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
774
775 /* check that the MM context has not been removed due to a
776 * failed authorization */
777 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
778 }
779
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100780 /* we expect an attach accept/reject */
781 OSMO_ASSERT(sgsn_tx_counter == 1);
782
783 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100784 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100785
786 /* inject the attach complete */
787 send_0408_message(ctx->llme, local_tlli,
788 attach_compl, ARRAY_SIZE(attach_compl));
789
790 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
791
792 /* we don't expect a response */
793 OSMO_ASSERT(sgsn_tx_counter == 0);
794
795 /* inject the detach */
796 send_0408_message(ctx->llme, local_tlli,
797 detach_req, ARRAY_SIZE(detach_req));
798
799 /* verify that things are gone */
800 OSMO_ASSERT(count(gprs_llme_list()) == 0);
801 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
802 OSMO_ASSERT(!ictx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100803}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100804
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100805static void test_gmm_attach_acl(void)
806{
807 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
808
809 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
810 sgsn_acl_add("123456789012345", &sgsn->cfg);
811 printf("Auth policy 'closed': ");
812 test_gmm_attach();
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100813 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100814
815 sgsn->cfg.auth_policy = saved_auth_policy;
816}
817
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100818int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100819 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100820 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100821 if (rc == -ENOTSUP) {
822 OSMO_ASSERT(mmctx->subscr);
823 gprs_subscr_update(mmctx->subscr);
824 }
825 return rc;
826};
827
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100828int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
829 gprs_subscr_update(mmctx->subscr);
830 return 0;
831};
832
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100833static void test_gmm_attach_subscr(void)
834{
835 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
836 struct gsm_subscriber *subscr;
837
838 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100839 subscr_request_update_location_cb = my_subscr_request_update_location;
840 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100841
842 subscr = gprs_subscr_get_or_create("123456789012345");
843 subscr->authorized = 1;
844 subscr_put(subscr);
845
846 printf("Auth policy 'remote': ");
847 test_gmm_attach();
848
849 subscr = gprs_subscr_get_by_imsi("123456789012345");
850 OSMO_ASSERT(subscr != NULL);
851 gprs_subscr_delete(subscr);
852
853 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100854 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
855 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100856}
857
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100858int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
859{
860 /* Fake an authentication */
861 OSMO_ASSERT(mmctx->subscr);
862 mmctx->is_authenticated = 1;
863 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100864
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100865 return 0;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100866};
867
868static void test_gmm_attach_subscr_fake_auth(void)
869{
870 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
871 struct gsm_subscriber *subscr;
872
873 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100874 subscr_request_update_location_cb = my_subscr_request_update_location;
875 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100876
877 subscr = gprs_subscr_get_or_create("123456789012345");
878 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +0100879 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +0100880 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100881 subscr_put(subscr);
882
883 printf("Auth policy 'remote', auth faked: ");
884 test_gmm_attach();
885
886 subscr = gprs_subscr_get_by_imsi("123456789012345");
887 OSMO_ASSERT(subscr != NULL);
888 gprs_subscr_delete(subscr);
889
890 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100891 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
892 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
893}
894
895int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
896{
897 struct gsm_auth_tuple at = {
898 .sres = {0x51, 0xe5, 0x51, 0xe5},
899 .key_seq = 0
900 };
901
902 /* Fake an authentication */
903 OSMO_ASSERT(mmctx->subscr);
904 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
905
906 gprs_subscr_update_auth_info(mmctx->subscr);
907
908 return 0;
909};
910
911static void test_gmm_attach_subscr_real_auth(void)
912{
913 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
914 struct gsm_subscriber *subscr;
915
916 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
917 subscr_request_update_location_cb = my_subscr_request_update_location;
918 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
919
920 subscr = gprs_subscr_get_or_create("123456789012345");
921 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +0100922 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +0100923 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100924 subscr_put(subscr);
925
926 printf("Auth policy 'remote', triplet based auth: ");
927 test_gmm_attach();
928
929 subscr = gprs_subscr_get_by_imsi("123456789012345");
930 OSMO_ASSERT(subscr != NULL);
931 gprs_subscr_delete(subscr);
932
933 sgsn->cfg.auth_policy = saved_auth_policy;
934 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
935 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100936}
937
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +0100938/*
939 * Test the GMM Rejects
940 */
941static void test_gmm_reject(void)
942{
943 struct gprs_ra_id raid = { 0, };
944 struct sgsn_mm_ctx *ctx = NULL;
945 uint32_t foreign_tlli;
946 struct gprs_llc_lle *lle;
947 int idx;
948
949 /* DTAP - Attach Request */
950 /* Invalid MI length */
951 static const unsigned char attach_req_inv_mi_len[] = {
952 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
953 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
954 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
955 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
956 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
957 };
958
959 /* DTAP - Attach Request */
960 /* Invalid MI type (IMEI) */
961 static const unsigned char attach_req_inv_mi_type[] = {
962 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
963 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
964 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
965 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
966 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
967 };
968
969 /* DTAP - Routing Area Update Request */
970 static const unsigned char dtap_ra_upd_req[] = {
971 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
972 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
973 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
974 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
975 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
976 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
977 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
978 };
979
980 /* DTAP - Routing Area Update Request */
981 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
982 static const unsigned char dtap_ra_upd_req_inv_type[] = {
983 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
984 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
985 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
986 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
987 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
988 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
989 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
990 };
991
992 /* DTAP - Routing Area Update Request */
993 /* Invalid cap length */
994 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
995 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
996 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
997 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
998 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
999 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1000 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1001 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1002 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1003 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1004 };
1005
1006 struct test {
1007 const char *title;
1008 const unsigned char *msg;
1009 unsigned msg_len;
1010 unsigned num_resp;
1011
1012 };
1013 static struct test tests[] = {
1014 {
1015 .title = "Attach Request (invalid MI length)",
1016 .msg = attach_req_inv_mi_len,
1017 .msg_len = sizeof(attach_req_inv_mi_len),
1018 .num_resp = 1 /* Reject */
1019
1020 },
1021 {
1022 .title = "Attach Request (invalid MI type)",
1023 .msg = attach_req_inv_mi_type,
1024 .msg_len = sizeof(attach_req_inv_mi_type),
1025 .num_resp = 1 /* Reject */
1026 },
1027 {
1028 .title = "Routing Area Update Request (valid)",
1029 .msg = dtap_ra_upd_req,
1030 .msg_len = sizeof(dtap_ra_upd_req),
1031 .num_resp = 2 /* XID Reset + Reject */
1032 },
1033 {
1034 .title = "Routing Area Update Request (invalid type)",
1035 .msg = dtap_ra_upd_req_inv_type,
1036 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1037 .num_resp = 1 /* Reject */
1038 },
1039 {
1040 .title = "Routing Area Update Request (invalid CAP length)",
1041 .msg = dtap_ra_upd_req_inv_cap_len,
1042 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1043 .num_resp = 1 /* Reject */
1044 },
1045 };
1046
1047 printf("Testing GMM reject\n");
1048
1049 /* reset the PRNG used by sgsn_alloc_ptmsi */
1050 srand(1);
1051
1052 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1053
1054 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1055
1056 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1057 const struct test *test = &tests[idx];
1058 printf(" - %s\n", test->title);
1059
1060 /* Create a LLE/LLME */
1061 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1062 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1063
1064 /* Inject the Request message */
1065 send_0408_message(lle->llme, foreign_tlli,
1066 test->msg, test->msg_len);
1067
1068 /* We expect a Reject message */
1069 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1070 sgsn_tx_counter, test->num_resp);
1071 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1072
1073 /* verify that LLME/MM are removed */
1074 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1075 OSMO_ASSERT(ctx == NULL);
1076 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1077 }
1078}
1079
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001080/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001081 * Test cancellation of attached MM contexts
1082 */
1083static void test_gmm_cancel(void)
1084{
1085 struct gprs_ra_id raid = { 0, };
1086 struct sgsn_mm_ctx *ctx = NULL;
1087 struct sgsn_mm_ctx *ictx;
1088 uint32_t ptmsi1;
1089 uint32_t foreign_tlli;
1090 uint32_t local_tlli = 0;
1091 struct gprs_llc_lle *lle;
1092 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1093
1094 /* DTAP - Attach Request */
1095 /* The P-TMSI is not known by the SGSN */
1096 static const unsigned char attach_req[] = {
1097 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1098 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1099 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1100 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1101 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1102 };
1103
1104 /* DTAP - Identity Response IMEI */
1105 static const unsigned char ident_resp_imei[] = {
1106 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1107 0x56
1108 };
1109
1110 /* DTAP - Identity Response IMSI */
1111 static const unsigned char ident_resp_imsi[] = {
1112 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1113 0x54
1114 };
1115
1116 /* DTAP - Attach Complete */
1117 static const unsigned char attach_compl[] = {
1118 0x08, 0x03
1119 };
1120
1121 printf("Testing cancellation\n");
1122
1123 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1124
1125 /* reset the PRNG used by sgsn_alloc_ptmsi */
1126 srand(1);
1127
1128 ptmsi1 = sgsn_alloc_ptmsi();
1129 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1130
1131 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1132 * again */
1133 srand(1);
1134
1135 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1136
1137 /* Create a LLE/LLME */
1138 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1139 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1140 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1141
1142 /* inject the attach request */
1143 send_0408_message(lle->llme, foreign_tlli,
1144 attach_req, ARRAY_SIZE(attach_req));
1145
1146 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1147 OSMO_ASSERT(ctx != NULL);
1148 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1149
1150 /* we expect an identity request (IMEI) */
1151 OSMO_ASSERT(sgsn_tx_counter == 1);
1152
1153 /* inject the identity response (IMEI) */
1154 send_0408_message(ctx->llme, foreign_tlli,
1155 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1156
1157 /* we expect an identity request (IMSI) */
1158 OSMO_ASSERT(sgsn_tx_counter == 1);
1159
1160 /* inject the identity response (IMSI) */
1161 send_0408_message(ctx->llme, foreign_tlli,
1162 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1163
1164 /* check that the MM context has not been removed due to a failed
1165 * authorization */
1166 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1167
1168 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1169
1170 /* we expect an attach accept/reject */
1171 OSMO_ASSERT(sgsn_tx_counter == 1);
1172
1173 /* this has been randomly assigned by the SGSN */
1174 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1175
1176 /* inject the attach complete */
1177 send_0408_message(ctx->llme, local_tlli,
1178 attach_compl, ARRAY_SIZE(attach_compl));
1179
1180 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1181
1182 /* we don't expect a response */
1183 OSMO_ASSERT(sgsn_tx_counter == 0);
1184
1185 /* cancel */
1186 gsm0408_gprs_access_cancelled(ctx);
1187
1188 /* verify that things are gone */
1189 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1190 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1191 OSMO_ASSERT(!ictx);
1192
1193 sgsn->cfg.auth_policy = saved_auth_policy;
1194}
1195
1196/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001197 * Test the dynamic allocation of P-TMSIs
1198 */
1199static void test_gmm_ptmsi_allocation(void)
1200{
1201 struct gprs_ra_id raid = { 0, };
1202 struct sgsn_mm_ctx *ctx = NULL;
1203 struct sgsn_mm_ctx *ictx;
1204 uint32_t foreign_tlli;
1205 uint32_t ptmsi1;
1206 uint32_t ptmsi2;
1207 uint32_t old_ptmsi;
1208 uint32_t local_tlli = 0;
1209 struct gprs_llc_lle *lle;
1210 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1211
1212 /* DTAP - Attach Request (IMSI 12131415161718) */
1213 static const unsigned char attach_req[] = {
1214 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1215 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1216 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1217 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1218 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1219 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1220 0x00,
1221 };
1222
1223 /* DTAP - Identity Response IMEI */
1224 static const unsigned char ident_resp_imei[] = {
1225 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1226 0x56
1227 };
1228
1229 /* DTAP - Attach Complete */
1230 static const unsigned char attach_compl[] = {
1231 0x08, 0x03
1232 };
1233
1234 /* DTAP - Routing Area Update Request */
1235 static const unsigned char ra_upd_req[] = {
1236 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1237 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1238 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1239 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1240 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1241 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1242 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1243 };
1244
1245 /* DTAP - Routing Area Update Complete */
1246 static const unsigned char ra_upd_complete[] = {
1247 0x08, 0x0a
1248 };
1249
1250 /* DTAP - Detach Request (MO) */
1251 /* normal detach, power_off = 1 */
1252 static const unsigned char detach_req[] = {
1253 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1254 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1255 };
1256
1257 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1258
1259 printf("Testing P-TMSI allocation\n");
1260
1261 printf(" - sgsn_alloc_ptmsi\n");
1262
1263 /* reset the PRNG used by sgsn_alloc_ptmsi */
1264 srand(1);
1265
1266 ptmsi1 = sgsn_alloc_ptmsi();
1267 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1268
1269 ptmsi2 = sgsn_alloc_ptmsi();
1270 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1271
1272 OSMO_ASSERT(ptmsi1 != ptmsi2);
1273
1274 printf(" - Repeated Attach Request\n");
1275
1276 /* reset the PRNG, so that the same P-TMSI will be generated
1277 * again */
1278 srand(1);
1279
1280 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1281
1282 /* Create a LLE/LLME */
1283 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1284 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1285 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1286
1287 /* inject the attach request */
1288 send_0408_message(lle->llme, foreign_tlli,
1289 attach_req, ARRAY_SIZE(attach_req));
1290
1291 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1292 OSMO_ASSERT(ctx != NULL);
1293 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1294 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1295
1296 old_ptmsi = ctx->p_tmsi_old;
1297
1298 /* we expect an identity request (IMEI) */
1299 OSMO_ASSERT(sgsn_tx_counter == 1);
1300
1301 /* inject the identity response (IMEI) */
1302 send_0408_message(ctx->llme, foreign_tlli,
1303 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1304
1305 /* check that the MM context has not been removed due to a failed
1306 * authorization */
1307 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1308
1309 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1310 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1311
1312 /* we expect an attach accept */
1313 OSMO_ASSERT(sgsn_tx_counter == 1);
1314
1315 /* we ignore this and send the attach again */
1316 send_0408_message(lle->llme, foreign_tlli,
1317 attach_req, ARRAY_SIZE(attach_req));
1318
1319 /* the allocated P-TMSI should be the same */
1320 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1321 OSMO_ASSERT(ctx != NULL);
1322 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1323 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1324 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1325
1326 /* inject the attach complete */
1327 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1328 send_0408_message(ctx->llme, local_tlli,
1329 attach_compl, ARRAY_SIZE(attach_compl));
1330
1331 /* we don't expect a response */
1332 OSMO_ASSERT(sgsn_tx_counter == 0);
1333
1334 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1335 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1336 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1337
1338 printf(" - Repeated RA Update Request\n");
1339
1340 /* inject the RA update request */
1341 send_0408_message(ctx->llme, local_tlli,
1342 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1343
1344 /* we expect an RA update accept */
1345 OSMO_ASSERT(sgsn_tx_counter == 1);
1346
1347 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1348 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1349 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1350
1351 /* repeat the RA update request */
1352 send_0408_message(ctx->llme, local_tlli,
1353 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1354
1355 /* we expect an RA update accept */
1356 OSMO_ASSERT(sgsn_tx_counter == 1);
1357
1358 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1359 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1360 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1361
1362 /* inject the RA update complete */
1363 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1364 send_0408_message(ctx->llme, local_tlli,
1365 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1366
1367 /* we don't expect a response */
1368 OSMO_ASSERT(sgsn_tx_counter == 0);
1369
1370 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1371 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1372 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1373
1374 /* inject the detach */
1375 send_0408_message(ctx->llme, local_tlli,
1376 detach_req, ARRAY_SIZE(detach_req));
1377
1378 /* verify that things are gone */
1379 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1380 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1381 OSMO_ASSERT(!ictx);
1382
1383 sgsn->cfg.auth_policy = saved_auth_policy;
1384}
1385
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001386static struct log_info_cat gprs_categories[] = {
1387 [DMM] = {
1388 .name = "DMM",
1389 .description = "Layer3 Mobility Management (MM)",
1390 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001391 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001392 },
1393 [DPAG] = {
1394 .name = "DPAG",
1395 .description = "Paging Subsystem",
1396 .color = "\033[1;38m",
1397 .enabled = 1, .loglevel = LOGL_NOTICE,
1398 },
1399 [DMEAS] = {
1400 .name = "DMEAS",
1401 .description = "Radio Measurement Processing",
1402 .enabled = 0, .loglevel = LOGL_NOTICE,
1403 },
1404 [DREF] = {
1405 .name = "DREF",
1406 .description = "Reference Counting",
1407 .enabled = 0, .loglevel = LOGL_NOTICE,
1408 },
1409 [DGPRS] = {
1410 .name = "DGPRS",
1411 .description = "GPRS Packet Service",
1412 .enabled = 1, .loglevel = LOGL_DEBUG,
1413 },
1414 [DNS] = {
1415 .name = "DNS",
1416 .description = "GPRS Network Service (NS)",
1417 .enabled = 1, .loglevel = LOGL_INFO,
1418 },
1419 [DBSSGP] = {
1420 .name = "DBSSGP",
1421 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1422 .enabled = 1, .loglevel = LOGL_DEBUG,
1423 },
1424 [DLLC] = {
1425 .name = "DLLC",
1426 .description = "GPRS Logical Link Control Protocol (LLC)",
1427 .enabled = 1, .loglevel = LOGL_DEBUG,
1428 },
1429 [DSNDCP] = {
1430 .name = "DSNDCP",
1431 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1432 .enabled = 1, .loglevel = LOGL_DEBUG,
1433 },
1434};
1435
1436static struct log_info info = {
1437 .cat = gprs_categories,
1438 .num_cat = ARRAY_SIZE(gprs_categories),
1439};
1440
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001441int main(int argc, char **argv)
1442{
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001443 osmo_init_logging(&info);
1444 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1445 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1446
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01001447 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001448 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001449
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001450 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001451 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01001452 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01001453 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02001454 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01001455 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02001456 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01001457 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01001458 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001459 test_gmm_attach_acl();
1460 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001461 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001462 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001463 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001464 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001465 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001466 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01001467
1468 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01001469 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001470 return 0;
1471}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001472
1473
1474/* stubs */
1475struct osmo_prim_hdr;
1476int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1477{
1478 abort();
1479}