blob: 7050a16eca236b6d79ea385cec08a688f1068861 [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 Erlbeck9999fd92015-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 Erlbecka6ddc2d2014-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 Erlbecke21e1842014-12-19 18:19:50 +0100510 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-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 Erlbecke21e1842014-12-19 18:19:50 +0100520 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100521 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-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 Erlbecke21e1842014-12-19 18:19:50 +0100530 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-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 Erlbecke21e1842014-12-19 18:19:50 +0100538 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100539 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100540 OSMO_ASSERT(last_updated_subscr == s1);
541
542 /* Check authorization */
543 OSMO_ASSERT(s1->authorized == 0);
544
Jacob Erlbeck9999fd92015-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 Erlbecke21e1842014-12-19 18:19:50 +0100558 rc = rx_gsup_message(location_cancellation_req,
559 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-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 Erlbeck9999fd92015-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));
576 /* TODO: Remove the comments when this is fixed */
577 /* OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN); */
578 OSMO_ASSERT(last_updated_subscr == NULL);
579
580 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
581 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
582 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
583 OSMO_ASSERT(last_updated_subscr == NULL);
584
585 /* Inject LocCancelReq GSUP message (unknown IMSI) */
586 rc = rx_gsup_message(location_cancellation_req,
587 sizeof(location_cancellation_req));
588 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
589 OSMO_ASSERT(last_updated_subscr == NULL);
590
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100591 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
592}
593
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100594int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
595{
596 msgb_free(msg);
597 return 0;
598};
599
600
601static void test_subscriber_blocking(void)
602{
603 struct gsm_subscriber *s1;
604 const char *imsi1 = "1234567890";
605 struct sgsn_mm_ctx *ctx;
606 struct gprs_ra_id raid = { 0, };
607 uint32_t local_tlli = 0xffeeddcc;
608 struct gprs_llc_llme *llme;
609 int rc;
610
611 printf("Testing subcriber procedure blocking\n");
612
613 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
614 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
615
616 /* Check for emptiness */
617 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
618
619 /* Create a context */
620 OSMO_ASSERT(count(gprs_llme_list()) == 0);
621 ctx = alloc_mm_ctx(local_tlli, &raid);
622 llme = ctx->llme;
623 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
624
625 /* Allocate and attach a subscriber */
626 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
627 assert_subscr(s1, imsi1);
628
629 /* Start SendAuthInfoRequest procedure */
630 rc = gprs_subscr_query_auth_info(s1);
631 /* Not blocking */
632 OSMO_ASSERT(rc == 0);
633
634 /* Start UpdateLocation procedure */
635 rc = gprs_subscr_location_update(s1);
636 /* Blocking */
637 OSMO_ASSERT(rc == 0);
638
639 /* Start PurgeMS procedure */
640 rc = gprs_subscr_purge(s1);
641 /* Not blocking */
642 OSMO_ASSERT(rc == 0);
643 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
644
645 /* Start PurgeMS procedure (retry) */
646 rc = gprs_subscr_purge(s1);
647 /* Not blocking */
648 OSMO_ASSERT(rc == 0);
649
650 /* Start SendAuthInfoRequest procedure */
651 rc = gprs_subscr_query_auth_info(s1);
652 /* Blocking */
653 OSMO_ASSERT(rc == -EAGAIN);
654
655 /* Start UpdateLocation procedure */
656 rc = gprs_subscr_location_update(s1);
657 /* Blocking */
658 OSMO_ASSERT(rc == -EAGAIN);
659
660 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
661 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
662
663 /* Start SendAuthInfoRequest procedure */
664 rc = gprs_subscr_query_auth_info(s1);
665 /* Not blocking */
666 OSMO_ASSERT(rc == 0);
667
668 /* Start UpdateLocation procedure */
669 rc = gprs_subscr_location_update(s1);
670 /* Blocking */
671 OSMO_ASSERT(rc == 0);
672
673 subscr_put(s1);
674 sgsn_mm_ctx_free(ctx);
675 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
676
677 assert_no_subscrs();
678
679 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
680 talloc_free(sgsn->gsup_client);
681 sgsn->gsup_client = NULL;
682}
683
684
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200685/*
686 * Test that a GMM Detach will remove the MMCTX and the
687 * associated LLME.
688 */
689static void test_gmm_detach(void)
690{
691 struct gprs_ra_id raid = { 0, };
692 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200693 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200694
695 printf("Testing GMM detach\n");
696
697 /* DTAP - Detach Request (MO) */
698 /* normal detach, power_off = 0 */
699 static const unsigned char detach_req[] = {
700 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
701 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
702 };
703
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200704 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200705
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100706 /* Create a context */
707 OSMO_ASSERT(count(gprs_llme_list()) == 0);
708 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200709
710 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100711 send_0408_message(ctx->llme, local_tlli,
712 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200713
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100714 /* verify that a single message (hopefully the Detach Accept) has been
715 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100716 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100717
718 /* verify that things are gone */
719 OSMO_ASSERT(count(gprs_llme_list()) == 0);
720 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
721 OSMO_ASSERT(!ictx);
722}
723
724/*
725 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
726 * will not sent a Detach Accept message (power_off = 1)
727 */
728static void test_gmm_detach_power_off(void)
729{
730 struct gprs_ra_id raid = { 0, };
731 struct sgsn_mm_ctx *ctx, *ictx;
732 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100733
734 printf("Testing GMM detach (power off)\n");
735
736 /* DTAP - Detach Request (MO) */
737 /* normal detach, power_off = 1 */
738 static const unsigned char detach_req[] = {
739 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
740 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
741 };
742
743 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
744
745 /* Create a context */
746 OSMO_ASSERT(count(gprs_llme_list()) == 0);
747 ctx = alloc_mm_ctx(local_tlli, &raid);
748
749 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100750 send_0408_message(ctx->llme, local_tlli,
751 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100752
753 /* verify that no message (and therefore no Detach Accept) has been
754 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100755 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100756
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200757 /* verify that things are gone */
758 OSMO_ASSERT(count(gprs_llme_list()) == 0);
759 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200760 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200761}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200762
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200763/*
764 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
765 */
766static void test_gmm_detach_no_mmctx(void)
767{
768 struct gprs_llc_lle *lle;
769 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200770
771 printf("Testing GMM detach (no MMCTX)\n");
772
773 /* DTAP - Detach Request (MO) */
774 /* normal detach, power_off = 0 */
775 static const unsigned char detach_req[] = {
776 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
777 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
778 };
779
780 /* Create an LLME */
781 OSMO_ASSERT(count(gprs_llme_list()) == 0);
782 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
783 lle = gprs_lle_get_or_create(local_tlli, 3);
784
785 OSMO_ASSERT(count(gprs_llme_list()) == 1);
786
787 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100788 send_0408_message(lle->llme, local_tlli,
789 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200790
791 /* verify that the LLME is gone */
792 OSMO_ASSERT(count(gprs_llme_list()) == 0);
793}
794
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100795/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100796 * Test that a single GMM Detach Accept message will not cause the SGSN to send
797 * any message or leave an MM context at the SGSN.
798 */
799static void test_gmm_detach_accept_unexpected(void)
800{
801 struct gprs_llc_lle *lle;
802 uint32_t local_tlli;
803
804 printf("Testing GMM detach accept (unexpected)\n");
805
806 /* DTAP - Detach Accept (MT) */
807 /* normal detach */
808 static const unsigned char detach_acc[] = {
809 0x08, 0x06
810 };
811
812 /* Create an LLME */
813 OSMO_ASSERT(count(gprs_llme_list()) == 0);
814 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
815 lle = gprs_lle_get_or_create(local_tlli, 3);
816
817 /* inject the detach */
818 send_0408_message(lle->llme, local_tlli,
819 detach_acc, ARRAY_SIZE(detach_acc));
820
821 /* verify that no message (and therefore no Status or XID reset) has been
822 * sent by the SGSN */
823 OSMO_ASSERT(sgsn_tx_counter == 0);
824
825 /* verify that things are gone */
826 OSMO_ASSERT(count(gprs_llme_list()) == 0);
827}
828
829/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100830 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
831 */
832static void test_gmm_status_no_mmctx(void)
833{
834 struct gprs_llc_lle *lle;
835 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100836
837 printf("Testing GMM Status (no MMCTX)\n");
838
839 /* DTAP - GMM Status, protocol error */
840 static const unsigned char gmm_status[] = {
841 0x08, 0x20, 0x6f
842 };
843
844 /* Create an LLME */
845 OSMO_ASSERT(count(gprs_llme_list()) == 0);
846 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
847 lle = gprs_lle_get_or_create(local_tlli, 3);
848
849 OSMO_ASSERT(count(gprs_llme_list()) == 1);
850
851 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100852 send_0408_message(lle->llme, local_tlli,
853 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100854
855 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100856 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100857
858 /* verify that the LLME is gone */
859 OSMO_ASSERT(count(gprs_llme_list()) == 0);
860}
861
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100862/*
863 * Test the GMM Attach procedure
864 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100865static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100866{
867 struct gprs_ra_id raid = { 0, };
868 struct sgsn_mm_ctx *ctx = NULL;
869 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100870 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100871 uint32_t foreign_tlli;
872 uint32_t local_tlli = 0;
873 struct gprs_llc_lle *lle;
874
875 /* DTAP - Attach Request */
876 /* The P-TMSI is not known by the SGSN */
877 static const unsigned char attach_req[] = {
878 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
879 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
880 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
881 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
882 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
883 };
884
885 /* DTAP - Identity Response IMEI */
886 static const unsigned char ident_resp_imei[] = {
887 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
888 0x56
889 };
890
891 /* DTAP - Identity Response IMSI */
892 static const unsigned char ident_resp_imsi[] = {
893 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
894 0x54
895 };
896
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100897 /* DTAP - Authentication and Ciphering Resp */
898 static const unsigned char auth_ciph_resp[] = {
899 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
900 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
901 };
902
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100903 /* DTAP - Attach Complete */
904 static const unsigned char attach_compl[] = {
905 0x08, 0x03
906 };
907
908 /* DTAP - Detach Request (MO) */
909 /* normal detach, power_off = 0 */
910 static const unsigned char detach_req[] = {
911 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
912 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
913 };
914
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100915 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100916
917 /* reset the PRNG used by sgsn_alloc_ptmsi */
918 srand(1);
919
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100920 ptmsi1 = sgsn_alloc_ptmsi();
921 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
922
923 /* reset the PRNG, so that the same P-TMSI sequence will be generated
924 * again */
925 srand(1);
926
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100927 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
928
929 /* Create a LLE/LLME */
930 OSMO_ASSERT(count(gprs_llme_list()) == 0);
931 lle = gprs_lle_get_or_create(foreign_tlli, 3);
932 OSMO_ASSERT(count(gprs_llme_list()) == 1);
933
934 /* inject the attach request */
935 send_0408_message(lle->llme, foreign_tlli,
936 attach_req, ARRAY_SIZE(attach_req));
937
938 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
939 OSMO_ASSERT(ctx != NULL);
940 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
941
942 /* we expect an identity request (IMEI) */
943 OSMO_ASSERT(sgsn_tx_counter == 1);
944
945 /* inject the identity response (IMEI) */
946 send_0408_message(ctx->llme, foreign_tlli,
947 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
948
949 /* we expect an identity request (IMSI) */
950 OSMO_ASSERT(sgsn_tx_counter == 1);
951
952 /* inject the identity response (IMSI) */
953 send_0408_message(ctx->llme, foreign_tlli,
954 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
955
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100956 /* check that the MM context has not been removed due to a failed
957 * authorization */
958 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
959
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100960 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100961
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100962retry_attach_req:
963
964 if (retry && sgsn_tx_counter == 0) {
965 fprintf(stderr, "Retrying attach request\n");
966 /* re-inject the attach request */
967 send_0408_message(lle->llme, foreign_tlli,
968 attach_req, ARRAY_SIZE(attach_req));
969 }
970
971 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
972 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100973
974 /* inject the auth & ciph response */
975 send_0408_message(ctx->llme, foreign_tlli,
976 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
977
978 /* check that the MM context has not been removed due to a
979 * failed authorization */
980 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
981 }
982
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100983 if (retry && sgsn_tx_counter == 0)
984 goto retry_attach_req;
985
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100986 /* we expect an attach accept/reject */
987 OSMO_ASSERT(sgsn_tx_counter == 1);
988
989 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100990 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100991
992 /* inject the attach complete */
993 send_0408_message(ctx->llme, local_tlli,
994 attach_compl, ARRAY_SIZE(attach_compl));
995
996 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
997
998 /* we don't expect a response */
999 OSMO_ASSERT(sgsn_tx_counter == 0);
1000
1001 /* inject the detach */
1002 send_0408_message(ctx->llme, local_tlli,
1003 detach_req, ARRAY_SIZE(detach_req));
1004
1005 /* verify that things are gone */
1006 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1007 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1008 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001009}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001010
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001011static void test_gmm_attach_acl(void)
1012{
1013 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1014
1015 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1016 sgsn_acl_add("123456789012345", &sgsn->cfg);
1017 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001018 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001019 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001020
1021 sgsn->cfg.auth_policy = saved_auth_policy;
1022}
1023
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001024int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001025 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001026 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001027 if (rc == -ENOTSUP) {
1028 OSMO_ASSERT(mmctx->subscr);
1029 gprs_subscr_update(mmctx->subscr);
1030 }
1031 return rc;
1032};
1033
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001034int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1035 gprs_subscr_update(mmctx->subscr);
1036 return 0;
1037};
1038
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001039static void cleanup_subscr_by_imsi(const char *imsi)
1040{
1041 struct gsm_subscriber *subscr;
1042
1043 subscr = gprs_subscr_get_by_imsi(imsi);
1044 OSMO_ASSERT(subscr != NULL);
Jacob Erlbecke1beb6f2015-01-08 14:13:46 +01001045 subscr->keep_in_ram = 0;
1046 subscr_put(subscr);
1047 subscr = gprs_subscr_get_by_imsi(imsi);
1048 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001049}
1050
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001051static void test_gmm_attach_subscr(void)
1052{
1053 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1054 struct gsm_subscriber *subscr;
1055
1056 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001057 subscr_request_update_location_cb = my_subscr_request_update_location;
1058 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001059
1060 subscr = gprs_subscr_get_or_create("123456789012345");
1061 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001062 subscr->keep_in_ram = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001063 subscr_put(subscr);
1064
1065 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001066 test_gmm_attach(0);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001067
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001068 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001069 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001070
1071 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001072 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1073 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001074}
1075
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001076int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1077{
1078 /* Fake an authentication */
1079 OSMO_ASSERT(mmctx->subscr);
1080 mmctx->is_authenticated = 1;
1081 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001082
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001083 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001084};
1085
1086static void test_gmm_attach_subscr_fake_auth(void)
1087{
1088 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1089 struct gsm_subscriber *subscr;
1090
1091 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001092 subscr_request_update_location_cb = my_subscr_request_update_location;
1093 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001094
1095 subscr = gprs_subscr_get_or_create("123456789012345");
1096 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001097 subscr->keep_in_ram = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001098 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001099 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001100 subscr_put(subscr);
1101
1102 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001103 test_gmm_attach(0);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001104
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001105 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001106 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001107
1108 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001109 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1110 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1111}
1112
1113int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1114{
1115 struct gsm_auth_tuple at = {
1116 .sres = {0x51, 0xe5, 0x51, 0xe5},
1117 .key_seq = 0
1118 };
1119
1120 /* Fake an authentication */
1121 OSMO_ASSERT(mmctx->subscr);
1122 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1123
1124 gprs_subscr_update_auth_info(mmctx->subscr);
1125
1126 return 0;
1127};
1128
1129static void test_gmm_attach_subscr_real_auth(void)
1130{
1131 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1132 struct gsm_subscriber *subscr;
1133
1134 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1135 subscr_request_update_location_cb = my_subscr_request_update_location;
1136 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1137
1138 subscr = gprs_subscr_get_or_create("123456789012345");
1139 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001140 subscr->keep_in_ram = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001141 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001142 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001143 subscr_put(subscr);
1144
1145 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001146
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001147 test_gmm_attach(0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001148
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001149 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001150 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001151
1152 sgsn->cfg.auth_policy = saved_auth_policy;
1153 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1154 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001155}
1156
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001157#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1158 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1159
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001160static int auth_info_skip = 0;
1161static int upd_loc_skip = 0;
1162
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001163int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1164{
1165 static const uint8_t send_auth_info_res[] = {
1166 0x0a,
1167 TEST_GSUP_IMSI_LONG_IE,
1168 0x03, 0x22, /* Auth tuple */
1169 0x20, 0x10,
1170 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1171 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1172 0x21, 0x04,
1173 0x51, 0xe5, 0x51, 0xe5,
1174 0x22, 0x08,
1175 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1176 };
1177
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001178 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001179
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001180 if (auth_info_skip > 0) {
1181 auth_info_skip -= 1;
1182 return -EAGAIN;
1183 }
1184
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001185 /* Fake an SendAuthInfoRes */
1186 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1187
1188 return 0;
1189};
1190
1191int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1192 static const uint8_t update_location_res[] = {
1193 0x06,
1194 TEST_GSUP_IMSI_LONG_IE,
1195 0x04, 0x00, /* PDP info complete */
1196 0x05, 0x12,
1197 0x10, 0x01, 0x01,
1198 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1199 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1200 };
1201
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001202 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001203
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001204 if (upd_loc_skip > 0) {
1205 upd_loc_skip -= 1;
1206 return -EAGAIN;
1207 }
1208
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001209 /* Fake an UpdateLocRes */
1210 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1211};
1212
1213
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001214static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001215{
1216 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1217 struct gsm_subscriber *subscr;
1218
1219 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1220 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1221 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001222 if (retry) {
1223 upd_loc_skip = 3;
1224 auth_info_skip = 3;
1225 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001226
1227 subscr = gprs_subscr_get_or_create("123456789012345");
1228 subscr->authorized = 1;
1229 sgsn->cfg.require_authentication = 1;
1230 sgsn->cfg.require_update_location = 1;
1231 subscr_put(subscr);
1232
1233 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001234 test_gmm_attach(retry);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001235
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001236 cleanup_subscr_by_imsi("123456789012345");
1237 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001238
1239 sgsn->cfg.auth_policy = saved_auth_policy;
1240 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1241 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001242 upd_loc_skip = 0;
1243 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001244}
1245
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001246int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1247{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001248 struct gprs_gsup_message to_peer = {0};
1249 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001250 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001251 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001252
1253 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001254 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1255 OSMO_ASSERT(rc >= 0);
1256 OSMO_ASSERT(to_peer.imsi[0] != 0);
1257 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001258
1259 /* This invalidates the pointers in to_peer */
1260 msgb_free(msg);
1261
1262 switch (to_peer.message_type) {
1263 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1264 /* Send UPDATE_LOCATION_RESULT */
1265 return my_subscr_request_update_gsup_auth(NULL);
1266
1267 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1268 /* Send SEND_AUTH_INFO_RESULT */
1269 return my_subscr_request_auth_info_gsup_auth(NULL);
1270
1271 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001272 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1273 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001274
1275 default:
1276 if ((to_peer.message_type & 0b00000011) == 0) {
1277 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001278 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001279 from_peer.message_type = to_peer.message_type + 1;
1280 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1281 break;
1282 }
1283
1284 /* Ignore it */
1285 return 0;
1286 }
1287
1288 reply_msg = gprs_gsup_msgb_alloc();
1289 reply_msg->l2h = reply_msg->data;
1290 gprs_gsup_encode(reply_msg, &from_peer);
1291 gprs_subscr_rx_gsup_message(reply_msg);
1292 msgb_free(reply_msg);
1293
1294 return 0;
1295};
1296
1297static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1298{
1299 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1300 struct gsm_subscriber *subscr;
1301
1302 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1303 sgsn_inst.cfg.subscriber_expiry_timeout = 0;
1304 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1305
1306 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1307
1308 if (retry) {
1309 upd_loc_skip = 3;
1310 auth_info_skip = 3;
1311 }
1312
1313 printf("Auth policy 'remote', real GSUP based auth: ");
1314 test_gmm_attach(retry);
1315
1316 subscr = gprs_subscr_get_by_imsi("123456789012345");
1317 OSMO_ASSERT(subscr != NULL);
1318 gprs_subscr_delete(subscr);
1319
1320 osmo_timers_update();
1321
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001322 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001323
1324 sgsn->cfg.auth_policy = saved_auth_policy;
1325 sgsn_inst.cfg.subscriber_expiry_timeout = SGSN_TIMEOUT_NEVER;
1326 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1327 upd_loc_skip = 0;
1328 auth_info_skip = 0;
1329 talloc_free(sgsn->gsup_client);
1330 sgsn->gsup_client = NULL;
1331}
1332
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001333/*
1334 * Test the GMM Rejects
1335 */
1336static void test_gmm_reject(void)
1337{
1338 struct gprs_ra_id raid = { 0, };
1339 struct sgsn_mm_ctx *ctx = NULL;
1340 uint32_t foreign_tlli;
1341 struct gprs_llc_lle *lle;
1342 int idx;
1343
1344 /* DTAP - Attach Request */
1345 /* Invalid MI length */
1346 static const unsigned char attach_req_inv_mi_len[] = {
1347 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1348 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1349 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1350 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1351 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1352 };
1353
1354 /* DTAP - Attach Request */
1355 /* Invalid MI type (IMEI) */
1356 static const unsigned char attach_req_inv_mi_type[] = {
1357 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1358 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1359 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1360 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1361 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1362 };
1363
1364 /* DTAP - Routing Area Update Request */
1365 static const unsigned char dtap_ra_upd_req[] = {
1366 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1367 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1368 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1369 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1370 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1371 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1372 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1373 };
1374
1375 /* DTAP - Routing Area Update Request */
1376 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1377 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1378 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1379 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1380 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1381 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1382 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1383 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1384 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1385 };
1386
1387 /* DTAP - Routing Area Update Request */
1388 /* Invalid cap length */
1389 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1390 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1391 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1392 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1393 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1394 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1395 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1396 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1397 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1398 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1399 };
1400
1401 struct test {
1402 const char *title;
1403 const unsigned char *msg;
1404 unsigned msg_len;
1405 unsigned num_resp;
1406
1407 };
1408 static struct test tests[] = {
1409 {
1410 .title = "Attach Request (invalid MI length)",
1411 .msg = attach_req_inv_mi_len,
1412 .msg_len = sizeof(attach_req_inv_mi_len),
1413 .num_resp = 1 /* Reject */
1414
1415 },
1416 {
1417 .title = "Attach Request (invalid MI type)",
1418 .msg = attach_req_inv_mi_type,
1419 .msg_len = sizeof(attach_req_inv_mi_type),
1420 .num_resp = 1 /* Reject */
1421 },
1422 {
1423 .title = "Routing Area Update Request (valid)",
1424 .msg = dtap_ra_upd_req,
1425 .msg_len = sizeof(dtap_ra_upd_req),
1426 .num_resp = 2 /* XID Reset + Reject */
1427 },
1428 {
1429 .title = "Routing Area Update Request (invalid type)",
1430 .msg = dtap_ra_upd_req_inv_type,
1431 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1432 .num_resp = 1 /* Reject */
1433 },
1434 {
1435 .title = "Routing Area Update Request (invalid CAP length)",
1436 .msg = dtap_ra_upd_req_inv_cap_len,
1437 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1438 .num_resp = 1 /* Reject */
1439 },
1440 };
1441
1442 printf("Testing GMM reject\n");
1443
1444 /* reset the PRNG used by sgsn_alloc_ptmsi */
1445 srand(1);
1446
1447 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1448
1449 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1450
1451 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1452 const struct test *test = &tests[idx];
1453 printf(" - %s\n", test->title);
1454
1455 /* Create a LLE/LLME */
1456 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1457 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1458
1459 /* Inject the Request message */
1460 send_0408_message(lle->llme, foreign_tlli,
1461 test->msg, test->msg_len);
1462
1463 /* We expect a Reject message */
1464 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1465 sgsn_tx_counter, test->num_resp);
1466 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1467
1468 /* verify that LLME/MM are removed */
1469 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1470 OSMO_ASSERT(ctx == NULL);
1471 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1472 }
1473}
1474
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001475/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001476 * Test cancellation of attached MM contexts
1477 */
1478static void test_gmm_cancel(void)
1479{
1480 struct gprs_ra_id raid = { 0, };
1481 struct sgsn_mm_ctx *ctx = NULL;
1482 struct sgsn_mm_ctx *ictx;
1483 uint32_t ptmsi1;
1484 uint32_t foreign_tlli;
1485 uint32_t local_tlli = 0;
1486 struct gprs_llc_lle *lle;
1487 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1488
1489 /* DTAP - Attach Request */
1490 /* The P-TMSI is not known by the SGSN */
1491 static const unsigned char attach_req[] = {
1492 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1493 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1494 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1495 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1496 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1497 };
1498
1499 /* DTAP - Identity Response IMEI */
1500 static const unsigned char ident_resp_imei[] = {
1501 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1502 0x56
1503 };
1504
1505 /* DTAP - Identity Response IMSI */
1506 static const unsigned char ident_resp_imsi[] = {
1507 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1508 0x54
1509 };
1510
1511 /* DTAP - Attach Complete */
1512 static const unsigned char attach_compl[] = {
1513 0x08, 0x03
1514 };
1515
1516 printf("Testing cancellation\n");
1517
1518 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1519
1520 /* reset the PRNG used by sgsn_alloc_ptmsi */
1521 srand(1);
1522
1523 ptmsi1 = sgsn_alloc_ptmsi();
1524 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1525
1526 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1527 * again */
1528 srand(1);
1529
1530 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1531
1532 /* Create a LLE/LLME */
1533 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1534 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1535 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1536
1537 /* inject the attach request */
1538 send_0408_message(lle->llme, foreign_tlli,
1539 attach_req, ARRAY_SIZE(attach_req));
1540
1541 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1542 OSMO_ASSERT(ctx != NULL);
1543 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1544
1545 /* we expect an identity request (IMEI) */
1546 OSMO_ASSERT(sgsn_tx_counter == 1);
1547
1548 /* inject the identity response (IMEI) */
1549 send_0408_message(ctx->llme, foreign_tlli,
1550 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1551
1552 /* we expect an identity request (IMSI) */
1553 OSMO_ASSERT(sgsn_tx_counter == 1);
1554
1555 /* inject the identity response (IMSI) */
1556 send_0408_message(ctx->llme, foreign_tlli,
1557 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1558
1559 /* check that the MM context has not been removed due to a failed
1560 * authorization */
1561 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1562
1563 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1564
1565 /* we expect an attach accept/reject */
1566 OSMO_ASSERT(sgsn_tx_counter == 1);
1567
1568 /* this has been randomly assigned by the SGSN */
1569 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1570
1571 /* inject the attach complete */
1572 send_0408_message(ctx->llme, local_tlli,
1573 attach_compl, ARRAY_SIZE(attach_compl));
1574
1575 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1576
1577 /* we don't expect a response */
1578 OSMO_ASSERT(sgsn_tx_counter == 0);
1579
1580 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001581 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001582
1583 /* verify that things are gone */
1584 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1585 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1586 OSMO_ASSERT(!ictx);
1587
1588 sgsn->cfg.auth_policy = saved_auth_policy;
1589}
1590
1591/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001592 * Test the dynamic allocation of P-TMSIs
1593 */
1594static void test_gmm_ptmsi_allocation(void)
1595{
1596 struct gprs_ra_id raid = { 0, };
1597 struct sgsn_mm_ctx *ctx = NULL;
1598 struct sgsn_mm_ctx *ictx;
1599 uint32_t foreign_tlli;
1600 uint32_t ptmsi1;
1601 uint32_t ptmsi2;
1602 uint32_t old_ptmsi;
1603 uint32_t local_tlli = 0;
1604 struct gprs_llc_lle *lle;
1605 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1606
1607 /* DTAP - Attach Request (IMSI 12131415161718) */
1608 static const unsigned char attach_req[] = {
1609 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1610 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1611 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1612 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1613 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1614 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1615 0x00,
1616 };
1617
1618 /* DTAP - Identity Response IMEI */
1619 static const unsigned char ident_resp_imei[] = {
1620 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1621 0x56
1622 };
1623
1624 /* DTAP - Attach Complete */
1625 static const unsigned char attach_compl[] = {
1626 0x08, 0x03
1627 };
1628
1629 /* DTAP - Routing Area Update Request */
1630 static const unsigned char ra_upd_req[] = {
1631 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1632 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1633 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1634 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1635 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1636 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1637 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1638 };
1639
1640 /* DTAP - Routing Area Update Complete */
1641 static const unsigned char ra_upd_complete[] = {
1642 0x08, 0x0a
1643 };
1644
1645 /* DTAP - Detach Request (MO) */
1646 /* normal detach, power_off = 1 */
1647 static const unsigned char detach_req[] = {
1648 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1649 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1650 };
1651
1652 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1653
1654 printf("Testing P-TMSI allocation\n");
1655
1656 printf(" - sgsn_alloc_ptmsi\n");
1657
1658 /* reset the PRNG used by sgsn_alloc_ptmsi */
1659 srand(1);
1660
1661 ptmsi1 = sgsn_alloc_ptmsi();
1662 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1663
1664 ptmsi2 = sgsn_alloc_ptmsi();
1665 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1666
1667 OSMO_ASSERT(ptmsi1 != ptmsi2);
1668
1669 printf(" - Repeated Attach Request\n");
1670
1671 /* reset the PRNG, so that the same P-TMSI will be generated
1672 * again */
1673 srand(1);
1674
1675 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1676
1677 /* Create a LLE/LLME */
1678 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1679 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1680 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1681
1682 /* inject the attach request */
1683 send_0408_message(lle->llme, foreign_tlli,
1684 attach_req, ARRAY_SIZE(attach_req));
1685
1686 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1687 OSMO_ASSERT(ctx != NULL);
1688 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1689 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1690
1691 old_ptmsi = ctx->p_tmsi_old;
1692
1693 /* we expect an identity request (IMEI) */
1694 OSMO_ASSERT(sgsn_tx_counter == 1);
1695
1696 /* inject the identity response (IMEI) */
1697 send_0408_message(ctx->llme, foreign_tlli,
1698 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1699
1700 /* check that the MM context has not been removed due to a failed
1701 * authorization */
1702 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1703
1704 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1705 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1706
1707 /* we expect an attach accept */
1708 OSMO_ASSERT(sgsn_tx_counter == 1);
1709
1710 /* we ignore this and send the attach again */
1711 send_0408_message(lle->llme, foreign_tlli,
1712 attach_req, ARRAY_SIZE(attach_req));
1713
1714 /* the allocated P-TMSI should be the same */
1715 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1716 OSMO_ASSERT(ctx != NULL);
1717 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1718 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1719 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1720
1721 /* inject the attach complete */
1722 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1723 send_0408_message(ctx->llme, local_tlli,
1724 attach_compl, ARRAY_SIZE(attach_compl));
1725
1726 /* we don't expect a response */
1727 OSMO_ASSERT(sgsn_tx_counter == 0);
1728
1729 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1730 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1731 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1732
1733 printf(" - Repeated RA Update Request\n");
1734
1735 /* inject the RA update request */
1736 send_0408_message(ctx->llme, local_tlli,
1737 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1738
1739 /* we expect an RA update accept */
1740 OSMO_ASSERT(sgsn_tx_counter == 1);
1741
1742 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1743 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1744 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1745
1746 /* repeat the RA update request */
1747 send_0408_message(ctx->llme, local_tlli,
1748 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1749
1750 /* we expect an RA update accept */
1751 OSMO_ASSERT(sgsn_tx_counter == 1);
1752
1753 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1754 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1755 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1756
1757 /* inject the RA update complete */
1758 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1759 send_0408_message(ctx->llme, local_tlli,
1760 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1761
1762 /* we don't expect a response */
1763 OSMO_ASSERT(sgsn_tx_counter == 0);
1764
1765 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1766 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1767 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1768
1769 /* inject the detach */
1770 send_0408_message(ctx->llme, local_tlli,
1771 detach_req, ARRAY_SIZE(detach_req));
1772
1773 /* verify that things are gone */
1774 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1775 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1776 OSMO_ASSERT(!ictx);
1777
1778 sgsn->cfg.auth_policy = saved_auth_policy;
1779}
1780
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001781static struct log_info_cat gprs_categories[] = {
1782 [DMM] = {
1783 .name = "DMM",
1784 .description = "Layer3 Mobility Management (MM)",
1785 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001786 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001787 },
1788 [DPAG] = {
1789 .name = "DPAG",
1790 .description = "Paging Subsystem",
1791 .color = "\033[1;38m",
1792 .enabled = 1, .loglevel = LOGL_NOTICE,
1793 },
1794 [DMEAS] = {
1795 .name = "DMEAS",
1796 .description = "Radio Measurement Processing",
1797 .enabled = 0, .loglevel = LOGL_NOTICE,
1798 },
1799 [DREF] = {
1800 .name = "DREF",
1801 .description = "Reference Counting",
1802 .enabled = 0, .loglevel = LOGL_NOTICE,
1803 },
1804 [DGPRS] = {
1805 .name = "DGPRS",
1806 .description = "GPRS Packet Service",
1807 .enabled = 1, .loglevel = LOGL_DEBUG,
1808 },
1809 [DNS] = {
1810 .name = "DNS",
1811 .description = "GPRS Network Service (NS)",
1812 .enabled = 1, .loglevel = LOGL_INFO,
1813 },
1814 [DBSSGP] = {
1815 .name = "DBSSGP",
1816 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1817 .enabled = 1, .loglevel = LOGL_DEBUG,
1818 },
1819 [DLLC] = {
1820 .name = "DLLC",
1821 .description = "GPRS Logical Link Control Protocol (LLC)",
1822 .enabled = 1, .loglevel = LOGL_DEBUG,
1823 },
1824 [DSNDCP] = {
1825 .name = "DSNDCP",
1826 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1827 .enabled = 1, .loglevel = LOGL_DEBUG,
1828 },
1829};
1830
1831static struct log_info info = {
1832 .cat = gprs_categories,
1833 .num_cat = ARRAY_SIZE(gprs_categories),
1834};
1835
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001836int main(int argc, char **argv)
1837{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001838 osmo_init_logging(&info);
1839 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1840 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1841
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001842 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001843 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001844
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001845 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001846 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001847 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001848 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001849 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001850 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001851 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001852 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001853 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001854 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001855 test_gmm_attach_acl();
1856 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001857 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001858 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001859 test_gmm_attach_subscr_gsup_auth(0);
1860 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001861 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001862 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001863 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001864 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001865 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001866
1867 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001868 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001869 return 0;
1870}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001871
1872
1873/* stubs */
1874struct osmo_prim_hdr;
1875int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1876{
1877 abort();
1878}