blob: 1ae94b0dd735959b369b89e90da247e385faff43 [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;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100206 OSMO_ASSERT(subscr);
207 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100208
209 sfound = gprs_subscr_get_by_imsi(imsi);
210 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100211
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100212 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100213}
214
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100215static void show_subscrs(FILE *out)
216{
217 struct gsm_subscriber *subscr;
218
219 llist_for_each_entry(subscr, &active_subscribers, entry) {
220 fprintf(out, " Subscriber: %s, "
221 "use count: %d, keep: %d, timer: %d\n",
222 subscr->imsi, subscr->use_count, subscr->keep_in_ram,
223 osmo_timer_pending(&subscr->sgsn_data->timer));
224 }
225}
226
227static void assert_no_subscrs()
228{
229 show_subscrs(stdout);
230 fflush(stdout);
231 OSMO_ASSERT(llist_empty(&active_subscribers));
232}
233
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100234static void test_subscriber(void)
235{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100236 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100237 const char *imsi1 = "1234567890";
238 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100239 const char *imsi3 = "5656565656";
240 int saved_expiry_timeout = sgsn->cfg.subscriber_expiry_timeout;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100241
242 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
243
244 printf("Testing core subscriber data API\n");
245
246 /* Check for emptiness */
247 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
248 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100249 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100250
251 /* Allocate entry 1 */
252 s1 = gprs_subscr_get_or_create(imsi1);
253 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100254 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100255 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100256
257 /* Allocate entry 2 */
258 s2 = gprs_subscr_get_or_create(imsi2);
259 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100260
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100261 /* Allocate entry 3 */
262 s3 = gprs_subscr_get_or_create(imsi3);
263
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100264 /* Check entries */
265 assert_subscr(s1, imsi1);
266 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100267 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100268
269 /* Update entry 1 */
270 last_updated_subscr = NULL;
271 gprs_subscr_update(s1);
272 OSMO_ASSERT(last_updated_subscr == s1);
273
274 /* Because of the update, it won't be freed on delete now */
275 gprs_subscr_delete(s1);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100276 sfound = gprs_subscr_get_by_imsi(imsi1);
277 OSMO_ASSERT(sfound != NULL);
278 s1 = sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100279
280 /* Cancel it, so that delete will free it.
281 * Refcount it to make sure s1 won't be freed here */
282 last_updated_subscr = NULL;
283 gprs_subscr_put_and_cancel(subscr_get(s1));
284 OSMO_ASSERT(last_updated_subscr == s1);
285
286 /* Cancelled entries are still being found */
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100287 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100288
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100289 /* Free entry 1 (GPRS_SUBSCRIBER_CANCELLED is set) */
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100290 gprs_subscr_delete(s1);
291 s1 = NULL;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100292 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100293 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100294 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100295
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100296 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100297 gprs_subscr_delete(s2);
298 s2 = NULL;
299 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
300 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100301 assert_subscr(s3, imsi3);
302
303 /* Try to delete entry 3 */
304 OSMO_ASSERT(sgsn->cfg.subscriber_expiry_timeout == SGSN_TIMEOUT_NEVER);
305 gprs_subscr_delete(s3);
306 assert_subscr(s3, imsi3);
307 /* Process timeouts, this shouldn't delete s3 (SGSN_TIMEOUT_NEVER) */
308 osmo_timers_update();
309 assert_subscr(s3, imsi3);
310 s3 = subscr_get(s3);
311
312 /* Free entry 3 (TIMEOUT == 0) */
313 sgsn->cfg.subscriber_expiry_timeout = 0;
314 gprs_subscr_delete(s3);
315 assert_subscr(s3, imsi3);
316 /* Process timeouts, this should delete s3 */
317 osmo_timers_update();
318 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
319 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
320 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
321 sgsn->cfg.subscriber_expiry_timeout = saved_expiry_timeout;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100322
323 OSMO_ASSERT(llist_empty(&active_subscribers));
324
325 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
326}
327
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100328static void test_auth_triplets(void)
329{
330 struct gsm_subscriber *s1, *s1found;
331 const char *imsi1 = "1234567890";
332 struct gsm_auth_tuple *at;
333 struct sgsn_mm_ctx *ctx;
334 struct gprs_ra_id raid = { 0, };
335 uint32_t local_tlli = 0xffeeddcc;
336 struct gprs_llc_llme *llme;
337
338 printf("Testing authentication triplet handling\n");
339
340 /* Check for emptiness */
341 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
342
343 /* Allocate entry 1 */
344 s1 = gprs_subscr_get_or_create(imsi1);
345 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
346 s1found = gprs_subscr_get_by_imsi(imsi1);
347 OSMO_ASSERT(s1found == s1);
348 subscr_put(s1found);
349
350 /* Create a context */
351 OSMO_ASSERT(count(gprs_llme_list()) == 0);
352 ctx = alloc_mm_ctx(local_tlli, &raid);
353
354 /* Attach s1 to ctx */
355 ctx->subscr = subscr_get(s1);
356 ctx->subscr->sgsn_data->mm = ctx;
357
358 /* Try to get auth tuple */
359 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
360 OSMO_ASSERT(at == NULL);
361
362 /* Add triplets */
363 s1->sgsn_data->auth_triplets[0].key_seq = 0;
364 s1->sgsn_data->auth_triplets[1].key_seq = 1;
365 s1->sgsn_data->auth_triplets[2].key_seq = 2;
366
367 /* Try to get auth tuple */
368 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
369 OSMO_ASSERT(at != NULL);
370 OSMO_ASSERT(at->key_seq == 0);
371 OSMO_ASSERT(at->use_count == 1);
372 at = sgsn_auth_get_tuple(ctx, at->key_seq);
373 OSMO_ASSERT(at != NULL);
374 OSMO_ASSERT(at->key_seq == 1);
375 OSMO_ASSERT(at->use_count == 1);
376 at = sgsn_auth_get_tuple(ctx, at->key_seq);
377 OSMO_ASSERT(at != NULL);
378 OSMO_ASSERT(at->key_seq == 2);
379 OSMO_ASSERT(at->use_count == 1);
380 at = sgsn_auth_get_tuple(ctx, at->key_seq);
381 OSMO_ASSERT(at == NULL);
382
383 /* Free MM context and subscriber */
384 subscr_put(s1);
385 llme = ctx->llme;
386 sgsn_mm_ctx_free(ctx);
387 s1found = gprs_subscr_get_by_imsi(imsi1);
388 OSMO_ASSERT(s1found == NULL);
389 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
390}
391
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100392#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
393
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100394static int rx_gsup_message(const uint8_t *data, size_t data_len)
395{
396 struct msgb *msg;
397 int rc;
398
399 msg = msgb_alloc(1024, __func__);
400 msg->l2h = msgb_put(msg, data_len);
401 OSMO_ASSERT(msg->l2h != NULL);
402 memcpy(msg->l2h, data, data_len);
403 rc = gprs_subscr_rx_gsup_message(msg);
404 msgb_free(msg);
405
406 return rc;
407}
408
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100409static void test_subscriber_gsup(void)
410{
411 struct gsm_subscriber *s1, *s1found;
412 const char *imsi1 = "1234567890";
413 struct sgsn_mm_ctx *ctx;
414 struct gprs_ra_id raid = { 0, };
415 uint32_t local_tlli = 0xffeeddcc;
416 struct gprs_llc_llme *llme;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100417 int rc;
418
419 static const uint8_t send_auth_info_res[] = {
420 0x0a,
421 TEST_GSUP_IMSI1_IE,
422 0x03, 0x22, /* Auth tuple */
423 0x20, 0x10,
424 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
425 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
426 0x21, 0x04,
427 0x21, 0x22, 0x23, 0x24,
428 0x22, 0x08,
429 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
430 0x03, 0x22, /* Auth tuple */
431 0x20, 0x10,
432 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
433 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
434 0x21, 0x04,
435 0xa1, 0xa2, 0xa3, 0xa4,
436 0x22, 0x08,
437 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
438 };
439
440 static const uint8_t send_auth_info_err[] = {
441 0x09,
442 TEST_GSUP_IMSI1_IE,
443 0x02, 0x01, 0x07 /* GPRS not allowed */
444 };
445
446 static const uint8_t update_location_res[] = {
447 0x06,
448 TEST_GSUP_IMSI1_IE,
449 0x04, 0x00, /* PDP info complete */
450 0x05, 0x12,
451 0x10, 0x01, 0x01,
452 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
453 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
454 0x05, 0x11,
455 0x10, 0x01, 0x02,
456 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
457 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
458 };
459
460 static const uint8_t update_location_err[] = {
461 0x05,
462 TEST_GSUP_IMSI1_IE,
463 0x02, 0x01, 0x07 /* GPRS not allowed */
464 };
465
466 static const uint8_t location_cancellation_req[] = {
467 0x1c,
468 TEST_GSUP_IMSI1_IE,
469 0x06, 0x01, 0x00,
470 };
471
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100472 static const uint8_t location_cancellation_req_other[] = {
473 0x1c,
474 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
475 0x06, 0x01, 0x00,
476 };
477
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100478 static const uint8_t insert_data_req[] = {
479 0x10,
480 TEST_GSUP_IMSI1_IE,
481 0x05, 0x11,
482 0x10, 0x01, 0x03,
483 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
484 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
485 };
486
487 static const uint8_t delete_data_req[] = {
488 0x14,
489 TEST_GSUP_IMSI1_IE,
490 0x10, 0x01, 0x03,
491 };
492
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100493 printf("Testing subcriber GSUP handling\n");
494
495 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
496
497 /* Check for emptiness */
498 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
499
500 /* Allocate entry 1 */
501 s1 = gprs_subscr_get_or_create(imsi1);
502 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
503 s1found = gprs_subscr_get_by_imsi(imsi1);
504 OSMO_ASSERT(s1found == s1);
505 subscr_put(s1found);
506
507 /* Create a context */
508 OSMO_ASSERT(count(gprs_llme_list()) == 0);
509 ctx = alloc_mm_ctx(local_tlli, &raid);
510 llme = ctx->llme;
511
512 /* Attach s1 to ctx */
513 ctx->subscr = subscr_get(s1);
514 ctx->subscr->sgsn_data->mm = ctx;
515
516 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100517 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100518 OSMO_ASSERT(rc >= 0);
519 OSMO_ASSERT(last_updated_subscr == s1);
520
521 /* Check triplets */
522 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
523 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
524 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
525
526 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100527 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100528 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100529 OSMO_ASSERT(last_updated_subscr == s1);
530
531 /* Check triplets */
532 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
533 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
534 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
535
536 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100537 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100538 OSMO_ASSERT(rc >= 0);
539 OSMO_ASSERT(last_updated_subscr == s1);
540
541 /* Check authorization */
542 OSMO_ASSERT(s1->authorized == 1);
543
544 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100545 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100546 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100547 OSMO_ASSERT(last_updated_subscr == s1);
548
549 /* Check authorization */
550 OSMO_ASSERT(s1->authorized == 0);
551
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100552 /* Inject InsertSubscrData GSUP message */
553 last_updated_subscr = NULL;
554 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
555 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
556 OSMO_ASSERT(last_updated_subscr == NULL);
557
558 /* Inject DeleteSubscrData GSUP message */
559 last_updated_subscr = NULL;
560 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
561 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
562 OSMO_ASSERT(last_updated_subscr == NULL);
563
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100564 /* Inject wrong LocCancelReq GSUP message */
565 last_updated_subscr = NULL;
566 rc = rx_gsup_message(location_cancellation_req_other,
567 sizeof(location_cancellation_req_other));
568 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
569 OSMO_ASSERT(last_updated_subscr == NULL);
570
571 /* Check cancellation result */
572 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
573 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
574
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100575 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100576 rc = rx_gsup_message(location_cancellation_req,
577 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100578 OSMO_ASSERT(rc >= 0);
579 OSMO_ASSERT(last_updated_subscr == s1);
580
581 /* Check cancellation result */
582 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
583 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
584
585 /* Free MM context and subscriber */
586 subscr_put(s1);
587 s1found = gprs_subscr_get_by_imsi(imsi1);
588 OSMO_ASSERT(s1found == NULL);
589 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
590
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100591 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
592 last_updated_subscr = NULL;
593 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100594 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100595 OSMO_ASSERT(last_updated_subscr == NULL);
596
597 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
598 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
599 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
600 OSMO_ASSERT(last_updated_subscr == NULL);
601
602 /* Inject LocCancelReq GSUP message (unknown IMSI) */
603 rc = rx_gsup_message(location_cancellation_req,
604 sizeof(location_cancellation_req));
605 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
606 OSMO_ASSERT(last_updated_subscr == NULL);
607
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100608 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
609}
610
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100611int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
612{
613 msgb_free(msg);
614 return 0;
615};
616
617
618static void test_subscriber_blocking(void)
619{
620 struct gsm_subscriber *s1;
621 const char *imsi1 = "1234567890";
622 struct sgsn_mm_ctx *ctx;
623 struct gprs_ra_id raid = { 0, };
624 uint32_t local_tlli = 0xffeeddcc;
625 struct gprs_llc_llme *llme;
626 int rc;
627
628 printf("Testing subcriber procedure blocking\n");
629
630 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
631 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
632
633 /* Check for emptiness */
634 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
635
636 /* Create a context */
637 OSMO_ASSERT(count(gprs_llme_list()) == 0);
638 ctx = alloc_mm_ctx(local_tlli, &raid);
639 llme = ctx->llme;
640 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
641
642 /* Allocate and attach a subscriber */
643 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
644 assert_subscr(s1, imsi1);
645
646 /* Start SendAuthInfoRequest procedure */
647 rc = gprs_subscr_query_auth_info(s1);
648 /* Not blocking */
649 OSMO_ASSERT(rc == 0);
650
651 /* Start UpdateLocation procedure */
652 rc = gprs_subscr_location_update(s1);
653 /* Blocking */
654 OSMO_ASSERT(rc == 0);
655
656 /* Start PurgeMS procedure */
657 rc = gprs_subscr_purge(s1);
658 /* Not blocking */
659 OSMO_ASSERT(rc == 0);
660 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
661
662 /* Start PurgeMS procedure (retry) */
663 rc = gprs_subscr_purge(s1);
664 /* Not blocking */
665 OSMO_ASSERT(rc == 0);
666
667 /* Start SendAuthInfoRequest procedure */
668 rc = gprs_subscr_query_auth_info(s1);
669 /* Blocking */
670 OSMO_ASSERT(rc == -EAGAIN);
671
672 /* Start UpdateLocation procedure */
673 rc = gprs_subscr_location_update(s1);
674 /* Blocking */
675 OSMO_ASSERT(rc == -EAGAIN);
676
677 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
678 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
679
680 /* Start SendAuthInfoRequest procedure */
681 rc = gprs_subscr_query_auth_info(s1);
682 /* Not blocking */
683 OSMO_ASSERT(rc == 0);
684
685 /* Start UpdateLocation procedure */
686 rc = gprs_subscr_location_update(s1);
687 /* Blocking */
688 OSMO_ASSERT(rc == 0);
689
690 subscr_put(s1);
691 sgsn_mm_ctx_free(ctx);
692 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
693
694 assert_no_subscrs();
695
696 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
697 talloc_free(sgsn->gsup_client);
698 sgsn->gsup_client = NULL;
699}
700
701
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200702/*
703 * Test that a GMM Detach will remove the MMCTX and the
704 * associated LLME.
705 */
706static void test_gmm_detach(void)
707{
708 struct gprs_ra_id raid = { 0, };
709 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200710 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200711
712 printf("Testing GMM detach\n");
713
714 /* DTAP - Detach Request (MO) */
715 /* normal detach, power_off = 0 */
716 static const unsigned char detach_req[] = {
717 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
718 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
719 };
720
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200721 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200722
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100723 /* Create a context */
724 OSMO_ASSERT(count(gprs_llme_list()) == 0);
725 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200726
727 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100728 send_0408_message(ctx->llme, local_tlli,
729 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200730
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100731 /* verify that a single message (hopefully the Detach Accept) has been
732 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100733 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100734
735 /* verify that things are gone */
736 OSMO_ASSERT(count(gprs_llme_list()) == 0);
737 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
738 OSMO_ASSERT(!ictx);
739}
740
741/*
742 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
743 * will not sent a Detach Accept message (power_off = 1)
744 */
745static void test_gmm_detach_power_off(void)
746{
747 struct gprs_ra_id raid = { 0, };
748 struct sgsn_mm_ctx *ctx, *ictx;
749 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100750
751 printf("Testing GMM detach (power off)\n");
752
753 /* DTAP - Detach Request (MO) */
754 /* normal detach, power_off = 1 */
755 static const unsigned char detach_req[] = {
756 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
757 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
758 };
759
760 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
761
762 /* Create a context */
763 OSMO_ASSERT(count(gprs_llme_list()) == 0);
764 ctx = alloc_mm_ctx(local_tlli, &raid);
765
766 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100767 send_0408_message(ctx->llme, local_tlli,
768 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100769
770 /* verify that no message (and therefore no Detach Accept) has been
771 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100772 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100773
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200774 /* verify that things are gone */
775 OSMO_ASSERT(count(gprs_llme_list()) == 0);
776 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200777 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200778}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200779
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200780/*
781 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
782 */
783static void test_gmm_detach_no_mmctx(void)
784{
785 struct gprs_llc_lle *lle;
786 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200787
788 printf("Testing GMM detach (no MMCTX)\n");
789
790 /* DTAP - Detach Request (MO) */
791 /* normal detach, power_off = 0 */
792 static const unsigned char detach_req[] = {
793 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
794 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
795 };
796
797 /* Create an LLME */
798 OSMO_ASSERT(count(gprs_llme_list()) == 0);
799 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
800 lle = gprs_lle_get_or_create(local_tlli, 3);
801
802 OSMO_ASSERT(count(gprs_llme_list()) == 1);
803
804 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100805 send_0408_message(lle->llme, local_tlli,
806 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200807
808 /* verify that the LLME is gone */
809 OSMO_ASSERT(count(gprs_llme_list()) == 0);
810}
811
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100812/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100813 * Test that a single GMM Detach Accept message will not cause the SGSN to send
814 * any message or leave an MM context at the SGSN.
815 */
816static void test_gmm_detach_accept_unexpected(void)
817{
818 struct gprs_llc_lle *lle;
819 uint32_t local_tlli;
820
821 printf("Testing GMM detach accept (unexpected)\n");
822
823 /* DTAP - Detach Accept (MT) */
824 /* normal detach */
825 static const unsigned char detach_acc[] = {
826 0x08, 0x06
827 };
828
829 /* Create an LLME */
830 OSMO_ASSERT(count(gprs_llme_list()) == 0);
831 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
832 lle = gprs_lle_get_or_create(local_tlli, 3);
833
834 /* inject the detach */
835 send_0408_message(lle->llme, local_tlli,
836 detach_acc, ARRAY_SIZE(detach_acc));
837
838 /* verify that no message (and therefore no Status or XID reset) has been
839 * sent by the SGSN */
840 OSMO_ASSERT(sgsn_tx_counter == 0);
841
842 /* verify that things are gone */
843 OSMO_ASSERT(count(gprs_llme_list()) == 0);
844}
845
846/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100847 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
848 */
849static void test_gmm_status_no_mmctx(void)
850{
851 struct gprs_llc_lle *lle;
852 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100853
854 printf("Testing GMM Status (no MMCTX)\n");
855
856 /* DTAP - GMM Status, protocol error */
857 static const unsigned char gmm_status[] = {
858 0x08, 0x20, 0x6f
859 };
860
861 /* Create an LLME */
862 OSMO_ASSERT(count(gprs_llme_list()) == 0);
863 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
864 lle = gprs_lle_get_or_create(local_tlli, 3);
865
866 OSMO_ASSERT(count(gprs_llme_list()) == 1);
867
868 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100869 send_0408_message(lle->llme, local_tlli,
870 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100871
872 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100873 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100874
875 /* verify that the LLME is gone */
876 OSMO_ASSERT(count(gprs_llme_list()) == 0);
877}
878
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100879/*
880 * Test the GMM Attach procedure
881 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100882static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100883{
884 struct gprs_ra_id raid = { 0, };
885 struct sgsn_mm_ctx *ctx = NULL;
886 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100887 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100888 uint32_t foreign_tlli;
889 uint32_t local_tlli = 0;
890 struct gprs_llc_lle *lle;
891
892 /* DTAP - Attach Request */
893 /* The P-TMSI is not known by the SGSN */
894 static const unsigned char attach_req[] = {
895 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
896 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
897 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
898 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
899 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
900 };
901
902 /* DTAP - Identity Response IMEI */
903 static const unsigned char ident_resp_imei[] = {
904 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
905 0x56
906 };
907
908 /* DTAP - Identity Response IMSI */
909 static const unsigned char ident_resp_imsi[] = {
910 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
911 0x54
912 };
913
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100914 /* DTAP - Authentication and Ciphering Resp */
915 static const unsigned char auth_ciph_resp[] = {
916 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
917 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
918 };
919
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100920 /* DTAP - Attach Complete */
921 static const unsigned char attach_compl[] = {
922 0x08, 0x03
923 };
924
925 /* DTAP - Detach Request (MO) */
926 /* normal detach, power_off = 0 */
927 static const unsigned char detach_req[] = {
928 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
929 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
930 };
931
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100932 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100933
934 /* reset the PRNG used by sgsn_alloc_ptmsi */
935 srand(1);
936
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100937 ptmsi1 = sgsn_alloc_ptmsi();
938 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
939
940 /* reset the PRNG, so that the same P-TMSI sequence will be generated
941 * again */
942 srand(1);
943
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100944 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
945
946 /* Create a LLE/LLME */
947 OSMO_ASSERT(count(gprs_llme_list()) == 0);
948 lle = gprs_lle_get_or_create(foreign_tlli, 3);
949 OSMO_ASSERT(count(gprs_llme_list()) == 1);
950
951 /* inject the attach request */
952 send_0408_message(lle->llme, foreign_tlli,
953 attach_req, ARRAY_SIZE(attach_req));
954
955 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
956 OSMO_ASSERT(ctx != NULL);
957 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
958
959 /* we expect an identity request (IMEI) */
960 OSMO_ASSERT(sgsn_tx_counter == 1);
961
962 /* inject the identity response (IMEI) */
963 send_0408_message(ctx->llme, foreign_tlli,
964 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
965
966 /* we expect an identity request (IMSI) */
967 OSMO_ASSERT(sgsn_tx_counter == 1);
968
969 /* inject the identity response (IMSI) */
970 send_0408_message(ctx->llme, foreign_tlli,
971 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
972
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100973 /* check that the MM context has not been removed due to a failed
974 * authorization */
975 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
976
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100977 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100978
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100979retry_attach_req:
980
981 if (retry && sgsn_tx_counter == 0) {
982 fprintf(stderr, "Retrying attach request\n");
983 /* re-inject the attach request */
984 send_0408_message(lle->llme, foreign_tlli,
985 attach_req, ARRAY_SIZE(attach_req));
986 }
987
988 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
989 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100990
991 /* inject the auth & ciph response */
992 send_0408_message(ctx->llme, foreign_tlli,
993 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
994
995 /* check that the MM context has not been removed due to a
996 * failed authorization */
997 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
998 }
999
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001000 if (retry && sgsn_tx_counter == 0)
1001 goto retry_attach_req;
1002
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001003 /* we expect an attach accept/reject */
1004 OSMO_ASSERT(sgsn_tx_counter == 1);
1005
1006 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001007 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001008
1009 /* inject the attach complete */
1010 send_0408_message(ctx->llme, local_tlli,
1011 attach_compl, ARRAY_SIZE(attach_compl));
1012
1013 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1014
1015 /* we don't expect a response */
1016 OSMO_ASSERT(sgsn_tx_counter == 0);
1017
1018 /* inject the detach */
1019 send_0408_message(ctx->llme, local_tlli,
1020 detach_req, ARRAY_SIZE(detach_req));
1021
1022 /* verify that things are gone */
1023 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1024 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1025 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001026}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001027
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001028static void test_gmm_attach_acl(void)
1029{
1030 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1031
1032 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1033 sgsn_acl_add("123456789012345", &sgsn->cfg);
1034 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001035 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001036 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001037
1038 sgsn->cfg.auth_policy = saved_auth_policy;
1039}
1040
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001041int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001042 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001043 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001044 if (rc == -ENOTSUP) {
1045 OSMO_ASSERT(mmctx->subscr);
1046 gprs_subscr_update(mmctx->subscr);
1047 }
1048 return rc;
1049};
1050
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001051int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1052 gprs_subscr_update(mmctx->subscr);
1053 return 0;
1054};
1055
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001056static void cleanup_subscr_by_imsi(const char *imsi)
1057{
1058 struct gsm_subscriber *subscr;
1059
1060 subscr = gprs_subscr_get_by_imsi(imsi);
1061 OSMO_ASSERT(subscr != NULL);
Jacob Erlbecke1beb6f2015-01-08 14:13:46 +01001062 subscr->keep_in_ram = 0;
1063 subscr_put(subscr);
1064 subscr = gprs_subscr_get_by_imsi(imsi);
1065 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001066}
1067
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001068static void test_gmm_attach_subscr(void)
1069{
1070 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1071 struct gsm_subscriber *subscr;
1072
1073 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001074 subscr_request_update_location_cb = my_subscr_request_update_location;
1075 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001076
1077 subscr = gprs_subscr_get_or_create("123456789012345");
1078 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001079 subscr->keep_in_ram = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001080 subscr_put(subscr);
1081
1082 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001083 test_gmm_attach(0);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001084
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001085 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001086 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001087
1088 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001089 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1090 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001091}
1092
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001093int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1094{
1095 /* Fake an authentication */
1096 OSMO_ASSERT(mmctx->subscr);
1097 mmctx->is_authenticated = 1;
1098 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001099
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001100 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001101};
1102
1103static void test_gmm_attach_subscr_fake_auth(void)
1104{
1105 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1106 struct gsm_subscriber *subscr;
1107
1108 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001109 subscr_request_update_location_cb = my_subscr_request_update_location;
1110 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001111
1112 subscr = gprs_subscr_get_or_create("123456789012345");
1113 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001114 subscr->keep_in_ram = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001115 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001116 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001117 subscr_put(subscr);
1118
1119 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001120 test_gmm_attach(0);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001121
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001122 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001123 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001124
1125 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001126 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1127 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1128}
1129
1130int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1131{
1132 struct gsm_auth_tuple at = {
1133 .sres = {0x51, 0xe5, 0x51, 0xe5},
1134 .key_seq = 0
1135 };
1136
1137 /* Fake an authentication */
1138 OSMO_ASSERT(mmctx->subscr);
1139 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1140
1141 gprs_subscr_update_auth_info(mmctx->subscr);
1142
1143 return 0;
1144};
1145
1146static void test_gmm_attach_subscr_real_auth(void)
1147{
1148 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1149 struct gsm_subscriber *subscr;
1150
1151 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1152 subscr_request_update_location_cb = my_subscr_request_update_location;
1153 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1154
1155 subscr = gprs_subscr_get_or_create("123456789012345");
1156 subscr->authorized = 1;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +01001157 subscr->keep_in_ram = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001158 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001159 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001160 subscr_put(subscr);
1161
1162 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001163
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001164 test_gmm_attach(0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001165
Jacob Erlbeckd3cde1e2015-01-08 14:08:16 +01001166 cleanup_subscr_by_imsi("123456789012345");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001167 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001168
1169 sgsn->cfg.auth_policy = saved_auth_policy;
1170 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1171 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001172}
1173
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001174#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1175 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1176
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001177static int auth_info_skip = 0;
1178static int upd_loc_skip = 0;
1179
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001180int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1181{
1182 static const uint8_t send_auth_info_res[] = {
1183 0x0a,
1184 TEST_GSUP_IMSI_LONG_IE,
1185 0x03, 0x22, /* Auth tuple */
1186 0x20, 0x10,
1187 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1188 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1189 0x21, 0x04,
1190 0x51, 0xe5, 0x51, 0xe5,
1191 0x22, 0x08,
1192 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1193 };
1194
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001195 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001196
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001197 if (auth_info_skip > 0) {
1198 auth_info_skip -= 1;
1199 return -EAGAIN;
1200 }
1201
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001202 /* Fake an SendAuthInfoRes */
1203 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1204
1205 return 0;
1206};
1207
1208int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1209 static const uint8_t update_location_res[] = {
1210 0x06,
1211 TEST_GSUP_IMSI_LONG_IE,
1212 0x04, 0x00, /* PDP info complete */
1213 0x05, 0x12,
1214 0x10, 0x01, 0x01,
1215 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1216 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1217 };
1218
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001219 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001220
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001221 if (upd_loc_skip > 0) {
1222 upd_loc_skip -= 1;
1223 return -EAGAIN;
1224 }
1225
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001226 /* Fake an UpdateLocRes */
1227 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1228};
1229
1230
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001231static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001232{
1233 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1234 struct gsm_subscriber *subscr;
1235
1236 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1237 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1238 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001239 if (retry) {
1240 upd_loc_skip = 3;
1241 auth_info_skip = 3;
1242 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001243
1244 subscr = gprs_subscr_get_or_create("123456789012345");
1245 subscr->authorized = 1;
1246 sgsn->cfg.require_authentication = 1;
1247 sgsn->cfg.require_update_location = 1;
1248 subscr_put(subscr);
1249
1250 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001251 test_gmm_attach(retry);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001252
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001253 cleanup_subscr_by_imsi("123456789012345");
1254 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001255
1256 sgsn->cfg.auth_policy = saved_auth_policy;
1257 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1258 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001259 upd_loc_skip = 0;
1260 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001261}
1262
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001263int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1264{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001265 struct gprs_gsup_message to_peer = {0};
1266 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001267 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001268 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001269
1270 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001271 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1272 OSMO_ASSERT(rc >= 0);
1273 OSMO_ASSERT(to_peer.imsi[0] != 0);
1274 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001275
1276 /* This invalidates the pointers in to_peer */
1277 msgb_free(msg);
1278
1279 switch (to_peer.message_type) {
1280 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1281 /* Send UPDATE_LOCATION_RESULT */
1282 return my_subscr_request_update_gsup_auth(NULL);
1283
1284 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1285 /* Send SEND_AUTH_INFO_RESULT */
1286 return my_subscr_request_auth_info_gsup_auth(NULL);
1287
1288 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001289 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1290 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001291
1292 default:
1293 if ((to_peer.message_type & 0b00000011) == 0) {
1294 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001295 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001296 from_peer.message_type = to_peer.message_type + 1;
1297 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1298 break;
1299 }
1300
1301 /* Ignore it */
1302 return 0;
1303 }
1304
1305 reply_msg = gprs_gsup_msgb_alloc();
1306 reply_msg->l2h = reply_msg->data;
1307 gprs_gsup_encode(reply_msg, &from_peer);
1308 gprs_subscr_rx_gsup_message(reply_msg);
1309 msgb_free(reply_msg);
1310
1311 return 0;
1312};
1313
1314static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1315{
1316 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1317 struct gsm_subscriber *subscr;
1318
1319 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1320 sgsn_inst.cfg.subscriber_expiry_timeout = 0;
1321 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1322
1323 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1324
1325 if (retry) {
1326 upd_loc_skip = 3;
1327 auth_info_skip = 3;
1328 }
1329
1330 printf("Auth policy 'remote', real GSUP based auth: ");
1331 test_gmm_attach(retry);
1332
1333 subscr = gprs_subscr_get_by_imsi("123456789012345");
1334 OSMO_ASSERT(subscr != NULL);
1335 gprs_subscr_delete(subscr);
1336
1337 osmo_timers_update();
1338
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001339 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001340
1341 sgsn->cfg.auth_policy = saved_auth_policy;
1342 sgsn_inst.cfg.subscriber_expiry_timeout = SGSN_TIMEOUT_NEVER;
1343 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1344 upd_loc_skip = 0;
1345 auth_info_skip = 0;
1346 talloc_free(sgsn->gsup_client);
1347 sgsn->gsup_client = NULL;
1348}
1349
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001350/*
1351 * Test the GMM Rejects
1352 */
1353static void test_gmm_reject(void)
1354{
1355 struct gprs_ra_id raid = { 0, };
1356 struct sgsn_mm_ctx *ctx = NULL;
1357 uint32_t foreign_tlli;
1358 struct gprs_llc_lle *lle;
1359 int idx;
1360
1361 /* DTAP - Attach Request */
1362 /* Invalid MI length */
1363 static const unsigned char attach_req_inv_mi_len[] = {
1364 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1365 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1366 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1367 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1368 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1369 };
1370
1371 /* DTAP - Attach Request */
1372 /* Invalid MI type (IMEI) */
1373 static const unsigned char attach_req_inv_mi_type[] = {
1374 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1375 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1376 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1377 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1378 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1379 };
1380
1381 /* DTAP - Routing Area Update Request */
1382 static const unsigned char dtap_ra_upd_req[] = {
1383 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1384 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1385 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1386 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1387 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1388 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1389 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1390 };
1391
1392 /* DTAP - Routing Area Update Request */
1393 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1394 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1395 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1396 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1397 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1398 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1399 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1400 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1401 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1402 };
1403
1404 /* DTAP - Routing Area Update Request */
1405 /* Invalid cap length */
1406 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1407 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1408 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1409 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1410 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1411 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1412 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1413 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1414 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1415 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1416 };
1417
1418 struct test {
1419 const char *title;
1420 const unsigned char *msg;
1421 unsigned msg_len;
1422 unsigned num_resp;
1423
1424 };
1425 static struct test tests[] = {
1426 {
1427 .title = "Attach Request (invalid MI length)",
1428 .msg = attach_req_inv_mi_len,
1429 .msg_len = sizeof(attach_req_inv_mi_len),
1430 .num_resp = 1 /* Reject */
1431
1432 },
1433 {
1434 .title = "Attach Request (invalid MI type)",
1435 .msg = attach_req_inv_mi_type,
1436 .msg_len = sizeof(attach_req_inv_mi_type),
1437 .num_resp = 1 /* Reject */
1438 },
1439 {
1440 .title = "Routing Area Update Request (valid)",
1441 .msg = dtap_ra_upd_req,
1442 .msg_len = sizeof(dtap_ra_upd_req),
1443 .num_resp = 2 /* XID Reset + Reject */
1444 },
1445 {
1446 .title = "Routing Area Update Request (invalid type)",
1447 .msg = dtap_ra_upd_req_inv_type,
1448 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1449 .num_resp = 1 /* Reject */
1450 },
1451 {
1452 .title = "Routing Area Update Request (invalid CAP length)",
1453 .msg = dtap_ra_upd_req_inv_cap_len,
1454 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1455 .num_resp = 1 /* Reject */
1456 },
1457 };
1458
1459 printf("Testing GMM reject\n");
1460
1461 /* reset the PRNG used by sgsn_alloc_ptmsi */
1462 srand(1);
1463
1464 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1465
1466 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1467
1468 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1469 const struct test *test = &tests[idx];
1470 printf(" - %s\n", test->title);
1471
1472 /* Create a LLE/LLME */
1473 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1474 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1475
1476 /* Inject the Request message */
1477 send_0408_message(lle->llme, foreign_tlli,
1478 test->msg, test->msg_len);
1479
1480 /* We expect a Reject message */
1481 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1482 sgsn_tx_counter, test->num_resp);
1483 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1484
1485 /* verify that LLME/MM are removed */
1486 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1487 OSMO_ASSERT(ctx == NULL);
1488 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1489 }
1490}
1491
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001492/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001493 * Test cancellation of attached MM contexts
1494 */
1495static void test_gmm_cancel(void)
1496{
1497 struct gprs_ra_id raid = { 0, };
1498 struct sgsn_mm_ctx *ctx = NULL;
1499 struct sgsn_mm_ctx *ictx;
1500 uint32_t ptmsi1;
1501 uint32_t foreign_tlli;
1502 uint32_t local_tlli = 0;
1503 struct gprs_llc_lle *lle;
1504 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1505
1506 /* DTAP - Attach Request */
1507 /* The P-TMSI is not known by the SGSN */
1508 static const unsigned char attach_req[] = {
1509 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1510 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1511 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1512 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1513 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1514 };
1515
1516 /* DTAP - Identity Response IMEI */
1517 static const unsigned char ident_resp_imei[] = {
1518 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1519 0x56
1520 };
1521
1522 /* DTAP - Identity Response IMSI */
1523 static const unsigned char ident_resp_imsi[] = {
1524 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1525 0x54
1526 };
1527
1528 /* DTAP - Attach Complete */
1529 static const unsigned char attach_compl[] = {
1530 0x08, 0x03
1531 };
1532
1533 printf("Testing cancellation\n");
1534
1535 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1536
1537 /* reset the PRNG used by sgsn_alloc_ptmsi */
1538 srand(1);
1539
1540 ptmsi1 = sgsn_alloc_ptmsi();
1541 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1542
1543 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1544 * again */
1545 srand(1);
1546
1547 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1548
1549 /* Create a LLE/LLME */
1550 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1551 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1552 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1553
1554 /* inject the attach request */
1555 send_0408_message(lle->llme, foreign_tlli,
1556 attach_req, ARRAY_SIZE(attach_req));
1557
1558 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1559 OSMO_ASSERT(ctx != NULL);
1560 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1561
1562 /* we expect an identity request (IMEI) */
1563 OSMO_ASSERT(sgsn_tx_counter == 1);
1564
1565 /* inject the identity response (IMEI) */
1566 send_0408_message(ctx->llme, foreign_tlli,
1567 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1568
1569 /* we expect an identity request (IMSI) */
1570 OSMO_ASSERT(sgsn_tx_counter == 1);
1571
1572 /* inject the identity response (IMSI) */
1573 send_0408_message(ctx->llme, foreign_tlli,
1574 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1575
1576 /* check that the MM context has not been removed due to a failed
1577 * authorization */
1578 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1579
1580 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1581
1582 /* we expect an attach accept/reject */
1583 OSMO_ASSERT(sgsn_tx_counter == 1);
1584
1585 /* this has been randomly assigned by the SGSN */
1586 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1587
1588 /* inject the attach complete */
1589 send_0408_message(ctx->llme, local_tlli,
1590 attach_compl, ARRAY_SIZE(attach_compl));
1591
1592 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1593
1594 /* we don't expect a response */
1595 OSMO_ASSERT(sgsn_tx_counter == 0);
1596
1597 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001598 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001599
1600 /* verify that things are gone */
1601 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1602 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1603 OSMO_ASSERT(!ictx);
1604
1605 sgsn->cfg.auth_policy = saved_auth_policy;
1606}
1607
1608/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001609 * Test the dynamic allocation of P-TMSIs
1610 */
1611static void test_gmm_ptmsi_allocation(void)
1612{
1613 struct gprs_ra_id raid = { 0, };
1614 struct sgsn_mm_ctx *ctx = NULL;
1615 struct sgsn_mm_ctx *ictx;
1616 uint32_t foreign_tlli;
1617 uint32_t ptmsi1;
1618 uint32_t ptmsi2;
1619 uint32_t old_ptmsi;
1620 uint32_t local_tlli = 0;
1621 struct gprs_llc_lle *lle;
1622 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1623
1624 /* DTAP - Attach Request (IMSI 12131415161718) */
1625 static const unsigned char attach_req[] = {
1626 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1627 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1628 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1629 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1630 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1631 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1632 0x00,
1633 };
1634
1635 /* DTAP - Identity Response IMEI */
1636 static const unsigned char ident_resp_imei[] = {
1637 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1638 0x56
1639 };
1640
1641 /* DTAP - Attach Complete */
1642 static const unsigned char attach_compl[] = {
1643 0x08, 0x03
1644 };
1645
1646 /* DTAP - Routing Area Update Request */
1647 static const unsigned char ra_upd_req[] = {
1648 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1649 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1650 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1651 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1652 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1653 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1654 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1655 };
1656
1657 /* DTAP - Routing Area Update Complete */
1658 static const unsigned char ra_upd_complete[] = {
1659 0x08, 0x0a
1660 };
1661
1662 /* DTAP - Detach Request (MO) */
1663 /* normal detach, power_off = 1 */
1664 static const unsigned char detach_req[] = {
1665 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1666 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1667 };
1668
1669 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1670
1671 printf("Testing P-TMSI allocation\n");
1672
1673 printf(" - sgsn_alloc_ptmsi\n");
1674
1675 /* reset the PRNG used by sgsn_alloc_ptmsi */
1676 srand(1);
1677
1678 ptmsi1 = sgsn_alloc_ptmsi();
1679 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1680
1681 ptmsi2 = sgsn_alloc_ptmsi();
1682 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1683
1684 OSMO_ASSERT(ptmsi1 != ptmsi2);
1685
1686 printf(" - Repeated Attach Request\n");
1687
1688 /* reset the PRNG, so that the same P-TMSI will be generated
1689 * again */
1690 srand(1);
1691
1692 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1693
1694 /* Create a LLE/LLME */
1695 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1696 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1697 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1698
1699 /* inject the attach request */
1700 send_0408_message(lle->llme, foreign_tlli,
1701 attach_req, ARRAY_SIZE(attach_req));
1702
1703 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1704 OSMO_ASSERT(ctx != NULL);
1705 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1706 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1707
1708 old_ptmsi = ctx->p_tmsi_old;
1709
1710 /* we expect an identity request (IMEI) */
1711 OSMO_ASSERT(sgsn_tx_counter == 1);
1712
1713 /* inject the identity response (IMEI) */
1714 send_0408_message(ctx->llme, foreign_tlli,
1715 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1716
1717 /* check that the MM context has not been removed due to a failed
1718 * authorization */
1719 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1720
1721 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1722 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1723
1724 /* we expect an attach accept */
1725 OSMO_ASSERT(sgsn_tx_counter == 1);
1726
1727 /* we ignore this and send the attach again */
1728 send_0408_message(lle->llme, foreign_tlli,
1729 attach_req, ARRAY_SIZE(attach_req));
1730
1731 /* the allocated P-TMSI should be the same */
1732 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1733 OSMO_ASSERT(ctx != NULL);
1734 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1735 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1736 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1737
1738 /* inject the attach complete */
1739 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1740 send_0408_message(ctx->llme, local_tlli,
1741 attach_compl, ARRAY_SIZE(attach_compl));
1742
1743 /* we don't expect a response */
1744 OSMO_ASSERT(sgsn_tx_counter == 0);
1745
1746 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1747 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1748 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1749
1750 printf(" - Repeated RA Update Request\n");
1751
1752 /* inject the RA update request */
1753 send_0408_message(ctx->llme, local_tlli,
1754 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1755
1756 /* we expect an RA update accept */
1757 OSMO_ASSERT(sgsn_tx_counter == 1);
1758
1759 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1760 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1761 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1762
1763 /* repeat the RA update request */
1764 send_0408_message(ctx->llme, local_tlli,
1765 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1766
1767 /* we expect an RA update accept */
1768 OSMO_ASSERT(sgsn_tx_counter == 1);
1769
1770 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1771 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1772 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1773
1774 /* inject the RA update complete */
1775 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1776 send_0408_message(ctx->llme, local_tlli,
1777 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1778
1779 /* we don't expect a response */
1780 OSMO_ASSERT(sgsn_tx_counter == 0);
1781
1782 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1783 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1784 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1785
1786 /* inject the detach */
1787 send_0408_message(ctx->llme, local_tlli,
1788 detach_req, ARRAY_SIZE(detach_req));
1789
1790 /* verify that things are gone */
1791 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1792 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1793 OSMO_ASSERT(!ictx);
1794
1795 sgsn->cfg.auth_policy = saved_auth_policy;
1796}
1797
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001798static struct log_info_cat gprs_categories[] = {
1799 [DMM] = {
1800 .name = "DMM",
1801 .description = "Layer3 Mobility Management (MM)",
1802 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001803 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001804 },
1805 [DPAG] = {
1806 .name = "DPAG",
1807 .description = "Paging Subsystem",
1808 .color = "\033[1;38m",
1809 .enabled = 1, .loglevel = LOGL_NOTICE,
1810 },
1811 [DMEAS] = {
1812 .name = "DMEAS",
1813 .description = "Radio Measurement Processing",
1814 .enabled = 0, .loglevel = LOGL_NOTICE,
1815 },
1816 [DREF] = {
1817 .name = "DREF",
1818 .description = "Reference Counting",
1819 .enabled = 0, .loglevel = LOGL_NOTICE,
1820 },
1821 [DGPRS] = {
1822 .name = "DGPRS",
1823 .description = "GPRS Packet Service",
1824 .enabled = 1, .loglevel = LOGL_DEBUG,
1825 },
1826 [DNS] = {
1827 .name = "DNS",
1828 .description = "GPRS Network Service (NS)",
1829 .enabled = 1, .loglevel = LOGL_INFO,
1830 },
1831 [DBSSGP] = {
1832 .name = "DBSSGP",
1833 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1834 .enabled = 1, .loglevel = LOGL_DEBUG,
1835 },
1836 [DLLC] = {
1837 .name = "DLLC",
1838 .description = "GPRS Logical Link Control Protocol (LLC)",
1839 .enabled = 1, .loglevel = LOGL_DEBUG,
1840 },
1841 [DSNDCP] = {
1842 .name = "DSNDCP",
1843 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1844 .enabled = 1, .loglevel = LOGL_DEBUG,
1845 },
1846};
1847
1848static struct log_info info = {
1849 .cat = gprs_categories,
1850 .num_cat = ARRAY_SIZE(gprs_categories),
1851};
1852
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001853int main(int argc, char **argv)
1854{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001855 osmo_init_logging(&info);
1856 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1857 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1858
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001859 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001860 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001861
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001862 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001863 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001864 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001865 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001866 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001867 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001868 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001869 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001870 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001871 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001872 test_gmm_attach_acl();
1873 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001874 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001875 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001876 test_gmm_attach_subscr_gsup_auth(0);
1877 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001878 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001879 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001880 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001881 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001882 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001883
1884 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001885 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001886 return 0;
1887}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001888
1889
1890/* stubs */
1891struct osmo_prim_hdr;
1892int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1893{
1894 abort();
1895}