blob: d419f0a92ecb0e9ad126f904c1ecf456c73812e3 [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
471 printf("Testing subcriber GSUP handling\n");
472
473 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
474
475 /* Check for emptiness */
476 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
477
478 /* Allocate entry 1 */
479 s1 = gprs_subscr_get_or_create(imsi1);
480 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
481 s1found = gprs_subscr_get_by_imsi(imsi1);
482 OSMO_ASSERT(s1found == s1);
483 subscr_put(s1found);
484
485 /* Create a context */
486 OSMO_ASSERT(count(gprs_llme_list()) == 0);
487 ctx = alloc_mm_ctx(local_tlli, &raid);
488 llme = ctx->llme;
489
490 /* Attach s1 to ctx */
491 ctx->subscr = subscr_get(s1);
492 ctx->subscr->sgsn_data->mm = ctx;
493
494 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100495 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100496 OSMO_ASSERT(rc >= 0);
497 OSMO_ASSERT(last_updated_subscr == s1);
498
499 /* Check triplets */
500 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
501 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
502 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
503
504 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100505 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100506 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100507 OSMO_ASSERT(last_updated_subscr == s1);
508
509 /* Check triplets */
510 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
511 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
512 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
513
514 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100515 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100516 OSMO_ASSERT(rc >= 0);
517 OSMO_ASSERT(last_updated_subscr == s1);
518
519 /* Check authorization */
520 OSMO_ASSERT(s1->authorized == 1);
521
522 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100523 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100524 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100525 OSMO_ASSERT(last_updated_subscr == s1);
526
527 /* Check authorization */
528 OSMO_ASSERT(s1->authorized == 0);
529
530 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100531 rc = rx_gsup_message(location_cancellation_req,
532 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100533 OSMO_ASSERT(rc >= 0);
534 OSMO_ASSERT(last_updated_subscr == s1);
535
536 /* Check cancellation result */
537 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
538 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
539
540 /* Free MM context and subscriber */
541 subscr_put(s1);
542 s1found = gprs_subscr_get_by_imsi(imsi1);
543 OSMO_ASSERT(s1found == NULL);
544 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
545
546 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
547}
548
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100549int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
550{
551 msgb_free(msg);
552 return 0;
553};
554
555
556static void test_subscriber_blocking(void)
557{
558 struct gsm_subscriber *s1;
559 const char *imsi1 = "1234567890";
560 struct sgsn_mm_ctx *ctx;
561 struct gprs_ra_id raid = { 0, };
562 uint32_t local_tlli = 0xffeeddcc;
563 struct gprs_llc_llme *llme;
564 int rc;
565
566 printf("Testing subcriber procedure blocking\n");
567
568 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
569 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
570
571 /* Check for emptiness */
572 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
573
574 /* Create a context */
575 OSMO_ASSERT(count(gprs_llme_list()) == 0);
576 ctx = alloc_mm_ctx(local_tlli, &raid);
577 llme = ctx->llme;
578 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
579
580 /* Allocate and attach a subscriber */
581 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
582 assert_subscr(s1, imsi1);
583
584 /* Start SendAuthInfoRequest procedure */
585 rc = gprs_subscr_query_auth_info(s1);
586 /* Not blocking */
587 OSMO_ASSERT(rc == 0);
588
589 /* Start UpdateLocation procedure */
590 rc = gprs_subscr_location_update(s1);
591 /* Blocking */
592 OSMO_ASSERT(rc == 0);
593
594 /* Start PurgeMS procedure */
595 rc = gprs_subscr_purge(s1);
596 /* Not blocking */
597 OSMO_ASSERT(rc == 0);
598 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
599
600 /* Start PurgeMS procedure (retry) */
601 rc = gprs_subscr_purge(s1);
602 /* Not blocking */
603 OSMO_ASSERT(rc == 0);
604
605 /* Start SendAuthInfoRequest procedure */
606 rc = gprs_subscr_query_auth_info(s1);
607 /* Blocking */
608 OSMO_ASSERT(rc == -EAGAIN);
609
610 /* Start UpdateLocation procedure */
611 rc = gprs_subscr_location_update(s1);
612 /* Blocking */
613 OSMO_ASSERT(rc == -EAGAIN);
614
615 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
616 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
617
618 /* Start SendAuthInfoRequest procedure */
619 rc = gprs_subscr_query_auth_info(s1);
620 /* Not blocking */
621 OSMO_ASSERT(rc == 0);
622
623 /* Start UpdateLocation procedure */
624 rc = gprs_subscr_location_update(s1);
625 /* Blocking */
626 OSMO_ASSERT(rc == 0);
627
628 subscr_put(s1);
629 sgsn_mm_ctx_free(ctx);
630 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
631
632 assert_no_subscrs();
633
634 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
635 talloc_free(sgsn->gsup_client);
636 sgsn->gsup_client = NULL;
637}
638
639
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200640/*
641 * Test that a GMM Detach will remove the MMCTX and the
642 * associated LLME.
643 */
644static void test_gmm_detach(void)
645{
646 struct gprs_ra_id raid = { 0, };
647 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200648 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200649
650 printf("Testing GMM detach\n");
651
652 /* DTAP - Detach Request (MO) */
653 /* normal detach, power_off = 0 */
654 static const unsigned char detach_req[] = {
655 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
656 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
657 };
658
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200659 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200660
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100661 /* Create a context */
662 OSMO_ASSERT(count(gprs_llme_list()) == 0);
663 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200664
665 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100666 send_0408_message(ctx->llme, local_tlli,
667 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200668
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100669 /* verify that a single message (hopefully the Detach Accept) has been
670 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100671 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100672
673 /* verify that things are gone */
674 OSMO_ASSERT(count(gprs_llme_list()) == 0);
675 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
676 OSMO_ASSERT(!ictx);
677}
678
679/*
680 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
681 * will not sent a Detach Accept message (power_off = 1)
682 */
683static void test_gmm_detach_power_off(void)
684{
685 struct gprs_ra_id raid = { 0, };
686 struct sgsn_mm_ctx *ctx, *ictx;
687 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100688
689 printf("Testing GMM detach (power off)\n");
690
691 /* DTAP - Detach Request (MO) */
692 /* normal detach, power_off = 1 */
693 static const unsigned char detach_req[] = {
694 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
695 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
696 };
697
698 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
699
700 /* Create a context */
701 OSMO_ASSERT(count(gprs_llme_list()) == 0);
702 ctx = alloc_mm_ctx(local_tlli, &raid);
703
704 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100705 send_0408_message(ctx->llme, local_tlli,
706 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100707
708 /* verify that no message (and therefore no Detach Accept) has been
709 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100710 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100711
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200712 /* verify that things are gone */
713 OSMO_ASSERT(count(gprs_llme_list()) == 0);
714 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200715 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200716}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200717
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200718/*
719 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
720 */
721static void test_gmm_detach_no_mmctx(void)
722{
723 struct gprs_llc_lle *lle;
724 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200725
726 printf("Testing GMM detach (no MMCTX)\n");
727
728 /* DTAP - Detach Request (MO) */
729 /* normal detach, power_off = 0 */
730 static const unsigned char detach_req[] = {
731 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
732 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
733 };
734
735 /* Create an LLME */
736 OSMO_ASSERT(count(gprs_llme_list()) == 0);
737 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
738 lle = gprs_lle_get_or_create(local_tlli, 3);
739
740 OSMO_ASSERT(count(gprs_llme_list()) == 1);
741
742 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100743 send_0408_message(lle->llme, local_tlli,
744 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200745
746 /* verify that the LLME is gone */
747 OSMO_ASSERT(count(gprs_llme_list()) == 0);
748}
749
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100750/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100751 * Test that a single GMM Detach Accept message will not cause the SGSN to send
752 * any message or leave an MM context at the SGSN.
753 */
754static void test_gmm_detach_accept_unexpected(void)
755{
756 struct gprs_llc_lle *lle;
757 uint32_t local_tlli;
758
759 printf("Testing GMM detach accept (unexpected)\n");
760
761 /* DTAP - Detach Accept (MT) */
762 /* normal detach */
763 static const unsigned char detach_acc[] = {
764 0x08, 0x06
765 };
766
767 /* Create an LLME */
768 OSMO_ASSERT(count(gprs_llme_list()) == 0);
769 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
770 lle = gprs_lle_get_or_create(local_tlli, 3);
771
772 /* inject the detach */
773 send_0408_message(lle->llme, local_tlli,
774 detach_acc, ARRAY_SIZE(detach_acc));
775
776 /* verify that no message (and therefore no Status or XID reset) has been
777 * sent by the SGSN */
778 OSMO_ASSERT(sgsn_tx_counter == 0);
779
780 /* verify that things are gone */
781 OSMO_ASSERT(count(gprs_llme_list()) == 0);
782}
783
784/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100785 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
786 */
787static void test_gmm_status_no_mmctx(void)
788{
789 struct gprs_llc_lle *lle;
790 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100791
792 printf("Testing GMM Status (no MMCTX)\n");
793
794 /* DTAP - GMM Status, protocol error */
795 static const unsigned char gmm_status[] = {
796 0x08, 0x20, 0x6f
797 };
798
799 /* Create an LLME */
800 OSMO_ASSERT(count(gprs_llme_list()) == 0);
801 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
802 lle = gprs_lle_get_or_create(local_tlli, 3);
803
804 OSMO_ASSERT(count(gprs_llme_list()) == 1);
805
806 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100807 send_0408_message(lle->llme, local_tlli,
808 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100809
810 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100811 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100812
813 /* verify that the LLME is gone */
814 OSMO_ASSERT(count(gprs_llme_list()) == 0);
815}
816
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100817/*
818 * Test the GMM Attach procedure
819 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100820static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100821{
822 struct gprs_ra_id raid = { 0, };
823 struct sgsn_mm_ctx *ctx = NULL;
824 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100825 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100826 uint32_t foreign_tlli;
827 uint32_t local_tlli = 0;
828 struct gprs_llc_lle *lle;
829
830 /* DTAP - Attach Request */
831 /* The P-TMSI is not known by the SGSN */
832 static const unsigned char attach_req[] = {
833 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
834 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
835 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
836 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
837 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
838 };
839
840 /* DTAP - Identity Response IMEI */
841 static const unsigned char ident_resp_imei[] = {
842 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
843 0x56
844 };
845
846 /* DTAP - Identity Response IMSI */
847 static const unsigned char ident_resp_imsi[] = {
848 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
849 0x54
850 };
851
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100852 /* DTAP - Authentication and Ciphering Resp */
853 static const unsigned char auth_ciph_resp[] = {
854 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
855 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
856 };
857
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100858 /* DTAP - Attach Complete */
859 static const unsigned char attach_compl[] = {
860 0x08, 0x03
861 };
862
863 /* DTAP - Detach Request (MO) */
864 /* normal detach, power_off = 0 */
865 static const unsigned char detach_req[] = {
866 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
867 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
868 };
869
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100870 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100871
872 /* reset the PRNG used by sgsn_alloc_ptmsi */
873 srand(1);
874
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100875 ptmsi1 = sgsn_alloc_ptmsi();
876 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
877
878 /* reset the PRNG, so that the same P-TMSI sequence will be generated
879 * again */
880 srand(1);
881
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100882 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
883
884 /* Create a LLE/LLME */
885 OSMO_ASSERT(count(gprs_llme_list()) == 0);
886 lle = gprs_lle_get_or_create(foreign_tlli, 3);
887 OSMO_ASSERT(count(gprs_llme_list()) == 1);
888
889 /* inject the attach request */
890 send_0408_message(lle->llme, foreign_tlli,
891 attach_req, ARRAY_SIZE(attach_req));
892
893 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
894 OSMO_ASSERT(ctx != NULL);
895 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
896
897 /* we expect an identity request (IMEI) */
898 OSMO_ASSERT(sgsn_tx_counter == 1);
899
900 /* inject the identity response (IMEI) */
901 send_0408_message(ctx->llme, foreign_tlli,
902 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
903
904 /* we expect an identity request (IMSI) */
905 OSMO_ASSERT(sgsn_tx_counter == 1);
906
907 /* inject the identity response (IMSI) */
908 send_0408_message(ctx->llme, foreign_tlli,
909 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
910
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100911 /* check that the MM context has not been removed due to a failed
912 * authorization */
913 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
914
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100915 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100916
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100917retry_attach_req:
918
919 if (retry && sgsn_tx_counter == 0) {
920 fprintf(stderr, "Retrying attach request\n");
921 /* re-inject the attach request */
922 send_0408_message(lle->llme, foreign_tlli,
923 attach_req, ARRAY_SIZE(attach_req));
924 }
925
926 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
927 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100928
929 /* inject the auth & ciph response */
930 send_0408_message(ctx->llme, foreign_tlli,
931 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
932
933 /* check that the MM context has not been removed due to a
934 * failed authorization */
935 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
936 }
937
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100938 if (retry && sgsn_tx_counter == 0)
939 goto retry_attach_req;
940
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100941 /* we expect an attach accept/reject */
942 OSMO_ASSERT(sgsn_tx_counter == 1);
943
944 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100945 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100946
947 /* inject the attach complete */
948 send_0408_message(ctx->llme, local_tlli,
949 attach_compl, ARRAY_SIZE(attach_compl));
950
951 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
952
953 /* we don't expect a response */
954 OSMO_ASSERT(sgsn_tx_counter == 0);
955
956 /* inject the detach */
957 send_0408_message(ctx->llme, local_tlli,
958 detach_req, ARRAY_SIZE(detach_req));
959
960 /* verify that things are gone */
961 OSMO_ASSERT(count(gprs_llme_list()) == 0);
962 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
963 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100964}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100965
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100966static void test_gmm_attach_acl(void)
967{
968 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
969
970 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
971 sgsn_acl_add("123456789012345", &sgsn->cfg);
972 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100973 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100974 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100975
976 sgsn->cfg.auth_policy = saved_auth_policy;
977}
978
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100979int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100980 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100981 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100982 if (rc == -ENOTSUP) {
983 OSMO_ASSERT(mmctx->subscr);
984 gprs_subscr_update(mmctx->subscr);
985 }
986 return rc;
987};
988
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100989int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
990 gprs_subscr_update(mmctx->subscr);
991 return 0;
992};
993
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +0100994static void cleanup_subscr_by_imsi(const char *imsi)
995{
996 struct gsm_subscriber *subscr;
997
998 subscr = gprs_subscr_get_by_imsi(imsi);
999 OSMO_ASSERT(subscr != NULL);
Jacob Erlbecke1beb6f2015-01-08 14:13:46 +01001000 subscr->keep_in_ram = 0;
1001 subscr_put(subscr);
1002 subscr = gprs_subscr_get_by_imsi(imsi);
1003 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001004}
1005
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001006static void test_gmm_attach_subscr(void)
1007{
1008 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1009 struct gsm_subscriber *subscr;
1010
1011 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001012 subscr_request_update_location_cb = my_subscr_request_update_location;
1013 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001014
1015 subscr = gprs_subscr_get_or_create("123456789012345");
1016 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001017 subscr->keep_in_ram = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001018 subscr_put(subscr);
1019
1020 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001021 test_gmm_attach(0);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001022
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001023 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001024 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001025
1026 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001027 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1028 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001029}
1030
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001031int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1032{
1033 /* Fake an authentication */
1034 OSMO_ASSERT(mmctx->subscr);
1035 mmctx->is_authenticated = 1;
1036 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001037
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001038 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001039};
1040
1041static void test_gmm_attach_subscr_fake_auth(void)
1042{
1043 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1044 struct gsm_subscriber *subscr;
1045
1046 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001047 subscr_request_update_location_cb = my_subscr_request_update_location;
1048 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001049
1050 subscr = gprs_subscr_get_or_create("123456789012345");
1051 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001052 subscr->keep_in_ram = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001053 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001054 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001055 subscr_put(subscr);
1056
1057 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001058 test_gmm_attach(0);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001059
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001060 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001061 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001062
1063 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001064 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1065 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1066}
1067
1068int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1069{
1070 struct gsm_auth_tuple at = {
1071 .sres = {0x51, 0xe5, 0x51, 0xe5},
1072 .key_seq = 0
1073 };
1074
1075 /* Fake an authentication */
1076 OSMO_ASSERT(mmctx->subscr);
1077 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1078
1079 gprs_subscr_update_auth_info(mmctx->subscr);
1080
1081 return 0;
1082};
1083
1084static void test_gmm_attach_subscr_real_auth(void)
1085{
1086 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1087 struct gsm_subscriber *subscr;
1088
1089 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1090 subscr_request_update_location_cb = my_subscr_request_update_location;
1091 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1092
1093 subscr = gprs_subscr_get_or_create("123456789012345");
1094 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001095 subscr->keep_in_ram = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001096 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001097 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001098 subscr_put(subscr);
1099
1100 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001101
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001102 test_gmm_attach(0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001103
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001104 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001105 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001106
1107 sgsn->cfg.auth_policy = saved_auth_policy;
1108 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1109 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001110}
1111
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001112#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1113 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1114
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001115static int auth_info_skip = 0;
1116static int upd_loc_skip = 0;
1117
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001118int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1119{
1120 static const uint8_t send_auth_info_res[] = {
1121 0x0a,
1122 TEST_GSUP_IMSI_LONG_IE,
1123 0x03, 0x22, /* Auth tuple */
1124 0x20, 0x10,
1125 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1126 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1127 0x21, 0x04,
1128 0x51, 0xe5, 0x51, 0xe5,
1129 0x22, 0x08,
1130 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1131 };
1132
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001133 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001134
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001135 if (auth_info_skip > 0) {
1136 auth_info_skip -= 1;
1137 return -EAGAIN;
1138 }
1139
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001140 /* Fake an SendAuthInfoRes */
1141 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1142
1143 return 0;
1144};
1145
1146int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1147 static const uint8_t update_location_res[] = {
1148 0x06,
1149 TEST_GSUP_IMSI_LONG_IE,
1150 0x04, 0x00, /* PDP info complete */
1151 0x05, 0x12,
1152 0x10, 0x01, 0x01,
1153 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1154 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1155 };
1156
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001157 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001158
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001159 if (upd_loc_skip > 0) {
1160 upd_loc_skip -= 1;
1161 return -EAGAIN;
1162 }
1163
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001164 /* Fake an UpdateLocRes */
1165 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1166};
1167
1168
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001169static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001170{
1171 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1172 struct gsm_subscriber *subscr;
1173
1174 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1175 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1176 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001177 if (retry) {
1178 upd_loc_skip = 3;
1179 auth_info_skip = 3;
1180 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001181
1182 subscr = gprs_subscr_get_or_create("123456789012345");
1183 subscr->authorized = 1;
1184 sgsn->cfg.require_authentication = 1;
1185 sgsn->cfg.require_update_location = 1;
1186 subscr_put(subscr);
1187
1188 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001189 test_gmm_attach(retry);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001190
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001191 cleanup_subscr_by_imsi("123456789012345");
1192 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001193
1194 sgsn->cfg.auth_policy = saved_auth_policy;
1195 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1196 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001197 upd_loc_skip = 0;
1198 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001199}
1200
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001201int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1202{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001203 struct gprs_gsup_message to_peer = {0};
1204 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001205 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001206 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001207
1208 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001209 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1210 OSMO_ASSERT(rc >= 0);
1211 OSMO_ASSERT(to_peer.imsi[0] != 0);
1212 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001213
1214 /* This invalidates the pointers in to_peer */
1215 msgb_free(msg);
1216
1217 switch (to_peer.message_type) {
1218 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1219 /* Send UPDATE_LOCATION_RESULT */
1220 return my_subscr_request_update_gsup_auth(NULL);
1221
1222 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1223 /* Send SEND_AUTH_INFO_RESULT */
1224 return my_subscr_request_auth_info_gsup_auth(NULL);
1225
1226 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001227 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1228 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001229
1230 default:
1231 if ((to_peer.message_type & 0b00000011) == 0) {
1232 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001233 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001234 from_peer.message_type = to_peer.message_type + 1;
1235 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1236 break;
1237 }
1238
1239 /* Ignore it */
1240 return 0;
1241 }
1242
1243 reply_msg = gprs_gsup_msgb_alloc();
1244 reply_msg->l2h = reply_msg->data;
1245 gprs_gsup_encode(reply_msg, &from_peer);
1246 gprs_subscr_rx_gsup_message(reply_msg);
1247 msgb_free(reply_msg);
1248
1249 return 0;
1250};
1251
1252static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1253{
1254 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1255 struct gsm_subscriber *subscr;
1256
1257 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1258 sgsn_inst.cfg.subscriber_expiry_timeout = 0;
1259 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1260
1261 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1262
1263 if (retry) {
1264 upd_loc_skip = 3;
1265 auth_info_skip = 3;
1266 }
1267
1268 printf("Auth policy 'remote', real GSUP based auth: ");
1269 test_gmm_attach(retry);
1270
1271 subscr = gprs_subscr_get_by_imsi("123456789012345");
1272 OSMO_ASSERT(subscr != NULL);
1273 gprs_subscr_delete(subscr);
1274
1275 osmo_timers_update();
1276
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001277 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001278
1279 sgsn->cfg.auth_policy = saved_auth_policy;
1280 sgsn_inst.cfg.subscriber_expiry_timeout = SGSN_TIMEOUT_NEVER;
1281 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1282 upd_loc_skip = 0;
1283 auth_info_skip = 0;
1284 talloc_free(sgsn->gsup_client);
1285 sgsn->gsup_client = NULL;
1286}
1287
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001288/*
1289 * Test the GMM Rejects
1290 */
1291static void test_gmm_reject(void)
1292{
1293 struct gprs_ra_id raid = { 0, };
1294 struct sgsn_mm_ctx *ctx = NULL;
1295 uint32_t foreign_tlli;
1296 struct gprs_llc_lle *lle;
1297 int idx;
1298
1299 /* DTAP - Attach Request */
1300 /* Invalid MI length */
1301 static const unsigned char attach_req_inv_mi_len[] = {
1302 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1303 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1304 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1305 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1306 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1307 };
1308
1309 /* DTAP - Attach Request */
1310 /* Invalid MI type (IMEI) */
1311 static const unsigned char attach_req_inv_mi_type[] = {
1312 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1313 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1314 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1315 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1316 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1317 };
1318
1319 /* DTAP - Routing Area Update Request */
1320 static const unsigned char dtap_ra_upd_req[] = {
1321 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1322 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1323 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1324 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1325 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1326 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1327 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1328 };
1329
1330 /* DTAP - Routing Area Update Request */
1331 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1332 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1333 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1334 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1335 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1336 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1337 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1338 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1339 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1340 };
1341
1342 /* DTAP - Routing Area Update Request */
1343 /* Invalid cap length */
1344 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1345 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1346 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1347 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1348 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1349 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1350 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1351 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1352 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1353 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1354 };
1355
1356 struct test {
1357 const char *title;
1358 const unsigned char *msg;
1359 unsigned msg_len;
1360 unsigned num_resp;
1361
1362 };
1363 static struct test tests[] = {
1364 {
1365 .title = "Attach Request (invalid MI length)",
1366 .msg = attach_req_inv_mi_len,
1367 .msg_len = sizeof(attach_req_inv_mi_len),
1368 .num_resp = 1 /* Reject */
1369
1370 },
1371 {
1372 .title = "Attach Request (invalid MI type)",
1373 .msg = attach_req_inv_mi_type,
1374 .msg_len = sizeof(attach_req_inv_mi_type),
1375 .num_resp = 1 /* Reject */
1376 },
1377 {
1378 .title = "Routing Area Update Request (valid)",
1379 .msg = dtap_ra_upd_req,
1380 .msg_len = sizeof(dtap_ra_upd_req),
1381 .num_resp = 2 /* XID Reset + Reject */
1382 },
1383 {
1384 .title = "Routing Area Update Request (invalid type)",
1385 .msg = dtap_ra_upd_req_inv_type,
1386 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1387 .num_resp = 1 /* Reject */
1388 },
1389 {
1390 .title = "Routing Area Update Request (invalid CAP length)",
1391 .msg = dtap_ra_upd_req_inv_cap_len,
1392 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1393 .num_resp = 1 /* Reject */
1394 },
1395 };
1396
1397 printf("Testing GMM reject\n");
1398
1399 /* reset the PRNG used by sgsn_alloc_ptmsi */
1400 srand(1);
1401
1402 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1403
1404 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1405
1406 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1407 const struct test *test = &tests[idx];
1408 printf(" - %s\n", test->title);
1409
1410 /* Create a LLE/LLME */
1411 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1412 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1413
1414 /* Inject the Request message */
1415 send_0408_message(lle->llme, foreign_tlli,
1416 test->msg, test->msg_len);
1417
1418 /* We expect a Reject message */
1419 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1420 sgsn_tx_counter, test->num_resp);
1421 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1422
1423 /* verify that LLME/MM are removed */
1424 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1425 OSMO_ASSERT(ctx == NULL);
1426 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1427 }
1428}
1429
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001430/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001431 * Test cancellation of attached MM contexts
1432 */
1433static void test_gmm_cancel(void)
1434{
1435 struct gprs_ra_id raid = { 0, };
1436 struct sgsn_mm_ctx *ctx = NULL;
1437 struct sgsn_mm_ctx *ictx;
1438 uint32_t ptmsi1;
1439 uint32_t foreign_tlli;
1440 uint32_t local_tlli = 0;
1441 struct gprs_llc_lle *lle;
1442 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1443
1444 /* DTAP - Attach Request */
1445 /* The P-TMSI is not known by the SGSN */
1446 static const unsigned char attach_req[] = {
1447 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1448 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1449 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1450 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1451 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1452 };
1453
1454 /* DTAP - Identity Response IMEI */
1455 static const unsigned char ident_resp_imei[] = {
1456 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1457 0x56
1458 };
1459
1460 /* DTAP - Identity Response IMSI */
1461 static const unsigned char ident_resp_imsi[] = {
1462 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1463 0x54
1464 };
1465
1466 /* DTAP - Attach Complete */
1467 static const unsigned char attach_compl[] = {
1468 0x08, 0x03
1469 };
1470
1471 printf("Testing cancellation\n");
1472
1473 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1474
1475 /* reset the PRNG used by sgsn_alloc_ptmsi */
1476 srand(1);
1477
1478 ptmsi1 = sgsn_alloc_ptmsi();
1479 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1480
1481 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1482 * again */
1483 srand(1);
1484
1485 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1486
1487 /* Create a LLE/LLME */
1488 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1489 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1490 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1491
1492 /* inject the attach request */
1493 send_0408_message(lle->llme, foreign_tlli,
1494 attach_req, ARRAY_SIZE(attach_req));
1495
1496 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1497 OSMO_ASSERT(ctx != NULL);
1498 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1499
1500 /* we expect an identity request (IMEI) */
1501 OSMO_ASSERT(sgsn_tx_counter == 1);
1502
1503 /* inject the identity response (IMEI) */
1504 send_0408_message(ctx->llme, foreign_tlli,
1505 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1506
1507 /* we expect an identity request (IMSI) */
1508 OSMO_ASSERT(sgsn_tx_counter == 1);
1509
1510 /* inject the identity response (IMSI) */
1511 send_0408_message(ctx->llme, foreign_tlli,
1512 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1513
1514 /* check that the MM context has not been removed due to a failed
1515 * authorization */
1516 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1517
1518 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1519
1520 /* we expect an attach accept/reject */
1521 OSMO_ASSERT(sgsn_tx_counter == 1);
1522
1523 /* this has been randomly assigned by the SGSN */
1524 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1525
1526 /* inject the attach complete */
1527 send_0408_message(ctx->llme, local_tlli,
1528 attach_compl, ARRAY_SIZE(attach_compl));
1529
1530 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1531
1532 /* we don't expect a response */
1533 OSMO_ASSERT(sgsn_tx_counter == 0);
1534
1535 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001536 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001537
1538 /* verify that things are gone */
1539 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1540 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1541 OSMO_ASSERT(!ictx);
1542
1543 sgsn->cfg.auth_policy = saved_auth_policy;
1544}
1545
1546/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001547 * Test the dynamic allocation of P-TMSIs
1548 */
1549static void test_gmm_ptmsi_allocation(void)
1550{
1551 struct gprs_ra_id raid = { 0, };
1552 struct sgsn_mm_ctx *ctx = NULL;
1553 struct sgsn_mm_ctx *ictx;
1554 uint32_t foreign_tlli;
1555 uint32_t ptmsi1;
1556 uint32_t ptmsi2;
1557 uint32_t old_ptmsi;
1558 uint32_t local_tlli = 0;
1559 struct gprs_llc_lle *lle;
1560 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1561
1562 /* DTAP - Attach Request (IMSI 12131415161718) */
1563 static const unsigned char attach_req[] = {
1564 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1565 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1566 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1567 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1568 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1569 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1570 0x00,
1571 };
1572
1573 /* DTAP - Identity Response IMEI */
1574 static const unsigned char ident_resp_imei[] = {
1575 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1576 0x56
1577 };
1578
1579 /* DTAP - Attach Complete */
1580 static const unsigned char attach_compl[] = {
1581 0x08, 0x03
1582 };
1583
1584 /* DTAP - Routing Area Update Request */
1585 static const unsigned char ra_upd_req[] = {
1586 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1587 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1588 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1589 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1590 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1591 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1592 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1593 };
1594
1595 /* DTAP - Routing Area Update Complete */
1596 static const unsigned char ra_upd_complete[] = {
1597 0x08, 0x0a
1598 };
1599
1600 /* DTAP - Detach Request (MO) */
1601 /* normal detach, power_off = 1 */
1602 static const unsigned char detach_req[] = {
1603 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1604 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1605 };
1606
1607 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1608
1609 printf("Testing P-TMSI allocation\n");
1610
1611 printf(" - sgsn_alloc_ptmsi\n");
1612
1613 /* reset the PRNG used by sgsn_alloc_ptmsi */
1614 srand(1);
1615
1616 ptmsi1 = sgsn_alloc_ptmsi();
1617 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1618
1619 ptmsi2 = sgsn_alloc_ptmsi();
1620 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1621
1622 OSMO_ASSERT(ptmsi1 != ptmsi2);
1623
1624 printf(" - Repeated Attach Request\n");
1625
1626 /* reset the PRNG, so that the same P-TMSI will be generated
1627 * again */
1628 srand(1);
1629
1630 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1631
1632 /* Create a LLE/LLME */
1633 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1634 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1635 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1636
1637 /* inject the attach request */
1638 send_0408_message(lle->llme, foreign_tlli,
1639 attach_req, ARRAY_SIZE(attach_req));
1640
1641 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1642 OSMO_ASSERT(ctx != NULL);
1643 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1644 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1645
1646 old_ptmsi = ctx->p_tmsi_old;
1647
1648 /* we expect an identity request (IMEI) */
1649 OSMO_ASSERT(sgsn_tx_counter == 1);
1650
1651 /* inject the identity response (IMEI) */
1652 send_0408_message(ctx->llme, foreign_tlli,
1653 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1654
1655 /* check that the MM context has not been removed due to a failed
1656 * authorization */
1657 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1658
1659 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1660 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1661
1662 /* we expect an attach accept */
1663 OSMO_ASSERT(sgsn_tx_counter == 1);
1664
1665 /* we ignore this and send the attach again */
1666 send_0408_message(lle->llme, foreign_tlli,
1667 attach_req, ARRAY_SIZE(attach_req));
1668
1669 /* the allocated P-TMSI should be the same */
1670 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1671 OSMO_ASSERT(ctx != NULL);
1672 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1673 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1674 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1675
1676 /* inject the attach complete */
1677 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1678 send_0408_message(ctx->llme, local_tlli,
1679 attach_compl, ARRAY_SIZE(attach_compl));
1680
1681 /* we don't expect a response */
1682 OSMO_ASSERT(sgsn_tx_counter == 0);
1683
1684 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1685 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1686 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1687
1688 printf(" - Repeated RA Update Request\n");
1689
1690 /* inject the RA update request */
1691 send_0408_message(ctx->llme, local_tlli,
1692 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1693
1694 /* we expect an RA update accept */
1695 OSMO_ASSERT(sgsn_tx_counter == 1);
1696
1697 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1698 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1699 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1700
1701 /* repeat the RA update request */
1702 send_0408_message(ctx->llme, local_tlli,
1703 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1704
1705 /* we expect an RA update accept */
1706 OSMO_ASSERT(sgsn_tx_counter == 1);
1707
1708 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1709 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1710 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1711
1712 /* inject the RA update complete */
1713 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1714 send_0408_message(ctx->llme, local_tlli,
1715 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1716
1717 /* we don't expect a response */
1718 OSMO_ASSERT(sgsn_tx_counter == 0);
1719
1720 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1721 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1722 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1723
1724 /* inject the detach */
1725 send_0408_message(ctx->llme, local_tlli,
1726 detach_req, ARRAY_SIZE(detach_req));
1727
1728 /* verify that things are gone */
1729 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1730 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1731 OSMO_ASSERT(!ictx);
1732
1733 sgsn->cfg.auth_policy = saved_auth_policy;
1734}
1735
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001736static struct log_info_cat gprs_categories[] = {
1737 [DMM] = {
1738 .name = "DMM",
1739 .description = "Layer3 Mobility Management (MM)",
1740 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001741 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001742 },
1743 [DPAG] = {
1744 .name = "DPAG",
1745 .description = "Paging Subsystem",
1746 .color = "\033[1;38m",
1747 .enabled = 1, .loglevel = LOGL_NOTICE,
1748 },
1749 [DMEAS] = {
1750 .name = "DMEAS",
1751 .description = "Radio Measurement Processing",
1752 .enabled = 0, .loglevel = LOGL_NOTICE,
1753 },
1754 [DREF] = {
1755 .name = "DREF",
1756 .description = "Reference Counting",
1757 .enabled = 0, .loglevel = LOGL_NOTICE,
1758 },
1759 [DGPRS] = {
1760 .name = "DGPRS",
1761 .description = "GPRS Packet Service",
1762 .enabled = 1, .loglevel = LOGL_DEBUG,
1763 },
1764 [DNS] = {
1765 .name = "DNS",
1766 .description = "GPRS Network Service (NS)",
1767 .enabled = 1, .loglevel = LOGL_INFO,
1768 },
1769 [DBSSGP] = {
1770 .name = "DBSSGP",
1771 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1772 .enabled = 1, .loglevel = LOGL_DEBUG,
1773 },
1774 [DLLC] = {
1775 .name = "DLLC",
1776 .description = "GPRS Logical Link Control Protocol (LLC)",
1777 .enabled = 1, .loglevel = LOGL_DEBUG,
1778 },
1779 [DSNDCP] = {
1780 .name = "DSNDCP",
1781 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1782 .enabled = 1, .loglevel = LOGL_DEBUG,
1783 },
1784};
1785
1786static struct log_info info = {
1787 .cat = gprs_categories,
1788 .num_cat = ARRAY_SIZE(gprs_categories),
1789};
1790
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001791int main(int argc, char **argv)
1792{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001793 osmo_init_logging(&info);
1794 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1795 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1796
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001797 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001798 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001799
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001800 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001801 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001802 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001803 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001804 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001805 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001806 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001807 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001808 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001809 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001810 test_gmm_attach_acl();
1811 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001812 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001813 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001814 test_gmm_attach_subscr_gsup_auth(0);
1815 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001816 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001817 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001818 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001819 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001820 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001821
1822 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001823 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001824 return 0;
1825}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001826
1827
1828/* stubs */
1829struct osmo_prim_hdr;
1830int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1831{
1832 abort();
1833}