blob: c09b16931c838cb2d5d80be9cf2c1fe00587f17f [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>
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020029
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010030#include <osmocom/gprs/gprs_bssgp.h>
31
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020032#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck092bbc82015-01-05 18:57:32 +010033#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020034
35#include <osmocom/core/application.h>
36#include <osmocom/core/msgb.h>
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010037#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020038
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +020039#include <stdio.h>
40
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020041extern void *tall_msgb_ctx;
42
43void *tall_bsc_ctx;
44static struct sgsn_instance sgsn_inst = {
45 .config_file = "osmo_sgsn.cfg",
46 .cfg = {
47 .gtp_statedir = "./",
Jacob Erlbeckd7b77732014-11-04 10:08:37 +010048 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +010049 .subscriber_expiry_timeout = SGSN_TIMEOUT_NEVER,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020050 },
51};
52struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010053unsigned sgsn_tx_counter = 0;
54
55/* override */
56int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
57 struct bssgp_dl_ud_par *dup)
58{
59 sgsn_tx_counter += 1;
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +010060 msgb_free(msg);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010061 return 0;
62}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020063
Jacob Erlbecke8b69682014-11-12 10:12:11 +010064/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
65void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *, struct gsm_subscriber *);
66void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *, struct gsm_subscriber *) =
67 &__real_sgsn_update_subscriber_data;
68
69void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
70 struct gsm_subscriber *subscr)
71{
72 (*update_subscriber_data_cb)(mmctx, subscr);
73}
74
Jacob Erlbeck828059f2014-11-28 14:55:25 +010075/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
76int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
77int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
78 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +010079
Jacob Erlbeck828059f2014-11-28 14:55:25 +010080int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
81 return (*subscr_request_update_location_cb)(mmctx);
82};
83
84/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
85int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
86int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
87 &__real_gprs_subscr_request_auth_info;
88
89int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
90 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +010091};
Jacob Erlbecke8b69682014-11-12 10:12:11 +010092
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +010093/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
94int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
95int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
96 &__real_gprs_gsup_client_send;
97
98int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
99{
100 return (*gprs_gsup_client_send_cb)(gsupc, msg);
101};
102
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200103static int count(struct llist_head *head)
104{
105 struct llist_head *cur;
106 int count = 0;
107
108 llist_for_each(cur, head)
109 count += 1;
110
111 return count;
112}
113
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200114static struct msgb *create_msg(const uint8_t *data, size_t len)
115{
116 struct msgb *msg = msgb_alloc(len + 8, "test message");
117 msg->l1h = msgb_put(msg, 8);
118 msg->l2h = msgb_put(msg, len);
119 memcpy(msg->l2h, data, len);
120
121 msgb_bcid(msg) = msg->l1h;
122 msgb_gmmh(msg) = msg->l2h;
123 return msg;
124}
125
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100126/*
127 * Create a context and search for it
128 */
129static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
130{
131 struct sgsn_mm_ctx *ctx, *ictx;
132 struct gprs_llc_lle *lle;
133 int old_count = count(gprs_llme_list());
134
135 lle = gprs_lle_get_or_create(tlli, 3);
136 ctx = sgsn_mm_ctx_alloc(tlli, raid);
137 ctx->mm_state = GMM_REGISTERED_NORMAL;
138 ctx->llme = lle->llme;
139
140 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
141 OSMO_ASSERT(ictx == ctx);
142
143 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
144
145 return ctx;
146}
147
Jacob Erlbeck75488292014-10-29 10:31:18 +0100148static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
149 const uint8_t *data, size_t data_len)
150{
151 struct msgb *msg;
152
153 sgsn_tx_counter = 0;
154
155 msg = create_msg(data, data_len);
156 msgb_tlli(msg) = tlli;
157 gsm0408_gprs_rcvmsg(msg, llme);
158 msgb_free(msg);
159}
160
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200161static void test_llme(void)
162{
163 struct gprs_llc_lle *lle, *lle_copy;
164 uint32_t local_tlli;
165 uint32_t foreign_tlli;
166
167 printf("Testing LLME allocations\n");
168 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
169 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
170
171 /* initial state */
172 OSMO_ASSERT(count(gprs_llme_list()) == 0);
173
174 /* Create a new entry */
175 lle = gprs_lle_get_or_create(local_tlli, 3);
176 OSMO_ASSERT(lle);
177 OSMO_ASSERT(count(gprs_llme_list()) == 1);
178
179 /* No new entry is created */
180 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
181 OSMO_ASSERT(lle == lle_copy);
182 OSMO_ASSERT(count(gprs_llme_list()) == 1);
183 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
184 OSMO_ASSERT(lle == lle_copy);
185 OSMO_ASSERT(count(gprs_llme_list()) == 1);
186
187 /* unassign which should delete it*/
188 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
189
190 /* Check that everything was cleaned up */
191 OSMO_ASSERT(count(gprs_llme_list()) == 0);
192}
193
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100194struct gsm_subscriber *last_updated_subscr = NULL;
195void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
196 struct gsm_subscriber *subscr)
197{
198 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
199 __func__, mmctx, subscr);
200 last_updated_subscr = subscr;
201}
202
Jacob Erlbecka695d242015-01-09 11:59:50 +0100203static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
204{
205 struct gsm_subscriber *sfound;
206
207 sfound = gprs_subscr_get_by_imsi(imsi);
208 OSMO_ASSERT(sfound == subscr);
209 subscr_put(sfound);
210
211 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
212}
213
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100214static void show_subscrs(FILE *out)
215{
216 struct gsm_subscriber *subscr;
217
218 llist_for_each_entry(subscr, &active_subscribers, entry) {
219 fprintf(out, " Subscriber: %s, "
220 "use count: %d, keep: %d, timer: %d\n",
221 subscr->imsi, subscr->use_count, subscr->keep_in_ram,
222 osmo_timer_pending(&subscr->sgsn_data->timer));
223 }
224}
225
226static void assert_no_subscrs()
227{
228 show_subscrs(stdout);
229 fflush(stdout);
230 OSMO_ASSERT(llist_empty(&active_subscribers));
231}
232
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100233static void test_subscriber(void)
234{
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100235 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100236 const char *imsi1 = "1234567890";
237 const char *imsi2 = "9876543210";
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100238 const char *imsi3 = "5656565656";
239 int saved_expiry_timeout = sgsn->cfg.subscriber_expiry_timeout;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100240
241 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
242
243 printf("Testing core subscriber data API\n");
244
245 /* Check for emptiness */
246 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
247 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100248 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100249
250 /* Allocate entry 1 */
251 s1 = gprs_subscr_get_or_create(imsi1);
252 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100253 assert_subscr(s1, imsi1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100254 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100255
256 /* Allocate entry 2 */
257 s2 = gprs_subscr_get_or_create(imsi2);
258 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100259
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100260 /* Allocate entry 3 */
261 s3 = gprs_subscr_get_or_create(imsi3);
262
Jacob Erlbecka695d242015-01-09 11:59:50 +0100263 /* Check entries */
264 assert_subscr(s1, imsi1);
265 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100266 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100267
268 /* Update entry 1 */
269 last_updated_subscr = NULL;
270 gprs_subscr_update(s1);
271 OSMO_ASSERT(last_updated_subscr == s1);
272
273 /* Because of the update, it won't be freed on delete now */
274 gprs_subscr_delete(s1);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100275 sfound = gprs_subscr_get_by_imsi(imsi1);
276 OSMO_ASSERT(sfound != NULL);
277 s1 = sfound;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100278
279 /* Cancel it, so that delete will free it.
280 * Refcount it to make sure s1 won't be freed here */
281 last_updated_subscr = NULL;
282 gprs_subscr_put_and_cancel(subscr_get(s1));
283 OSMO_ASSERT(last_updated_subscr == s1);
284
285 /* Cancelled entries are still being found */
Jacob Erlbecka695d242015-01-09 11:59:50 +0100286 assert_subscr(s1, imsi1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100287
Jacob Erlbecka695d242015-01-09 11:59:50 +0100288 /* Free entry 1 (GPRS_SUBSCRIBER_CANCELLED is set) */
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100289 gprs_subscr_delete(s1);
290 s1 = NULL;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100291 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100292 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100293 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100294
Jacob Erlbecka695d242015-01-09 11:59:50 +0100295 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100296 gprs_subscr_delete(s2);
297 s2 = NULL;
298 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
299 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100300 assert_subscr(s3, imsi3);
301
302 /* Try to delete entry 3 */
303 OSMO_ASSERT(sgsn->cfg.subscriber_expiry_timeout == SGSN_TIMEOUT_NEVER);
304 gprs_subscr_delete(s3);
305 assert_subscr(s3, imsi3);
306 /* Process timeouts, this shouldn't delete s3 (SGSN_TIMEOUT_NEVER) */
307 osmo_timers_update();
308 assert_subscr(s3, imsi3);
309 s3 = subscr_get(s3);
310
311 /* Free entry 3 (TIMEOUT == 0) */
312 sgsn->cfg.subscriber_expiry_timeout = 0;
313 gprs_subscr_delete(s3);
314 assert_subscr(s3, imsi3);
315 /* Process timeouts, this should delete s3 */
316 osmo_timers_update();
317 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
318 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
319 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
320 sgsn->cfg.subscriber_expiry_timeout = saved_expiry_timeout;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100321
322 OSMO_ASSERT(llist_empty(&active_subscribers));
323
324 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
325}
326
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100327static void test_auth_triplets(void)
328{
329 struct gsm_subscriber *s1, *s1found;
330 const char *imsi1 = "1234567890";
331 struct gsm_auth_tuple *at;
332 struct sgsn_mm_ctx *ctx;
333 struct gprs_ra_id raid = { 0, };
334 uint32_t local_tlli = 0xffeeddcc;
335 struct gprs_llc_llme *llme;
336
337 printf("Testing authentication triplet handling\n");
338
339 /* Check for emptiness */
340 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
341
342 /* Allocate entry 1 */
343 s1 = gprs_subscr_get_or_create(imsi1);
344 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
345 s1found = gprs_subscr_get_by_imsi(imsi1);
346 OSMO_ASSERT(s1found == s1);
347 subscr_put(s1found);
348
349 /* Create a context */
350 OSMO_ASSERT(count(gprs_llme_list()) == 0);
351 ctx = alloc_mm_ctx(local_tlli, &raid);
352
353 /* Attach s1 to ctx */
354 ctx->subscr = subscr_get(s1);
355 ctx->subscr->sgsn_data->mm = ctx;
356
357 /* Try to get auth tuple */
358 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
359 OSMO_ASSERT(at == NULL);
360
361 /* Add triplets */
362 s1->sgsn_data->auth_triplets[0].key_seq = 0;
363 s1->sgsn_data->auth_triplets[1].key_seq = 1;
364 s1->sgsn_data->auth_triplets[2].key_seq = 2;
365
366 /* Try to get auth tuple */
367 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
368 OSMO_ASSERT(at != NULL);
369 OSMO_ASSERT(at->key_seq == 0);
370 OSMO_ASSERT(at->use_count == 1);
371 at = sgsn_auth_get_tuple(ctx, at->key_seq);
372 OSMO_ASSERT(at != NULL);
373 OSMO_ASSERT(at->key_seq == 1);
374 OSMO_ASSERT(at->use_count == 1);
375 at = sgsn_auth_get_tuple(ctx, at->key_seq);
376 OSMO_ASSERT(at != NULL);
377 OSMO_ASSERT(at->key_seq == 2);
378 OSMO_ASSERT(at->use_count == 1);
379 at = sgsn_auth_get_tuple(ctx, at->key_seq);
380 OSMO_ASSERT(at == NULL);
381
382 /* Free MM context and subscriber */
383 subscr_put(s1);
384 llme = ctx->llme;
385 sgsn_mm_ctx_free(ctx);
386 s1found = gprs_subscr_get_by_imsi(imsi1);
387 OSMO_ASSERT(s1found == NULL);
388 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
389}
390
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100391#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
392
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100393static int rx_gsup_message(const uint8_t *data, size_t data_len)
394{
395 struct msgb *msg;
396 int rc;
397
398 msg = msgb_alloc(1024, __func__);
399 msg->l2h = msgb_put(msg, data_len);
400 OSMO_ASSERT(msg->l2h != NULL);
401 memcpy(msg->l2h, data, data_len);
402 rc = gprs_subscr_rx_gsup_message(msg);
403 msgb_free(msg);
404
405 return rc;
406}
407
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100408static void test_subscriber_gsup(void)
409{
410 struct gsm_subscriber *s1, *s1found;
411 const char *imsi1 = "1234567890";
412 struct sgsn_mm_ctx *ctx;
413 struct gprs_ra_id raid = { 0, };
414 uint32_t local_tlli = 0xffeeddcc;
415 struct gprs_llc_llme *llme;
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100416 int rc;
417
418 static const uint8_t send_auth_info_res[] = {
419 0x0a,
420 TEST_GSUP_IMSI1_IE,
421 0x03, 0x22, /* Auth tuple */
422 0x20, 0x10,
423 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
424 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
425 0x21, 0x04,
426 0x21, 0x22, 0x23, 0x24,
427 0x22, 0x08,
428 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
429 0x03, 0x22, /* Auth tuple */
430 0x20, 0x10,
431 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
432 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
433 0x21, 0x04,
434 0xa1, 0xa2, 0xa3, 0xa4,
435 0x22, 0x08,
436 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
437 };
438
439 static const uint8_t send_auth_info_err[] = {
440 0x09,
441 TEST_GSUP_IMSI1_IE,
442 0x02, 0x01, 0x07 /* GPRS not allowed */
443 };
444
445 static const uint8_t update_location_res[] = {
446 0x06,
447 TEST_GSUP_IMSI1_IE,
448 0x04, 0x00, /* PDP info complete */
449 0x05, 0x12,
450 0x10, 0x01, 0x01,
451 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
452 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
453 0x05, 0x11,
454 0x10, 0x01, 0x02,
455 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
456 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
457 };
458
459 static const uint8_t update_location_err[] = {
460 0x05,
461 TEST_GSUP_IMSI1_IE,
462 0x02, 0x01, 0x07 /* GPRS not allowed */
463 };
464
465 static const uint8_t location_cancellation_req[] = {
466 0x1c,
467 TEST_GSUP_IMSI1_IE,
468 0x06, 0x01, 0x00,
469 };
470
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100471 static const uint8_t insert_data_req[] = {
472 0x10,
473 TEST_GSUP_IMSI1_IE,
474 0x05, 0x11,
475 0x10, 0x01, 0x03,
476 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
477 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
478 };
479
480 static const uint8_t delete_data_req[] = {
481 0x14,
482 TEST_GSUP_IMSI1_IE,
483 0x10, 0x01, 0x03,
484 };
485
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100486 printf("Testing subcriber GSUP handling\n");
487
488 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
489
490 /* Check for emptiness */
491 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
492
493 /* Allocate entry 1 */
494 s1 = gprs_subscr_get_or_create(imsi1);
495 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
496 s1found = gprs_subscr_get_by_imsi(imsi1);
497 OSMO_ASSERT(s1found == s1);
498 subscr_put(s1found);
499
500 /* Create a context */
501 OSMO_ASSERT(count(gprs_llme_list()) == 0);
502 ctx = alloc_mm_ctx(local_tlli, &raid);
503 llme = ctx->llme;
504
505 /* Attach s1 to ctx */
506 ctx->subscr = subscr_get(s1);
507 ctx->subscr->sgsn_data->mm = ctx;
508
509 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100510 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100511 OSMO_ASSERT(rc >= 0);
512 OSMO_ASSERT(last_updated_subscr == s1);
513
514 /* Check triplets */
515 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
516 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
517 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
518
519 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100520 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100521 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100522 OSMO_ASSERT(last_updated_subscr == s1);
523
524 /* Check triplets */
525 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
526 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
527 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
528
529 /* Inject UpdateLocReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100530 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100531 OSMO_ASSERT(rc >= 0);
532 OSMO_ASSERT(last_updated_subscr == s1);
533
534 /* Check authorization */
535 OSMO_ASSERT(s1->authorized == 1);
536
537 /* Inject UpdateLocErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100538 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100539 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100540 OSMO_ASSERT(last_updated_subscr == s1);
541
542 /* Check authorization */
543 OSMO_ASSERT(s1->authorized == 0);
544
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100545 /* Inject InsertSubscrData GSUP message */
546 last_updated_subscr = NULL;
547 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
548 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
549 OSMO_ASSERT(last_updated_subscr == NULL);
550
551 /* Inject DeleteSubscrData GSUP message */
552 last_updated_subscr = NULL;
553 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
554 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
555 OSMO_ASSERT(last_updated_subscr == NULL);
556
557 /* Inject LocCancelReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100558 rc = rx_gsup_message(location_cancellation_req,
559 sizeof(location_cancellation_req));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100560 OSMO_ASSERT(rc >= 0);
561 OSMO_ASSERT(last_updated_subscr == s1);
562
563 /* Check cancellation result */
564 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
565 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
566
567 /* Free MM context and subscriber */
568 subscr_put(s1);
569 s1found = gprs_subscr_get_by_imsi(imsi1);
570 OSMO_ASSERT(s1found == NULL);
571 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
572
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100573 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
574 last_updated_subscr = NULL;
575 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck629dacc2015-01-15 17:50:16 +0100576 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100577 OSMO_ASSERT(last_updated_subscr == NULL);
578
579 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
580 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
581 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
582 OSMO_ASSERT(last_updated_subscr == NULL);
583
584 /* Inject LocCancelReq GSUP message (unknown IMSI) */
585 rc = rx_gsup_message(location_cancellation_req,
586 sizeof(location_cancellation_req));
587 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
588 OSMO_ASSERT(last_updated_subscr == NULL);
589
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100590 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
591}
592
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +0100593int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
594{
595 msgb_free(msg);
596 return 0;
597};
598
599
600static void test_subscriber_blocking(void)
601{
602 struct gsm_subscriber *s1;
603 const char *imsi1 = "1234567890";
604 struct sgsn_mm_ctx *ctx;
605 struct gprs_ra_id raid = { 0, };
606 uint32_t local_tlli = 0xffeeddcc;
607 struct gprs_llc_llme *llme;
608 int rc;
609
610 printf("Testing subcriber procedure blocking\n");
611
612 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
613 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
614
615 /* Check for emptiness */
616 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
617
618 /* Create a context */
619 OSMO_ASSERT(count(gprs_llme_list()) == 0);
620 ctx = alloc_mm_ctx(local_tlli, &raid);
621 llme = ctx->llme;
622 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
623
624 /* Allocate and attach a subscriber */
625 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
626 assert_subscr(s1, imsi1);
627
628 /* Start SendAuthInfoRequest procedure */
629 rc = gprs_subscr_query_auth_info(s1);
630 /* Not blocking */
631 OSMO_ASSERT(rc == 0);
632
633 /* Start UpdateLocation procedure */
634 rc = gprs_subscr_location_update(s1);
635 /* Blocking */
636 OSMO_ASSERT(rc == 0);
637
638 /* Start PurgeMS procedure */
639 rc = gprs_subscr_purge(s1);
640 /* Not blocking */
641 OSMO_ASSERT(rc == 0);
642 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
643
644 /* Start PurgeMS procedure (retry) */
645 rc = gprs_subscr_purge(s1);
646 /* Not blocking */
647 OSMO_ASSERT(rc == 0);
648
649 /* Start SendAuthInfoRequest procedure */
650 rc = gprs_subscr_query_auth_info(s1);
651 /* Blocking */
652 OSMO_ASSERT(rc == -EAGAIN);
653
654 /* Start UpdateLocation procedure */
655 rc = gprs_subscr_location_update(s1);
656 /* Blocking */
657 OSMO_ASSERT(rc == -EAGAIN);
658
659 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
660 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
661
662 /* Start SendAuthInfoRequest procedure */
663 rc = gprs_subscr_query_auth_info(s1);
664 /* Not blocking */
665 OSMO_ASSERT(rc == 0);
666
667 /* Start UpdateLocation procedure */
668 rc = gprs_subscr_location_update(s1);
669 /* Blocking */
670 OSMO_ASSERT(rc == 0);
671
672 subscr_put(s1);
673 sgsn_mm_ctx_free(ctx);
674 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
675
676 assert_no_subscrs();
677
678 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
679 talloc_free(sgsn->gsup_client);
680 sgsn->gsup_client = NULL;
681}
682
683
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200684/*
685 * Test that a GMM Detach will remove the MMCTX and the
686 * associated LLME.
687 */
688static void test_gmm_detach(void)
689{
690 struct gprs_ra_id raid = { 0, };
691 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200692 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200693
694 printf("Testing GMM detach\n");
695
696 /* DTAP - Detach Request (MO) */
697 /* normal detach, power_off = 0 */
698 static const unsigned char detach_req[] = {
699 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
700 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
701 };
702
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200703 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200704
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100705 /* Create a context */
706 OSMO_ASSERT(count(gprs_llme_list()) == 0);
707 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200708
709 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100710 send_0408_message(ctx->llme, local_tlli,
711 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200712
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100713 /* verify that a single message (hopefully the Detach Accept) has been
714 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100715 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100716
717 /* verify that things are gone */
718 OSMO_ASSERT(count(gprs_llme_list()) == 0);
719 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
720 OSMO_ASSERT(!ictx);
721}
722
723/*
724 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
725 * will not sent a Detach Accept message (power_off = 1)
726 */
727static void test_gmm_detach_power_off(void)
728{
729 struct gprs_ra_id raid = { 0, };
730 struct sgsn_mm_ctx *ctx, *ictx;
731 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100732
733 printf("Testing GMM detach (power off)\n");
734
735 /* DTAP - Detach Request (MO) */
736 /* normal detach, power_off = 1 */
737 static const unsigned char detach_req[] = {
738 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
739 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
740 };
741
742 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
743
744 /* Create a context */
745 OSMO_ASSERT(count(gprs_llme_list()) == 0);
746 ctx = alloc_mm_ctx(local_tlli, &raid);
747
748 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100749 send_0408_message(ctx->llme, local_tlli,
750 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100751
752 /* verify that no message (and therefore no Detach Accept) has been
753 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100754 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100755
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200756 /* verify that things are gone */
757 OSMO_ASSERT(count(gprs_llme_list()) == 0);
758 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200759 OSMO_ASSERT(!ictx);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200760}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200761
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200762/*
763 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
764 */
765static void test_gmm_detach_no_mmctx(void)
766{
767 struct gprs_llc_lle *lle;
768 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200769
770 printf("Testing GMM detach (no MMCTX)\n");
771
772 /* DTAP - Detach Request (MO) */
773 /* normal detach, power_off = 0 */
774 static const unsigned char detach_req[] = {
775 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
776 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
777 };
778
779 /* Create an LLME */
780 OSMO_ASSERT(count(gprs_llme_list()) == 0);
781 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
782 lle = gprs_lle_get_or_create(local_tlli, 3);
783
784 OSMO_ASSERT(count(gprs_llme_list()) == 1);
785
786 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100787 send_0408_message(lle->llme, local_tlli,
788 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200789
790 /* verify that the LLME is gone */
791 OSMO_ASSERT(count(gprs_llme_list()) == 0);
792}
793
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100794/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100795 * Test that a single GMM Detach Accept message will not cause the SGSN to send
796 * any message or leave an MM context at the SGSN.
797 */
798static void test_gmm_detach_accept_unexpected(void)
799{
800 struct gprs_llc_lle *lle;
801 uint32_t local_tlli;
802
803 printf("Testing GMM detach accept (unexpected)\n");
804
805 /* DTAP - Detach Accept (MT) */
806 /* normal detach */
807 static const unsigned char detach_acc[] = {
808 0x08, 0x06
809 };
810
811 /* Create an LLME */
812 OSMO_ASSERT(count(gprs_llme_list()) == 0);
813 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
814 lle = gprs_lle_get_or_create(local_tlli, 3);
815
816 /* inject the detach */
817 send_0408_message(lle->llme, local_tlli,
818 detach_acc, ARRAY_SIZE(detach_acc));
819
820 /* verify that no message (and therefore no Status or XID reset) has been
821 * sent by the SGSN */
822 OSMO_ASSERT(sgsn_tx_counter == 0);
823
824 /* verify that things are gone */
825 OSMO_ASSERT(count(gprs_llme_list()) == 0);
826}
827
828/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100829 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
830 */
831static void test_gmm_status_no_mmctx(void)
832{
833 struct gprs_llc_lle *lle;
834 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100835
836 printf("Testing GMM Status (no MMCTX)\n");
837
838 /* DTAP - GMM Status, protocol error */
839 static const unsigned char gmm_status[] = {
840 0x08, 0x20, 0x6f
841 };
842
843 /* Create an LLME */
844 OSMO_ASSERT(count(gprs_llme_list()) == 0);
845 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
846 lle = gprs_lle_get_or_create(local_tlli, 3);
847
848 OSMO_ASSERT(count(gprs_llme_list()) == 1);
849
850 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100851 send_0408_message(lle->llme, local_tlli,
852 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100853
854 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100855 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100856
857 /* verify that the LLME is gone */
858 OSMO_ASSERT(count(gprs_llme_list()) == 0);
859}
860
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100861/*
862 * Test the GMM Attach procedure
863 */
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100864static void test_gmm_attach(int retry)
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100865{
866 struct gprs_ra_id raid = { 0, };
867 struct sgsn_mm_ctx *ctx = NULL;
868 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100869 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100870 uint32_t foreign_tlli;
871 uint32_t local_tlli = 0;
872 struct gprs_llc_lle *lle;
873
874 /* DTAP - Attach Request */
875 /* The P-TMSI is not known by the SGSN */
876 static const unsigned char attach_req[] = {
877 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
878 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
879 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
880 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
881 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
882 };
883
884 /* DTAP - Identity Response IMEI */
885 static const unsigned char ident_resp_imei[] = {
886 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
887 0x56
888 };
889
890 /* DTAP - Identity Response IMSI */
891 static const unsigned char ident_resp_imsi[] = {
892 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
893 0x54
894 };
895
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100896 /* DTAP - Authentication and Ciphering Resp */
897 static const unsigned char auth_ciph_resp[] = {
898 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
899 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
900 };
901
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100902 /* DTAP - Attach Complete */
903 static const unsigned char attach_compl[] = {
904 0x08, 0x03
905 };
906
907 /* DTAP - Detach Request (MO) */
908 /* normal detach, power_off = 0 */
909 static const unsigned char detach_req[] = {
910 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
911 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
912 };
913
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100914 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100915
916 /* reset the PRNG used by sgsn_alloc_ptmsi */
917 srand(1);
918
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100919 ptmsi1 = sgsn_alloc_ptmsi();
920 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
921
922 /* reset the PRNG, so that the same P-TMSI sequence will be generated
923 * again */
924 srand(1);
925
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100926 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
927
928 /* Create a LLE/LLME */
929 OSMO_ASSERT(count(gprs_llme_list()) == 0);
930 lle = gprs_lle_get_or_create(foreign_tlli, 3);
931 OSMO_ASSERT(count(gprs_llme_list()) == 1);
932
933 /* inject the attach request */
934 send_0408_message(lle->llme, foreign_tlli,
935 attach_req, ARRAY_SIZE(attach_req));
936
937 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
938 OSMO_ASSERT(ctx != NULL);
939 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
940
941 /* we expect an identity request (IMEI) */
942 OSMO_ASSERT(sgsn_tx_counter == 1);
943
944 /* inject the identity response (IMEI) */
945 send_0408_message(ctx->llme, foreign_tlli,
946 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
947
948 /* we expect an identity request (IMSI) */
949 OSMO_ASSERT(sgsn_tx_counter == 1);
950
951 /* inject the identity response (IMSI) */
952 send_0408_message(ctx->llme, foreign_tlli,
953 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
954
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100955 /* check that the MM context has not been removed due to a failed
956 * authorization */
957 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
958
Jacob Erlbeck67318ef2014-10-28 16:23:46 +0100959 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100960
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100961retry_attach_req:
962
963 if (retry && sgsn_tx_counter == 0) {
964 fprintf(stderr, "Retrying attach request\n");
965 /* re-inject the attach request */
966 send_0408_message(lle->llme, foreign_tlli,
967 attach_req, ARRAY_SIZE(attach_req));
968 }
969
970 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
971 /* we got an auth & ciph request */
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100972
973 /* inject the auth & ciph response */
974 send_0408_message(ctx->llme, foreign_tlli,
975 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
976
977 /* check that the MM context has not been removed due to a
978 * failed authorization */
979 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
980 }
981
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100982 if (retry && sgsn_tx_counter == 0)
983 goto retry_attach_req;
984
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100985 /* we expect an attach accept/reject */
986 OSMO_ASSERT(sgsn_tx_counter == 1);
987
988 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100989 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100990
991 /* inject the attach complete */
992 send_0408_message(ctx->llme, local_tlli,
993 attach_compl, ARRAY_SIZE(attach_compl));
994
995 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
996
997 /* we don't expect a response */
998 OSMO_ASSERT(sgsn_tx_counter == 0);
999
1000 /* inject the detach */
1001 send_0408_message(ctx->llme, local_tlli,
1002 detach_req, ARRAY_SIZE(detach_req));
1003
1004 /* verify that things are gone */
1005 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1006 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1007 OSMO_ASSERT(!ictx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001008}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001009
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001010static void test_gmm_attach_acl(void)
1011{
1012 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1013
1014 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1015 sgsn_acl_add("123456789012345", &sgsn->cfg);
1016 printf("Auth policy 'closed': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001017 test_gmm_attach(0);
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001018 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001019
1020 sgsn->cfg.auth_policy = saved_auth_policy;
1021}
1022
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001023int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001024 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001025 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001026 if (rc == -ENOTSUP) {
1027 OSMO_ASSERT(mmctx->subscr);
1028 gprs_subscr_update(mmctx->subscr);
1029 }
1030 return rc;
1031};
1032
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001033int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1034 gprs_subscr_update(mmctx->subscr);
1035 return 0;
1036};
1037
Jacob Erlbeck03386f62015-01-08 14:08:16 +01001038static void cleanup_subscr_by_imsi(const char *imsi)
1039{
1040 struct gsm_subscriber *subscr;
1041
1042 subscr = gprs_subscr_get_by_imsi(imsi);
1043 OSMO_ASSERT(subscr != NULL);
Jacob Erlbeckdc7e8b92015-01-08 14:13:46 +01001044 subscr->keep_in_ram = 0;
1045 subscr_put(subscr);
1046 subscr = gprs_subscr_get_by_imsi(imsi);
1047 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck03386f62015-01-08 14:08:16 +01001048}
1049
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001050static void test_gmm_attach_subscr(void)
1051{
1052 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1053 struct gsm_subscriber *subscr;
1054
1055 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001056 subscr_request_update_location_cb = my_subscr_request_update_location;
1057 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001058
1059 subscr = gprs_subscr_get_or_create("123456789012345");
1060 subscr->authorized = 1;
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +01001061 subscr->keep_in_ram = 1;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001062 subscr_put(subscr);
1063
1064 printf("Auth policy 'remote': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001065 test_gmm_attach(0);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001066
Jacob Erlbeck03386f62015-01-08 14:08:16 +01001067 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001068 assert_no_subscrs();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001069
1070 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001071 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1072 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001073}
1074
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001075int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1076{
1077 /* Fake an authentication */
1078 OSMO_ASSERT(mmctx->subscr);
1079 mmctx->is_authenticated = 1;
1080 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001081
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001082 return 0;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001083};
1084
1085static void test_gmm_attach_subscr_fake_auth(void)
1086{
1087 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1088 struct gsm_subscriber *subscr;
1089
1090 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001091 subscr_request_update_location_cb = my_subscr_request_update_location;
1092 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001093
1094 subscr = gprs_subscr_get_or_create("123456789012345");
1095 subscr->authorized = 1;
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +01001096 subscr->keep_in_ram = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001097 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001098 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001099 subscr_put(subscr);
1100
1101 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001102 test_gmm_attach(0);
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001103
Jacob Erlbeck03386f62015-01-08 14:08:16 +01001104 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001105 assert_no_subscrs();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001106
1107 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001108 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1109 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1110}
1111
1112int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1113{
1114 struct gsm_auth_tuple at = {
1115 .sres = {0x51, 0xe5, 0x51, 0xe5},
1116 .key_seq = 0
1117 };
1118
1119 /* Fake an authentication */
1120 OSMO_ASSERT(mmctx->subscr);
1121 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1122
1123 gprs_subscr_update_auth_info(mmctx->subscr);
1124
1125 return 0;
1126};
1127
1128static void test_gmm_attach_subscr_real_auth(void)
1129{
1130 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1131 struct gsm_subscriber *subscr;
1132
1133 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1134 subscr_request_update_location_cb = my_subscr_request_update_location;
1135 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1136
1137 subscr = gprs_subscr_get_or_create("123456789012345");
1138 subscr->authorized = 1;
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +01001139 subscr->keep_in_ram = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001140 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001141 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001142 subscr_put(subscr);
1143
1144 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001145
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001146 test_gmm_attach(0);
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001147
Jacob Erlbeck03386f62015-01-08 14:08:16 +01001148 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001149 assert_no_subscrs();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001150
1151 sgsn->cfg.auth_policy = saved_auth_policy;
1152 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1153 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001154}
1155
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001156#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1157 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1158
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001159static int auth_info_skip = 0;
1160static int upd_loc_skip = 0;
1161
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001162int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1163{
1164 static const uint8_t send_auth_info_res[] = {
1165 0x0a,
1166 TEST_GSUP_IMSI_LONG_IE,
1167 0x03, 0x22, /* Auth tuple */
1168 0x20, 0x10,
1169 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1170 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1171 0x21, 0x04,
1172 0x51, 0xe5, 0x51, 0xe5,
1173 0x22, 0x08,
1174 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1175 };
1176
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001177 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001178
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001179 if (auth_info_skip > 0) {
1180 auth_info_skip -= 1;
1181 return -EAGAIN;
1182 }
1183
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001184 /* Fake an SendAuthInfoRes */
1185 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1186
1187 return 0;
1188};
1189
1190int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1191 static const uint8_t update_location_res[] = {
1192 0x06,
1193 TEST_GSUP_IMSI_LONG_IE,
1194 0x04, 0x00, /* PDP info complete */
1195 0x05, 0x12,
1196 0x10, 0x01, 0x01,
1197 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1198 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1199 };
1200
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001201 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001202
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001203 if (upd_loc_skip > 0) {
1204 upd_loc_skip -= 1;
1205 return -EAGAIN;
1206 }
1207
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001208 /* Fake an UpdateLocRes */
1209 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1210};
1211
1212
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001213static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001214{
1215 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1216 struct gsm_subscriber *subscr;
1217
1218 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1219 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1220 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001221 if (retry) {
1222 upd_loc_skip = 3;
1223 auth_info_skip = 3;
1224 }
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001225
1226 subscr = gprs_subscr_get_or_create("123456789012345");
1227 subscr->authorized = 1;
1228 sgsn->cfg.require_authentication = 1;
1229 sgsn->cfg.require_update_location = 1;
1230 subscr_put(subscr);
1231
1232 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001233 test_gmm_attach(retry);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001234
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001235 cleanup_subscr_by_imsi("123456789012345");
1236 assert_no_subscrs();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001237
1238 sgsn->cfg.auth_policy = saved_auth_policy;
1239 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1240 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001241 upd_loc_skip = 0;
1242 auth_info_skip = 0;
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001243}
1244
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001245int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1246{
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001247 struct gprs_gsup_message to_peer = {0};
1248 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001249 struct msgb *reply_msg;
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001250 int rc;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001251
1252 /* Simulate the GSUP peer */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001253 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1254 OSMO_ASSERT(rc >= 0);
1255 OSMO_ASSERT(to_peer.imsi[0] != 0);
1256 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001257
1258 /* This invalidates the pointers in to_peer */
1259 msgb_free(msg);
1260
1261 switch (to_peer.message_type) {
1262 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1263 /* Send UPDATE_LOCATION_RESULT */
1264 return my_subscr_request_update_gsup_auth(NULL);
1265
1266 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1267 /* Send SEND_AUTH_INFO_RESULT */
1268 return my_subscr_request_auth_info_gsup_auth(NULL);
1269
1270 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001271 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1272 break;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001273
1274 default:
1275 if ((to_peer.message_type & 0b00000011) == 0) {
1276 /* Unhandled request */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001277 /* Send error(NOT_IMPL) */
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001278 from_peer.message_type = to_peer.message_type + 1;
1279 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1280 break;
1281 }
1282
1283 /* Ignore it */
1284 return 0;
1285 }
1286
1287 reply_msg = gprs_gsup_msgb_alloc();
1288 reply_msg->l2h = reply_msg->data;
1289 gprs_gsup_encode(reply_msg, &from_peer);
1290 gprs_subscr_rx_gsup_message(reply_msg);
1291 msgb_free(reply_msg);
1292
1293 return 0;
1294};
1295
1296static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1297{
1298 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1299 struct gsm_subscriber *subscr;
1300
1301 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1302 sgsn_inst.cfg.subscriber_expiry_timeout = 0;
1303 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1304
1305 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1306
1307 if (retry) {
1308 upd_loc_skip = 3;
1309 auth_info_skip = 3;
1310 }
1311
1312 printf("Auth policy 'remote', real GSUP based auth: ");
1313 test_gmm_attach(retry);
1314
1315 subscr = gprs_subscr_get_by_imsi("123456789012345");
1316 OSMO_ASSERT(subscr != NULL);
1317 gprs_subscr_delete(subscr);
1318
1319 osmo_timers_update();
1320
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001321 assert_no_subscrs();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001322
1323 sgsn->cfg.auth_policy = saved_auth_policy;
1324 sgsn_inst.cfg.subscriber_expiry_timeout = SGSN_TIMEOUT_NEVER;
1325 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1326 upd_loc_skip = 0;
1327 auth_info_skip = 0;
1328 talloc_free(sgsn->gsup_client);
1329 sgsn->gsup_client = NULL;
1330}
1331
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001332/*
1333 * Test the GMM Rejects
1334 */
1335static void test_gmm_reject(void)
1336{
1337 struct gprs_ra_id raid = { 0, };
1338 struct sgsn_mm_ctx *ctx = NULL;
1339 uint32_t foreign_tlli;
1340 struct gprs_llc_lle *lle;
1341 int idx;
1342
1343 /* DTAP - Attach Request */
1344 /* Invalid MI length */
1345 static const unsigned char attach_req_inv_mi_len[] = {
1346 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1347 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1348 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1349 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1350 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1351 };
1352
1353 /* DTAP - Attach Request */
1354 /* Invalid MI type (IMEI) */
1355 static const unsigned char attach_req_inv_mi_type[] = {
1356 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1357 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1358 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1359 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1360 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1361 };
1362
1363 /* DTAP - Routing Area Update Request */
1364 static const unsigned char dtap_ra_upd_req[] = {
1365 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1366 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1367 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1368 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1369 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1370 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1371 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1372 };
1373
1374 /* DTAP - Routing Area Update Request */
1375 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1376 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1377 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1378 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1379 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1380 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1381 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1382 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1383 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1384 };
1385
1386 /* DTAP - Routing Area Update Request */
1387 /* Invalid cap length */
1388 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1389 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1390 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1391 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1392 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1393 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1394 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1395 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1396 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1397 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1398 };
1399
1400 struct test {
1401 const char *title;
1402 const unsigned char *msg;
1403 unsigned msg_len;
1404 unsigned num_resp;
1405
1406 };
1407 static struct test tests[] = {
1408 {
1409 .title = "Attach Request (invalid MI length)",
1410 .msg = attach_req_inv_mi_len,
1411 .msg_len = sizeof(attach_req_inv_mi_len),
1412 .num_resp = 1 /* Reject */
1413
1414 },
1415 {
1416 .title = "Attach Request (invalid MI type)",
1417 .msg = attach_req_inv_mi_type,
1418 .msg_len = sizeof(attach_req_inv_mi_type),
1419 .num_resp = 1 /* Reject */
1420 },
1421 {
1422 .title = "Routing Area Update Request (valid)",
1423 .msg = dtap_ra_upd_req,
1424 .msg_len = sizeof(dtap_ra_upd_req),
1425 .num_resp = 2 /* XID Reset + Reject */
1426 },
1427 {
1428 .title = "Routing Area Update Request (invalid type)",
1429 .msg = dtap_ra_upd_req_inv_type,
1430 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1431 .num_resp = 1 /* Reject */
1432 },
1433 {
1434 .title = "Routing Area Update Request (invalid CAP length)",
1435 .msg = dtap_ra_upd_req_inv_cap_len,
1436 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1437 .num_resp = 1 /* Reject */
1438 },
1439 };
1440
1441 printf("Testing GMM reject\n");
1442
1443 /* reset the PRNG used by sgsn_alloc_ptmsi */
1444 srand(1);
1445
1446 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1447
1448 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1449
1450 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1451 const struct test *test = &tests[idx];
1452 printf(" - %s\n", test->title);
1453
1454 /* Create a LLE/LLME */
1455 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1456 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1457
1458 /* Inject the Request message */
1459 send_0408_message(lle->llme, foreign_tlli,
1460 test->msg, test->msg_len);
1461
1462 /* We expect a Reject message */
1463 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1464 sgsn_tx_counter, test->num_resp);
1465 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1466
1467 /* verify that LLME/MM are removed */
1468 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1469 OSMO_ASSERT(ctx == NULL);
1470 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1471 }
1472}
1473
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001474/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001475 * Test cancellation of attached MM contexts
1476 */
1477static void test_gmm_cancel(void)
1478{
1479 struct gprs_ra_id raid = { 0, };
1480 struct sgsn_mm_ctx *ctx = NULL;
1481 struct sgsn_mm_ctx *ictx;
1482 uint32_t ptmsi1;
1483 uint32_t foreign_tlli;
1484 uint32_t local_tlli = 0;
1485 struct gprs_llc_lle *lle;
1486 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1487
1488 /* DTAP - Attach Request */
1489 /* The P-TMSI is not known by the SGSN */
1490 static const unsigned char attach_req[] = {
1491 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1492 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1493 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1494 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1495 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1496 };
1497
1498 /* DTAP - Identity Response IMEI */
1499 static const unsigned char ident_resp_imei[] = {
1500 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1501 0x56
1502 };
1503
1504 /* DTAP - Identity Response IMSI */
1505 static const unsigned char ident_resp_imsi[] = {
1506 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1507 0x54
1508 };
1509
1510 /* DTAP - Attach Complete */
1511 static const unsigned char attach_compl[] = {
1512 0x08, 0x03
1513 };
1514
1515 printf("Testing cancellation\n");
1516
1517 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1518
1519 /* reset the PRNG used by sgsn_alloc_ptmsi */
1520 srand(1);
1521
1522 ptmsi1 = sgsn_alloc_ptmsi();
1523 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1524
1525 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1526 * again */
1527 srand(1);
1528
1529 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1530
1531 /* Create a LLE/LLME */
1532 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1533 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1534 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1535
1536 /* inject the attach request */
1537 send_0408_message(lle->llme, foreign_tlli,
1538 attach_req, ARRAY_SIZE(attach_req));
1539
1540 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1541 OSMO_ASSERT(ctx != NULL);
1542 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1543
1544 /* we expect an identity request (IMEI) */
1545 OSMO_ASSERT(sgsn_tx_counter == 1);
1546
1547 /* inject the identity response (IMEI) */
1548 send_0408_message(ctx->llme, foreign_tlli,
1549 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1550
1551 /* we expect an identity request (IMSI) */
1552 OSMO_ASSERT(sgsn_tx_counter == 1);
1553
1554 /* inject the identity response (IMSI) */
1555 send_0408_message(ctx->llme, foreign_tlli,
1556 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1557
1558 /* check that the MM context has not been removed due to a failed
1559 * authorization */
1560 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1561
1562 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1563
1564 /* we expect an attach accept/reject */
1565 OSMO_ASSERT(sgsn_tx_counter == 1);
1566
1567 /* this has been randomly assigned by the SGSN */
1568 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1569
1570 /* inject the attach complete */
1571 send_0408_message(ctx->llme, local_tlli,
1572 attach_compl, ARRAY_SIZE(attach_compl));
1573
1574 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1575
1576 /* we don't expect a response */
1577 OSMO_ASSERT(sgsn_tx_counter == 0);
1578
1579 /* cancel */
Jacob Erlbeck41010082015-01-05 17:51:17 +01001580 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001581
1582 /* verify that things are gone */
1583 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1584 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1585 OSMO_ASSERT(!ictx);
1586
1587 sgsn->cfg.auth_policy = saved_auth_policy;
1588}
1589
1590/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001591 * Test the dynamic allocation of P-TMSIs
1592 */
1593static void test_gmm_ptmsi_allocation(void)
1594{
1595 struct gprs_ra_id raid = { 0, };
1596 struct sgsn_mm_ctx *ctx = NULL;
1597 struct sgsn_mm_ctx *ictx;
1598 uint32_t foreign_tlli;
1599 uint32_t ptmsi1;
1600 uint32_t ptmsi2;
1601 uint32_t old_ptmsi;
1602 uint32_t local_tlli = 0;
1603 struct gprs_llc_lle *lle;
1604 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1605
1606 /* DTAP - Attach Request (IMSI 12131415161718) */
1607 static const unsigned char attach_req[] = {
1608 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1609 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1610 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1611 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1612 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1613 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1614 0x00,
1615 };
1616
1617 /* DTAP - Identity Response IMEI */
1618 static const unsigned char ident_resp_imei[] = {
1619 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1620 0x56
1621 };
1622
1623 /* DTAP - Attach Complete */
1624 static const unsigned char attach_compl[] = {
1625 0x08, 0x03
1626 };
1627
1628 /* DTAP - Routing Area Update Request */
1629 static const unsigned char ra_upd_req[] = {
1630 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1631 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1632 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1633 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1634 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1635 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1636 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1637 };
1638
1639 /* DTAP - Routing Area Update Complete */
1640 static const unsigned char ra_upd_complete[] = {
1641 0x08, 0x0a
1642 };
1643
1644 /* DTAP - Detach Request (MO) */
1645 /* normal detach, power_off = 1 */
1646 static const unsigned char detach_req[] = {
1647 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1648 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1649 };
1650
1651 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1652
1653 printf("Testing P-TMSI allocation\n");
1654
1655 printf(" - sgsn_alloc_ptmsi\n");
1656
1657 /* reset the PRNG used by sgsn_alloc_ptmsi */
1658 srand(1);
1659
1660 ptmsi1 = sgsn_alloc_ptmsi();
1661 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1662
1663 ptmsi2 = sgsn_alloc_ptmsi();
1664 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1665
1666 OSMO_ASSERT(ptmsi1 != ptmsi2);
1667
1668 printf(" - Repeated Attach Request\n");
1669
1670 /* reset the PRNG, so that the same P-TMSI will be generated
1671 * again */
1672 srand(1);
1673
1674 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1675
1676 /* Create a LLE/LLME */
1677 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1678 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1679 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1680
1681 /* inject the attach request */
1682 send_0408_message(lle->llme, foreign_tlli,
1683 attach_req, ARRAY_SIZE(attach_req));
1684
1685 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1686 OSMO_ASSERT(ctx != NULL);
1687 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1688 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1689
1690 old_ptmsi = ctx->p_tmsi_old;
1691
1692 /* we expect an identity request (IMEI) */
1693 OSMO_ASSERT(sgsn_tx_counter == 1);
1694
1695 /* inject the identity response (IMEI) */
1696 send_0408_message(ctx->llme, foreign_tlli,
1697 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1698
1699 /* check that the MM context has not been removed due to a failed
1700 * authorization */
1701 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1702
1703 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1704 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1705
1706 /* we expect an attach accept */
1707 OSMO_ASSERT(sgsn_tx_counter == 1);
1708
1709 /* we ignore this and send the attach again */
1710 send_0408_message(lle->llme, foreign_tlli,
1711 attach_req, ARRAY_SIZE(attach_req));
1712
1713 /* the allocated P-TMSI should be the same */
1714 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1715 OSMO_ASSERT(ctx != NULL);
1716 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1717 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1718 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1719
1720 /* inject the attach complete */
1721 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1722 send_0408_message(ctx->llme, local_tlli,
1723 attach_compl, ARRAY_SIZE(attach_compl));
1724
1725 /* we don't expect a response */
1726 OSMO_ASSERT(sgsn_tx_counter == 0);
1727
1728 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1729 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1730 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1731
1732 printf(" - Repeated RA Update Request\n");
1733
1734 /* inject the RA update request */
1735 send_0408_message(ctx->llme, local_tlli,
1736 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1737
1738 /* we expect an RA update accept */
1739 OSMO_ASSERT(sgsn_tx_counter == 1);
1740
1741 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1742 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1743 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1744
1745 /* repeat the RA update request */
1746 send_0408_message(ctx->llme, local_tlli,
1747 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1748
1749 /* we expect an RA update accept */
1750 OSMO_ASSERT(sgsn_tx_counter == 1);
1751
1752 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1753 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1754 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1755
1756 /* inject the RA update complete */
1757 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1758 send_0408_message(ctx->llme, local_tlli,
1759 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1760
1761 /* we don't expect a response */
1762 OSMO_ASSERT(sgsn_tx_counter == 0);
1763
1764 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1765 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1766 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1767
1768 /* inject the detach */
1769 send_0408_message(ctx->llme, local_tlli,
1770 detach_req, ARRAY_SIZE(detach_req));
1771
1772 /* verify that things are gone */
1773 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1774 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1775 OSMO_ASSERT(!ictx);
1776
1777 sgsn->cfg.auth_policy = saved_auth_policy;
1778}
1779
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001780static struct log_info_cat gprs_categories[] = {
1781 [DMM] = {
1782 .name = "DMM",
1783 .description = "Layer3 Mobility Management (MM)",
1784 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001785 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001786 },
1787 [DPAG] = {
1788 .name = "DPAG",
1789 .description = "Paging Subsystem",
1790 .color = "\033[1;38m",
1791 .enabled = 1, .loglevel = LOGL_NOTICE,
1792 },
1793 [DMEAS] = {
1794 .name = "DMEAS",
1795 .description = "Radio Measurement Processing",
1796 .enabled = 0, .loglevel = LOGL_NOTICE,
1797 },
1798 [DREF] = {
1799 .name = "DREF",
1800 .description = "Reference Counting",
1801 .enabled = 0, .loglevel = LOGL_NOTICE,
1802 },
1803 [DGPRS] = {
1804 .name = "DGPRS",
1805 .description = "GPRS Packet Service",
1806 .enabled = 1, .loglevel = LOGL_DEBUG,
1807 },
1808 [DNS] = {
1809 .name = "DNS",
1810 .description = "GPRS Network Service (NS)",
1811 .enabled = 1, .loglevel = LOGL_INFO,
1812 },
1813 [DBSSGP] = {
1814 .name = "DBSSGP",
1815 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1816 .enabled = 1, .loglevel = LOGL_DEBUG,
1817 },
1818 [DLLC] = {
1819 .name = "DLLC",
1820 .description = "GPRS Logical Link Control Protocol (LLC)",
1821 .enabled = 1, .loglevel = LOGL_DEBUG,
1822 },
1823 [DSNDCP] = {
1824 .name = "DSNDCP",
1825 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1826 .enabled = 1, .loglevel = LOGL_DEBUG,
1827 },
1828};
1829
1830static struct log_info info = {
1831 .cat = gprs_categories,
1832 .num_cat = ARRAY_SIZE(gprs_categories),
1833};
1834
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001835int main(int argc, char **argv)
1836{
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001837 osmo_init_logging(&info);
1838 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1839 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1840
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01001841 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001842 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001843
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001844 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001845 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01001846 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01001847 test_subscriber_gsup();
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +01001848 test_subscriber_blocking();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02001849 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01001850 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02001851 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01001852 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01001853 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001854 test_gmm_attach_acl();
1855 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001856 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001857 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001858 test_gmm_attach_subscr_gsup_auth(0);
1859 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001860 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001861 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001862 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001863 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001864 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01001865
1866 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01001867 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001868 return 0;
1869}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001870
1871
1872/* stubs */
1873struct osmo_prim_hdr;
1874int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1875{
1876 abort();
1877}