blob: 34ad6473f6490873d436c375d1c2139fc6896e72 [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,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020049 },
50};
51struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010052unsigned sgsn_tx_counter = 0;
53
54/* override */
55int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
56 struct bssgp_dl_ud_par *dup)
57{
58 sgsn_tx_counter += 1;
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +010059 msgb_free(msg);
Jacob Erlbeck189999d2014-10-27 14:34:13 +010060 return 0;
61}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020062
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010063/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
64void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *, struct gsm_subscriber *);
65void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *, struct gsm_subscriber *) =
66 &__real_sgsn_update_subscriber_data;
67
68void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
69 struct gsm_subscriber *subscr)
70{
71 (*update_subscriber_data_cb)(mmctx, subscr);
72}
73
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010074/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
75int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
76int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
77 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010078
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010079int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
80 return (*subscr_request_update_location_cb)(mmctx);
81};
82
83/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
84int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
85int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
86 &__real_gprs_subscr_request_auth_info;
87
88int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
89 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010090};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010091
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010092/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
93int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
94int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
95 &__real_gprs_gsup_client_send;
96
97int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
98{
99 return (*gprs_gsup_client_send_cb)(gsupc, msg);
100};
101
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200102static int count(struct llist_head *head)
103{
104 struct llist_head *cur;
105 int count = 0;
106
107 llist_for_each(cur, head)
108 count += 1;
109
110 return count;
111}
112
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200113static struct msgb *create_msg(const uint8_t *data, size_t len)
114{
115 struct msgb *msg = msgb_alloc(len + 8, "test message");
116 msg->l1h = msgb_put(msg, 8);
117 msg->l2h = msgb_put(msg, len);
118 memcpy(msg->l2h, data, len);
119
120 msgb_bcid(msg) = msg->l1h;
121 msgb_gmmh(msg) = msg->l2h;
122 return msg;
123}
124
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100125/*
126 * Create a context and search for it
127 */
128static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
129{
130 struct sgsn_mm_ctx *ctx, *ictx;
131 struct gprs_llc_lle *lle;
132 int old_count = count(gprs_llme_list());
133
134 lle = gprs_lle_get_or_create(tlli, 3);
135 ctx = sgsn_mm_ctx_alloc(tlli, raid);
136 ctx->mm_state = GMM_REGISTERED_NORMAL;
137 ctx->llme = lle->llme;
138
139 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
140 OSMO_ASSERT(ictx == ctx);
141
142 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
143
144 return ctx;
145}
146
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100147static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
148 const uint8_t *data, size_t data_len)
149{
150 struct msgb *msg;
151
152 sgsn_tx_counter = 0;
153
154 msg = create_msg(data, data_len);
155 msgb_tlli(msg) = tlli;
156 gsm0408_gprs_rcvmsg(msg, llme);
157 msgb_free(msg);
158}
159
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200160static void test_llme(void)
161{
162 struct gprs_llc_lle *lle, *lle_copy;
163 uint32_t local_tlli;
164 uint32_t foreign_tlli;
165
166 printf("Testing LLME allocations\n");
167 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
168 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
169
170 /* initial state */
171 OSMO_ASSERT(count(gprs_llme_list()) == 0);
172
173 /* Create a new entry */
174 lle = gprs_lle_get_or_create(local_tlli, 3);
175 OSMO_ASSERT(lle);
176 OSMO_ASSERT(count(gprs_llme_list()) == 1);
177
178 /* No new entry is created */
179 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
180 OSMO_ASSERT(lle == lle_copy);
181 OSMO_ASSERT(count(gprs_llme_list()) == 1);
182 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
183 OSMO_ASSERT(lle == lle_copy);
184 OSMO_ASSERT(count(gprs_llme_list()) == 1);
185
186 /* unassign which should delete it*/
187 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
188
189 /* Check that everything was cleaned up */
190 OSMO_ASSERT(count(gprs_llme_list()) == 0);
191}
192
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100193struct gsm_subscriber *last_updated_subscr = NULL;
194void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx,
195 struct gsm_subscriber *subscr)
196{
197 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
198 __func__, mmctx, subscr);
199 last_updated_subscr = subscr;
200}
201
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100202static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
203{
204 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100205 OSMO_ASSERT(subscr);
206 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100207
208 sfound = gprs_subscr_get_by_imsi(imsi);
209 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100210
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100211 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100212}
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, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100220 "use count: %d\n",
221 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100222 }
223}
224
225static void assert_no_subscrs()
226{
227 show_subscrs(stdout);
228 fflush(stdout);
229 OSMO_ASSERT(llist_empty(&active_subscribers));
230}
231
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100232static void test_subscriber(void)
233{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100234 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100235 const char *imsi1 = "1234567890";
236 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100237 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100238
239 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
240
241 printf("Testing core subscriber data API\n");
242
243 /* Check for emptiness */
244 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
245 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100246 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100247
248 /* Allocate entry 1 */
249 s1 = gprs_subscr_get_or_create(imsi1);
250 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100251 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100252 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100253
254 /* Allocate entry 2 */
255 s2 = gprs_subscr_get_or_create(imsi2);
256 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100257
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100258 /* Allocate entry 3 */
259 s3 = gprs_subscr_get_or_create(imsi3);
260
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100261 /* Check entries */
262 assert_subscr(s1, imsi1);
263 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100264 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100265
266 /* Update entry 1 */
267 last_updated_subscr = NULL;
268 gprs_subscr_update(s1);
269 OSMO_ASSERT(last_updated_subscr == s1);
270
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100271 /* There is no subscriber cache. Verify it */
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100272 gprs_subscr_delete(s1);
273 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100274 sfound = gprs_subscr_get_by_imsi(imsi1);
275 OSMO_ASSERT(sfound == NULL);
276
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100277 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100278 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100279
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100280 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100281 gprs_subscr_delete(s2);
282 s2 = NULL;
283 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
284 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100285 assert_subscr(s3, imsi3);
286
287 /* Try to delete entry 3 */
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100288 gprs_subscr_delete(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100289 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100290 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100291
292 OSMO_ASSERT(llist_empty(&active_subscribers));
293
294 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
295}
296
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100297static void test_auth_triplets(void)
298{
299 struct gsm_subscriber *s1, *s1found;
300 const char *imsi1 = "1234567890";
301 struct gsm_auth_tuple *at;
302 struct sgsn_mm_ctx *ctx;
303 struct gprs_ra_id raid = { 0, };
304 uint32_t local_tlli = 0xffeeddcc;
305 struct gprs_llc_llme *llme;
306
307 printf("Testing authentication triplet handling\n");
308
309 /* Check for emptiness */
310 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
311
312 /* Allocate entry 1 */
313 s1 = gprs_subscr_get_or_create(imsi1);
314 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
315 s1found = gprs_subscr_get_by_imsi(imsi1);
316 OSMO_ASSERT(s1found == s1);
317 subscr_put(s1found);
318
319 /* Create a context */
320 OSMO_ASSERT(count(gprs_llme_list()) == 0);
321 ctx = alloc_mm_ctx(local_tlli, &raid);
322
323 /* Attach s1 to ctx */
324 ctx->subscr = subscr_get(s1);
325 ctx->subscr->sgsn_data->mm = ctx;
326
327 /* Try to get auth tuple */
328 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
329 OSMO_ASSERT(at == NULL);
330
331 /* Add triplets */
332 s1->sgsn_data->auth_triplets[0].key_seq = 0;
333 s1->sgsn_data->auth_triplets[1].key_seq = 1;
334 s1->sgsn_data->auth_triplets[2].key_seq = 2;
335
336 /* Try to get auth tuple */
337 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
338 OSMO_ASSERT(at != NULL);
339 OSMO_ASSERT(at->key_seq == 0);
340 OSMO_ASSERT(at->use_count == 1);
341 at = sgsn_auth_get_tuple(ctx, at->key_seq);
342 OSMO_ASSERT(at != NULL);
343 OSMO_ASSERT(at->key_seq == 1);
344 OSMO_ASSERT(at->use_count == 1);
345 at = sgsn_auth_get_tuple(ctx, at->key_seq);
346 OSMO_ASSERT(at != NULL);
347 OSMO_ASSERT(at->key_seq == 2);
348 OSMO_ASSERT(at->use_count == 1);
349 at = sgsn_auth_get_tuple(ctx, at->key_seq);
350 OSMO_ASSERT(at == NULL);
351
352 /* Free MM context and subscriber */
353 subscr_put(s1);
354 llme = ctx->llme;
355 sgsn_mm_ctx_free(ctx);
356 s1found = gprs_subscr_get_by_imsi(imsi1);
357 OSMO_ASSERT(s1found == NULL);
358 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
359}
360
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100361#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
362
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100363static int rx_gsup_message(const uint8_t *data, size_t data_len)
364{
365 struct msgb *msg;
366 int rc;
367
368 msg = msgb_alloc(1024, __func__);
369 msg->l2h = msgb_put(msg, data_len);
370 OSMO_ASSERT(msg->l2h != NULL);
371 memcpy(msg->l2h, data, data_len);
372 rc = gprs_subscr_rx_gsup_message(msg);
373 msgb_free(msg);
374
375 return rc;
376}
377
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100378static void test_subscriber_gsup(void)
379{
380 struct gsm_subscriber *s1, *s1found;
381 const char *imsi1 = "1234567890";
382 struct sgsn_mm_ctx *ctx;
383 struct gprs_ra_id raid = { 0, };
384 uint32_t local_tlli = 0xffeeddcc;
385 struct gprs_llc_llme *llme;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100386 int rc;
387
388 static const uint8_t send_auth_info_res[] = {
389 0x0a,
390 TEST_GSUP_IMSI1_IE,
391 0x03, 0x22, /* Auth tuple */
392 0x20, 0x10,
393 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
394 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
395 0x21, 0x04,
396 0x21, 0x22, 0x23, 0x24,
397 0x22, 0x08,
398 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
399 0x03, 0x22, /* Auth tuple */
400 0x20, 0x10,
401 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
402 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
403 0x21, 0x04,
404 0xa1, 0xa2, 0xa3, 0xa4,
405 0x22, 0x08,
406 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
407 };
408
409 static const uint8_t send_auth_info_err[] = {
410 0x09,
411 TEST_GSUP_IMSI1_IE,
412 0x02, 0x01, 0x07 /* GPRS not allowed */
413 };
414
415 static const uint8_t update_location_res[] = {
416 0x06,
417 TEST_GSUP_IMSI1_IE,
418 0x04, 0x00, /* PDP info complete */
419 0x05, 0x12,
420 0x10, 0x01, 0x01,
421 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
422 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
423 0x05, 0x11,
424 0x10, 0x01, 0x02,
425 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
426 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
427 };
428
429 static const uint8_t update_location_err[] = {
430 0x05,
431 TEST_GSUP_IMSI1_IE,
432 0x02, 0x01, 0x07 /* GPRS not allowed */
433 };
434
435 static const uint8_t location_cancellation_req[] = {
436 0x1c,
437 TEST_GSUP_IMSI1_IE,
438 0x06, 0x01, 0x00,
439 };
440
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100441 static const uint8_t location_cancellation_req_other[] = {
442 0x1c,
443 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
444 0x06, 0x01, 0x00,
445 };
446
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100447 static const uint8_t insert_data_req[] = {
448 0x10,
449 TEST_GSUP_IMSI1_IE,
450 0x05, 0x11,
451 0x10, 0x01, 0x03,
452 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
453 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
454 };
455
456 static const uint8_t delete_data_req[] = {
457 0x14,
458 TEST_GSUP_IMSI1_IE,
459 0x10, 0x01, 0x03,
460 };
461
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100462 printf("Testing subcriber GSUP handling\n");
463
464 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
465
466 /* Check for emptiness */
467 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
468
469 /* Allocate entry 1 */
470 s1 = gprs_subscr_get_or_create(imsi1);
471 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
472 s1found = gprs_subscr_get_by_imsi(imsi1);
473 OSMO_ASSERT(s1found == s1);
474 subscr_put(s1found);
475
476 /* Create a context */
477 OSMO_ASSERT(count(gprs_llme_list()) == 0);
478 ctx = alloc_mm_ctx(local_tlli, &raid);
479 llme = ctx->llme;
480
481 /* Attach s1 to ctx */
482 ctx->subscr = subscr_get(s1);
483 ctx->subscr->sgsn_data->mm = ctx;
484
485 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100486 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100487 OSMO_ASSERT(rc >= 0);
488 OSMO_ASSERT(last_updated_subscr == s1);
489
490 /* Check triplets */
491 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
492 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
493 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
494
495 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100496 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100497 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100498 OSMO_ASSERT(last_updated_subscr == s1);
499
500 /* Check triplets */
501 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
502 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
503 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
504
505 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100506 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100507 OSMO_ASSERT(rc >= 0);
508 OSMO_ASSERT(last_updated_subscr == s1);
509
510 /* Check authorization */
511 OSMO_ASSERT(s1->authorized == 1);
512
513 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100514 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100515 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100516 OSMO_ASSERT(last_updated_subscr == s1);
517
518 /* Check authorization */
519 OSMO_ASSERT(s1->authorized == 0);
520
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100521 /* Inject InsertSubscrData GSUP message */
522 last_updated_subscr = NULL;
523 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
524 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
525 OSMO_ASSERT(last_updated_subscr == NULL);
526
527 /* Inject DeleteSubscrData GSUP message */
528 last_updated_subscr = NULL;
529 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
530 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
531 OSMO_ASSERT(last_updated_subscr == NULL);
532
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100533 /* Inject wrong LocCancelReq GSUP message */
534 last_updated_subscr = NULL;
535 rc = rx_gsup_message(location_cancellation_req_other,
536 sizeof(location_cancellation_req_other));
537 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
538 OSMO_ASSERT(last_updated_subscr == NULL);
539
540 /* Check cancellation result */
541 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
542 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
543
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100544 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100545 rc = rx_gsup_message(location_cancellation_req,
546 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100547 OSMO_ASSERT(rc >= 0);
548 OSMO_ASSERT(last_updated_subscr == s1);
549
550 /* Check cancellation result */
551 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
552 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
553
554 /* Free MM context and subscriber */
555 subscr_put(s1);
556 s1found = gprs_subscr_get_by_imsi(imsi1);
557 OSMO_ASSERT(s1found == NULL);
558 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
559
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100560 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
561 last_updated_subscr = NULL;
562 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100563 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100564 OSMO_ASSERT(last_updated_subscr == NULL);
565
566 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
567 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
568 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
569 OSMO_ASSERT(last_updated_subscr == NULL);
570
571 /* Inject LocCancelReq GSUP message (unknown IMSI) */
572 rc = rx_gsup_message(location_cancellation_req,
573 sizeof(location_cancellation_req));
574 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
575 OSMO_ASSERT(last_updated_subscr == NULL);
576
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100577 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
578}
579
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100580int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
581{
582 msgb_free(msg);
583 return 0;
584};
585
586
587static void test_subscriber_blocking(void)
588{
589 struct gsm_subscriber *s1;
590 const char *imsi1 = "1234567890";
591 struct sgsn_mm_ctx *ctx;
592 struct gprs_ra_id raid = { 0, };
593 uint32_t local_tlli = 0xffeeddcc;
594 struct gprs_llc_llme *llme;
595 int rc;
596
597 printf("Testing subcriber procedure blocking\n");
598
599 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
600 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
601
602 /* Check for emptiness */
603 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
604
605 /* Create a context */
606 OSMO_ASSERT(count(gprs_llme_list()) == 0);
607 ctx = alloc_mm_ctx(local_tlli, &raid);
608 llme = ctx->llme;
609 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
610
611 /* Allocate and attach a subscriber */
612 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
613 assert_subscr(s1, imsi1);
614
615 /* Start SendAuthInfoRequest procedure */
616 rc = gprs_subscr_query_auth_info(s1);
617 /* Not blocking */
618 OSMO_ASSERT(rc == 0);
619
620 /* Start UpdateLocation procedure */
621 rc = gprs_subscr_location_update(s1);
622 /* Blocking */
623 OSMO_ASSERT(rc == 0);
624
625 /* Start PurgeMS procedure */
626 rc = gprs_subscr_purge(s1);
627 /* Not blocking */
628 OSMO_ASSERT(rc == 0);
629 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
630
631 /* Start PurgeMS procedure (retry) */
632 rc = gprs_subscr_purge(s1);
633 /* Not blocking */
634 OSMO_ASSERT(rc == 0);
635
636 /* Start SendAuthInfoRequest procedure */
637 rc = gprs_subscr_query_auth_info(s1);
638 /* Blocking */
639 OSMO_ASSERT(rc == -EAGAIN);
640
641 /* Start UpdateLocation procedure */
642 rc = gprs_subscr_location_update(s1);
643 /* Blocking */
644 OSMO_ASSERT(rc == -EAGAIN);
645
646 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
647 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
648
649 /* Start SendAuthInfoRequest procedure */
650 rc = gprs_subscr_query_auth_info(s1);
651 /* Not blocking */
652 OSMO_ASSERT(rc == 0);
653
654 /* Start UpdateLocation procedure */
655 rc = gprs_subscr_location_update(s1);
656 /* Blocking */
657 OSMO_ASSERT(rc == 0);
658
659 subscr_put(s1);
660 sgsn_mm_ctx_free(ctx);
661 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
662
663 assert_no_subscrs();
664
665 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
666 talloc_free(sgsn->gsup_client);
667 sgsn->gsup_client = NULL;
668}
669
670
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200671/*
672 * Test that a GMM Detach will remove the MMCTX and the
673 * associated LLME.
674 */
675static void test_gmm_detach(void)
676{
677 struct gprs_ra_id raid = { 0, };
678 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200679 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200680
681 printf("Testing GMM detach\n");
682
683 /* DTAP - Detach Request (MO) */
684 /* normal detach, power_off = 0 */
685 static const unsigned char detach_req[] = {
686 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
687 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
688 };
689
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200690 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200691
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100692 /* Create a context */
693 OSMO_ASSERT(count(gprs_llme_list()) == 0);
694 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200695
696 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100697 send_0408_message(ctx->llme, local_tlli,
698 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200699
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100700 /* verify that a single message (hopefully the Detach Accept) has been
701 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100702 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100703
704 /* verify that things are gone */
705 OSMO_ASSERT(count(gprs_llme_list()) == 0);
706 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
707 OSMO_ASSERT(!ictx);
708}
709
710/*
711 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
712 * will not sent a Detach Accept message (power_off = 1)
713 */
714static void test_gmm_detach_power_off(void)
715{
716 struct gprs_ra_id raid = { 0, };
717 struct sgsn_mm_ctx *ctx, *ictx;
718 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100719
720 printf("Testing GMM detach (power off)\n");
721
722 /* DTAP - Detach Request (MO) */
723 /* normal detach, power_off = 1 */
724 static const unsigned char detach_req[] = {
725 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
726 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
727 };
728
729 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
730
731 /* Create a context */
732 OSMO_ASSERT(count(gprs_llme_list()) == 0);
733 ctx = alloc_mm_ctx(local_tlli, &raid);
734
735 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100736 send_0408_message(ctx->llme, local_tlli,
737 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100738
739 /* verify that no message (and therefore no Detach Accept) has been
740 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100741 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100742
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200743 /* verify that things are gone */
744 OSMO_ASSERT(count(gprs_llme_list()) == 0);
745 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200746 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200747}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200748
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200749/*
750 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
751 */
752static void test_gmm_detach_no_mmctx(void)
753{
754 struct gprs_llc_lle *lle;
755 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200756
757 printf("Testing GMM detach (no MMCTX)\n");
758
759 /* DTAP - Detach Request (MO) */
760 /* normal detach, power_off = 0 */
761 static const unsigned char detach_req[] = {
762 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
763 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
764 };
765
766 /* Create an LLME */
767 OSMO_ASSERT(count(gprs_llme_list()) == 0);
768 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
769 lle = gprs_lle_get_or_create(local_tlli, 3);
770
771 OSMO_ASSERT(count(gprs_llme_list()) == 1);
772
773 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100774 send_0408_message(lle->llme, local_tlli,
775 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200776
777 /* verify that the LLME is gone */
778 OSMO_ASSERT(count(gprs_llme_list()) == 0);
779}
780
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100781/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100782 * Test that a single GMM Detach Accept message will not cause the SGSN to send
783 * any message or leave an MM context at the SGSN.
784 */
785static void test_gmm_detach_accept_unexpected(void)
786{
787 struct gprs_llc_lle *lle;
788 uint32_t local_tlli;
789
790 printf("Testing GMM detach accept (unexpected)\n");
791
792 /* DTAP - Detach Accept (MT) */
793 /* normal detach */
794 static const unsigned char detach_acc[] = {
795 0x08, 0x06
796 };
797
798 /* Create an LLME */
799 OSMO_ASSERT(count(gprs_llme_list()) == 0);
800 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
801 lle = gprs_lle_get_or_create(local_tlli, 3);
802
803 /* inject the detach */
804 send_0408_message(lle->llme, local_tlli,
805 detach_acc, ARRAY_SIZE(detach_acc));
806
807 /* verify that no message (and therefore no Status or XID reset) has been
808 * sent by the SGSN */
809 OSMO_ASSERT(sgsn_tx_counter == 0);
810
811 /* verify that things are gone */
812 OSMO_ASSERT(count(gprs_llme_list()) == 0);
813}
814
815/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100816 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
817 */
818static void test_gmm_status_no_mmctx(void)
819{
820 struct gprs_llc_lle *lle;
821 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100822
823 printf("Testing GMM Status (no MMCTX)\n");
824
825 /* DTAP - GMM Status, protocol error */
826 static const unsigned char gmm_status[] = {
827 0x08, 0x20, 0x6f
828 };
829
830 /* Create an LLME */
831 OSMO_ASSERT(count(gprs_llme_list()) == 0);
832 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
833 lle = gprs_lle_get_or_create(local_tlli, 3);
834
835 OSMO_ASSERT(count(gprs_llme_list()) == 1);
836
837 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100838 send_0408_message(lle->llme, local_tlli,
839 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100840
841 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100842 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100843
844 /* verify that the LLME is gone */
845 OSMO_ASSERT(count(gprs_llme_list()) == 0);
846}
847
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100848/*
849 * Test the GMM Attach procedure
850 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100851static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100852{
853 struct gprs_ra_id raid = { 0, };
854 struct sgsn_mm_ctx *ctx = NULL;
855 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100856 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100857 uint32_t foreign_tlli;
858 uint32_t local_tlli = 0;
859 struct gprs_llc_lle *lle;
860
861 /* DTAP - Attach Request */
862 /* The P-TMSI is not known by the SGSN */
863 static const unsigned char attach_req[] = {
864 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
865 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
866 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
867 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
868 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
869 };
870
871 /* DTAP - Identity Response IMEI */
872 static const unsigned char ident_resp_imei[] = {
873 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
874 0x56
875 };
876
877 /* DTAP - Identity Response IMSI */
878 static const unsigned char ident_resp_imsi[] = {
879 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
880 0x54
881 };
882
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100883 /* DTAP - Authentication and Ciphering Resp */
884 static const unsigned char auth_ciph_resp[] = {
885 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
886 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
887 };
888
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100889 /* DTAP - Attach Complete */
890 static const unsigned char attach_compl[] = {
891 0x08, 0x03
892 };
893
894 /* DTAP - Detach Request (MO) */
895 /* normal detach, power_off = 0 */
896 static const unsigned char detach_req[] = {
897 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
898 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
899 };
900
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100901 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100902
903 /* reset the PRNG used by sgsn_alloc_ptmsi */
904 srand(1);
905
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100906 ptmsi1 = sgsn_alloc_ptmsi();
907 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
908
909 /* reset the PRNG, so that the same P-TMSI sequence will be generated
910 * again */
911 srand(1);
912
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100913 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
914
915 /* Create a LLE/LLME */
916 OSMO_ASSERT(count(gprs_llme_list()) == 0);
917 lle = gprs_lle_get_or_create(foreign_tlli, 3);
918 OSMO_ASSERT(count(gprs_llme_list()) == 1);
919
920 /* inject the attach request */
921 send_0408_message(lle->llme, foreign_tlli,
922 attach_req, ARRAY_SIZE(attach_req));
923
924 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
925 OSMO_ASSERT(ctx != NULL);
926 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
927
928 /* we expect an identity request (IMEI) */
929 OSMO_ASSERT(sgsn_tx_counter == 1);
930
931 /* inject the identity response (IMEI) */
932 send_0408_message(ctx->llme, foreign_tlli,
933 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
934
935 /* we expect an identity request (IMSI) */
936 OSMO_ASSERT(sgsn_tx_counter == 1);
937
938 /* inject the identity response (IMSI) */
939 send_0408_message(ctx->llme, foreign_tlli,
940 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
941
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100942 /* check that the MM context has not been removed due to a failed
943 * authorization */
944 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
945
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100946 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100947
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100948retry_attach_req:
949
950 if (retry && sgsn_tx_counter == 0) {
951 fprintf(stderr, "Retrying attach request\n");
952 /* re-inject the attach request */
953 send_0408_message(lle->llme, foreign_tlli,
954 attach_req, ARRAY_SIZE(attach_req));
955 }
956
957 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
958 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100959
960 /* inject the auth & ciph response */
961 send_0408_message(ctx->llme, foreign_tlli,
962 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
963
964 /* check that the MM context has not been removed due to a
965 * failed authorization */
966 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
967 }
968
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100969 if (retry && sgsn_tx_counter == 0)
970 goto retry_attach_req;
971
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100972 /* we expect an attach accept/reject */
973 OSMO_ASSERT(sgsn_tx_counter == 1);
974
975 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100976 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100977
978 /* inject the attach complete */
979 send_0408_message(ctx->llme, local_tlli,
980 attach_compl, ARRAY_SIZE(attach_compl));
981
982 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
983
984 /* we don't expect a response */
985 OSMO_ASSERT(sgsn_tx_counter == 0);
986
987 /* inject the detach */
988 send_0408_message(ctx->llme, local_tlli,
989 detach_req, ARRAY_SIZE(detach_req));
990
991 /* verify that things are gone */
992 OSMO_ASSERT(count(gprs_llme_list()) == 0);
993 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
994 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100995}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100996
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100997static void test_gmm_attach_acl(void)
998{
999 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1000
1001 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1002 sgsn_acl_add("123456789012345", &sgsn->cfg);
1003 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001004 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001005 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001006
1007 sgsn->cfg.auth_policy = saved_auth_policy;
1008}
1009
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001010int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001011 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001012 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001013 if (rc == -ENOTSUP) {
1014 OSMO_ASSERT(mmctx->subscr);
1015 gprs_subscr_update(mmctx->subscr);
1016 }
1017 return rc;
1018};
1019
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001020int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1021 gprs_subscr_update(mmctx->subscr);
1022 return 0;
1023};
1024
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001025static void test_gmm_attach_subscr(void)
1026{
1027 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1028 struct gsm_subscriber *subscr;
1029
1030 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001031 subscr_request_update_location_cb = my_subscr_request_update_location;
1032 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001033
1034 subscr = gprs_subscr_get_or_create("123456789012345");
1035 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001036
1037 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001038 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001039 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001040 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001041
1042 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001043 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1044 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001045}
1046
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001047int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1048{
1049 /* Fake an authentication */
1050 OSMO_ASSERT(mmctx->subscr);
1051 mmctx->is_authenticated = 1;
1052 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001053
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001054 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001055};
1056
1057static void test_gmm_attach_subscr_fake_auth(void)
1058{
1059 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1060 struct gsm_subscriber *subscr;
1061
1062 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001063 subscr_request_update_location_cb = my_subscr_request_update_location;
1064 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001065
1066 subscr = gprs_subscr_get_or_create("123456789012345");
1067 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001068 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001069 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001070
1071 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001072 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001073 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001074 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001075
1076 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001077 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1078 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1079}
1080
1081int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1082{
1083 struct gsm_auth_tuple at = {
1084 .sres = {0x51, 0xe5, 0x51, 0xe5},
1085 .key_seq = 0
1086 };
1087
1088 /* Fake an authentication */
1089 OSMO_ASSERT(mmctx->subscr);
1090 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1091
1092 gprs_subscr_update_auth_info(mmctx->subscr);
1093
1094 return 0;
1095};
1096
1097static void test_gmm_attach_subscr_real_auth(void)
1098{
1099 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1100 struct gsm_subscriber *subscr;
1101
1102 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1103 subscr_request_update_location_cb = my_subscr_request_update_location;
1104 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1105
1106 subscr = gprs_subscr_get_or_create("123456789012345");
1107 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001108 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001109 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001110
1111 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001112
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001113 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001114 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001115 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001116
1117 sgsn->cfg.auth_policy = saved_auth_policy;
1118 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1119 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001120}
1121
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001122#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1123 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1124
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001125static int auth_info_skip = 0;
1126static int upd_loc_skip = 0;
1127
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001128int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1129{
1130 static const uint8_t send_auth_info_res[] = {
1131 0x0a,
1132 TEST_GSUP_IMSI_LONG_IE,
1133 0x03, 0x22, /* Auth tuple */
1134 0x20, 0x10,
1135 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1136 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1137 0x21, 0x04,
1138 0x51, 0xe5, 0x51, 0xe5,
1139 0x22, 0x08,
1140 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1141 };
1142
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001143 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001144
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001145 if (auth_info_skip > 0) {
1146 auth_info_skip -= 1;
1147 return -EAGAIN;
1148 }
1149
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001150 /* Fake an SendAuthInfoRes */
1151 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1152
1153 return 0;
1154};
1155
1156int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1157 static const uint8_t update_location_res[] = {
1158 0x06,
1159 TEST_GSUP_IMSI_LONG_IE,
1160 0x04, 0x00, /* PDP info complete */
1161 0x05, 0x12,
1162 0x10, 0x01, 0x01,
1163 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1164 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1165 };
1166
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001167 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001168
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001169 if (upd_loc_skip > 0) {
1170 upd_loc_skip -= 1;
1171 return -EAGAIN;
1172 }
1173
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001174 /* Fake an UpdateLocRes */
1175 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1176};
1177
1178
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001179static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001180{
1181 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1182 struct gsm_subscriber *subscr;
1183
1184 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1185 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1186 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001187 if (retry) {
1188 upd_loc_skip = 3;
1189 auth_info_skip = 3;
1190 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001191
1192 subscr = gprs_subscr_get_or_create("123456789012345");
1193 subscr->authorized = 1;
1194 sgsn->cfg.require_authentication = 1;
1195 sgsn->cfg.require_update_location = 1;
1196 subscr_put(subscr);
1197
1198 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001199 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001200 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001201
1202 sgsn->cfg.auth_policy = saved_auth_policy;
1203 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1204 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001205 upd_loc_skip = 0;
1206 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001207}
1208
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001209int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1210{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001211 struct gprs_gsup_message to_peer = {0};
1212 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001213 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001214 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001215
1216 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001217 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1218 OSMO_ASSERT(rc >= 0);
1219 OSMO_ASSERT(to_peer.imsi[0] != 0);
1220 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001221
1222 /* This invalidates the pointers in to_peer */
1223 msgb_free(msg);
1224
1225 switch (to_peer.message_type) {
1226 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1227 /* Send UPDATE_LOCATION_RESULT */
1228 return my_subscr_request_update_gsup_auth(NULL);
1229
1230 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1231 /* Send SEND_AUTH_INFO_RESULT */
1232 return my_subscr_request_auth_info_gsup_auth(NULL);
1233
1234 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001235 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1236 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001237
1238 default:
1239 if ((to_peer.message_type & 0b00000011) == 0) {
1240 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001241 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001242 from_peer.message_type = to_peer.message_type + 1;
1243 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1244 break;
1245 }
1246
1247 /* Ignore it */
1248 return 0;
1249 }
1250
1251 reply_msg = gprs_gsup_msgb_alloc();
1252 reply_msg->l2h = reply_msg->data;
1253 gprs_gsup_encode(reply_msg, &from_peer);
1254 gprs_subscr_rx_gsup_message(reply_msg);
1255 msgb_free(reply_msg);
1256
1257 return 0;
1258};
1259
1260static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1261{
1262 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1263 struct gsm_subscriber *subscr;
1264
1265 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001266 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1267
1268 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1269
1270 if (retry) {
1271 upd_loc_skip = 3;
1272 auth_info_skip = 3;
1273 }
1274
1275 printf("Auth policy 'remote', real GSUP based auth: ");
1276 test_gmm_attach(retry);
1277
1278 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001279 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001280 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001281
1282 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001283 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1284 upd_loc_skip = 0;
1285 auth_info_skip = 0;
1286 talloc_free(sgsn->gsup_client);
1287 sgsn->gsup_client = NULL;
1288}
1289
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001290/*
1291 * Test the GMM Rejects
1292 */
1293static void test_gmm_reject(void)
1294{
1295 struct gprs_ra_id raid = { 0, };
1296 struct sgsn_mm_ctx *ctx = NULL;
1297 uint32_t foreign_tlli;
1298 struct gprs_llc_lle *lle;
1299 int idx;
1300
1301 /* DTAP - Attach Request */
1302 /* Invalid MI length */
1303 static const unsigned char attach_req_inv_mi_len[] = {
1304 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1305 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1306 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1307 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1308 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1309 };
1310
1311 /* DTAP - Attach Request */
1312 /* Invalid MI type (IMEI) */
1313 static const unsigned char attach_req_inv_mi_type[] = {
1314 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1315 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1316 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1317 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1318 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1319 };
1320
1321 /* DTAP - Routing Area Update Request */
1322 static const unsigned char dtap_ra_upd_req[] = {
1323 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1324 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1325 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1326 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1327 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1328 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1329 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1330 };
1331
1332 /* DTAP - Routing Area Update Request */
1333 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1334 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1335 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1336 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1337 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1338 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1339 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1340 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1341 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1342 };
1343
1344 /* DTAP - Routing Area Update Request */
1345 /* Invalid cap length */
1346 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1347 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1348 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1349 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1350 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1351 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1352 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1353 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1354 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1355 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1356 };
1357
1358 struct test {
1359 const char *title;
1360 const unsigned char *msg;
1361 unsigned msg_len;
1362 unsigned num_resp;
1363
1364 };
1365 static struct test tests[] = {
1366 {
1367 .title = "Attach Request (invalid MI length)",
1368 .msg = attach_req_inv_mi_len,
1369 .msg_len = sizeof(attach_req_inv_mi_len),
1370 .num_resp = 1 /* Reject */
1371
1372 },
1373 {
1374 .title = "Attach Request (invalid MI type)",
1375 .msg = attach_req_inv_mi_type,
1376 .msg_len = sizeof(attach_req_inv_mi_type),
1377 .num_resp = 1 /* Reject */
1378 },
1379 {
1380 .title = "Routing Area Update Request (valid)",
1381 .msg = dtap_ra_upd_req,
1382 .msg_len = sizeof(dtap_ra_upd_req),
1383 .num_resp = 2 /* XID Reset + Reject */
1384 },
1385 {
1386 .title = "Routing Area Update Request (invalid type)",
1387 .msg = dtap_ra_upd_req_inv_type,
1388 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1389 .num_resp = 1 /* Reject */
1390 },
1391 {
1392 .title = "Routing Area Update Request (invalid CAP length)",
1393 .msg = dtap_ra_upd_req_inv_cap_len,
1394 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1395 .num_resp = 1 /* Reject */
1396 },
1397 };
1398
1399 printf("Testing GMM reject\n");
1400
1401 /* reset the PRNG used by sgsn_alloc_ptmsi */
1402 srand(1);
1403
1404 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1405
1406 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1407
1408 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1409 const struct test *test = &tests[idx];
1410 printf(" - %s\n", test->title);
1411
1412 /* Create a LLE/LLME */
1413 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1414 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1415
1416 /* Inject the Request message */
1417 send_0408_message(lle->llme, foreign_tlli,
1418 test->msg, test->msg_len);
1419
1420 /* We expect a Reject message */
1421 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1422 sgsn_tx_counter, test->num_resp);
1423 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1424
1425 /* verify that LLME/MM are removed */
1426 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1427 OSMO_ASSERT(ctx == NULL);
1428 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1429 }
1430}
1431
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001432/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001433 * Test cancellation of attached MM contexts
1434 */
1435static void test_gmm_cancel(void)
1436{
1437 struct gprs_ra_id raid = { 0, };
1438 struct sgsn_mm_ctx *ctx = NULL;
1439 struct sgsn_mm_ctx *ictx;
1440 uint32_t ptmsi1;
1441 uint32_t foreign_tlli;
1442 uint32_t local_tlli = 0;
1443 struct gprs_llc_lle *lle;
1444 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1445
1446 /* DTAP - Attach Request */
1447 /* The P-TMSI is not known by the SGSN */
1448 static const unsigned char attach_req[] = {
1449 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1450 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1451 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1452 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1453 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1454 };
1455
1456 /* DTAP - Identity Response IMEI */
1457 static const unsigned char ident_resp_imei[] = {
1458 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1459 0x56
1460 };
1461
1462 /* DTAP - Identity Response IMSI */
1463 static const unsigned char ident_resp_imsi[] = {
1464 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1465 0x54
1466 };
1467
1468 /* DTAP - Attach Complete */
1469 static const unsigned char attach_compl[] = {
1470 0x08, 0x03
1471 };
1472
1473 printf("Testing cancellation\n");
1474
1475 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1476
1477 /* reset the PRNG used by sgsn_alloc_ptmsi */
1478 srand(1);
1479
1480 ptmsi1 = sgsn_alloc_ptmsi();
1481 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1482
1483 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1484 * again */
1485 srand(1);
1486
1487 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1488
1489 /* Create a LLE/LLME */
1490 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1491 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1492 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1493
1494 /* inject the attach request */
1495 send_0408_message(lle->llme, foreign_tlli,
1496 attach_req, ARRAY_SIZE(attach_req));
1497
1498 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1499 OSMO_ASSERT(ctx != NULL);
1500 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1501
1502 /* we expect an identity request (IMEI) */
1503 OSMO_ASSERT(sgsn_tx_counter == 1);
1504
1505 /* inject the identity response (IMEI) */
1506 send_0408_message(ctx->llme, foreign_tlli,
1507 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1508
1509 /* we expect an identity request (IMSI) */
1510 OSMO_ASSERT(sgsn_tx_counter == 1);
1511
1512 /* inject the identity response (IMSI) */
1513 send_0408_message(ctx->llme, foreign_tlli,
1514 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1515
1516 /* check that the MM context has not been removed due to a failed
1517 * authorization */
1518 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1519
1520 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1521
1522 /* we expect an attach accept/reject */
1523 OSMO_ASSERT(sgsn_tx_counter == 1);
1524
1525 /* this has been randomly assigned by the SGSN */
1526 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1527
1528 /* inject the attach complete */
1529 send_0408_message(ctx->llme, local_tlli,
1530 attach_compl, ARRAY_SIZE(attach_compl));
1531
1532 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1533
1534 /* we don't expect a response */
1535 OSMO_ASSERT(sgsn_tx_counter == 0);
1536
1537 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001538 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001539
1540 /* verify that things are gone */
1541 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1542 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1543 OSMO_ASSERT(!ictx);
1544
1545 sgsn->cfg.auth_policy = saved_auth_policy;
1546}
1547
1548/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001549 * Test the dynamic allocation of P-TMSIs
1550 */
1551static void test_gmm_ptmsi_allocation(void)
1552{
1553 struct gprs_ra_id raid = { 0, };
1554 struct sgsn_mm_ctx *ctx = NULL;
1555 struct sgsn_mm_ctx *ictx;
1556 uint32_t foreign_tlli;
1557 uint32_t ptmsi1;
1558 uint32_t ptmsi2;
1559 uint32_t old_ptmsi;
1560 uint32_t local_tlli = 0;
1561 struct gprs_llc_lle *lle;
1562 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1563
1564 /* DTAP - Attach Request (IMSI 12131415161718) */
1565 static const unsigned char attach_req[] = {
1566 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1567 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1568 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1569 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1570 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1571 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1572 0x00,
1573 };
1574
1575 /* DTAP - Identity Response IMEI */
1576 static const unsigned char ident_resp_imei[] = {
1577 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1578 0x56
1579 };
1580
1581 /* DTAP - Attach Complete */
1582 static const unsigned char attach_compl[] = {
1583 0x08, 0x03
1584 };
1585
1586 /* DTAP - Routing Area Update Request */
1587 static const unsigned char ra_upd_req[] = {
1588 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1589 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1590 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1591 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1592 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1593 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1594 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1595 };
1596
1597 /* DTAP - Routing Area Update Complete */
1598 static const unsigned char ra_upd_complete[] = {
1599 0x08, 0x0a
1600 };
1601
1602 /* DTAP - Detach Request (MO) */
1603 /* normal detach, power_off = 1 */
1604 static const unsigned char detach_req[] = {
1605 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1606 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1607 };
1608
1609 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1610
1611 printf("Testing P-TMSI allocation\n");
1612
1613 printf(" - sgsn_alloc_ptmsi\n");
1614
1615 /* reset the PRNG used by sgsn_alloc_ptmsi */
1616 srand(1);
1617
1618 ptmsi1 = sgsn_alloc_ptmsi();
1619 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1620
1621 ptmsi2 = sgsn_alloc_ptmsi();
1622 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1623
1624 OSMO_ASSERT(ptmsi1 != ptmsi2);
1625
1626 printf(" - Repeated Attach Request\n");
1627
1628 /* reset the PRNG, so that the same P-TMSI will be generated
1629 * again */
1630 srand(1);
1631
1632 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1633
1634 /* Create a LLE/LLME */
1635 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1636 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1637 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1638
1639 /* inject the attach request */
1640 send_0408_message(lle->llme, foreign_tlli,
1641 attach_req, ARRAY_SIZE(attach_req));
1642
1643 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1644 OSMO_ASSERT(ctx != NULL);
1645 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1646 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1647
1648 old_ptmsi = ctx->p_tmsi_old;
1649
1650 /* we expect an identity request (IMEI) */
1651 OSMO_ASSERT(sgsn_tx_counter == 1);
1652
1653 /* inject the identity response (IMEI) */
1654 send_0408_message(ctx->llme, foreign_tlli,
1655 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1656
1657 /* check that the MM context has not been removed due to a failed
1658 * authorization */
1659 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1660
1661 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1662 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1663
1664 /* we expect an attach accept */
1665 OSMO_ASSERT(sgsn_tx_counter == 1);
1666
1667 /* we ignore this and send the attach again */
1668 send_0408_message(lle->llme, foreign_tlli,
1669 attach_req, ARRAY_SIZE(attach_req));
1670
1671 /* the allocated P-TMSI should be the same */
1672 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1673 OSMO_ASSERT(ctx != NULL);
1674 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1675 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1676 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1677
1678 /* inject the attach complete */
1679 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1680 send_0408_message(ctx->llme, local_tlli,
1681 attach_compl, ARRAY_SIZE(attach_compl));
1682
1683 /* we don't expect a response */
1684 OSMO_ASSERT(sgsn_tx_counter == 0);
1685
1686 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1687 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1688 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1689
1690 printf(" - Repeated RA Update Request\n");
1691
1692 /* inject the RA update request */
1693 send_0408_message(ctx->llme, local_tlli,
1694 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1695
1696 /* we expect an RA update accept */
1697 OSMO_ASSERT(sgsn_tx_counter == 1);
1698
1699 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1700 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1701 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1702
1703 /* repeat the RA update request */
1704 send_0408_message(ctx->llme, local_tlli,
1705 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1706
1707 /* we expect an RA update accept */
1708 OSMO_ASSERT(sgsn_tx_counter == 1);
1709
1710 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1711 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1712 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1713
1714 /* inject the RA update complete */
1715 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1716 send_0408_message(ctx->llme, local_tlli,
1717 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1718
1719 /* we don't expect a response */
1720 OSMO_ASSERT(sgsn_tx_counter == 0);
1721
1722 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1723 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1724 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1725
1726 /* inject the detach */
1727 send_0408_message(ctx->llme, local_tlli,
1728 detach_req, ARRAY_SIZE(detach_req));
1729
1730 /* verify that things are gone */
1731 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1732 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1733 OSMO_ASSERT(!ictx);
1734
1735 sgsn->cfg.auth_policy = saved_auth_policy;
1736}
1737
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001738static struct log_info_cat gprs_categories[] = {
1739 [DMM] = {
1740 .name = "DMM",
1741 .description = "Layer3 Mobility Management (MM)",
1742 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001743 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001744 },
1745 [DPAG] = {
1746 .name = "DPAG",
1747 .description = "Paging Subsystem",
1748 .color = "\033[1;38m",
1749 .enabled = 1, .loglevel = LOGL_NOTICE,
1750 },
1751 [DMEAS] = {
1752 .name = "DMEAS",
1753 .description = "Radio Measurement Processing",
1754 .enabled = 0, .loglevel = LOGL_NOTICE,
1755 },
1756 [DREF] = {
1757 .name = "DREF",
1758 .description = "Reference Counting",
1759 .enabled = 0, .loglevel = LOGL_NOTICE,
1760 },
1761 [DGPRS] = {
1762 .name = "DGPRS",
1763 .description = "GPRS Packet Service",
1764 .enabled = 1, .loglevel = LOGL_DEBUG,
1765 },
1766 [DNS] = {
1767 .name = "DNS",
1768 .description = "GPRS Network Service (NS)",
1769 .enabled = 1, .loglevel = LOGL_INFO,
1770 },
1771 [DBSSGP] = {
1772 .name = "DBSSGP",
1773 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1774 .enabled = 1, .loglevel = LOGL_DEBUG,
1775 },
1776 [DLLC] = {
1777 .name = "DLLC",
1778 .description = "GPRS Logical Link Control Protocol (LLC)",
1779 .enabled = 1, .loglevel = LOGL_DEBUG,
1780 },
1781 [DSNDCP] = {
1782 .name = "DSNDCP",
1783 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1784 .enabled = 1, .loglevel = LOGL_DEBUG,
1785 },
1786};
1787
1788static struct log_info info = {
1789 .cat = gprs_categories,
1790 .num_cat = ARRAY_SIZE(gprs_categories),
1791};
1792
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001793int main(int argc, char **argv)
1794{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001795 osmo_init_logging(&info);
1796 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1797 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1798
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001799 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001800 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001801
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001802 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001803 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001804 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001805 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001806 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001807 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001808 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001809 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001810 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001811 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001812 test_gmm_attach_acl();
1813 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001814 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001815 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001816 test_gmm_attach_subscr_gsup_auth(0);
1817 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001818 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001819 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001820 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001821 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001822 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001823
1824 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001825 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001826 return 0;
1827}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001828
1829
1830/* stubs */
1831struct osmo_prim_hdr;
1832int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1833{
1834 abort();
1835}