blob: 662227d6509cd1884fd34fb2bc4e41797ae907c2 [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>
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020029
Jacob Erlbeck189999d2014-10-27 14:34:13 +010030#include <osmocom/gprs/gprs_bssgp.h>
31
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020032#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeckbce20612015-01-05 18:57:32 +010033#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020034
35#include <osmocom/core/application.h>
36#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010037#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020038
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020039#include <stdio.h>
40
Holger Hans Peter Freyther4299c052014-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 Erlbeck106f5472014-11-04 10:08:37 +010048 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +010049 .subscriber_expiry_timeout = SGSN_TIMEOUT_NEVER,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020050 },
51};
52struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-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 Erlbeckf0b06d82015-01-13 11:56:28 +010060 msgb_free(msg);
Jacob Erlbeck189999d2014-10-27 14:34:13 +010061 return 0;
62}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020063
Jacob Erlbeck33b6dad2014-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 Erlbeck98a95ac2014-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 Erlbeckbe2c8d92014-11-12 10:18:09 +010079
Jacob Erlbeck98a95ac2014-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 Erlbeckbe2c8d92014-11-12 10:18:09 +010091};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010092
Jacob Erlbeckc157ee72015-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 Freyther4299c052014-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 Freytherfe921332014-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 Erlbeckabc16a52014-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 Erlbeck94ef1c02014-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 Freyther4299c052014-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 Erlbeck33b6dad2014-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 Erlbeckb8fb1402015-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 Erlbeck058bc262015-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 Erlbeck33b6dad2014-11-12 10:12:11 +0100233static void test_subscriber(void)
234{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100235 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100236 const char *imsi1 = "1234567890";
237 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100238 const char *imsi3 = "5656565656";
239 int saved_expiry_timeout = sgsn->cfg.subscriber_expiry_timeout;
Jacob Erlbeck33b6dad2014-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 Erlbeck0f47b8f2015-01-06 16:32:41 +0100248 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-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 Erlbeckb8fb1402015-01-09 11:59:50 +0100253 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100254 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-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 Erlbeckb8fb1402015-01-09 11:59:50 +0100259
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100260 /* Allocate entry 3 */
261 s3 = gprs_subscr_get_or_create(imsi3);
262
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100263 /* Check entries */
264 assert_subscr(s1, imsi1);
265 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100266 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-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 Erlbeckb8fb1402015-01-09 11:59:50 +0100275 sfound = gprs_subscr_get_by_imsi(imsi1);
276 OSMO_ASSERT(sfound != NULL);
277 s1 = sfound;
Jacob Erlbeck33b6dad2014-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 Erlbeckb8fb1402015-01-09 11:59:50 +0100286 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100287
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100288 /* Free entry 1 (GPRS_SUBSCRIBER_CANCELLED is set) */
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100289 gprs_subscr_delete(s1);
290 s1 = NULL;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100291 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100292 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100293 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100294
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100295 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck33b6dad2014-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 Erlbeck0f47b8f2015-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 Erlbeck33b6dad2014-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 Erlbeck7921ab12014-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 Erlbecka6ddc2d2014-12-12 15:01:37 +0100391#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
392
Jacob Erlbecke21e1842014-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 Erlbecka6ddc2d2014-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 Erlbecka6ddc2d2014-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 Erlbeck87c7ffc2015-01-08 15:29:01 +0100471 static const uint8_t location_cancellation_req_other[] = {
472 0x1c,
473 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
474 0x06, 0x01, 0x00,
475 };
476
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100477 static const uint8_t insert_data_req[] = {
478 0x10,
479 TEST_GSUP_IMSI1_IE,
480 0x05, 0x11,
481 0x10, 0x01, 0x03,
482 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
483 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
484 };
485
486 static const uint8_t delete_data_req[] = {
487 0x14,
488 TEST_GSUP_IMSI1_IE,
489 0x10, 0x01, 0x03,
490 };
491
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100492 printf("Testing subcriber GSUP handling\n");
493
494 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
495
496 /* Check for emptiness */
497 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
498
499 /* Allocate entry 1 */
500 s1 = gprs_subscr_get_or_create(imsi1);
501 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
502 s1found = gprs_subscr_get_by_imsi(imsi1);
503 OSMO_ASSERT(s1found == s1);
504 subscr_put(s1found);
505
506 /* Create a context */
507 OSMO_ASSERT(count(gprs_llme_list()) == 0);
508 ctx = alloc_mm_ctx(local_tlli, &raid);
509 llme = ctx->llme;
510
511 /* Attach s1 to ctx */
512 ctx->subscr = subscr_get(s1);
513 ctx->subscr->sgsn_data->mm = ctx;
514
515 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100516 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100517 OSMO_ASSERT(rc >= 0);
518 OSMO_ASSERT(last_updated_subscr == s1);
519
520 /* Check triplets */
521 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
522 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
523 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
524
525 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100526 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100527 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100528 OSMO_ASSERT(last_updated_subscr == s1);
529
530 /* Check triplets */
531 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
532 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
533 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
534
535 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100536 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100537 OSMO_ASSERT(rc >= 0);
538 OSMO_ASSERT(last_updated_subscr == s1);
539
540 /* Check authorization */
541 OSMO_ASSERT(s1->authorized == 1);
542
543 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100544 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100545 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100546 OSMO_ASSERT(last_updated_subscr == s1);
547
548 /* Check authorization */
549 OSMO_ASSERT(s1->authorized == 0);
550
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100551 /* Inject InsertSubscrData GSUP message */
552 last_updated_subscr = NULL;
553 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
554 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
555 OSMO_ASSERT(last_updated_subscr == NULL);
556
557 /* Inject DeleteSubscrData GSUP message */
558 last_updated_subscr = NULL;
559 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
560 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
561 OSMO_ASSERT(last_updated_subscr == NULL);
562
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100563 /* Inject wrong LocCancelReq GSUP message */
564 last_updated_subscr = NULL;
565 rc = rx_gsup_message(location_cancellation_req_other,
566 sizeof(location_cancellation_req_other));
567 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
568 OSMO_ASSERT(last_updated_subscr == NULL);
569
570 /* Check cancellation result */
571 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
572 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
573
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100574 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100575 rc = rx_gsup_message(location_cancellation_req,
576 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100577 OSMO_ASSERT(rc >= 0);
578 OSMO_ASSERT(last_updated_subscr == s1);
579
580 /* Check cancellation result */
581 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
582 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
583
584 /* Free MM context and subscriber */
585 subscr_put(s1);
586 s1found = gprs_subscr_get_by_imsi(imsi1);
587 OSMO_ASSERT(s1found == NULL);
588 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
589
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100590 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
591 last_updated_subscr = NULL;
592 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100593 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100594 OSMO_ASSERT(last_updated_subscr == NULL);
595
596 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
597 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
598 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
599 OSMO_ASSERT(last_updated_subscr == NULL);
600
601 /* Inject LocCancelReq GSUP message (unknown IMSI) */
602 rc = rx_gsup_message(location_cancellation_req,
603 sizeof(location_cancellation_req));
604 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
605 OSMO_ASSERT(last_updated_subscr == NULL);
606
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100607 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
608}
609
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100610int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
611{
612 msgb_free(msg);
613 return 0;
614};
615
616
617static void test_subscriber_blocking(void)
618{
619 struct gsm_subscriber *s1;
620 const char *imsi1 = "1234567890";
621 struct sgsn_mm_ctx *ctx;
622 struct gprs_ra_id raid = { 0, };
623 uint32_t local_tlli = 0xffeeddcc;
624 struct gprs_llc_llme *llme;
625 int rc;
626
627 printf("Testing subcriber procedure blocking\n");
628
629 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
630 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
631
632 /* Check for emptiness */
633 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
634
635 /* Create a context */
636 OSMO_ASSERT(count(gprs_llme_list()) == 0);
637 ctx = alloc_mm_ctx(local_tlli, &raid);
638 llme = ctx->llme;
639 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
640
641 /* Allocate and attach a subscriber */
642 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
643 assert_subscr(s1, imsi1);
644
645 /* Start SendAuthInfoRequest procedure */
646 rc = gprs_subscr_query_auth_info(s1);
647 /* Not blocking */
648 OSMO_ASSERT(rc == 0);
649
650 /* Start UpdateLocation procedure */
651 rc = gprs_subscr_location_update(s1);
652 /* Blocking */
653 OSMO_ASSERT(rc == 0);
654
655 /* Start PurgeMS procedure */
656 rc = gprs_subscr_purge(s1);
657 /* Not blocking */
658 OSMO_ASSERT(rc == 0);
659 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
660
661 /* Start PurgeMS procedure (retry) */
662 rc = gprs_subscr_purge(s1);
663 /* Not blocking */
664 OSMO_ASSERT(rc == 0);
665
666 /* Start SendAuthInfoRequest procedure */
667 rc = gprs_subscr_query_auth_info(s1);
668 /* Blocking */
669 OSMO_ASSERT(rc == -EAGAIN);
670
671 /* Start UpdateLocation procedure */
672 rc = gprs_subscr_location_update(s1);
673 /* Blocking */
674 OSMO_ASSERT(rc == -EAGAIN);
675
676 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
677 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
678
679 /* Start SendAuthInfoRequest procedure */
680 rc = gprs_subscr_query_auth_info(s1);
681 /* Not blocking */
682 OSMO_ASSERT(rc == 0);
683
684 /* Start UpdateLocation procedure */
685 rc = gprs_subscr_location_update(s1);
686 /* Blocking */
687 OSMO_ASSERT(rc == 0);
688
689 subscr_put(s1);
690 sgsn_mm_ctx_free(ctx);
691 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
692
693 assert_no_subscrs();
694
695 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
696 talloc_free(sgsn->gsup_client);
697 sgsn->gsup_client = NULL;
698}
699
700
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200701/*
702 * Test that a GMM Detach will remove the MMCTX and the
703 * associated LLME.
704 */
705static void test_gmm_detach(void)
706{
707 struct gprs_ra_id raid = { 0, };
708 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200709 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200710
711 printf("Testing GMM detach\n");
712
713 /* DTAP - Detach Request (MO) */
714 /* normal detach, power_off = 0 */
715 static const unsigned char detach_req[] = {
716 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
717 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
718 };
719
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200720 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200721
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100722 /* Create a context */
723 OSMO_ASSERT(count(gprs_llme_list()) == 0);
724 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200725
726 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100727 send_0408_message(ctx->llme, local_tlli,
728 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200729
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100730 /* verify that a single message (hopefully the Detach Accept) has been
731 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100732 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100733
734 /* verify that things are gone */
735 OSMO_ASSERT(count(gprs_llme_list()) == 0);
736 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
737 OSMO_ASSERT(!ictx);
738}
739
740/*
741 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
742 * will not sent a Detach Accept message (power_off = 1)
743 */
744static void test_gmm_detach_power_off(void)
745{
746 struct gprs_ra_id raid = { 0, };
747 struct sgsn_mm_ctx *ctx, *ictx;
748 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100749
750 printf("Testing GMM detach (power off)\n");
751
752 /* DTAP - Detach Request (MO) */
753 /* normal detach, power_off = 1 */
754 static const unsigned char detach_req[] = {
755 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
756 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
757 };
758
759 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
760
761 /* Create a context */
762 OSMO_ASSERT(count(gprs_llme_list()) == 0);
763 ctx = alloc_mm_ctx(local_tlli, &raid);
764
765 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100766 send_0408_message(ctx->llme, local_tlli,
767 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100768
769 /* verify that no message (and therefore no Detach Accept) has been
770 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100771 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100772
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200773 /* verify that things are gone */
774 OSMO_ASSERT(count(gprs_llme_list()) == 0);
775 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200776 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200777}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200778
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200779/*
780 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
781 */
782static void test_gmm_detach_no_mmctx(void)
783{
784 struct gprs_llc_lle *lle;
785 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200786
787 printf("Testing GMM detach (no MMCTX)\n");
788
789 /* DTAP - Detach Request (MO) */
790 /* normal detach, power_off = 0 */
791 static const unsigned char detach_req[] = {
792 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
793 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
794 };
795
796 /* Create an LLME */
797 OSMO_ASSERT(count(gprs_llme_list()) == 0);
798 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
799 lle = gprs_lle_get_or_create(local_tlli, 3);
800
801 OSMO_ASSERT(count(gprs_llme_list()) == 1);
802
803 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100804 send_0408_message(lle->llme, local_tlli,
805 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200806
807 /* verify that the LLME is gone */
808 OSMO_ASSERT(count(gprs_llme_list()) == 0);
809}
810
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100811/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100812 * Test that a single GMM Detach Accept message will not cause the SGSN to send
813 * any message or leave an MM context at the SGSN.
814 */
815static void test_gmm_detach_accept_unexpected(void)
816{
817 struct gprs_llc_lle *lle;
818 uint32_t local_tlli;
819
820 printf("Testing GMM detach accept (unexpected)\n");
821
822 /* DTAP - Detach Accept (MT) */
823 /* normal detach */
824 static const unsigned char detach_acc[] = {
825 0x08, 0x06
826 };
827
828 /* Create an LLME */
829 OSMO_ASSERT(count(gprs_llme_list()) == 0);
830 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
831 lle = gprs_lle_get_or_create(local_tlli, 3);
832
833 /* inject the detach */
834 send_0408_message(lle->llme, local_tlli,
835 detach_acc, ARRAY_SIZE(detach_acc));
836
837 /* verify that no message (and therefore no Status or XID reset) has been
838 * sent by the SGSN */
839 OSMO_ASSERT(sgsn_tx_counter == 0);
840
841 /* verify that things are gone */
842 OSMO_ASSERT(count(gprs_llme_list()) == 0);
843}
844
845/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100846 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
847 */
848static void test_gmm_status_no_mmctx(void)
849{
850 struct gprs_llc_lle *lle;
851 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100852
853 printf("Testing GMM Status (no MMCTX)\n");
854
855 /* DTAP - GMM Status, protocol error */
856 static const unsigned char gmm_status[] = {
857 0x08, 0x20, 0x6f
858 };
859
860 /* Create an LLME */
861 OSMO_ASSERT(count(gprs_llme_list()) == 0);
862 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
863 lle = gprs_lle_get_or_create(local_tlli, 3);
864
865 OSMO_ASSERT(count(gprs_llme_list()) == 1);
866
867 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100868 send_0408_message(lle->llme, local_tlli,
869 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100870
871 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100872 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100873
874 /* verify that the LLME is gone */
875 OSMO_ASSERT(count(gprs_llme_list()) == 0);
876}
877
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100878/*
879 * Test the GMM Attach procedure
880 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100881static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100882{
883 struct gprs_ra_id raid = { 0, };
884 struct sgsn_mm_ctx *ctx = NULL;
885 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100886 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100887 uint32_t foreign_tlli;
888 uint32_t local_tlli = 0;
889 struct gprs_llc_lle *lle;
890
891 /* DTAP - Attach Request */
892 /* The P-TMSI is not known by the SGSN */
893 static const unsigned char attach_req[] = {
894 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
895 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
896 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
897 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
898 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
899 };
900
901 /* DTAP - Identity Response IMEI */
902 static const unsigned char ident_resp_imei[] = {
903 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
904 0x56
905 };
906
907 /* DTAP - Identity Response IMSI */
908 static const unsigned char ident_resp_imsi[] = {
909 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
910 0x54
911 };
912
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100913 /* DTAP - Authentication and Ciphering Resp */
914 static const unsigned char auth_ciph_resp[] = {
915 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
916 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
917 };
918
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100919 /* DTAP - Attach Complete */
920 static const unsigned char attach_compl[] = {
921 0x08, 0x03
922 };
923
924 /* DTAP - Detach Request (MO) */
925 /* normal detach, power_off = 0 */
926 static const unsigned char detach_req[] = {
927 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
928 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
929 };
930
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100931 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100932
933 /* reset the PRNG used by sgsn_alloc_ptmsi */
934 srand(1);
935
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100936 ptmsi1 = sgsn_alloc_ptmsi();
937 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
938
939 /* reset the PRNG, so that the same P-TMSI sequence will be generated
940 * again */
941 srand(1);
942
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100943 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
944
945 /* Create a LLE/LLME */
946 OSMO_ASSERT(count(gprs_llme_list()) == 0);
947 lle = gprs_lle_get_or_create(foreign_tlli, 3);
948 OSMO_ASSERT(count(gprs_llme_list()) == 1);
949
950 /* inject the attach request */
951 send_0408_message(lle->llme, foreign_tlli,
952 attach_req, ARRAY_SIZE(attach_req));
953
954 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
955 OSMO_ASSERT(ctx != NULL);
956 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
957
958 /* we expect an identity request (IMEI) */
959 OSMO_ASSERT(sgsn_tx_counter == 1);
960
961 /* inject the identity response (IMEI) */
962 send_0408_message(ctx->llme, foreign_tlli,
963 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
964
965 /* we expect an identity request (IMSI) */
966 OSMO_ASSERT(sgsn_tx_counter == 1);
967
968 /* inject the identity response (IMSI) */
969 send_0408_message(ctx->llme, foreign_tlli,
970 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
971
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100972 /* check that the MM context has not been removed due to a failed
973 * authorization */
974 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
975
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100976 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100977
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100978retry_attach_req:
979
980 if (retry && sgsn_tx_counter == 0) {
981 fprintf(stderr, "Retrying attach request\n");
982 /* re-inject the attach request */
983 send_0408_message(lle->llme, foreign_tlli,
984 attach_req, ARRAY_SIZE(attach_req));
985 }
986
987 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
988 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100989
990 /* inject the auth & ciph response */
991 send_0408_message(ctx->llme, foreign_tlli,
992 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
993
994 /* check that the MM context has not been removed due to a
995 * failed authorization */
996 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
997 }
998
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100999 if (retry && sgsn_tx_counter == 0)
1000 goto retry_attach_req;
1001
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001002 /* we expect an attach accept/reject */
1003 OSMO_ASSERT(sgsn_tx_counter == 1);
1004
1005 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001006 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001007
1008 /* inject the attach complete */
1009 send_0408_message(ctx->llme, local_tlli,
1010 attach_compl, ARRAY_SIZE(attach_compl));
1011
1012 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1013
1014 /* we don't expect a response */
1015 OSMO_ASSERT(sgsn_tx_counter == 0);
1016
1017 /* inject the detach */
1018 send_0408_message(ctx->llme, local_tlli,
1019 detach_req, ARRAY_SIZE(detach_req));
1020
1021 /* verify that things are gone */
1022 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1023 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1024 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001025}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001026
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001027static void test_gmm_attach_acl(void)
1028{
1029 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1030
1031 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1032 sgsn_acl_add("123456789012345", &sgsn->cfg);
1033 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001034 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001035 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001036
1037 sgsn->cfg.auth_policy = saved_auth_policy;
1038}
1039
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001040int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001041 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001042 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001043 if (rc == -ENOTSUP) {
1044 OSMO_ASSERT(mmctx->subscr);
1045 gprs_subscr_update(mmctx->subscr);
1046 }
1047 return rc;
1048};
1049
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001050int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1051 gprs_subscr_update(mmctx->subscr);
1052 return 0;
1053};
1054
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001055static void cleanup_subscr_by_imsi(const char *imsi)
1056{
1057 struct gsm_subscriber *subscr;
1058
1059 subscr = gprs_subscr_get_by_imsi(imsi);
1060 OSMO_ASSERT(subscr != NULL);
Jacob Erlbecke1beb6f2015-01-08 14:13:46 +01001061 subscr->keep_in_ram = 0;
1062 subscr_put(subscr);
1063 subscr = gprs_subscr_get_by_imsi(imsi);
1064 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001065}
1066
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001067static void test_gmm_attach_subscr(void)
1068{
1069 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1070 struct gsm_subscriber *subscr;
1071
1072 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001073 subscr_request_update_location_cb = my_subscr_request_update_location;
1074 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001075
1076 subscr = gprs_subscr_get_or_create("123456789012345");
1077 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001078 subscr->keep_in_ram = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001079 subscr_put(subscr);
1080
1081 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001082 test_gmm_attach(0);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001083
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001084 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001085 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001086
1087 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001088 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1089 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001090}
1091
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001092int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1093{
1094 /* Fake an authentication */
1095 OSMO_ASSERT(mmctx->subscr);
1096 mmctx->is_authenticated = 1;
1097 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001098
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001099 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001100};
1101
1102static void test_gmm_attach_subscr_fake_auth(void)
1103{
1104 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1105 struct gsm_subscriber *subscr;
1106
1107 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001108 subscr_request_update_location_cb = my_subscr_request_update_location;
1109 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001110
1111 subscr = gprs_subscr_get_or_create("123456789012345");
1112 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001113 subscr->keep_in_ram = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001114 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001115 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001116 subscr_put(subscr);
1117
1118 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001119 test_gmm_attach(0);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001120
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001121 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001122 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001123
1124 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001125 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1126 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1127}
1128
1129int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1130{
1131 struct gsm_auth_tuple at = {
1132 .sres = {0x51, 0xe5, 0x51, 0xe5},
1133 .key_seq = 0
1134 };
1135
1136 /* Fake an authentication */
1137 OSMO_ASSERT(mmctx->subscr);
1138 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1139
1140 gprs_subscr_update_auth_info(mmctx->subscr);
1141
1142 return 0;
1143};
1144
1145static void test_gmm_attach_subscr_real_auth(void)
1146{
1147 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1148 struct gsm_subscriber *subscr;
1149
1150 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1151 subscr_request_update_location_cb = my_subscr_request_update_location;
1152 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1153
1154 subscr = gprs_subscr_get_or_create("123456789012345");
1155 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001156 subscr->keep_in_ram = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001157 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001158 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001159 subscr_put(subscr);
1160
1161 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001162
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001163 test_gmm_attach(0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001164
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001165 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001166 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001167
1168 sgsn->cfg.auth_policy = saved_auth_policy;
1169 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1170 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001171}
1172
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001173#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1174 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1175
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001176static int auth_info_skip = 0;
1177static int upd_loc_skip = 0;
1178
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001179int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1180{
1181 static const uint8_t send_auth_info_res[] = {
1182 0x0a,
1183 TEST_GSUP_IMSI_LONG_IE,
1184 0x03, 0x22, /* Auth tuple */
1185 0x20, 0x10,
1186 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1187 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1188 0x21, 0x04,
1189 0x51, 0xe5, 0x51, 0xe5,
1190 0x22, 0x08,
1191 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1192 };
1193
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001194 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001195
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001196 if (auth_info_skip > 0) {
1197 auth_info_skip -= 1;
1198 return -EAGAIN;
1199 }
1200
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001201 /* Fake an SendAuthInfoRes */
1202 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1203
1204 return 0;
1205};
1206
1207int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1208 static const uint8_t update_location_res[] = {
1209 0x06,
1210 TEST_GSUP_IMSI_LONG_IE,
1211 0x04, 0x00, /* PDP info complete */
1212 0x05, 0x12,
1213 0x10, 0x01, 0x01,
1214 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1215 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1216 };
1217
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001218 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001219
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001220 if (upd_loc_skip > 0) {
1221 upd_loc_skip -= 1;
1222 return -EAGAIN;
1223 }
1224
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001225 /* Fake an UpdateLocRes */
1226 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1227};
1228
1229
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001230static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001231{
1232 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1233 struct gsm_subscriber *subscr;
1234
1235 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1236 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1237 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001238 if (retry) {
1239 upd_loc_skip = 3;
1240 auth_info_skip = 3;
1241 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001242
1243 subscr = gprs_subscr_get_or_create("123456789012345");
1244 subscr->authorized = 1;
1245 sgsn->cfg.require_authentication = 1;
1246 sgsn->cfg.require_update_location = 1;
1247 subscr_put(subscr);
1248
1249 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001250 test_gmm_attach(retry);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001251
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001252 cleanup_subscr_by_imsi("123456789012345");
1253 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001254
1255 sgsn->cfg.auth_policy = saved_auth_policy;
1256 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1257 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001258 upd_loc_skip = 0;
1259 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001260}
1261
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001262int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1263{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001264 struct gprs_gsup_message to_peer = {0};
1265 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001266 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001267 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001268
1269 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001270 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1271 OSMO_ASSERT(rc >= 0);
1272 OSMO_ASSERT(to_peer.imsi[0] != 0);
1273 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001274
1275 /* This invalidates the pointers in to_peer */
1276 msgb_free(msg);
1277
1278 switch (to_peer.message_type) {
1279 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1280 /* Send UPDATE_LOCATION_RESULT */
1281 return my_subscr_request_update_gsup_auth(NULL);
1282
1283 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1284 /* Send SEND_AUTH_INFO_RESULT */
1285 return my_subscr_request_auth_info_gsup_auth(NULL);
1286
1287 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001288 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1289 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001290
1291 default:
1292 if ((to_peer.message_type & 0b00000011) == 0) {
1293 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001294 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001295 from_peer.message_type = to_peer.message_type + 1;
1296 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1297 break;
1298 }
1299
1300 /* Ignore it */
1301 return 0;
1302 }
1303
1304 reply_msg = gprs_gsup_msgb_alloc();
1305 reply_msg->l2h = reply_msg->data;
1306 gprs_gsup_encode(reply_msg, &from_peer);
1307 gprs_subscr_rx_gsup_message(reply_msg);
1308 msgb_free(reply_msg);
1309
1310 return 0;
1311};
1312
1313static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1314{
1315 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1316 struct gsm_subscriber *subscr;
1317
1318 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1319 sgsn_inst.cfg.subscriber_expiry_timeout = 0;
1320 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1321
1322 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1323
1324 if (retry) {
1325 upd_loc_skip = 3;
1326 auth_info_skip = 3;
1327 }
1328
1329 printf("Auth policy 'remote', real GSUP based auth: ");
1330 test_gmm_attach(retry);
1331
1332 subscr = gprs_subscr_get_by_imsi("123456789012345");
1333 OSMO_ASSERT(subscr != NULL);
1334 gprs_subscr_delete(subscr);
1335
1336 osmo_timers_update();
1337
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001338 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001339
1340 sgsn->cfg.auth_policy = saved_auth_policy;
1341 sgsn_inst.cfg.subscriber_expiry_timeout = SGSN_TIMEOUT_NEVER;
1342 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1343 upd_loc_skip = 0;
1344 auth_info_skip = 0;
1345 talloc_free(sgsn->gsup_client);
1346 sgsn->gsup_client = NULL;
1347}
1348
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001349/*
1350 * Test the GMM Rejects
1351 */
1352static void test_gmm_reject(void)
1353{
1354 struct gprs_ra_id raid = { 0, };
1355 struct sgsn_mm_ctx *ctx = NULL;
1356 uint32_t foreign_tlli;
1357 struct gprs_llc_lle *lle;
1358 int idx;
1359
1360 /* DTAP - Attach Request */
1361 /* Invalid MI length */
1362 static const unsigned char attach_req_inv_mi_len[] = {
1363 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1364 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1365 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1366 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1367 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1368 };
1369
1370 /* DTAP - Attach Request */
1371 /* Invalid MI type (IMEI) */
1372 static const unsigned char attach_req_inv_mi_type[] = {
1373 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1374 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1375 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1376 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1377 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1378 };
1379
1380 /* DTAP - Routing Area Update Request */
1381 static const unsigned char dtap_ra_upd_req[] = {
1382 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1383 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1384 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1385 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1386 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1387 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1388 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1389 };
1390
1391 /* DTAP - Routing Area Update Request */
1392 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1393 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1394 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1395 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1396 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1397 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1398 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1399 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1400 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1401 };
1402
1403 /* DTAP - Routing Area Update Request */
1404 /* Invalid cap length */
1405 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1406 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1407 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1408 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1409 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1410 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1411 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1412 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1413 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1414 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1415 };
1416
1417 struct test {
1418 const char *title;
1419 const unsigned char *msg;
1420 unsigned msg_len;
1421 unsigned num_resp;
1422
1423 };
1424 static struct test tests[] = {
1425 {
1426 .title = "Attach Request (invalid MI length)",
1427 .msg = attach_req_inv_mi_len,
1428 .msg_len = sizeof(attach_req_inv_mi_len),
1429 .num_resp = 1 /* Reject */
1430
1431 },
1432 {
1433 .title = "Attach Request (invalid MI type)",
1434 .msg = attach_req_inv_mi_type,
1435 .msg_len = sizeof(attach_req_inv_mi_type),
1436 .num_resp = 1 /* Reject */
1437 },
1438 {
1439 .title = "Routing Area Update Request (valid)",
1440 .msg = dtap_ra_upd_req,
1441 .msg_len = sizeof(dtap_ra_upd_req),
1442 .num_resp = 2 /* XID Reset + Reject */
1443 },
1444 {
1445 .title = "Routing Area Update Request (invalid type)",
1446 .msg = dtap_ra_upd_req_inv_type,
1447 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1448 .num_resp = 1 /* Reject */
1449 },
1450 {
1451 .title = "Routing Area Update Request (invalid CAP length)",
1452 .msg = dtap_ra_upd_req_inv_cap_len,
1453 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1454 .num_resp = 1 /* Reject */
1455 },
1456 };
1457
1458 printf("Testing GMM reject\n");
1459
1460 /* reset the PRNG used by sgsn_alloc_ptmsi */
1461 srand(1);
1462
1463 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1464
1465 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1466
1467 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1468 const struct test *test = &tests[idx];
1469 printf(" - %s\n", test->title);
1470
1471 /* Create a LLE/LLME */
1472 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1473 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1474
1475 /* Inject the Request message */
1476 send_0408_message(lle->llme, foreign_tlli,
1477 test->msg, test->msg_len);
1478
1479 /* We expect a Reject message */
1480 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1481 sgsn_tx_counter, test->num_resp);
1482 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1483
1484 /* verify that LLME/MM are removed */
1485 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1486 OSMO_ASSERT(ctx == NULL);
1487 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1488 }
1489}
1490
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001491/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001492 * Test cancellation of attached MM contexts
1493 */
1494static void test_gmm_cancel(void)
1495{
1496 struct gprs_ra_id raid = { 0, };
1497 struct sgsn_mm_ctx *ctx = NULL;
1498 struct sgsn_mm_ctx *ictx;
1499 uint32_t ptmsi1;
1500 uint32_t foreign_tlli;
1501 uint32_t local_tlli = 0;
1502 struct gprs_llc_lle *lle;
1503 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1504
1505 /* DTAP - Attach Request */
1506 /* The P-TMSI is not known by the SGSN */
1507 static const unsigned char attach_req[] = {
1508 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1509 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1510 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1511 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1512 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1513 };
1514
1515 /* DTAP - Identity Response IMEI */
1516 static const unsigned char ident_resp_imei[] = {
1517 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1518 0x56
1519 };
1520
1521 /* DTAP - Identity Response IMSI */
1522 static const unsigned char ident_resp_imsi[] = {
1523 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1524 0x54
1525 };
1526
1527 /* DTAP - Attach Complete */
1528 static const unsigned char attach_compl[] = {
1529 0x08, 0x03
1530 };
1531
1532 printf("Testing cancellation\n");
1533
1534 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1535
1536 /* reset the PRNG used by sgsn_alloc_ptmsi */
1537 srand(1);
1538
1539 ptmsi1 = sgsn_alloc_ptmsi();
1540 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1541
1542 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1543 * again */
1544 srand(1);
1545
1546 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1547
1548 /* Create a LLE/LLME */
1549 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1550 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1551 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1552
1553 /* inject the attach request */
1554 send_0408_message(lle->llme, foreign_tlli,
1555 attach_req, ARRAY_SIZE(attach_req));
1556
1557 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1558 OSMO_ASSERT(ctx != NULL);
1559 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1560
1561 /* we expect an identity request (IMEI) */
1562 OSMO_ASSERT(sgsn_tx_counter == 1);
1563
1564 /* inject the identity response (IMEI) */
1565 send_0408_message(ctx->llme, foreign_tlli,
1566 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1567
1568 /* we expect an identity request (IMSI) */
1569 OSMO_ASSERT(sgsn_tx_counter == 1);
1570
1571 /* inject the identity response (IMSI) */
1572 send_0408_message(ctx->llme, foreign_tlli,
1573 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1574
1575 /* check that the MM context has not been removed due to a failed
1576 * authorization */
1577 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1578
1579 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1580
1581 /* we expect an attach accept/reject */
1582 OSMO_ASSERT(sgsn_tx_counter == 1);
1583
1584 /* this has been randomly assigned by the SGSN */
1585 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1586
1587 /* inject the attach complete */
1588 send_0408_message(ctx->llme, local_tlli,
1589 attach_compl, ARRAY_SIZE(attach_compl));
1590
1591 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1592
1593 /* we don't expect a response */
1594 OSMO_ASSERT(sgsn_tx_counter == 0);
1595
1596 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001597 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001598
1599 /* verify that things are gone */
1600 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1601 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1602 OSMO_ASSERT(!ictx);
1603
1604 sgsn->cfg.auth_policy = saved_auth_policy;
1605}
1606
1607/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001608 * Test the dynamic allocation of P-TMSIs
1609 */
1610static void test_gmm_ptmsi_allocation(void)
1611{
1612 struct gprs_ra_id raid = { 0, };
1613 struct sgsn_mm_ctx *ctx = NULL;
1614 struct sgsn_mm_ctx *ictx;
1615 uint32_t foreign_tlli;
1616 uint32_t ptmsi1;
1617 uint32_t ptmsi2;
1618 uint32_t old_ptmsi;
1619 uint32_t local_tlli = 0;
1620 struct gprs_llc_lle *lle;
1621 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1622
1623 /* DTAP - Attach Request (IMSI 12131415161718) */
1624 static const unsigned char attach_req[] = {
1625 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1626 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1627 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1628 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1629 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1630 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1631 0x00,
1632 };
1633
1634 /* DTAP - Identity Response IMEI */
1635 static const unsigned char ident_resp_imei[] = {
1636 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1637 0x56
1638 };
1639
1640 /* DTAP - Attach Complete */
1641 static const unsigned char attach_compl[] = {
1642 0x08, 0x03
1643 };
1644
1645 /* DTAP - Routing Area Update Request */
1646 static const unsigned char ra_upd_req[] = {
1647 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1648 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1649 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1650 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1651 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1652 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1653 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1654 };
1655
1656 /* DTAP - Routing Area Update Complete */
1657 static const unsigned char ra_upd_complete[] = {
1658 0x08, 0x0a
1659 };
1660
1661 /* DTAP - Detach Request (MO) */
1662 /* normal detach, power_off = 1 */
1663 static const unsigned char detach_req[] = {
1664 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1665 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1666 };
1667
1668 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1669
1670 printf("Testing P-TMSI allocation\n");
1671
1672 printf(" - sgsn_alloc_ptmsi\n");
1673
1674 /* reset the PRNG used by sgsn_alloc_ptmsi */
1675 srand(1);
1676
1677 ptmsi1 = sgsn_alloc_ptmsi();
1678 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1679
1680 ptmsi2 = sgsn_alloc_ptmsi();
1681 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1682
1683 OSMO_ASSERT(ptmsi1 != ptmsi2);
1684
1685 printf(" - Repeated Attach Request\n");
1686
1687 /* reset the PRNG, so that the same P-TMSI will be generated
1688 * again */
1689 srand(1);
1690
1691 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1692
1693 /* Create a LLE/LLME */
1694 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1695 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1696 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1697
1698 /* inject the attach request */
1699 send_0408_message(lle->llme, foreign_tlli,
1700 attach_req, ARRAY_SIZE(attach_req));
1701
1702 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1703 OSMO_ASSERT(ctx != NULL);
1704 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1705 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1706
1707 old_ptmsi = ctx->p_tmsi_old;
1708
1709 /* we expect an identity request (IMEI) */
1710 OSMO_ASSERT(sgsn_tx_counter == 1);
1711
1712 /* inject the identity response (IMEI) */
1713 send_0408_message(ctx->llme, foreign_tlli,
1714 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1715
1716 /* check that the MM context has not been removed due to a failed
1717 * authorization */
1718 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1719
1720 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1721 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1722
1723 /* we expect an attach accept */
1724 OSMO_ASSERT(sgsn_tx_counter == 1);
1725
1726 /* we ignore this and send the attach again */
1727 send_0408_message(lle->llme, foreign_tlli,
1728 attach_req, ARRAY_SIZE(attach_req));
1729
1730 /* the allocated P-TMSI should be the same */
1731 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1732 OSMO_ASSERT(ctx != NULL);
1733 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1734 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1735 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1736
1737 /* inject the attach complete */
1738 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1739 send_0408_message(ctx->llme, local_tlli,
1740 attach_compl, ARRAY_SIZE(attach_compl));
1741
1742 /* we don't expect a response */
1743 OSMO_ASSERT(sgsn_tx_counter == 0);
1744
1745 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1746 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1747 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1748
1749 printf(" - Repeated RA Update Request\n");
1750
1751 /* inject the RA update request */
1752 send_0408_message(ctx->llme, local_tlli,
1753 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1754
1755 /* we expect an RA update accept */
1756 OSMO_ASSERT(sgsn_tx_counter == 1);
1757
1758 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1759 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1760 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1761
1762 /* repeat the RA update request */
1763 send_0408_message(ctx->llme, local_tlli,
1764 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1765
1766 /* we expect an RA update accept */
1767 OSMO_ASSERT(sgsn_tx_counter == 1);
1768
1769 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1770 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1771 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1772
1773 /* inject the RA update complete */
1774 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1775 send_0408_message(ctx->llme, local_tlli,
1776 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1777
1778 /* we don't expect a response */
1779 OSMO_ASSERT(sgsn_tx_counter == 0);
1780
1781 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1782 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1783 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1784
1785 /* inject the detach */
1786 send_0408_message(ctx->llme, local_tlli,
1787 detach_req, ARRAY_SIZE(detach_req));
1788
1789 /* verify that things are gone */
1790 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1791 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1792 OSMO_ASSERT(!ictx);
1793
1794 sgsn->cfg.auth_policy = saved_auth_policy;
1795}
1796
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001797static struct log_info_cat gprs_categories[] = {
1798 [DMM] = {
1799 .name = "DMM",
1800 .description = "Layer3 Mobility Management (MM)",
1801 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001802 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001803 },
1804 [DPAG] = {
1805 .name = "DPAG",
1806 .description = "Paging Subsystem",
1807 .color = "\033[1;38m",
1808 .enabled = 1, .loglevel = LOGL_NOTICE,
1809 },
1810 [DMEAS] = {
1811 .name = "DMEAS",
1812 .description = "Radio Measurement Processing",
1813 .enabled = 0, .loglevel = LOGL_NOTICE,
1814 },
1815 [DREF] = {
1816 .name = "DREF",
1817 .description = "Reference Counting",
1818 .enabled = 0, .loglevel = LOGL_NOTICE,
1819 },
1820 [DGPRS] = {
1821 .name = "DGPRS",
1822 .description = "GPRS Packet Service",
1823 .enabled = 1, .loglevel = LOGL_DEBUG,
1824 },
1825 [DNS] = {
1826 .name = "DNS",
1827 .description = "GPRS Network Service (NS)",
1828 .enabled = 1, .loglevel = LOGL_INFO,
1829 },
1830 [DBSSGP] = {
1831 .name = "DBSSGP",
1832 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1833 .enabled = 1, .loglevel = LOGL_DEBUG,
1834 },
1835 [DLLC] = {
1836 .name = "DLLC",
1837 .description = "GPRS Logical Link Control Protocol (LLC)",
1838 .enabled = 1, .loglevel = LOGL_DEBUG,
1839 },
1840 [DSNDCP] = {
1841 .name = "DSNDCP",
1842 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1843 .enabled = 1, .loglevel = LOGL_DEBUG,
1844 },
1845};
1846
1847static struct log_info info = {
1848 .cat = gprs_categories,
1849 .num_cat = ARRAY_SIZE(gprs_categories),
1850};
1851
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001852int main(int argc, char **argv)
1853{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001854 osmo_init_logging(&info);
1855 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1856 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1857
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001858 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001859 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001860
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001861 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001862 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001863 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001864 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001865 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001866 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001867 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001868 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001869 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001870 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001871 test_gmm_attach_acl();
1872 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001873 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001874 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001875 test_gmm_attach_subscr_gsup_auth(0);
1876 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001877 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001878 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001879 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001880 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001881 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001882
1883 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001884 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001885 return 0;
1886}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001887
1888
1889/* stubs */
1890struct osmo_prim_hdr;
1891int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1892{
1893 abort();
1894}