blob: ebe12c906dc44bf21d06ba2c6da4fc1acb6fc77a [file] [log] [blame]
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020027
Jacob Erlbeck189999d2014-10-27 14:34:13 +010028#include <osmocom/gprs/gprs_bssgp.h>
29
Holger Hans Peter Freyther4299c052014-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 Erlbeck189999d2014-10-27 14:34:13 +010034#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020035
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020036#include <stdio.h>
37
Holger Hans Peter Freyther4299c052014-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 Erlbeck106f5472014-11-04 10:08:37 +010045 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020046 },
47};
48struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-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 Erlbeckf0b06d82015-01-13 11:56:28 +010056 msgb_free(msg);
Jacob Erlbeck189999d2014-10-27 14:34:13 +010057 return 0;
58}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020059
Jacob Erlbeck33b6dad2014-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 Erlbeck98a95ac2014-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 Erlbeckbe2c8d92014-11-12 10:18:09 +010075
Jacob Erlbeck98a95ac2014-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 Erlbeckbe2c8d92014-11-12 10:18:09 +010087};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010088
Holger Hans Peter Freyther4299c052014-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 Freytherfe921332014-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 Erlbeckabc16a52014-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 Erlbeck94ef1c02014-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 Freyther4299c052014-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 Erlbeck33b6dad2014-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 Erlbeck7921ab12014-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 Erlbecka6ddc2d2014-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 Freytherfe921332014-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 Freytherfe921332014-10-02 22:24:47 +0200498 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-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 Freytherfe921332014-10-02 22:24:47 +0200509 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200510
Jacob Erlbeckabc16a52014-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 Freytherfe921332014-10-02 22:24:47 +0200514
515 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100516 send_0408_message(ctx->llme, local_tlli,
517 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200518
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100519 /* verify that a single message (hopefully the Detach Accept) has been
520 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100521 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-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 Erlbeck189999d2014-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 Erlbeck94ef1c02014-10-29 10:31:18 +0100555 send_0408_message(ctx->llme, local_tlli,
556 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100557
558 /* verify that no message (and therefore no Detach Accept) has been
559 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100560 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100561
Holger Hans Peter Freytherfe921332014-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 Erlbeck258ce3d2014-09-30 13:51:45 +0200565 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200566}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200567
Jacob Erlbeck5a38f642014-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 Erlbeck5a38f642014-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 Erlbeck94ef1c02014-10-29 10:31:18 +0100593 send_0408_message(lle->llme, local_tlli,
594 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200595
596 /* verify that the LLME is gone */
597 OSMO_ASSERT(count(gprs_llme_list()) == 0);
598}
599
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100600/*
Jacob Erlbeckde4bbc72014-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 Erlbeck14ae5822014-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 Erlbeck14ae5822014-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 Erlbeck94ef1c02014-10-29 10:31:18 +0100657 send_0408_message(lle->llme, local_tlli,
658 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100659
660 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100661 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100662
663 /* verify that the LLME is gone */
664 OSMO_ASSERT(count(gprs_llme_list()) == 0);
665}
666
Jacob Erlbeck27cb4d52014-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 Erlbeckaec03a12014-11-24 14:40:28 +0100675 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-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 Erlbeck98a95ac2014-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 Erlbeck27cb4d52014-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 Erlbeckaec03a12014-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 Erlbeck27cb4d52014-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 Erlbeck27cb4d52014-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 Erlbeck0074a772014-10-28 16:23:46 +0100765 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100766
Jacob Erlbeck98a95ac2014-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 Erlbeck27cb4d52014-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 Erlbeckaec03a12014-11-24 14:40:28 +0100784 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-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 Erlbeckbe2c8d92014-11-12 10:18:09 +0100803}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100804
Jacob Erlbeckbe2c8d92014-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 Erlbeck0c06f982014-10-29 22:12:20 +0100813 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100814
815 sgsn->cfg.auth_policy = saved_auth_policy;
816}
817
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100818int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100819 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100820 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-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 Erlbeck98a95ac2014-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 Erlbeckbe2c8d92014-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 Erlbeck98a95ac2014-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 Erlbeckbe2c8d92014-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 Erlbeck98a95ac2014-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 Erlbeck27cb4d52014-10-29 12:11:58 +0100856}
857
Jacob Erlbeck98a95ac2014-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 Erlbeck2e5e94c2014-12-08 15:26:47 +0100864
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100865 return 0;
Jacob Erlbeck2e5e94c2014-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 Erlbeck98a95ac2014-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 Erlbeck2e5e94c2014-12-08 15:26:47 +0100876
877 subscr = gprs_subscr_get_or_create("123456789012345");
878 subscr->authorized = 1;
879 subscr->sgsn_data->authenticate = 1;
880 subscr_put(subscr);
881
882 printf("Auth policy 'remote', auth faked: ");
883 test_gmm_attach();
884
885 subscr = gprs_subscr_get_by_imsi("123456789012345");
886 OSMO_ASSERT(subscr != NULL);
887 gprs_subscr_delete(subscr);
888
889 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100890 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
891 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
892}
893
894int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
895{
896 struct gsm_auth_tuple at = {
897 .sres = {0x51, 0xe5, 0x51, 0xe5},
898 .key_seq = 0
899 };
900
901 /* Fake an authentication */
902 OSMO_ASSERT(mmctx->subscr);
903 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
904
905 gprs_subscr_update_auth_info(mmctx->subscr);
906
907 return 0;
908};
909
910static void test_gmm_attach_subscr_real_auth(void)
911{
912 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
913 struct gsm_subscriber *subscr;
914
915 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
916 subscr_request_update_location_cb = my_subscr_request_update_location;
917 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
918
919 subscr = gprs_subscr_get_or_create("123456789012345");
920 subscr->authorized = 1;
921 subscr->sgsn_data->authenticate = 1;
922 subscr_put(subscr);
923
924 printf("Auth policy 'remote', triplet based auth: ");
925 test_gmm_attach();
926
927 subscr = gprs_subscr_get_by_imsi("123456789012345");
928 OSMO_ASSERT(subscr != NULL);
929 gprs_subscr_delete(subscr);
930
931 sgsn->cfg.auth_policy = saved_auth_policy;
932 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
933 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +0100934}
935
Jacob Erlbeck80d07e32014-11-06 13:43:41 +0100936/*
937 * Test the GMM Rejects
938 */
939static void test_gmm_reject(void)
940{
941 struct gprs_ra_id raid = { 0, };
942 struct sgsn_mm_ctx *ctx = NULL;
943 uint32_t foreign_tlli;
944 struct gprs_llc_lle *lle;
945 int idx;
946
947 /* DTAP - Attach Request */
948 /* Invalid MI length */
949 static const unsigned char attach_req_inv_mi_len[] = {
950 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
951 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
952 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
953 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
954 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
955 };
956
957 /* DTAP - Attach Request */
958 /* Invalid MI type (IMEI) */
959 static const unsigned char attach_req_inv_mi_type[] = {
960 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
961 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
962 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
963 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
964 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
965 };
966
967 /* DTAP - Routing Area Update Request */
968 static const unsigned char dtap_ra_upd_req[] = {
969 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
970 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
971 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
972 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
973 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
974 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
975 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
976 };
977
978 /* DTAP - Routing Area Update Request */
979 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
980 static const unsigned char dtap_ra_upd_req_inv_type[] = {
981 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
982 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
983 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
984 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
985 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
986 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
987 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
988 };
989
990 /* DTAP - Routing Area Update Request */
991 /* Invalid cap length */
992 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
993 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
994 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
995 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
996 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
997 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
998 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
999 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1000 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1001 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1002 };
1003
1004 struct test {
1005 const char *title;
1006 const unsigned char *msg;
1007 unsigned msg_len;
1008 unsigned num_resp;
1009
1010 };
1011 static struct test tests[] = {
1012 {
1013 .title = "Attach Request (invalid MI length)",
1014 .msg = attach_req_inv_mi_len,
1015 .msg_len = sizeof(attach_req_inv_mi_len),
1016 .num_resp = 1 /* Reject */
1017
1018 },
1019 {
1020 .title = "Attach Request (invalid MI type)",
1021 .msg = attach_req_inv_mi_type,
1022 .msg_len = sizeof(attach_req_inv_mi_type),
1023 .num_resp = 1 /* Reject */
1024 },
1025 {
1026 .title = "Routing Area Update Request (valid)",
1027 .msg = dtap_ra_upd_req,
1028 .msg_len = sizeof(dtap_ra_upd_req),
1029 .num_resp = 2 /* XID Reset + Reject */
1030 },
1031 {
1032 .title = "Routing Area Update Request (invalid type)",
1033 .msg = dtap_ra_upd_req_inv_type,
1034 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1035 .num_resp = 1 /* Reject */
1036 },
1037 {
1038 .title = "Routing Area Update Request (invalid CAP length)",
1039 .msg = dtap_ra_upd_req_inv_cap_len,
1040 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1041 .num_resp = 1 /* Reject */
1042 },
1043 };
1044
1045 printf("Testing GMM reject\n");
1046
1047 /* reset the PRNG used by sgsn_alloc_ptmsi */
1048 srand(1);
1049
1050 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1051
1052 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1053
1054 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1055 const struct test *test = &tests[idx];
1056 printf(" - %s\n", test->title);
1057
1058 /* Create a LLE/LLME */
1059 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1060 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1061
1062 /* Inject the Request message */
1063 send_0408_message(lle->llme, foreign_tlli,
1064 test->msg, test->msg_len);
1065
1066 /* We expect a Reject message */
1067 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1068 sgsn_tx_counter, test->num_resp);
1069 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1070
1071 /* verify that LLME/MM are removed */
1072 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1073 OSMO_ASSERT(ctx == NULL);
1074 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1075 }
1076}
1077
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001078/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001079 * Test cancellation of attached MM contexts
1080 */
1081static void test_gmm_cancel(void)
1082{
1083 struct gprs_ra_id raid = { 0, };
1084 struct sgsn_mm_ctx *ctx = NULL;
1085 struct sgsn_mm_ctx *ictx;
1086 uint32_t ptmsi1;
1087 uint32_t foreign_tlli;
1088 uint32_t local_tlli = 0;
1089 struct gprs_llc_lle *lle;
1090 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1091
1092 /* DTAP - Attach Request */
1093 /* The P-TMSI is not known by the SGSN */
1094 static const unsigned char attach_req[] = {
1095 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1096 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1097 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1098 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1099 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1100 };
1101
1102 /* DTAP - Identity Response IMEI */
1103 static const unsigned char ident_resp_imei[] = {
1104 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1105 0x56
1106 };
1107
1108 /* DTAP - Identity Response IMSI */
1109 static const unsigned char ident_resp_imsi[] = {
1110 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1111 0x54
1112 };
1113
1114 /* DTAP - Attach Complete */
1115 static const unsigned char attach_compl[] = {
1116 0x08, 0x03
1117 };
1118
1119 printf("Testing cancellation\n");
1120
1121 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1122
1123 /* reset the PRNG used by sgsn_alloc_ptmsi */
1124 srand(1);
1125
1126 ptmsi1 = sgsn_alloc_ptmsi();
1127 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1128
1129 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1130 * again */
1131 srand(1);
1132
1133 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1134
1135 /* Create a LLE/LLME */
1136 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1137 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1138 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1139
1140 /* inject the attach request */
1141 send_0408_message(lle->llme, foreign_tlli,
1142 attach_req, ARRAY_SIZE(attach_req));
1143
1144 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1145 OSMO_ASSERT(ctx != NULL);
1146 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1147
1148 /* we expect an identity request (IMEI) */
1149 OSMO_ASSERT(sgsn_tx_counter == 1);
1150
1151 /* inject the identity response (IMEI) */
1152 send_0408_message(ctx->llme, foreign_tlli,
1153 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1154
1155 /* we expect an identity request (IMSI) */
1156 OSMO_ASSERT(sgsn_tx_counter == 1);
1157
1158 /* inject the identity response (IMSI) */
1159 send_0408_message(ctx->llme, foreign_tlli,
1160 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1161
1162 /* check that the MM context has not been removed due to a failed
1163 * authorization */
1164 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1165
1166 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1167
1168 /* we expect an attach accept/reject */
1169 OSMO_ASSERT(sgsn_tx_counter == 1);
1170
1171 /* this has been randomly assigned by the SGSN */
1172 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1173
1174 /* inject the attach complete */
1175 send_0408_message(ctx->llme, local_tlli,
1176 attach_compl, ARRAY_SIZE(attach_compl));
1177
1178 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1179
1180 /* we don't expect a response */
1181 OSMO_ASSERT(sgsn_tx_counter == 0);
1182
1183 /* cancel */
1184 gsm0408_gprs_access_cancelled(ctx);
1185
1186 /* verify that things are gone */
1187 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1188 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1189 OSMO_ASSERT(!ictx);
1190
1191 sgsn->cfg.auth_policy = saved_auth_policy;
1192}
1193
1194/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001195 * Test the dynamic allocation of P-TMSIs
1196 */
1197static void test_gmm_ptmsi_allocation(void)
1198{
1199 struct gprs_ra_id raid = { 0, };
1200 struct sgsn_mm_ctx *ctx = NULL;
1201 struct sgsn_mm_ctx *ictx;
1202 uint32_t foreign_tlli;
1203 uint32_t ptmsi1;
1204 uint32_t ptmsi2;
1205 uint32_t old_ptmsi;
1206 uint32_t local_tlli = 0;
1207 struct gprs_llc_lle *lle;
1208 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1209
1210 /* DTAP - Attach Request (IMSI 12131415161718) */
1211 static const unsigned char attach_req[] = {
1212 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1213 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1214 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1215 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1216 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1217 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1218 0x00,
1219 };
1220
1221 /* DTAP - Identity Response IMEI */
1222 static const unsigned char ident_resp_imei[] = {
1223 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1224 0x56
1225 };
1226
1227 /* DTAP - Attach Complete */
1228 static const unsigned char attach_compl[] = {
1229 0x08, 0x03
1230 };
1231
1232 /* DTAP - Routing Area Update Request */
1233 static const unsigned char ra_upd_req[] = {
1234 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1235 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1236 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1237 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1238 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1239 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1240 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1241 };
1242
1243 /* DTAP - Routing Area Update Complete */
1244 static const unsigned char ra_upd_complete[] = {
1245 0x08, 0x0a
1246 };
1247
1248 /* DTAP - Detach Request (MO) */
1249 /* normal detach, power_off = 1 */
1250 static const unsigned char detach_req[] = {
1251 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1252 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1253 };
1254
1255 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1256
1257 printf("Testing P-TMSI allocation\n");
1258
1259 printf(" - sgsn_alloc_ptmsi\n");
1260
1261 /* reset the PRNG used by sgsn_alloc_ptmsi */
1262 srand(1);
1263
1264 ptmsi1 = sgsn_alloc_ptmsi();
1265 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1266
1267 ptmsi2 = sgsn_alloc_ptmsi();
1268 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1269
1270 OSMO_ASSERT(ptmsi1 != ptmsi2);
1271
1272 printf(" - Repeated Attach Request\n");
1273
1274 /* reset the PRNG, so that the same P-TMSI will be generated
1275 * again */
1276 srand(1);
1277
1278 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1279
1280 /* Create a LLE/LLME */
1281 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1282 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1283 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1284
1285 /* inject the attach request */
1286 send_0408_message(lle->llme, foreign_tlli,
1287 attach_req, ARRAY_SIZE(attach_req));
1288
1289 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1290 OSMO_ASSERT(ctx != NULL);
1291 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1292 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1293
1294 old_ptmsi = ctx->p_tmsi_old;
1295
1296 /* we expect an identity request (IMEI) */
1297 OSMO_ASSERT(sgsn_tx_counter == 1);
1298
1299 /* inject the identity response (IMEI) */
1300 send_0408_message(ctx->llme, foreign_tlli,
1301 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1302
1303 /* check that the MM context has not been removed due to a failed
1304 * authorization */
1305 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1306
1307 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1308 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1309
1310 /* we expect an attach accept */
1311 OSMO_ASSERT(sgsn_tx_counter == 1);
1312
1313 /* we ignore this and send the attach again */
1314 send_0408_message(lle->llme, foreign_tlli,
1315 attach_req, ARRAY_SIZE(attach_req));
1316
1317 /* the allocated P-TMSI should be the same */
1318 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1319 OSMO_ASSERT(ctx != NULL);
1320 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1321 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1322 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1323
1324 /* inject the attach complete */
1325 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1326 send_0408_message(ctx->llme, local_tlli,
1327 attach_compl, ARRAY_SIZE(attach_compl));
1328
1329 /* we don't expect a response */
1330 OSMO_ASSERT(sgsn_tx_counter == 0);
1331
1332 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1333 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1334 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1335
1336 printf(" - Repeated RA Update Request\n");
1337
1338 /* inject the RA update request */
1339 send_0408_message(ctx->llme, local_tlli,
1340 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1341
1342 /* we expect an RA update accept */
1343 OSMO_ASSERT(sgsn_tx_counter == 1);
1344
1345 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1346 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1347 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1348
1349 /* repeat the RA update request */
1350 send_0408_message(ctx->llme, local_tlli,
1351 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1352
1353 /* we expect an RA update accept */
1354 OSMO_ASSERT(sgsn_tx_counter == 1);
1355
1356 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1357 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1358 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1359
1360 /* inject the RA update complete */
1361 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1362 send_0408_message(ctx->llme, local_tlli,
1363 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1364
1365 /* we don't expect a response */
1366 OSMO_ASSERT(sgsn_tx_counter == 0);
1367
1368 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1369 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1370 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1371
1372 /* inject the detach */
1373 send_0408_message(ctx->llme, local_tlli,
1374 detach_req, ARRAY_SIZE(detach_req));
1375
1376 /* verify that things are gone */
1377 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1378 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1379 OSMO_ASSERT(!ictx);
1380
1381 sgsn->cfg.auth_policy = saved_auth_policy;
1382}
1383
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001384static struct log_info_cat gprs_categories[] = {
1385 [DMM] = {
1386 .name = "DMM",
1387 .description = "Layer3 Mobility Management (MM)",
1388 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001389 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001390 },
1391 [DPAG] = {
1392 .name = "DPAG",
1393 .description = "Paging Subsystem",
1394 .color = "\033[1;38m",
1395 .enabled = 1, .loglevel = LOGL_NOTICE,
1396 },
1397 [DMEAS] = {
1398 .name = "DMEAS",
1399 .description = "Radio Measurement Processing",
1400 .enabled = 0, .loglevel = LOGL_NOTICE,
1401 },
1402 [DREF] = {
1403 .name = "DREF",
1404 .description = "Reference Counting",
1405 .enabled = 0, .loglevel = LOGL_NOTICE,
1406 },
1407 [DGPRS] = {
1408 .name = "DGPRS",
1409 .description = "GPRS Packet Service",
1410 .enabled = 1, .loglevel = LOGL_DEBUG,
1411 },
1412 [DNS] = {
1413 .name = "DNS",
1414 .description = "GPRS Network Service (NS)",
1415 .enabled = 1, .loglevel = LOGL_INFO,
1416 },
1417 [DBSSGP] = {
1418 .name = "DBSSGP",
1419 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1420 .enabled = 1, .loglevel = LOGL_DEBUG,
1421 },
1422 [DLLC] = {
1423 .name = "DLLC",
1424 .description = "GPRS Logical Link Control Protocol (LLC)",
1425 .enabled = 1, .loglevel = LOGL_DEBUG,
1426 },
1427 [DSNDCP] = {
1428 .name = "DSNDCP",
1429 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1430 .enabled = 1, .loglevel = LOGL_DEBUG,
1431 },
1432};
1433
1434static struct log_info info = {
1435 .cat = gprs_categories,
1436 .num_cat = ARRAY_SIZE(gprs_categories),
1437};
1438
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001439int main(int argc, char **argv)
1440{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001441 osmo_init_logging(&info);
1442 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1443 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1444
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001445 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001446 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001447
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001448 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001449 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001450 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001451 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001452 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001453 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001454 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001455 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001456 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001457 test_gmm_attach_acl();
1458 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001459 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001460 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001461 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001462 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001463 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001464 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001465
1466 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001467 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001468 return 0;
1469}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001470
1471
1472/* stubs */
1473struct osmo_prim_hdr;
1474int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1475{
1476 abort();
1477}