blob: f5f68206b0a8ceae7abb1c33bb9ae9f6888977f0 [file] [log] [blame]
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020027
Jacob Erlbeck189999d2014-10-27 14:34:13 +010028#include <osmocom/gprs/gprs_bssgp.h>
29
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020030#include <osmocom/gsm/gsm_utils.h>
31
32#include <osmocom/core/application.h>
33#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010034#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020035
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020036#include <stdio.h>
37
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020038extern void *tall_msgb_ctx;
39
40void *tall_bsc_ctx;
41static struct sgsn_instance sgsn_inst = {
42 .config_file = "osmo_sgsn.cfg",
43 .cfg = {
44 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010045 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020046 },
47};
48struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010049unsigned sgsn_tx_counter = 0;
50
51/* override */
52int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
53 struct bssgp_dl_ud_par *dup)
54{
55 sgsn_tx_counter += 1;
56 return 0;
57}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020058
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010059/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
60void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *, struct gsm_subscriber *);
61void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *, struct gsm_subscriber *) =
62 &__real_sgsn_update_subscriber_data;
63
64void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
65 struct gsm_subscriber *subscr)
66{
67 (*update_subscriber_data_cb)(mmctx, subscr);
68}
69
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010070/* override, requires '-Wl,--wrap=gprs_subscr_request_update' */
71int __real_gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx);
72int (*subscr_request_update_cb)(struct sgsn_mm_ctx *mmctx) =
73 &__real_gprs_subscr_request_update;
74
75int __wrap_gprs_subscr_request_update(struct sgsn_mm_ctx *mmctx) {
76 return (*subscr_request_update_cb)(mmctx);
77};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010078
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020079static int count(struct llist_head *head)
80{
81 struct llist_head *cur;
82 int count = 0;
83
84 llist_for_each(cur, head)
85 count += 1;
86
87 return count;
88}
89
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +020090static struct msgb *create_msg(const uint8_t *data, size_t len)
91{
92 struct msgb *msg = msgb_alloc(len + 8, "test message");
93 msg->l1h = msgb_put(msg, 8);
94 msg->l2h = msgb_put(msg, len);
95 memcpy(msg->l2h, data, len);
96
97 msgb_bcid(msg) = msg->l1h;
98 msgb_gmmh(msg) = msg->l2h;
99 return msg;
100}
101
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100102/*
103 * Create a context and search for it
104 */
105static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
106{
107 struct sgsn_mm_ctx *ctx, *ictx;
108 struct gprs_llc_lle *lle;
109 int old_count = count(gprs_llme_list());
110
111 lle = gprs_lle_get_or_create(tlli, 3);
112 ctx = sgsn_mm_ctx_alloc(tlli, raid);
113 ctx->mm_state = GMM_REGISTERED_NORMAL;
114 ctx->llme = lle->llme;
115
116 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
117 OSMO_ASSERT(ictx == ctx);
118
119 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
120
121 return ctx;
122}
123
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100124static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
125 const uint8_t *data, size_t data_len)
126{
127 struct msgb *msg;
128
129 sgsn_tx_counter = 0;
130
131 msg = create_msg(data, data_len);
132 msgb_tlli(msg) = tlli;
133 gsm0408_gprs_rcvmsg(msg, llme);
134 msgb_free(msg);
135}
136
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200137static void test_llme(void)
138{
139 struct gprs_llc_lle *lle, *lle_copy;
140 uint32_t local_tlli;
141 uint32_t foreign_tlli;
142
143 printf("Testing LLME allocations\n");
144 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
145 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
146
147 /* initial state */
148 OSMO_ASSERT(count(gprs_llme_list()) == 0);
149
150 /* Create a new entry */
151 lle = gprs_lle_get_or_create(local_tlli, 3);
152 OSMO_ASSERT(lle);
153 OSMO_ASSERT(count(gprs_llme_list()) == 1);
154
155 /* No new entry is created */
156 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
157 OSMO_ASSERT(lle == lle_copy);
158 OSMO_ASSERT(count(gprs_llme_list()) == 1);
159 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
160 OSMO_ASSERT(lle == lle_copy);
161 OSMO_ASSERT(count(gprs_llme_list()) == 1);
162
163 /* unassign which should delete it*/
164 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
165
166 /* Check that everything was cleaned up */
167 OSMO_ASSERT(count(gprs_llme_list()) == 0);
168}
169
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100170struct gsm_subscriber *last_updated_subscr = NULL;
171void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
172 struct gsm_subscriber *subscr)
173{
174 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
175 __func__, mmctx, subscr);
176 last_updated_subscr = subscr;
177}
178
179static void test_subscriber(void)
180{
181 struct gsm_subscriber *s1, *s2, *s1found, *s2found;
182 const char *imsi1 = "1234567890";
183 const char *imsi2 = "9876543210";
184
185 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
186
187 printf("Testing core subscriber data API\n");
188
189 /* Check for emptiness */
190 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
191 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
192
193 /* Allocate entry 1 */
194 s1 = gprs_subscr_get_or_create(imsi1);
195 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
196 s1found = gprs_subscr_get_by_imsi(imsi1);
197 OSMO_ASSERT(s1found == s1);
198 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
199 subscr_put(s1found);
200
201 /* Allocate entry 2 */
202 s2 = gprs_subscr_get_or_create(imsi2);
203 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
204 s1found = gprs_subscr_get_by_imsi(imsi1);
205 s2found = gprs_subscr_get_by_imsi(imsi2);
206 OSMO_ASSERT(s1found == s1);
207 OSMO_ASSERT(s2found == s2);
208 subscr_put(s1found);
209 subscr_put(s2found);
210
211 /* Update entry 1 */
212 last_updated_subscr = NULL;
213 gprs_subscr_update(s1);
214 OSMO_ASSERT(last_updated_subscr == s1);
215
216 /* Because of the update, it won't be freed on delete now */
217 gprs_subscr_delete(s1);
218 s1found = gprs_subscr_get_by_imsi(imsi1);
219 OSMO_ASSERT(s1found != NULL);
220 s1 = s1found;
221
222 /* Cancel it, so that delete will free it.
223 * Refcount it to make sure s1 won't be freed here */
224 last_updated_subscr = NULL;
225 gprs_subscr_put_and_cancel(subscr_get(s1));
226 OSMO_ASSERT(last_updated_subscr == s1);
227
228 /* Cancelled entries are still being found */
229 s1found = gprs_subscr_get_by_imsi(imsi1);
230 OSMO_ASSERT(s1found != NULL);
231 subscr_put(s1found);
232
233 /* Free entry 1 */
234 gprs_subscr_delete(s1);
235 s1 = NULL;
236 s2found = gprs_subscr_get_by_imsi(imsi2);
237 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
238 OSMO_ASSERT(s2found == s2);
239 subscr_put(s2found);
240
241 /* Free entry 2 */
242 gprs_subscr_delete(s2);
243 s2 = NULL;
244 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
245 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
246
247 OSMO_ASSERT(llist_empty(&active_subscribers));
248
249 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
250}
251
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200252/*
253 * Test that a GMM Detach will remove the MMCTX and the
254 * associated LLME.
255 */
256static void test_gmm_detach(void)
257{
258 struct gprs_ra_id raid = { 0, };
259 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200260 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200261
262 printf("Testing GMM detach\n");
263
264 /* DTAP - Detach Request (MO) */
265 /* normal detach, power_off = 0 */
266 static const unsigned char detach_req[] = {
267 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
268 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
269 };
270
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200271 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200272
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100273 /* Create a context */
274 OSMO_ASSERT(count(gprs_llme_list()) == 0);
275 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200276
277 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100278 send_0408_message(ctx->llme, local_tlli,
279 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200280
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100281 /* verify that a single message (hopefully the Detach Accept) has been
282 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100283 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100284
285 /* verify that things are gone */
286 OSMO_ASSERT(count(gprs_llme_list()) == 0);
287 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
288 OSMO_ASSERT(!ictx);
289}
290
291/*
292 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
293 * will not sent a Detach Accept message (power_off = 1)
294 */
295static void test_gmm_detach_power_off(void)
296{
297 struct gprs_ra_id raid = { 0, };
298 struct sgsn_mm_ctx *ctx, *ictx;
299 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100300
301 printf("Testing GMM detach (power off)\n");
302
303 /* DTAP - Detach Request (MO) */
304 /* normal detach, power_off = 1 */
305 static const unsigned char detach_req[] = {
306 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
307 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
308 };
309
310 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
311
312 /* Create a context */
313 OSMO_ASSERT(count(gprs_llme_list()) == 0);
314 ctx = alloc_mm_ctx(local_tlli, &raid);
315
316 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100317 send_0408_message(ctx->llme, local_tlli,
318 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100319
320 /* verify that no message (and therefore no Detach Accept) has been
321 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100322 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100323
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200324 /* verify that things are gone */
325 OSMO_ASSERT(count(gprs_llme_list()) == 0);
326 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200327 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200328}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200329
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200330/*
331 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
332 */
333static void test_gmm_detach_no_mmctx(void)
334{
335 struct gprs_llc_lle *lle;
336 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200337
338 printf("Testing GMM detach (no MMCTX)\n");
339
340 /* DTAP - Detach Request (MO) */
341 /* normal detach, power_off = 0 */
342 static const unsigned char detach_req[] = {
343 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
344 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
345 };
346
347 /* Create an LLME */
348 OSMO_ASSERT(count(gprs_llme_list()) == 0);
349 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
350 lle = gprs_lle_get_or_create(local_tlli, 3);
351
352 OSMO_ASSERT(count(gprs_llme_list()) == 1);
353
354 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100355 send_0408_message(lle->llme, local_tlli,
356 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200357
358 /* verify that the LLME is gone */
359 OSMO_ASSERT(count(gprs_llme_list()) == 0);
360}
361
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100362/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100363 * Test that a single GMM Detach Accept message will not cause the SGSN to send
364 * any message or leave an MM context at the SGSN.
365 */
366static void test_gmm_detach_accept_unexpected(void)
367{
368 struct gprs_llc_lle *lle;
369 uint32_t local_tlli;
370
371 printf("Testing GMM detach accept (unexpected)\n");
372
373 /* DTAP - Detach Accept (MT) */
374 /* normal detach */
375 static const unsigned char detach_acc[] = {
376 0x08, 0x06
377 };
378
379 /* Create an LLME */
380 OSMO_ASSERT(count(gprs_llme_list()) == 0);
381 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
382 lle = gprs_lle_get_or_create(local_tlli, 3);
383
384 /* inject the detach */
385 send_0408_message(lle->llme, local_tlli,
386 detach_acc, ARRAY_SIZE(detach_acc));
387
388 /* verify that no message (and therefore no Status or XID reset) has been
389 * sent by the SGSN */
390 OSMO_ASSERT(sgsn_tx_counter == 0);
391
392 /* verify that things are gone */
393 OSMO_ASSERT(count(gprs_llme_list()) == 0);
394}
395
396/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100397 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
398 */
399static void test_gmm_status_no_mmctx(void)
400{
401 struct gprs_llc_lle *lle;
402 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100403
404 printf("Testing GMM Status (no MMCTX)\n");
405
406 /* DTAP - GMM Status, protocol error */
407 static const unsigned char gmm_status[] = {
408 0x08, 0x20, 0x6f
409 };
410
411 /* Create an LLME */
412 OSMO_ASSERT(count(gprs_llme_list()) == 0);
413 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
414 lle = gprs_lle_get_or_create(local_tlli, 3);
415
416 OSMO_ASSERT(count(gprs_llme_list()) == 1);
417
418 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100419 send_0408_message(lle->llme, local_tlli,
420 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100421
422 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100423 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100424
425 /* verify that the LLME is gone */
426 OSMO_ASSERT(count(gprs_llme_list()) == 0);
427}
428
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100429/*
430 * Test the GMM Attach procedure
431 */
432static void test_gmm_attach(void)
433{
434 struct gprs_ra_id raid = { 0, };
435 struct sgsn_mm_ctx *ctx = NULL;
436 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100437 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100438 uint32_t foreign_tlli;
439 uint32_t local_tlli = 0;
440 struct gprs_llc_lle *lle;
441
442 /* DTAP - Attach Request */
443 /* The P-TMSI is not known by the SGSN */
444 static const unsigned char attach_req[] = {
445 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
446 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
447 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
448 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
449 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
450 };
451
452 /* DTAP - Identity Response IMEI */
453 static const unsigned char ident_resp_imei[] = {
454 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
455 0x56
456 };
457
458 /* DTAP - Identity Response IMSI */
459 static const unsigned char ident_resp_imsi[] = {
460 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
461 0x54
462 };
463
464 /* DTAP - Attach Complete */
465 static const unsigned char attach_compl[] = {
466 0x08, 0x03
467 };
468
469 /* DTAP - Detach Request (MO) */
470 /* normal detach, power_off = 0 */
471 static const unsigned char detach_req[] = {
472 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
473 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
474 };
475
476 printf("Testing GMM attach\n");
477
478 /* reset the PRNG used by sgsn_alloc_ptmsi */
479 srand(1);
480
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100481 ptmsi1 = sgsn_alloc_ptmsi();
482 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
483
484 /* reset the PRNG, so that the same P-TMSI sequence will be generated
485 * again */
486 srand(1);
487
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100488 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
489
490 /* Create a LLE/LLME */
491 OSMO_ASSERT(count(gprs_llme_list()) == 0);
492 lle = gprs_lle_get_or_create(foreign_tlli, 3);
493 OSMO_ASSERT(count(gprs_llme_list()) == 1);
494
495 /* inject the attach request */
496 send_0408_message(lle->llme, foreign_tlli,
497 attach_req, ARRAY_SIZE(attach_req));
498
499 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
500 OSMO_ASSERT(ctx != NULL);
501 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
502
503 /* we expect an identity request (IMEI) */
504 OSMO_ASSERT(sgsn_tx_counter == 1);
505
506 /* inject the identity response (IMEI) */
507 send_0408_message(ctx->llme, foreign_tlli,
508 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
509
510 /* we expect an identity request (IMSI) */
511 OSMO_ASSERT(sgsn_tx_counter == 1);
512
513 /* inject the identity response (IMSI) */
514 send_0408_message(ctx->llme, foreign_tlli,
515 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
516
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100517 /* check that the MM context has not been removed due to a failed
518 * authorization */
519 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
520
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100521 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100522
523 /* we expect an attach accept/reject */
524 OSMO_ASSERT(sgsn_tx_counter == 1);
525
526 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100527 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100528
529 /* inject the attach complete */
530 send_0408_message(ctx->llme, local_tlli,
531 attach_compl, ARRAY_SIZE(attach_compl));
532
533 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
534
535 /* we don't expect a response */
536 OSMO_ASSERT(sgsn_tx_counter == 0);
537
538 /* inject the detach */
539 send_0408_message(ctx->llme, local_tlli,
540 detach_req, ARRAY_SIZE(detach_req));
541
542 /* verify that things are gone */
543 OSMO_ASSERT(count(gprs_llme_list()) == 0);
544 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
545 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100546}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100547
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100548static void test_gmm_attach_acl(void)
549{
550 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
551
552 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
553 sgsn_acl_add("123456789012345", &sgsn->cfg);
554 printf("Auth policy 'closed': ");
555 test_gmm_attach();
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100556 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100557
558 sgsn->cfg.auth_policy = saved_auth_policy;
559}
560
561int my_subscr_request_update(struct sgsn_mm_ctx *mmctx) {
562 int rc;
563 rc = __real_gprs_subscr_request_update(mmctx);
564 if (rc == -ENOTSUP) {
565 OSMO_ASSERT(mmctx->subscr);
566 gprs_subscr_update(mmctx->subscr);
567 }
568 return rc;
569};
570
571static void test_gmm_attach_subscr(void)
572{
573 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
574 struct gsm_subscriber *subscr;
575
576 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
577 subscr_request_update_cb = my_subscr_request_update;
578
579 subscr = gprs_subscr_get_or_create("123456789012345");
580 subscr->authorized = 1;
581 subscr_put(subscr);
582
583 printf("Auth policy 'remote': ");
584 test_gmm_attach();
585
586 subscr = gprs_subscr_get_by_imsi("123456789012345");
587 OSMO_ASSERT(subscr != NULL);
588 gprs_subscr_delete(subscr);
589
590 sgsn->cfg.auth_policy = saved_auth_policy;
591 subscr_request_update_cb = __real_gprs_subscr_request_update;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100592}
593
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +0100594int my_subscr_request_update_fake_auth(struct sgsn_mm_ctx *mmctx) {
595 int rc;
596 rc = __real_gprs_subscr_request_update(mmctx);
597 if (rc == -ENOTSUP) {
598 struct gsm_subscriber *subscr;
599 int old_sgsn_tx_counter = sgsn_tx_counter;
600
601 OSMO_ASSERT(mmctx->subscr);
602 /* Prevent subscr from being deleted */
603 subscr = subscr_get(mmctx->subscr);
604
605 /* Start authentication procedure */
606 gprs_subscr_update(subscr);
607
608 /* This will cause a GPRS AUTH AND CIPHERING REQ (cksn broken) */
609 OSMO_ASSERT(old_sgsn_tx_counter == sgsn_tx_counter - 1);
610
611 /* Restore sgsn_tx_counter to keep test_gmm_attach happy */
612 sgsn_tx_counter = old_sgsn_tx_counter;
613
614 /* Fake an authentication */
615 OSMO_ASSERT(subscr->sgsn_data->mm);
616 subscr->sgsn_data->mm->is_authenticated = 1;
617 gprs_subscr_update(subscr);
618
619 subscr_put(subscr);
620 }
621 return rc;
622};
623
624static void test_gmm_attach_subscr_fake_auth(void)
625{
626 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
627 struct gsm_subscriber *subscr;
628
629 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
630 subscr_request_update_cb = my_subscr_request_update_fake_auth;
631
632 subscr = gprs_subscr_get_or_create("123456789012345");
633 subscr->authorized = 1;
634 subscr->sgsn_data->authenticate = 1;
635 subscr_put(subscr);
636
637 printf("Auth policy 'remote', auth faked: ");
638 test_gmm_attach();
639
640 subscr = gprs_subscr_get_by_imsi("123456789012345");
641 OSMO_ASSERT(subscr != NULL);
642 gprs_subscr_delete(subscr);
643
644 sgsn->cfg.auth_policy = saved_auth_policy;
645 subscr_request_update_cb = __real_gprs_subscr_request_update;
646}
647
Jacob Erlbeck80d07e32014-11-06 13:43:41 +0100648/*
649 * Test the GMM Rejects
650 */
651static void test_gmm_reject(void)
652{
653 struct gprs_ra_id raid = { 0, };
654 struct sgsn_mm_ctx *ctx = NULL;
655 uint32_t foreign_tlli;
656 struct gprs_llc_lle *lle;
657 int idx;
658
659 /* DTAP - Attach Request */
660 /* Invalid MI length */
661 static const unsigned char attach_req_inv_mi_len[] = {
662 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
663 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
664 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
665 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
666 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
667 };
668
669 /* DTAP - Attach Request */
670 /* Invalid MI type (IMEI) */
671 static const unsigned char attach_req_inv_mi_type[] = {
672 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
673 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
674 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
675 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
676 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
677 };
678
679 /* DTAP - Routing Area Update Request */
680 static const unsigned char dtap_ra_upd_req[] = {
681 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
682 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
683 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
684 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
685 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
686 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
687 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
688 };
689
690 /* DTAP - Routing Area Update Request */
691 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
692 static const unsigned char dtap_ra_upd_req_inv_type[] = {
693 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
694 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
695 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
696 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
697 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
698 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
699 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
700 };
701
702 /* DTAP - Routing Area Update Request */
703 /* Invalid cap length */
704 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
705 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
706 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
707 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
708 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
709 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
710 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
711 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
712 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
713 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
714 };
715
716 struct test {
717 const char *title;
718 const unsigned char *msg;
719 unsigned msg_len;
720 unsigned num_resp;
721
722 };
723 static struct test tests[] = {
724 {
725 .title = "Attach Request (invalid MI length)",
726 .msg = attach_req_inv_mi_len,
727 .msg_len = sizeof(attach_req_inv_mi_len),
728 .num_resp = 1 /* Reject */
729
730 },
731 {
732 .title = "Attach Request (invalid MI type)",
733 .msg = attach_req_inv_mi_type,
734 .msg_len = sizeof(attach_req_inv_mi_type),
735 .num_resp = 1 /* Reject */
736 },
737 {
738 .title = "Routing Area Update Request (valid)",
739 .msg = dtap_ra_upd_req,
740 .msg_len = sizeof(dtap_ra_upd_req),
741 .num_resp = 2 /* XID Reset + Reject */
742 },
743 {
744 .title = "Routing Area Update Request (invalid type)",
745 .msg = dtap_ra_upd_req_inv_type,
746 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
747 .num_resp = 1 /* Reject */
748 },
749 {
750 .title = "Routing Area Update Request (invalid CAP length)",
751 .msg = dtap_ra_upd_req_inv_cap_len,
752 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
753 .num_resp = 1 /* Reject */
754 },
755 };
756
757 printf("Testing GMM reject\n");
758
759 /* reset the PRNG used by sgsn_alloc_ptmsi */
760 srand(1);
761
762 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
763
764 OSMO_ASSERT(count(gprs_llme_list()) == 0);
765
766 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
767 const struct test *test = &tests[idx];
768 printf(" - %s\n", test->title);
769
770 /* Create a LLE/LLME */
771 lle = gprs_lle_get_or_create(foreign_tlli, 3);
772 OSMO_ASSERT(count(gprs_llme_list()) == 1);
773
774 /* Inject the Request message */
775 send_0408_message(lle->llme, foreign_tlli,
776 test->msg, test->msg_len);
777
778 /* We expect a Reject message */
779 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
780 sgsn_tx_counter, test->num_resp);
781 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
782
783 /* verify that LLME/MM are removed */
784 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
785 OSMO_ASSERT(ctx == NULL);
786 OSMO_ASSERT(count(gprs_llme_list()) == 0);
787 }
788}
789
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +0100790/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +0100791 * Test cancellation of attached MM contexts
792 */
793static void test_gmm_cancel(void)
794{
795 struct gprs_ra_id raid = { 0, };
796 struct sgsn_mm_ctx *ctx = NULL;
797 struct sgsn_mm_ctx *ictx;
798 uint32_t ptmsi1;
799 uint32_t foreign_tlli;
800 uint32_t local_tlli = 0;
801 struct gprs_llc_lle *lle;
802 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
803
804 /* DTAP - Attach Request */
805 /* The P-TMSI is not known by the SGSN */
806 static const unsigned char attach_req[] = {
807 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
808 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
809 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
810 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
811 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
812 };
813
814 /* DTAP - Identity Response IMEI */
815 static const unsigned char ident_resp_imei[] = {
816 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
817 0x56
818 };
819
820 /* DTAP - Identity Response IMSI */
821 static const unsigned char ident_resp_imsi[] = {
822 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
823 0x54
824 };
825
826 /* DTAP - Attach Complete */
827 static const unsigned char attach_compl[] = {
828 0x08, 0x03
829 };
830
831 printf("Testing cancellation\n");
832
833 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
834
835 /* reset the PRNG used by sgsn_alloc_ptmsi */
836 srand(1);
837
838 ptmsi1 = sgsn_alloc_ptmsi();
839 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
840
841 /* reset the PRNG, so that the same P-TMSI sequence will be generated
842 * again */
843 srand(1);
844
845 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
846
847 /* Create a LLE/LLME */
848 OSMO_ASSERT(count(gprs_llme_list()) == 0);
849 lle = gprs_lle_get_or_create(foreign_tlli, 3);
850 OSMO_ASSERT(count(gprs_llme_list()) == 1);
851
852 /* inject the attach request */
853 send_0408_message(lle->llme, foreign_tlli,
854 attach_req, ARRAY_SIZE(attach_req));
855
856 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
857 OSMO_ASSERT(ctx != NULL);
858 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
859
860 /* we expect an identity request (IMEI) */
861 OSMO_ASSERT(sgsn_tx_counter == 1);
862
863 /* inject the identity response (IMEI) */
864 send_0408_message(ctx->llme, foreign_tlli,
865 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
866
867 /* we expect an identity request (IMSI) */
868 OSMO_ASSERT(sgsn_tx_counter == 1);
869
870 /* inject the identity response (IMSI) */
871 send_0408_message(ctx->llme, foreign_tlli,
872 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
873
874 /* check that the MM context has not been removed due to a failed
875 * authorization */
876 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
877
878 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
879
880 /* we expect an attach accept/reject */
881 OSMO_ASSERT(sgsn_tx_counter == 1);
882
883 /* this has been randomly assigned by the SGSN */
884 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
885
886 /* inject the attach complete */
887 send_0408_message(ctx->llme, local_tlli,
888 attach_compl, ARRAY_SIZE(attach_compl));
889
890 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
891
892 /* we don't expect a response */
893 OSMO_ASSERT(sgsn_tx_counter == 0);
894
895 /* cancel */
896 gsm0408_gprs_access_cancelled(ctx);
897
898 /* verify that things are gone */
899 OSMO_ASSERT(count(gprs_llme_list()) == 0);
900 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
901 OSMO_ASSERT(!ictx);
902
903 sgsn->cfg.auth_policy = saved_auth_policy;
904}
905
906/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +0100907 * Test the dynamic allocation of P-TMSIs
908 */
909static void test_gmm_ptmsi_allocation(void)
910{
911 struct gprs_ra_id raid = { 0, };
912 struct sgsn_mm_ctx *ctx = NULL;
913 struct sgsn_mm_ctx *ictx;
914 uint32_t foreign_tlli;
915 uint32_t ptmsi1;
916 uint32_t ptmsi2;
917 uint32_t old_ptmsi;
918 uint32_t local_tlli = 0;
919 struct gprs_llc_lle *lle;
920 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
921
922 /* DTAP - Attach Request (IMSI 12131415161718) */
923 static const unsigned char attach_req[] = {
924 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
925 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
926 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
927 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
928 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
929 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
930 0x00,
931 };
932
933 /* DTAP - Identity Response IMEI */
934 static const unsigned char ident_resp_imei[] = {
935 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
936 0x56
937 };
938
939 /* DTAP - Attach Complete */
940 static const unsigned char attach_compl[] = {
941 0x08, 0x03
942 };
943
944 /* DTAP - Routing Area Update Request */
945 static const unsigned char ra_upd_req[] = {
946 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
947 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
948 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
949 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
950 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
951 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
952 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
953 };
954
955 /* DTAP - Routing Area Update Complete */
956 static const unsigned char ra_upd_complete[] = {
957 0x08, 0x0a
958 };
959
960 /* DTAP - Detach Request (MO) */
961 /* normal detach, power_off = 1 */
962 static const unsigned char detach_req[] = {
963 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
964 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
965 };
966
967 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
968
969 printf("Testing P-TMSI allocation\n");
970
971 printf(" - sgsn_alloc_ptmsi\n");
972
973 /* reset the PRNG used by sgsn_alloc_ptmsi */
974 srand(1);
975
976 ptmsi1 = sgsn_alloc_ptmsi();
977 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
978
979 ptmsi2 = sgsn_alloc_ptmsi();
980 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
981
982 OSMO_ASSERT(ptmsi1 != ptmsi2);
983
984 printf(" - Repeated Attach Request\n");
985
986 /* reset the PRNG, so that the same P-TMSI will be generated
987 * again */
988 srand(1);
989
990 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
991
992 /* Create a LLE/LLME */
993 OSMO_ASSERT(count(gprs_llme_list()) == 0);
994 lle = gprs_lle_get_or_create(foreign_tlli, 3);
995 OSMO_ASSERT(count(gprs_llme_list()) == 1);
996
997 /* inject the attach request */
998 send_0408_message(lle->llme, foreign_tlli,
999 attach_req, ARRAY_SIZE(attach_req));
1000
1001 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1002 OSMO_ASSERT(ctx != NULL);
1003 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1004 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1005
1006 old_ptmsi = ctx->p_tmsi_old;
1007
1008 /* we expect an identity request (IMEI) */
1009 OSMO_ASSERT(sgsn_tx_counter == 1);
1010
1011 /* inject the identity response (IMEI) */
1012 send_0408_message(ctx->llme, foreign_tlli,
1013 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1014
1015 /* check that the MM context has not been removed due to a failed
1016 * authorization */
1017 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1018
1019 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1020 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1021
1022 /* we expect an attach accept */
1023 OSMO_ASSERT(sgsn_tx_counter == 1);
1024
1025 /* we ignore this and send the attach again */
1026 send_0408_message(lle->llme, foreign_tlli,
1027 attach_req, ARRAY_SIZE(attach_req));
1028
1029 /* the allocated P-TMSI should be the same */
1030 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1031 OSMO_ASSERT(ctx != NULL);
1032 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1033 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1034 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1035
1036 /* inject the attach complete */
1037 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1038 send_0408_message(ctx->llme, local_tlli,
1039 attach_compl, ARRAY_SIZE(attach_compl));
1040
1041 /* we don't expect a response */
1042 OSMO_ASSERT(sgsn_tx_counter == 0);
1043
1044 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1045 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1046 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1047
1048 printf(" - Repeated RA Update Request\n");
1049
1050 /* inject the RA update request */
1051 send_0408_message(ctx->llme, local_tlli,
1052 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1053
1054 /* we expect an RA update accept */
1055 OSMO_ASSERT(sgsn_tx_counter == 1);
1056
1057 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1058 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1059 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1060
1061 /* repeat the RA update request */
1062 send_0408_message(ctx->llme, local_tlli,
1063 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1064
1065 /* we expect an RA update accept */
1066 OSMO_ASSERT(sgsn_tx_counter == 1);
1067
1068 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1069 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1070 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1071
1072 /* inject the RA update complete */
1073 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1074 send_0408_message(ctx->llme, local_tlli,
1075 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1076
1077 /* we don't expect a response */
1078 OSMO_ASSERT(sgsn_tx_counter == 0);
1079
1080 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1081 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1082 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1083
1084 /* inject the detach */
1085 send_0408_message(ctx->llme, local_tlli,
1086 detach_req, ARRAY_SIZE(detach_req));
1087
1088 /* verify that things are gone */
1089 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1090 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1091 OSMO_ASSERT(!ictx);
1092
1093 sgsn->cfg.auth_policy = saved_auth_policy;
1094}
1095
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001096static struct log_info_cat gprs_categories[] = {
1097 [DMM] = {
1098 .name = "DMM",
1099 .description = "Layer3 Mobility Management (MM)",
1100 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001101 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001102 },
1103 [DPAG] = {
1104 .name = "DPAG",
1105 .description = "Paging Subsystem",
1106 .color = "\033[1;38m",
1107 .enabled = 1, .loglevel = LOGL_NOTICE,
1108 },
1109 [DMEAS] = {
1110 .name = "DMEAS",
1111 .description = "Radio Measurement Processing",
1112 .enabled = 0, .loglevel = LOGL_NOTICE,
1113 },
1114 [DREF] = {
1115 .name = "DREF",
1116 .description = "Reference Counting",
1117 .enabled = 0, .loglevel = LOGL_NOTICE,
1118 },
1119 [DGPRS] = {
1120 .name = "DGPRS",
1121 .description = "GPRS Packet Service",
1122 .enabled = 1, .loglevel = LOGL_DEBUG,
1123 },
1124 [DNS] = {
1125 .name = "DNS",
1126 .description = "GPRS Network Service (NS)",
1127 .enabled = 1, .loglevel = LOGL_INFO,
1128 },
1129 [DBSSGP] = {
1130 .name = "DBSSGP",
1131 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1132 .enabled = 1, .loglevel = LOGL_DEBUG,
1133 },
1134 [DLLC] = {
1135 .name = "DLLC",
1136 .description = "GPRS Logical Link Control Protocol (LLC)",
1137 .enabled = 1, .loglevel = LOGL_DEBUG,
1138 },
1139 [DSNDCP] = {
1140 .name = "DSNDCP",
1141 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1142 .enabled = 1, .loglevel = LOGL_DEBUG,
1143 },
1144};
1145
1146static struct log_info info = {
1147 .cat = gprs_categories,
1148 .num_cat = ARRAY_SIZE(gprs_categories),
1149};
1150
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001151int main(int argc, char **argv)
1152{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001153 osmo_init_logging(&info);
1154 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1155 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1156
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001157 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001158 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001159
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001160 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001161 test_subscriber();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001162 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001163 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001164 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001165 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001166 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001167 test_gmm_attach_acl();
1168 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001169 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001170 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001171 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001172 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001173 printf("Done\n");
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001174 return 0;
1175}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001176
1177
1178/* stubs */
1179struct osmo_prim_hdr;
1180int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1181{
1182 abort();
1183}