blob: e36fa5a1902dcc7eac809987f36d8cee15e89150 [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
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100328static int rx_gsup_message(const uint8_t *data, size_t data_len)
329{
330 struct msgb *msg;
331 int rc;
332
333 msg = msgb_alloc(1024, __func__);
334 msg->l2h = msgb_put(msg, data_len);
335 OSMO_ASSERT(msg->l2h != NULL);
336 memcpy(msg->l2h, data, data_len);
337 rc = gprs_subscr_rx_gsup_message(msg);
338 msgb_free(msg);
339
340 return rc;
341}
342
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100343static void test_subscriber_gsup(void)
344{
345 struct gsm_subscriber *s1, *s1found;
346 const char *imsi1 = "1234567890";
347 struct sgsn_mm_ctx *ctx;
348 struct gprs_ra_id raid = { 0, };
349 uint32_t local_tlli = 0xffeeddcc;
350 struct gprs_llc_llme *llme;
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100351 int rc;
352
353 static const uint8_t send_auth_info_res[] = {
354 0x0a,
355 TEST_GSUP_IMSI1_IE,
356 0x03, 0x22, /* Auth tuple */
357 0x20, 0x10,
358 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
359 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
360 0x21, 0x04,
361 0x21, 0x22, 0x23, 0x24,
362 0x22, 0x08,
363 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
364 0x03, 0x22, /* Auth tuple */
365 0x20, 0x10,
366 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
367 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
368 0x21, 0x04,
369 0xa1, 0xa2, 0xa3, 0xa4,
370 0x22, 0x08,
371 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
372 };
373
374 static const uint8_t send_auth_info_err[] = {
375 0x09,
376 TEST_GSUP_IMSI1_IE,
377 0x02, 0x01, 0x07 /* GPRS not allowed */
378 };
379
380 static const uint8_t update_location_res[] = {
381 0x06,
382 TEST_GSUP_IMSI1_IE,
383 0x04, 0x00, /* PDP info complete */
384 0x05, 0x12,
385 0x10, 0x01, 0x01,
386 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
387 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
388 0x05, 0x11,
389 0x10, 0x01, 0x02,
390 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
391 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
392 };
393
394 static const uint8_t update_location_err[] = {
395 0x05,
396 TEST_GSUP_IMSI1_IE,
397 0x02, 0x01, 0x07 /* GPRS not allowed */
398 };
399
400 static const uint8_t location_cancellation_req[] = {
401 0x1c,
402 TEST_GSUP_IMSI1_IE,
403 0x06, 0x01, 0x00,
404 };
405
406 printf("Testing subcriber GSUP handling\n");
407
408 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
409
410 /* Check for emptiness */
411 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
412
413 /* Allocate entry 1 */
414 s1 = gprs_subscr_get_or_create(imsi1);
415 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
416 s1found = gprs_subscr_get_by_imsi(imsi1);
417 OSMO_ASSERT(s1found == s1);
418 subscr_put(s1found);
419
420 /* Create a context */
421 OSMO_ASSERT(count(gprs_llme_list()) == 0);
422 ctx = alloc_mm_ctx(local_tlli, &raid);
423 llme = ctx->llme;
424
425 /* Attach s1 to ctx */
426 ctx->subscr = subscr_get(s1);
427 ctx->subscr->sgsn_data->mm = ctx;
428
429 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100430 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100431 OSMO_ASSERT(rc >= 0);
432 OSMO_ASSERT(last_updated_subscr == s1);
433
434 /* Check triplets */
435 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
436 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
437 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
438
439 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100440 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100441 OSMO_ASSERT(rc >= 0);
442 OSMO_ASSERT(last_updated_subscr == s1);
443
444 /* Check triplets */
445 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
446 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
447 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
448
449 /* Inject UpdateLocReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100450 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100451 OSMO_ASSERT(rc >= 0);
452 OSMO_ASSERT(last_updated_subscr == s1);
453
454 /* Check authorization */
455 OSMO_ASSERT(s1->authorized == 1);
456
457 /* Inject UpdateLocErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100458 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100459 OSMO_ASSERT(rc >= 0);
460 OSMO_ASSERT(last_updated_subscr == s1);
461
462 /* Check authorization */
463 OSMO_ASSERT(s1->authorized == 0);
464
465 /* Inject UpdateLocReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100466 rc = rx_gsup_message(location_cancellation_req,
467 sizeof(location_cancellation_req));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100468 OSMO_ASSERT(rc >= 0);
469 OSMO_ASSERT(last_updated_subscr == s1);
470
471 /* Check cancellation result */
472 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
473 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
474
475 /* Free MM context and subscriber */
476 subscr_put(s1);
477 s1found = gprs_subscr_get_by_imsi(imsi1);
478 OSMO_ASSERT(s1found == NULL);
479 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
480
481 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
482}
483
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200484/*
485 * Test that a GMM Detach will remove the MMCTX and the
486 * associated LLME.
487 */
488static void test_gmm_detach(void)
489{
490 struct gprs_ra_id raid = { 0, };
491 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200492 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200493
494 printf("Testing GMM detach\n");
495
496 /* DTAP - Detach Request (MO) */
497 /* normal detach, power_off = 0 */
498 static const unsigned char detach_req[] = {
499 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
500 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
501 };
502
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200503 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200504
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100505 /* Create a context */
506 OSMO_ASSERT(count(gprs_llme_list()) == 0);
507 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200508
509 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100510 send_0408_message(ctx->llme, local_tlli,
511 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200512
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100513 /* verify that a single message (hopefully the Detach Accept) has been
514 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100515 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100516
517 /* verify that things are gone */
518 OSMO_ASSERT(count(gprs_llme_list()) == 0);
519 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
520 OSMO_ASSERT(!ictx);
521}
522
523/*
524 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
525 * will not sent a Detach Accept message (power_off = 1)
526 */
527static void test_gmm_detach_power_off(void)
528{
529 struct gprs_ra_id raid = { 0, };
530 struct sgsn_mm_ctx *ctx, *ictx;
531 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100532
533 printf("Testing GMM detach (power off)\n");
534
535 /* DTAP - Detach Request (MO) */
536 /* normal detach, power_off = 1 */
537 static const unsigned char detach_req[] = {
538 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
539 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
540 };
541
542 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
543
544 /* Create a context */
545 OSMO_ASSERT(count(gprs_llme_list()) == 0);
546 ctx = alloc_mm_ctx(local_tlli, &raid);
547
548 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100549 send_0408_message(ctx->llme, local_tlli,
550 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100551
552 /* verify that no message (and therefore no Detach Accept) has been
553 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100554 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100555
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200556 /* verify that things are gone */
557 OSMO_ASSERT(count(gprs_llme_list()) == 0);
558 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200559 OSMO_ASSERT(!ictx);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200560}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200561
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200562/*
563 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
564 */
565static void test_gmm_detach_no_mmctx(void)
566{
567 struct gprs_llc_lle *lle;
568 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200569
570 printf("Testing GMM detach (no MMCTX)\n");
571
572 /* DTAP - Detach Request (MO) */
573 /* normal detach, power_off = 0 */
574 static const unsigned char detach_req[] = {
575 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
576 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
577 };
578
579 /* Create an LLME */
580 OSMO_ASSERT(count(gprs_llme_list()) == 0);
581 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
582 lle = gprs_lle_get_or_create(local_tlli, 3);
583
584 OSMO_ASSERT(count(gprs_llme_list()) == 1);
585
586 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100587 send_0408_message(lle->llme, local_tlli,
588 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200589
590 /* verify that the LLME is gone */
591 OSMO_ASSERT(count(gprs_llme_list()) == 0);
592}
593
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100594/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100595 * Test that a single GMM Detach Accept message will not cause the SGSN to send
596 * any message or leave an MM context at the SGSN.
597 */
598static void test_gmm_detach_accept_unexpected(void)
599{
600 struct gprs_llc_lle *lle;
601 uint32_t local_tlli;
602
603 printf("Testing GMM detach accept (unexpected)\n");
604
605 /* DTAP - Detach Accept (MT) */
606 /* normal detach */
607 static const unsigned char detach_acc[] = {
608 0x08, 0x06
609 };
610
611 /* Create an LLME */
612 OSMO_ASSERT(count(gprs_llme_list()) == 0);
613 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
614 lle = gprs_lle_get_or_create(local_tlli, 3);
615
616 /* inject the detach */
617 send_0408_message(lle->llme, local_tlli,
618 detach_acc, ARRAY_SIZE(detach_acc));
619
620 /* verify that no message (and therefore no Status or XID reset) has been
621 * sent by the SGSN */
622 OSMO_ASSERT(sgsn_tx_counter == 0);
623
624 /* verify that things are gone */
625 OSMO_ASSERT(count(gprs_llme_list()) == 0);
626}
627
628/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100629 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
630 */
631static void test_gmm_status_no_mmctx(void)
632{
633 struct gprs_llc_lle *lle;
634 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100635
636 printf("Testing GMM Status (no MMCTX)\n");
637
638 /* DTAP - GMM Status, protocol error */
639 static const unsigned char gmm_status[] = {
640 0x08, 0x20, 0x6f
641 };
642
643 /* Create an LLME */
644 OSMO_ASSERT(count(gprs_llme_list()) == 0);
645 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
646 lle = gprs_lle_get_or_create(local_tlli, 3);
647
648 OSMO_ASSERT(count(gprs_llme_list()) == 1);
649
650 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100651 send_0408_message(lle->llme, local_tlli,
652 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100653
654 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100655 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100656
657 /* verify that the LLME is gone */
658 OSMO_ASSERT(count(gprs_llme_list()) == 0);
659}
660
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100661/*
662 * Test the GMM Attach procedure
663 */
664static void test_gmm_attach(void)
665{
666 struct gprs_ra_id raid = { 0, };
667 struct sgsn_mm_ctx *ctx = NULL;
668 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100669 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100670 uint32_t foreign_tlli;
671 uint32_t local_tlli = 0;
672 struct gprs_llc_lle *lle;
673
674 /* DTAP - Attach Request */
675 /* The P-TMSI is not known by the SGSN */
676 static const unsigned char attach_req[] = {
677 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
678 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
679 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
680 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
681 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
682 };
683
684 /* DTAP - Identity Response IMEI */
685 static const unsigned char ident_resp_imei[] = {
686 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
687 0x56
688 };
689
690 /* DTAP - Identity Response IMSI */
691 static const unsigned char ident_resp_imsi[] = {
692 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
693 0x54
694 };
695
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100696 /* DTAP - Authentication and Ciphering Resp */
697 static const unsigned char auth_ciph_resp[] = {
698 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
699 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
700 };
701
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100702 /* DTAP - Attach Complete */
703 static const unsigned char attach_compl[] = {
704 0x08, 0x03
705 };
706
707 /* DTAP - Detach Request (MO) */
708 /* normal detach, power_off = 0 */
709 static const unsigned char detach_req[] = {
710 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
711 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
712 };
713
714 printf("Testing GMM attach\n");
715
716 /* reset the PRNG used by sgsn_alloc_ptmsi */
717 srand(1);
718
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100719 ptmsi1 = sgsn_alloc_ptmsi();
720 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
721
722 /* reset the PRNG, so that the same P-TMSI sequence will be generated
723 * again */
724 srand(1);
725
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100726 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
727
728 /* Create a LLE/LLME */
729 OSMO_ASSERT(count(gprs_llme_list()) == 0);
730 lle = gprs_lle_get_or_create(foreign_tlli, 3);
731 OSMO_ASSERT(count(gprs_llme_list()) == 1);
732
733 /* inject the attach request */
734 send_0408_message(lle->llme, foreign_tlli,
735 attach_req, ARRAY_SIZE(attach_req));
736
737 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
738 OSMO_ASSERT(ctx != NULL);
739 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
740
741 /* we expect an identity request (IMEI) */
742 OSMO_ASSERT(sgsn_tx_counter == 1);
743
744 /* inject the identity response (IMEI) */
745 send_0408_message(ctx->llme, foreign_tlli,
746 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
747
748 /* we expect an identity request (IMSI) */
749 OSMO_ASSERT(sgsn_tx_counter == 1);
750
751 /* inject the identity response (IMSI) */
752 send_0408_message(ctx->llme, foreign_tlli,
753 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
754
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100755 /* check that the MM context has not been removed due to a failed
756 * authorization */
757 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
758
Jacob Erlbeck67318ef2014-10-28 16:23:46 +0100759 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100760
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100761 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE) {
762 /* we expect an auth & ciph request */
763 OSMO_ASSERT(sgsn_tx_counter == 1);
764
765 /* inject the auth & ciph response */
766 send_0408_message(ctx->llme, foreign_tlli,
767 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
768
769 /* check that the MM context has not been removed due to a
770 * failed authorization */
771 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
772 }
773
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100774 /* we expect an attach accept/reject */
775 OSMO_ASSERT(sgsn_tx_counter == 1);
776
777 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100778 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100779
780 /* inject the attach complete */
781 send_0408_message(ctx->llme, local_tlli,
782 attach_compl, ARRAY_SIZE(attach_compl));
783
784 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
785
786 /* we don't expect a response */
787 OSMO_ASSERT(sgsn_tx_counter == 0);
788
789 /* inject the detach */
790 send_0408_message(ctx->llme, local_tlli,
791 detach_req, ARRAY_SIZE(detach_req));
792
793 /* verify that things are gone */
794 OSMO_ASSERT(count(gprs_llme_list()) == 0);
795 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
796 OSMO_ASSERT(!ictx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100797}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100798
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100799static void test_gmm_attach_acl(void)
800{
801 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
802
803 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
804 sgsn_acl_add("123456789012345", &sgsn->cfg);
805 printf("Auth policy 'closed': ");
806 test_gmm_attach();
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100807 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100808
809 sgsn->cfg.auth_policy = saved_auth_policy;
810}
811
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100812int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100813 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100814 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100815 if (rc == -ENOTSUP) {
816 OSMO_ASSERT(mmctx->subscr);
817 gprs_subscr_update(mmctx->subscr);
818 }
819 return rc;
820};
821
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100822int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
823 gprs_subscr_update(mmctx->subscr);
824 return 0;
825};
826
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100827static void test_gmm_attach_subscr(void)
828{
829 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
830 struct gsm_subscriber *subscr;
831
832 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100833 subscr_request_update_location_cb = my_subscr_request_update_location;
834 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100835
836 subscr = gprs_subscr_get_or_create("123456789012345");
837 subscr->authorized = 1;
838 subscr_put(subscr);
839
840 printf("Auth policy 'remote': ");
841 test_gmm_attach();
842
843 subscr = gprs_subscr_get_by_imsi("123456789012345");
844 OSMO_ASSERT(subscr != NULL);
845 gprs_subscr_delete(subscr);
846
847 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100848 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
849 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100850}
851
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100852int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
853{
854 /* Fake an authentication */
855 OSMO_ASSERT(mmctx->subscr);
856 mmctx->is_authenticated = 1;
857 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100858
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100859 return 0;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100860};
861
862static void test_gmm_attach_subscr_fake_auth(void)
863{
864 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
865 struct gsm_subscriber *subscr;
866
867 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100868 subscr_request_update_location_cb = my_subscr_request_update_location;
869 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100870
871 subscr = gprs_subscr_get_or_create("123456789012345");
872 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +0100873 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +0100874 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100875 subscr_put(subscr);
876
877 printf("Auth policy 'remote', auth faked: ");
878 test_gmm_attach();
879
880 subscr = gprs_subscr_get_by_imsi("123456789012345");
881 OSMO_ASSERT(subscr != NULL);
882 gprs_subscr_delete(subscr);
883
884 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100885 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
886 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
887}
888
889int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
890{
891 struct gsm_auth_tuple at = {
892 .sres = {0x51, 0xe5, 0x51, 0xe5},
893 .key_seq = 0
894 };
895
896 /* Fake an authentication */
897 OSMO_ASSERT(mmctx->subscr);
898 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
899
900 gprs_subscr_update_auth_info(mmctx->subscr);
901
902 return 0;
903};
904
905static void test_gmm_attach_subscr_real_auth(void)
906{
907 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
908 struct gsm_subscriber *subscr;
909
910 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
911 subscr_request_update_location_cb = my_subscr_request_update_location;
912 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
913
914 subscr = gprs_subscr_get_or_create("123456789012345");
915 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +0100916 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +0100917 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100918 subscr_put(subscr);
919
920 printf("Auth policy 'remote', triplet based auth: ");
921 test_gmm_attach();
922
923 subscr = gprs_subscr_get_by_imsi("123456789012345");
924 OSMO_ASSERT(subscr != NULL);
925 gprs_subscr_delete(subscr);
926
927 sgsn->cfg.auth_policy = saved_auth_policy;
928 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
929 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100930}
931
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +0100932/*
933 * Test the GMM Rejects
934 */
935static void test_gmm_reject(void)
936{
937 struct gprs_ra_id raid = { 0, };
938 struct sgsn_mm_ctx *ctx = NULL;
939 uint32_t foreign_tlli;
940 struct gprs_llc_lle *lle;
941 int idx;
942
943 /* DTAP - Attach Request */
944 /* Invalid MI length */
945 static const unsigned char attach_req_inv_mi_len[] = {
946 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
947 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
948 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
949 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
950 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
951 };
952
953 /* DTAP - Attach Request */
954 /* Invalid MI type (IMEI) */
955 static const unsigned char attach_req_inv_mi_type[] = {
956 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
957 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
958 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
959 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
960 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
961 };
962
963 /* DTAP - Routing Area Update Request */
964 static const unsigned char dtap_ra_upd_req[] = {
965 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
966 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
967 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
968 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
969 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
970 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
971 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
972 };
973
974 /* DTAP - Routing Area Update Request */
975 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
976 static const unsigned char dtap_ra_upd_req_inv_type[] = {
977 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
978 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
979 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
980 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
981 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
982 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
983 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
984 };
985
986 /* DTAP - Routing Area Update Request */
987 /* Invalid cap length */
988 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
989 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
990 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
991 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
992 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
993 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
994 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
995 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
996 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
997 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
998 };
999
1000 struct test {
1001 const char *title;
1002 const unsigned char *msg;
1003 unsigned msg_len;
1004 unsigned num_resp;
1005
1006 };
1007 static struct test tests[] = {
1008 {
1009 .title = "Attach Request (invalid MI length)",
1010 .msg = attach_req_inv_mi_len,
1011 .msg_len = sizeof(attach_req_inv_mi_len),
1012 .num_resp = 1 /* Reject */
1013
1014 },
1015 {
1016 .title = "Attach Request (invalid MI type)",
1017 .msg = attach_req_inv_mi_type,
1018 .msg_len = sizeof(attach_req_inv_mi_type),
1019 .num_resp = 1 /* Reject */
1020 },
1021 {
1022 .title = "Routing Area Update Request (valid)",
1023 .msg = dtap_ra_upd_req,
1024 .msg_len = sizeof(dtap_ra_upd_req),
1025 .num_resp = 2 /* XID Reset + Reject */
1026 },
1027 {
1028 .title = "Routing Area Update Request (invalid type)",
1029 .msg = dtap_ra_upd_req_inv_type,
1030 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1031 .num_resp = 1 /* Reject */
1032 },
1033 {
1034 .title = "Routing Area Update Request (invalid CAP length)",
1035 .msg = dtap_ra_upd_req_inv_cap_len,
1036 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1037 .num_resp = 1 /* Reject */
1038 },
1039 };
1040
1041 printf("Testing GMM reject\n");
1042
1043 /* reset the PRNG used by sgsn_alloc_ptmsi */
1044 srand(1);
1045
1046 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1047
1048 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1049
1050 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1051 const struct test *test = &tests[idx];
1052 printf(" - %s\n", test->title);
1053
1054 /* Create a LLE/LLME */
1055 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1056 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1057
1058 /* Inject the Request message */
1059 send_0408_message(lle->llme, foreign_tlli,
1060 test->msg, test->msg_len);
1061
1062 /* We expect a Reject message */
1063 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1064 sgsn_tx_counter, test->num_resp);
1065 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1066
1067 /* verify that LLME/MM are removed */
1068 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1069 OSMO_ASSERT(ctx == NULL);
1070 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1071 }
1072}
1073
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001074/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001075 * Test cancellation of attached MM contexts
1076 */
1077static void test_gmm_cancel(void)
1078{
1079 struct gprs_ra_id raid = { 0, };
1080 struct sgsn_mm_ctx *ctx = NULL;
1081 struct sgsn_mm_ctx *ictx;
1082 uint32_t ptmsi1;
1083 uint32_t foreign_tlli;
1084 uint32_t local_tlli = 0;
1085 struct gprs_llc_lle *lle;
1086 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1087
1088 /* DTAP - Attach Request */
1089 /* The P-TMSI is not known by the SGSN */
1090 static const unsigned char attach_req[] = {
1091 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1092 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1093 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1094 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1095 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1096 };
1097
1098 /* DTAP - Identity Response IMEI */
1099 static const unsigned char ident_resp_imei[] = {
1100 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1101 0x56
1102 };
1103
1104 /* DTAP - Identity Response IMSI */
1105 static const unsigned char ident_resp_imsi[] = {
1106 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1107 0x54
1108 };
1109
1110 /* DTAP - Attach Complete */
1111 static const unsigned char attach_compl[] = {
1112 0x08, 0x03
1113 };
1114
1115 printf("Testing cancellation\n");
1116
1117 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1118
1119 /* reset the PRNG used by sgsn_alloc_ptmsi */
1120 srand(1);
1121
1122 ptmsi1 = sgsn_alloc_ptmsi();
1123 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1124
1125 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1126 * again */
1127 srand(1);
1128
1129 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1130
1131 /* Create a LLE/LLME */
1132 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1133 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1134 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1135
1136 /* inject the attach request */
1137 send_0408_message(lle->llme, foreign_tlli,
1138 attach_req, ARRAY_SIZE(attach_req));
1139
1140 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1141 OSMO_ASSERT(ctx != NULL);
1142 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1143
1144 /* we expect an identity request (IMEI) */
1145 OSMO_ASSERT(sgsn_tx_counter == 1);
1146
1147 /* inject the identity response (IMEI) */
1148 send_0408_message(ctx->llme, foreign_tlli,
1149 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1150
1151 /* we expect an identity request (IMSI) */
1152 OSMO_ASSERT(sgsn_tx_counter == 1);
1153
1154 /* inject the identity response (IMSI) */
1155 send_0408_message(ctx->llme, foreign_tlli,
1156 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1157
1158 /* check that the MM context has not been removed due to a failed
1159 * authorization */
1160 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1161
1162 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1163
1164 /* we expect an attach accept/reject */
1165 OSMO_ASSERT(sgsn_tx_counter == 1);
1166
1167 /* this has been randomly assigned by the SGSN */
1168 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1169
1170 /* inject the attach complete */
1171 send_0408_message(ctx->llme, local_tlli,
1172 attach_compl, ARRAY_SIZE(attach_compl));
1173
1174 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1175
1176 /* we don't expect a response */
1177 OSMO_ASSERT(sgsn_tx_counter == 0);
1178
1179 /* cancel */
1180 gsm0408_gprs_access_cancelled(ctx);
1181
1182 /* verify that things are gone */
1183 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1184 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1185 OSMO_ASSERT(!ictx);
1186
1187 sgsn->cfg.auth_policy = saved_auth_policy;
1188}
1189
1190/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001191 * Test the dynamic allocation of P-TMSIs
1192 */
1193static void test_gmm_ptmsi_allocation(void)
1194{
1195 struct gprs_ra_id raid = { 0, };
1196 struct sgsn_mm_ctx *ctx = NULL;
1197 struct sgsn_mm_ctx *ictx;
1198 uint32_t foreign_tlli;
1199 uint32_t ptmsi1;
1200 uint32_t ptmsi2;
1201 uint32_t old_ptmsi;
1202 uint32_t local_tlli = 0;
1203 struct gprs_llc_lle *lle;
1204 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1205
1206 /* DTAP - Attach Request (IMSI 12131415161718) */
1207 static const unsigned char attach_req[] = {
1208 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1209 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1210 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1211 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1212 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1213 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1214 0x00,
1215 };
1216
1217 /* DTAP - Identity Response IMEI */
1218 static const unsigned char ident_resp_imei[] = {
1219 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1220 0x56
1221 };
1222
1223 /* DTAP - Attach Complete */
1224 static const unsigned char attach_compl[] = {
1225 0x08, 0x03
1226 };
1227
1228 /* DTAP - Routing Area Update Request */
1229 static const unsigned char ra_upd_req[] = {
1230 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1231 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1232 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1233 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1234 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1235 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1236 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1237 };
1238
1239 /* DTAP - Routing Area Update Complete */
1240 static const unsigned char ra_upd_complete[] = {
1241 0x08, 0x0a
1242 };
1243
1244 /* DTAP - Detach Request (MO) */
1245 /* normal detach, power_off = 1 */
1246 static const unsigned char detach_req[] = {
1247 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1248 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1249 };
1250
1251 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1252
1253 printf("Testing P-TMSI allocation\n");
1254
1255 printf(" - sgsn_alloc_ptmsi\n");
1256
1257 /* reset the PRNG used by sgsn_alloc_ptmsi */
1258 srand(1);
1259
1260 ptmsi1 = sgsn_alloc_ptmsi();
1261 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1262
1263 ptmsi2 = sgsn_alloc_ptmsi();
1264 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1265
1266 OSMO_ASSERT(ptmsi1 != ptmsi2);
1267
1268 printf(" - Repeated Attach Request\n");
1269
1270 /* reset the PRNG, so that the same P-TMSI will be generated
1271 * again */
1272 srand(1);
1273
1274 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1275
1276 /* Create a LLE/LLME */
1277 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1278 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1279 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1280
1281 /* inject the attach request */
1282 send_0408_message(lle->llme, foreign_tlli,
1283 attach_req, ARRAY_SIZE(attach_req));
1284
1285 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1286 OSMO_ASSERT(ctx != NULL);
1287 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1288 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1289
1290 old_ptmsi = ctx->p_tmsi_old;
1291
1292 /* we expect an identity request (IMEI) */
1293 OSMO_ASSERT(sgsn_tx_counter == 1);
1294
1295 /* inject the identity response (IMEI) */
1296 send_0408_message(ctx->llme, foreign_tlli,
1297 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1298
1299 /* check that the MM context has not been removed due to a failed
1300 * authorization */
1301 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1302
1303 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1304 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1305
1306 /* we expect an attach accept */
1307 OSMO_ASSERT(sgsn_tx_counter == 1);
1308
1309 /* we ignore this and send the attach again */
1310 send_0408_message(lle->llme, foreign_tlli,
1311 attach_req, ARRAY_SIZE(attach_req));
1312
1313 /* the allocated P-TMSI should be the same */
1314 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1315 OSMO_ASSERT(ctx != NULL);
1316 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1317 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1318 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1319
1320 /* inject the attach complete */
1321 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1322 send_0408_message(ctx->llme, local_tlli,
1323 attach_compl, ARRAY_SIZE(attach_compl));
1324
1325 /* we don't expect a response */
1326 OSMO_ASSERT(sgsn_tx_counter == 0);
1327
1328 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1329 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1330 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1331
1332 printf(" - Repeated RA Update Request\n");
1333
1334 /* inject the RA update request */
1335 send_0408_message(ctx->llme, local_tlli,
1336 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1337
1338 /* we expect an RA update accept */
1339 OSMO_ASSERT(sgsn_tx_counter == 1);
1340
1341 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1342 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1343 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1344
1345 /* repeat the RA update request */
1346 send_0408_message(ctx->llme, local_tlli,
1347 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1348
1349 /* we expect an RA update accept */
1350 OSMO_ASSERT(sgsn_tx_counter == 1);
1351
1352 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1353 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1354 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1355
1356 /* inject the RA update complete */
1357 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1358 send_0408_message(ctx->llme, local_tlli,
1359 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1360
1361 /* we don't expect a response */
1362 OSMO_ASSERT(sgsn_tx_counter == 0);
1363
1364 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1365 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1366 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1367
1368 /* inject the detach */
1369 send_0408_message(ctx->llme, local_tlli,
1370 detach_req, ARRAY_SIZE(detach_req));
1371
1372 /* verify that things are gone */
1373 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1374 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1375 OSMO_ASSERT(!ictx);
1376
1377 sgsn->cfg.auth_policy = saved_auth_policy;
1378}
1379
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001380static struct log_info_cat gprs_categories[] = {
1381 [DMM] = {
1382 .name = "DMM",
1383 .description = "Layer3 Mobility Management (MM)",
1384 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001385 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001386 },
1387 [DPAG] = {
1388 .name = "DPAG",
1389 .description = "Paging Subsystem",
1390 .color = "\033[1;38m",
1391 .enabled = 1, .loglevel = LOGL_NOTICE,
1392 },
1393 [DMEAS] = {
1394 .name = "DMEAS",
1395 .description = "Radio Measurement Processing",
1396 .enabled = 0, .loglevel = LOGL_NOTICE,
1397 },
1398 [DREF] = {
1399 .name = "DREF",
1400 .description = "Reference Counting",
1401 .enabled = 0, .loglevel = LOGL_NOTICE,
1402 },
1403 [DGPRS] = {
1404 .name = "DGPRS",
1405 .description = "GPRS Packet Service",
1406 .enabled = 1, .loglevel = LOGL_DEBUG,
1407 },
1408 [DNS] = {
1409 .name = "DNS",
1410 .description = "GPRS Network Service (NS)",
1411 .enabled = 1, .loglevel = LOGL_INFO,
1412 },
1413 [DBSSGP] = {
1414 .name = "DBSSGP",
1415 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1416 .enabled = 1, .loglevel = LOGL_DEBUG,
1417 },
1418 [DLLC] = {
1419 .name = "DLLC",
1420 .description = "GPRS Logical Link Control Protocol (LLC)",
1421 .enabled = 1, .loglevel = LOGL_DEBUG,
1422 },
1423 [DSNDCP] = {
1424 .name = "DSNDCP",
1425 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1426 .enabled = 1, .loglevel = LOGL_DEBUG,
1427 },
1428};
1429
1430static struct log_info info = {
1431 .cat = gprs_categories,
1432 .num_cat = ARRAY_SIZE(gprs_categories),
1433};
1434
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001435int main(int argc, char **argv)
1436{
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001437 osmo_init_logging(&info);
1438 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1439 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1440
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01001441 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001442 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001443
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001444 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001445 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01001446 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01001447 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02001448 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01001449 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02001450 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01001451 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01001452 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001453 test_gmm_attach_acl();
1454 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001455 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001456 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001457 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001458 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001459 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001460 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01001461
1462 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01001463 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001464 return 0;
1465}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001466
1467
1468/* stubs */
1469struct osmo_prim_hdr;
1470int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1471{
1472 abort();
1473}