blob: d9cb8421232cbe75fe5ce6d90eeeb853366f7dc0 [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 */
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100664static void test_gmm_attach(int retry)
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100665{
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
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100714 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100715
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 Erlbeck803ebfa2014-12-19 18:30:41 +0100761retry_attach_req:
762
763 if (retry && sgsn_tx_counter == 0) {
764 fprintf(stderr, "Retrying attach request\n");
765 /* re-inject the attach request */
766 send_0408_message(lle->llme, foreign_tlli,
767 attach_req, ARRAY_SIZE(attach_req));
768 }
769
770 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
771 /* we got an auth & ciph request */
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100772
773 /* inject the auth & ciph response */
774 send_0408_message(ctx->llme, foreign_tlli,
775 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
776
777 /* check that the MM context has not been removed due to a
778 * failed authorization */
779 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
780 }
781
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100782 if (retry && sgsn_tx_counter == 0)
783 goto retry_attach_req;
784
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100785 /* we expect an attach accept/reject */
786 OSMO_ASSERT(sgsn_tx_counter == 1);
787
788 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100789 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100790
791 /* inject the attach complete */
792 send_0408_message(ctx->llme, local_tlli,
793 attach_compl, ARRAY_SIZE(attach_compl));
794
795 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
796
797 /* we don't expect a response */
798 OSMO_ASSERT(sgsn_tx_counter == 0);
799
800 /* inject the detach */
801 send_0408_message(ctx->llme, local_tlli,
802 detach_req, ARRAY_SIZE(detach_req));
803
804 /* verify that things are gone */
805 OSMO_ASSERT(count(gprs_llme_list()) == 0);
806 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
807 OSMO_ASSERT(!ictx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100808}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100809
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100810static void test_gmm_attach_acl(void)
811{
812 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
813
814 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
815 sgsn_acl_add("123456789012345", &sgsn->cfg);
816 printf("Auth policy 'closed': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100817 test_gmm_attach(0);
Jacob Erlbeck79d438a2014-10-29 22:12:20 +0100818 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100819
820 sgsn->cfg.auth_policy = saved_auth_policy;
821}
822
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100823int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100824 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100825 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100826 if (rc == -ENOTSUP) {
827 OSMO_ASSERT(mmctx->subscr);
828 gprs_subscr_update(mmctx->subscr);
829 }
830 return rc;
831};
832
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100833int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
834 gprs_subscr_update(mmctx->subscr);
835 return 0;
836};
837
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100838static void test_gmm_attach_subscr(void)
839{
840 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
841 struct gsm_subscriber *subscr;
842
843 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100844 subscr_request_update_location_cb = my_subscr_request_update_location;
845 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100846
847 subscr = gprs_subscr_get_or_create("123456789012345");
848 subscr->authorized = 1;
849 subscr_put(subscr);
850
851 printf("Auth policy 'remote': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100852 test_gmm_attach(0);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100853
854 subscr = gprs_subscr_get_by_imsi("123456789012345");
855 OSMO_ASSERT(subscr != NULL);
856 gprs_subscr_delete(subscr);
857
858 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100859 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
860 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100861}
862
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100863int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
864{
865 /* Fake an authentication */
866 OSMO_ASSERT(mmctx->subscr);
867 mmctx->is_authenticated = 1;
868 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100869
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100870 return 0;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100871};
872
873static void test_gmm_attach_subscr_fake_auth(void)
874{
875 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
876 struct gsm_subscriber *subscr;
877
878 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100879 subscr_request_update_location_cb = my_subscr_request_update_location;
880 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100881
882 subscr = gprs_subscr_get_or_create("123456789012345");
883 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +0100884 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +0100885 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100886 subscr_put(subscr);
887
888 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100889 test_gmm_attach(0);
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100890
891 subscr = gprs_subscr_get_by_imsi("123456789012345");
892 OSMO_ASSERT(subscr != NULL);
893 gprs_subscr_delete(subscr);
894
895 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100896 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
897 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
898}
899
900int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
901{
902 struct gsm_auth_tuple at = {
903 .sres = {0x51, 0xe5, 0x51, 0xe5},
904 .key_seq = 0
905 };
906
907 /* Fake an authentication */
908 OSMO_ASSERT(mmctx->subscr);
909 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
910
911 gprs_subscr_update_auth_info(mmctx->subscr);
912
913 return 0;
914};
915
916static void test_gmm_attach_subscr_real_auth(void)
917{
918 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
919 struct gsm_subscriber *subscr;
920
921 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
922 subscr_request_update_location_cb = my_subscr_request_update_location;
923 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
924
925 subscr = gprs_subscr_get_or_create("123456789012345");
926 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +0100927 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +0100928 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100929 subscr_put(subscr);
930
931 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100932 test_gmm_attach(0);
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100933
934 subscr = gprs_subscr_get_by_imsi("123456789012345");
935 OSMO_ASSERT(subscr != NULL);
936 gprs_subscr_delete(subscr);
937
938 sgsn->cfg.auth_policy = saved_auth_policy;
939 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
940 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckd8126992014-12-08 15:26:47 +0100941}
942
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +0100943#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
944 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
945
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100946static int auth_info_skip = 0;
947static int upd_loc_skip = 0;
948
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +0100949int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
950{
951 static const uint8_t send_auth_info_res[] = {
952 0x0a,
953 TEST_GSUP_IMSI_LONG_IE,
954 0x03, 0x22, /* Auth tuple */
955 0x20, 0x10,
956 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
957 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
958 0x21, 0x04,
959 0x51, 0xe5, 0x51, 0xe5,
960 0x22, 0x08,
961 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
962 };
963
964 OSMO_ASSERT(mmctx->subscr);
965
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100966 if (auth_info_skip > 0) {
967 auth_info_skip -= 1;
968 return -EAGAIN;
969 }
970
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +0100971 /* Fake an SendAuthInfoRes */
972 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
973
974 return 0;
975};
976
977int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
978 static const uint8_t update_location_res[] = {
979 0x06,
980 TEST_GSUP_IMSI_LONG_IE,
981 0x04, 0x00, /* PDP info complete */
982 0x05, 0x12,
983 0x10, 0x01, 0x01,
984 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
985 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
986 };
987
988 OSMO_ASSERT(mmctx->subscr);
989
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100990 if (upd_loc_skip > 0) {
991 upd_loc_skip -= 1;
992 return -EAGAIN;
993 }
994
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +0100995 /* Fake an UpdateLocRes */
996 return rx_gsup_message(update_location_res, sizeof(update_location_res));
997};
998
999
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001000static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001001{
1002 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1003 struct gsm_subscriber *subscr;
1004
1005 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1006 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1007 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001008 if (retry) {
1009 upd_loc_skip = 3;
1010 auth_info_skip = 3;
1011 }
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001012
1013 subscr = gprs_subscr_get_or_create("123456789012345");
1014 subscr->authorized = 1;
1015 sgsn->cfg.require_authentication = 1;
1016 sgsn->cfg.require_update_location = 1;
1017 subscr_put(subscr);
1018
1019 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001020 test_gmm_attach(retry);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001021
1022 subscr = gprs_subscr_get_by_imsi("123456789012345");
1023 OSMO_ASSERT(subscr != NULL);
1024 gprs_subscr_delete(subscr);
1025
1026 sgsn->cfg.auth_policy = saved_auth_policy;
1027 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1028 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001029 upd_loc_skip = 0;
1030 auth_info_skip = 0;
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001031}
1032
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001033/*
1034 * Test the GMM Rejects
1035 */
1036static void test_gmm_reject(void)
1037{
1038 struct gprs_ra_id raid = { 0, };
1039 struct sgsn_mm_ctx *ctx = NULL;
1040 uint32_t foreign_tlli;
1041 struct gprs_llc_lle *lle;
1042 int idx;
1043
1044 /* DTAP - Attach Request */
1045 /* Invalid MI length */
1046 static const unsigned char attach_req_inv_mi_len[] = {
1047 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1048 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1049 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1050 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1051 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1052 };
1053
1054 /* DTAP - Attach Request */
1055 /* Invalid MI type (IMEI) */
1056 static const unsigned char attach_req_inv_mi_type[] = {
1057 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1058 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1059 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1060 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1061 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1062 };
1063
1064 /* DTAP - Routing Area Update Request */
1065 static const unsigned char dtap_ra_upd_req[] = {
1066 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1067 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1068 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1069 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1070 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1071 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1072 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1073 };
1074
1075 /* DTAP - Routing Area Update Request */
1076 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1077 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1078 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1079 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1080 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1081 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1082 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1083 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1084 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1085 };
1086
1087 /* DTAP - Routing Area Update Request */
1088 /* Invalid cap length */
1089 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1090 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1091 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1092 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1093 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1094 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1095 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1096 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1097 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1098 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1099 };
1100
1101 struct test {
1102 const char *title;
1103 const unsigned char *msg;
1104 unsigned msg_len;
1105 unsigned num_resp;
1106
1107 };
1108 static struct test tests[] = {
1109 {
1110 .title = "Attach Request (invalid MI length)",
1111 .msg = attach_req_inv_mi_len,
1112 .msg_len = sizeof(attach_req_inv_mi_len),
1113 .num_resp = 1 /* Reject */
1114
1115 },
1116 {
1117 .title = "Attach Request (invalid MI type)",
1118 .msg = attach_req_inv_mi_type,
1119 .msg_len = sizeof(attach_req_inv_mi_type),
1120 .num_resp = 1 /* Reject */
1121 },
1122 {
1123 .title = "Routing Area Update Request (valid)",
1124 .msg = dtap_ra_upd_req,
1125 .msg_len = sizeof(dtap_ra_upd_req),
1126 .num_resp = 2 /* XID Reset + Reject */
1127 },
1128 {
1129 .title = "Routing Area Update Request (invalid type)",
1130 .msg = dtap_ra_upd_req_inv_type,
1131 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1132 .num_resp = 1 /* Reject */
1133 },
1134 {
1135 .title = "Routing Area Update Request (invalid CAP length)",
1136 .msg = dtap_ra_upd_req_inv_cap_len,
1137 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1138 .num_resp = 1 /* Reject */
1139 },
1140 };
1141
1142 printf("Testing GMM reject\n");
1143
1144 /* reset the PRNG used by sgsn_alloc_ptmsi */
1145 srand(1);
1146
1147 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1148
1149 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1150
1151 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1152 const struct test *test = &tests[idx];
1153 printf(" - %s\n", test->title);
1154
1155 /* Create a LLE/LLME */
1156 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1157 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1158
1159 /* Inject the Request message */
1160 send_0408_message(lle->llme, foreign_tlli,
1161 test->msg, test->msg_len);
1162
1163 /* We expect a Reject message */
1164 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1165 sgsn_tx_counter, test->num_resp);
1166 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1167
1168 /* verify that LLME/MM are removed */
1169 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1170 OSMO_ASSERT(ctx == NULL);
1171 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1172 }
1173}
1174
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001175/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001176 * Test cancellation of attached MM contexts
1177 */
1178static void test_gmm_cancel(void)
1179{
1180 struct gprs_ra_id raid = { 0, };
1181 struct sgsn_mm_ctx *ctx = NULL;
1182 struct sgsn_mm_ctx *ictx;
1183 uint32_t ptmsi1;
1184 uint32_t foreign_tlli;
1185 uint32_t local_tlli = 0;
1186 struct gprs_llc_lle *lle;
1187 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1188
1189 /* DTAP - Attach Request */
1190 /* The P-TMSI is not known by the SGSN */
1191 static const unsigned char attach_req[] = {
1192 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1193 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1194 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1195 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1196 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1197 };
1198
1199 /* DTAP - Identity Response IMEI */
1200 static const unsigned char ident_resp_imei[] = {
1201 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1202 0x56
1203 };
1204
1205 /* DTAP - Identity Response IMSI */
1206 static const unsigned char ident_resp_imsi[] = {
1207 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1208 0x54
1209 };
1210
1211 /* DTAP - Attach Complete */
1212 static const unsigned char attach_compl[] = {
1213 0x08, 0x03
1214 };
1215
1216 printf("Testing cancellation\n");
1217
1218 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1219
1220 /* reset the PRNG used by sgsn_alloc_ptmsi */
1221 srand(1);
1222
1223 ptmsi1 = sgsn_alloc_ptmsi();
1224 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1225
1226 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1227 * again */
1228 srand(1);
1229
1230 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1231
1232 /* Create a LLE/LLME */
1233 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1234 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1235 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1236
1237 /* inject the attach request */
1238 send_0408_message(lle->llme, foreign_tlli,
1239 attach_req, ARRAY_SIZE(attach_req));
1240
1241 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1242 OSMO_ASSERT(ctx != NULL);
1243 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1244
1245 /* we expect an identity request (IMEI) */
1246 OSMO_ASSERT(sgsn_tx_counter == 1);
1247
1248 /* inject the identity response (IMEI) */
1249 send_0408_message(ctx->llme, foreign_tlli,
1250 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1251
1252 /* we expect an identity request (IMSI) */
1253 OSMO_ASSERT(sgsn_tx_counter == 1);
1254
1255 /* inject the identity response (IMSI) */
1256 send_0408_message(ctx->llme, foreign_tlli,
1257 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1258
1259 /* check that the MM context has not been removed due to a failed
1260 * authorization */
1261 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1262
1263 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1264
1265 /* we expect an attach accept/reject */
1266 OSMO_ASSERT(sgsn_tx_counter == 1);
1267
1268 /* this has been randomly assigned by the SGSN */
1269 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1270
1271 /* inject the attach complete */
1272 send_0408_message(ctx->llme, local_tlli,
1273 attach_compl, ARRAY_SIZE(attach_compl));
1274
1275 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1276
1277 /* we don't expect a response */
1278 OSMO_ASSERT(sgsn_tx_counter == 0);
1279
1280 /* cancel */
1281 gsm0408_gprs_access_cancelled(ctx);
1282
1283 /* verify that things are gone */
1284 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1285 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1286 OSMO_ASSERT(!ictx);
1287
1288 sgsn->cfg.auth_policy = saved_auth_policy;
1289}
1290
1291/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001292 * Test the dynamic allocation of P-TMSIs
1293 */
1294static void test_gmm_ptmsi_allocation(void)
1295{
1296 struct gprs_ra_id raid = { 0, };
1297 struct sgsn_mm_ctx *ctx = NULL;
1298 struct sgsn_mm_ctx *ictx;
1299 uint32_t foreign_tlli;
1300 uint32_t ptmsi1;
1301 uint32_t ptmsi2;
1302 uint32_t old_ptmsi;
1303 uint32_t local_tlli = 0;
1304 struct gprs_llc_lle *lle;
1305 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1306
1307 /* DTAP - Attach Request (IMSI 12131415161718) */
1308 static const unsigned char attach_req[] = {
1309 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1310 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1311 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1312 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1313 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1314 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1315 0x00,
1316 };
1317
1318 /* DTAP - Identity Response IMEI */
1319 static const unsigned char ident_resp_imei[] = {
1320 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1321 0x56
1322 };
1323
1324 /* DTAP - Attach Complete */
1325 static const unsigned char attach_compl[] = {
1326 0x08, 0x03
1327 };
1328
1329 /* DTAP - Routing Area Update Request */
1330 static const unsigned char ra_upd_req[] = {
1331 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1332 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1333 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1334 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1335 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1336 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1337 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1338 };
1339
1340 /* DTAP - Routing Area Update Complete */
1341 static const unsigned char ra_upd_complete[] = {
1342 0x08, 0x0a
1343 };
1344
1345 /* DTAP - Detach Request (MO) */
1346 /* normal detach, power_off = 1 */
1347 static const unsigned char detach_req[] = {
1348 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1349 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1350 };
1351
1352 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1353
1354 printf("Testing P-TMSI allocation\n");
1355
1356 printf(" - sgsn_alloc_ptmsi\n");
1357
1358 /* reset the PRNG used by sgsn_alloc_ptmsi */
1359 srand(1);
1360
1361 ptmsi1 = sgsn_alloc_ptmsi();
1362 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1363
1364 ptmsi2 = sgsn_alloc_ptmsi();
1365 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1366
1367 OSMO_ASSERT(ptmsi1 != ptmsi2);
1368
1369 printf(" - Repeated Attach Request\n");
1370
1371 /* reset the PRNG, so that the same P-TMSI will be generated
1372 * again */
1373 srand(1);
1374
1375 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1376
1377 /* Create a LLE/LLME */
1378 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1379 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1380 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1381
1382 /* inject the attach request */
1383 send_0408_message(lle->llme, foreign_tlli,
1384 attach_req, ARRAY_SIZE(attach_req));
1385
1386 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1387 OSMO_ASSERT(ctx != NULL);
1388 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1389 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1390
1391 old_ptmsi = ctx->p_tmsi_old;
1392
1393 /* we expect an identity request (IMEI) */
1394 OSMO_ASSERT(sgsn_tx_counter == 1);
1395
1396 /* inject the identity response (IMEI) */
1397 send_0408_message(ctx->llme, foreign_tlli,
1398 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1399
1400 /* check that the MM context has not been removed due to a failed
1401 * authorization */
1402 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1403
1404 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1405 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1406
1407 /* we expect an attach accept */
1408 OSMO_ASSERT(sgsn_tx_counter == 1);
1409
1410 /* we ignore this and send the attach again */
1411 send_0408_message(lle->llme, foreign_tlli,
1412 attach_req, ARRAY_SIZE(attach_req));
1413
1414 /* the allocated P-TMSI should be the same */
1415 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1416 OSMO_ASSERT(ctx != NULL);
1417 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1418 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1419 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1420
1421 /* inject the attach complete */
1422 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1423 send_0408_message(ctx->llme, local_tlli,
1424 attach_compl, ARRAY_SIZE(attach_compl));
1425
1426 /* we don't expect a response */
1427 OSMO_ASSERT(sgsn_tx_counter == 0);
1428
1429 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1430 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1431 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1432
1433 printf(" - Repeated RA Update Request\n");
1434
1435 /* inject the RA update request */
1436 send_0408_message(ctx->llme, local_tlli,
1437 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1438
1439 /* we expect an RA update accept */
1440 OSMO_ASSERT(sgsn_tx_counter == 1);
1441
1442 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1443 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1444 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1445
1446 /* repeat the RA update request */
1447 send_0408_message(ctx->llme, local_tlli,
1448 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1449
1450 /* we expect an RA update accept */
1451 OSMO_ASSERT(sgsn_tx_counter == 1);
1452
1453 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1454 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1455 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1456
1457 /* inject the RA update complete */
1458 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1459 send_0408_message(ctx->llme, local_tlli,
1460 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1461
1462 /* we don't expect a response */
1463 OSMO_ASSERT(sgsn_tx_counter == 0);
1464
1465 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1466 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1467 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1468
1469 /* inject the detach */
1470 send_0408_message(ctx->llme, local_tlli,
1471 detach_req, ARRAY_SIZE(detach_req));
1472
1473 /* verify that things are gone */
1474 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1475 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1476 OSMO_ASSERT(!ictx);
1477
1478 sgsn->cfg.auth_policy = saved_auth_policy;
1479}
1480
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001481static struct log_info_cat gprs_categories[] = {
1482 [DMM] = {
1483 .name = "DMM",
1484 .description = "Layer3 Mobility Management (MM)",
1485 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001486 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001487 },
1488 [DPAG] = {
1489 .name = "DPAG",
1490 .description = "Paging Subsystem",
1491 .color = "\033[1;38m",
1492 .enabled = 1, .loglevel = LOGL_NOTICE,
1493 },
1494 [DMEAS] = {
1495 .name = "DMEAS",
1496 .description = "Radio Measurement Processing",
1497 .enabled = 0, .loglevel = LOGL_NOTICE,
1498 },
1499 [DREF] = {
1500 .name = "DREF",
1501 .description = "Reference Counting",
1502 .enabled = 0, .loglevel = LOGL_NOTICE,
1503 },
1504 [DGPRS] = {
1505 .name = "DGPRS",
1506 .description = "GPRS Packet Service",
1507 .enabled = 1, .loglevel = LOGL_DEBUG,
1508 },
1509 [DNS] = {
1510 .name = "DNS",
1511 .description = "GPRS Network Service (NS)",
1512 .enabled = 1, .loglevel = LOGL_INFO,
1513 },
1514 [DBSSGP] = {
1515 .name = "DBSSGP",
1516 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1517 .enabled = 1, .loglevel = LOGL_DEBUG,
1518 },
1519 [DLLC] = {
1520 .name = "DLLC",
1521 .description = "GPRS Logical Link Control Protocol (LLC)",
1522 .enabled = 1, .loglevel = LOGL_DEBUG,
1523 },
1524 [DSNDCP] = {
1525 .name = "DSNDCP",
1526 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1527 .enabled = 1, .loglevel = LOGL_DEBUG,
1528 },
1529};
1530
1531static struct log_info info = {
1532 .cat = gprs_categories,
1533 .num_cat = ARRAY_SIZE(gprs_categories),
1534};
1535
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001536int main(int argc, char **argv)
1537{
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001538 osmo_init_logging(&info);
1539 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1540 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1541
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01001542 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001543 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001544
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001545 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001546 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01001547 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01001548 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02001549 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01001550 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02001551 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01001552 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01001553 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001554 test_gmm_attach_acl();
1555 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001556 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001557 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001558 test_gmm_attach_subscr_gsup_auth(0);
1559 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001560 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001561 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001562 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001563 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01001564
1565 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01001566 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001567 return 0;
1568}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001569
1570
1571/* stubs */
1572struct osmo_prim_hdr;
1573int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1574{
1575 abort();
1576}