blob: e7b74585b3862bcc2477198f6f676960e7a308cc [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>
Harald Welte23d77d52016-04-25 19:07:34 +020027#include <osmocom/gsm/gsup.h>
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010028#include <openbsc/gprs_gsup_client.h>
Jacob Erlbeck277b71e2015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Jacob Erlbeck133e8622015-10-12 19:36:32 +020030#include <openbsc/gprs_gb_parse.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020031
Jacob Erlbeck189999d2014-10-27 14:34:13 +010032#include <osmocom/gprs/gprs_bssgp.h>
33
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020034#include <osmocom/gsm/gsm_utils.h>
35
36#include <osmocom/core/application.h>
37#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010038#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020039
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020040#include <stdio.h>
41
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020042void *tall_bsc_ctx;
43static struct sgsn_instance sgsn_inst = {
44 .config_file = "osmo_sgsn.cfg",
45 .cfg = {
46 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010047 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020048 },
49};
50struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010051unsigned sgsn_tx_counter = 0;
Jacob Erlbeck133e8622015-10-12 19:36:32 +020052struct msgb *last_msg = NULL;
53struct gprs_gb_parse_context last_dl_parse_ctx;
54
55static void reset_last_msg()
56{
57 if (last_msg)
58 msgb_free(last_msg);
59
60 last_msg = NULL;
61 memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx));
62}
Jacob Erlbeck189999d2014-10-27 14:34:13 +010063
Jacob Erlbeckcf151872015-10-12 19:36:31 +020064static void cleanup_test()
65{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020066 reset_last_msg();
67}
68
69static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
70{
71 uint32_t new_ptmsi = GSM_RESERVED_TMSI;
72
73 if (parse_ctx->new_ptmsi_enc)
74 gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
75
76 return new_ptmsi;
Jacob Erlbeckcf151872015-10-12 19:36:31 +020077}
78
Jacob Erlbeck189999d2014-10-27 14:34:13 +010079/* override */
80int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
81 struct bssgp_dl_ud_par *dup)
82{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020083 int rc;
84
85 reset_last_msg();
86
87 last_msg = msg;
88 OSMO_ASSERT(msgb_data(last_msg) != NULL);
89
90 rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg),
91 &last_dl_parse_ctx);
92
93 fprintf(stderr, "Got DL LLC message: %s\n",
94 gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN"));
95
96 OSMO_ASSERT(rc > 0);
97
Jacob Erlbeck189999d2014-10-27 14:34:13 +010098 sgsn_tx_counter += 1;
99 return 0;
100}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200101
Max4011e722016-07-05 15:19:12 +0200102/* override, requires '-Wl,--wrap=RAND_bytes' */
103int __real_RAND_bytes(unsigned char *buf, int num);
104int mock_RAND_bytes(unsigned char *buf, int num);
105int (*RAND_bytes_cb)(unsigned char *, int) =
106 &mock_RAND_bytes;
107
108int __wrap_RAND_bytes(unsigned char *buf, int num)
109{
110 return (*RAND_bytes_cb)(buf, num);
111}
112/* make results of A&C ref predictable */
113int mock_RAND_bytes(unsigned char *buf, int num)
114{
115 if (num > 1)
116 return __real_RAND_bytes(buf, num);
117 buf[0] = 0;
118 return 1;
119}
120
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100121/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100122void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
123void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100124 &__real_sgsn_update_subscriber_data;
125
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100126void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100127{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100128 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100129}
130
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100131/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
132int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
133int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
134 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100135
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100136int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
137 return (*subscr_request_update_location_cb)(mmctx);
138};
139
140/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
141int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
142int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
143 &__real_gprs_subscr_request_auth_info;
144
145int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
146 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100147};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100148
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100149/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
150int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
151int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
152 &__real_gprs_gsup_client_send;
153
154int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
155{
156 return (*gprs_gsup_client_send_cb)(gsupc, msg);
157};
158
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200159static int count(struct llist_head *head)
160{
161 struct llist_head *cur;
162 int count = 0;
163
164 llist_for_each(cur, head)
165 count += 1;
166
167 return count;
168}
169
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200170static struct msgb *create_msg(const uint8_t *data, size_t len)
171{
172 struct msgb *msg = msgb_alloc(len + 8, "test message");
173 msg->l1h = msgb_put(msg, 8);
174 msg->l2h = msgb_put(msg, len);
175 memcpy(msg->l2h, data, len);
176
177 msgb_bcid(msg) = msg->l1h;
178 msgb_gmmh(msg) = msg->l2h;
179 return msg;
180}
181
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100182/*
183 * Create a context and search for it
184 */
185static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
186{
187 struct sgsn_mm_ctx *ctx, *ictx;
188 struct gprs_llc_lle *lle;
189 int old_count = count(gprs_llme_list());
190
191 lle = gprs_lle_get_or_create(tlli, 3);
192 ctx = sgsn_mm_ctx_alloc(tlli, raid);
193 ctx->mm_state = GMM_REGISTERED_NORMAL;
Harald Weltef97ee042015-12-25 19:12:21 +0100194 ctx->gb.llme = lle->llme;
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100195
196 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
197 OSMO_ASSERT(ictx == ctx);
198
199 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
200
201 return ctx;
202}
203
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100204static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck91580892016-01-04 18:43:33 +0100205 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100206 const uint8_t *data, size_t data_len)
207{
208 struct msgb *msg;
209
Jacob Erlbeck133e8622015-10-12 19:36:32 +0200210 reset_last_msg();
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100211 sgsn_tx_counter = 0;
212
213 msg = create_msg(data, data_len);
214 msgb_tlli(msg) = tlli;
Jacob Erlbeck91580892016-01-04 18:43:33 +0100215 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Max82040102016-07-06 11:59:18 +0200216 gsm0408_gprs_rcvmsg_gb(msg, llme, false);
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100217 msgb_free(msg);
218}
219
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200220static void test_llme(void)
221{
222 struct gprs_llc_lle *lle, *lle_copy;
223 uint32_t local_tlli;
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200224
225 printf("Testing LLME allocations\n");
226 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200227
228 /* initial state */
229 OSMO_ASSERT(count(gprs_llme_list()) == 0);
230
231 /* Create a new entry */
232 lle = gprs_lle_get_or_create(local_tlli, 3);
233 OSMO_ASSERT(lle);
234 OSMO_ASSERT(count(gprs_llme_list()) == 1);
235
236 /* No new entry is created */
237 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
238 OSMO_ASSERT(lle == lle_copy);
239 OSMO_ASSERT(count(gprs_llme_list()) == 1);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200240
241 /* unassign which should delete it*/
Max39550252016-06-28 17:39:20 +0200242 gprs_llgmm_unassign(lle->llme);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200243
244 /* Check that everything was cleaned up */
245 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200246
247 cleanup_test();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200248}
249
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100250struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100251void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100252{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100253 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100254 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100255 __func__, mmctx, mmctx->subscr);
256 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100257}
258
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100259static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
260{
261 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100262 OSMO_ASSERT(subscr);
263 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100264
265 sfound = gprs_subscr_get_by_imsi(imsi);
266 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100267
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100268 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100269}
270
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100271static void show_subscrs(FILE *out)
272{
273 struct gsm_subscriber *subscr;
274
275 llist_for_each_entry(subscr, &active_subscribers, entry) {
276 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100277 "use count: %d\n",
278 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100279 }
280}
281
282static void assert_no_subscrs()
283{
284 show_subscrs(stdout);
285 fflush(stdout);
286 OSMO_ASSERT(llist_empty(&active_subscribers));
287}
288
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100289static void test_subscriber(void)
290{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100291 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100292 const char *imsi1 = "1234567890";
293 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100294 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100295
296 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
297
298 printf("Testing core subscriber data API\n");
299
300 /* Check for emptiness */
301 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
302 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100303 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100304
305 /* Allocate entry 1 */
306 s1 = gprs_subscr_get_or_create(imsi1);
307 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100308 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100309 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100310
311 /* Allocate entry 2 */
312 s2 = gprs_subscr_get_or_create(imsi2);
313 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100314
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100315 /* Allocate entry 3 */
316 s3 = gprs_subscr_get_or_create(imsi3);
317
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100318 /* Check entries */
319 assert_subscr(s1, imsi1);
320 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100321 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100322
323 /* Update entry 1 */
324 last_updated_subscr = NULL;
325 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100326 OSMO_ASSERT(last_updated_subscr == NULL);
327 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
328 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100329
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100330 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100331 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100332 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100333 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100334 sfound = gprs_subscr_get_by_imsi(imsi1);
335 OSMO_ASSERT(sfound == NULL);
336
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100337 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100338 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100339
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100340 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100341 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100342 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100343 s2 = NULL;
344 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
345 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100346 assert_subscr(s3, imsi3);
347
348 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100349 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100350 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100351 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100352 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100353
354 OSMO_ASSERT(llist_empty(&active_subscribers));
355
356 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200357
358 cleanup_test();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100359}
360
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100361static void test_auth_triplets(void)
362{
363 struct gsm_subscriber *s1, *s1found;
364 const char *imsi1 = "1234567890";
365 struct gsm_auth_tuple *at;
366 struct sgsn_mm_ctx *ctx;
367 struct gprs_ra_id raid = { 0, };
368 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100369
370 printf("Testing authentication triplet handling\n");
371
372 /* Check for emptiness */
373 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
374
375 /* Allocate entry 1 */
376 s1 = gprs_subscr_get_or_create(imsi1);
377 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
378 s1found = gprs_subscr_get_by_imsi(imsi1);
379 OSMO_ASSERT(s1found == s1);
380 subscr_put(s1found);
381
382 /* Create a context */
383 OSMO_ASSERT(count(gprs_llme_list()) == 0);
384 ctx = alloc_mm_ctx(local_tlli, &raid);
385
386 /* Attach s1 to ctx */
387 ctx->subscr = subscr_get(s1);
388 ctx->subscr->sgsn_data->mm = ctx;
389
390 /* Try to get auth tuple */
391 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
392 OSMO_ASSERT(at == NULL);
393
394 /* Add triplets */
395 s1->sgsn_data->auth_triplets[0].key_seq = 0;
396 s1->sgsn_data->auth_triplets[1].key_seq = 1;
397 s1->sgsn_data->auth_triplets[2].key_seq = 2;
398
399 /* Try to get auth tuple */
400 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
401 OSMO_ASSERT(at != NULL);
402 OSMO_ASSERT(at->key_seq == 0);
403 OSMO_ASSERT(at->use_count == 1);
404 at = sgsn_auth_get_tuple(ctx, at->key_seq);
405 OSMO_ASSERT(at != NULL);
406 OSMO_ASSERT(at->key_seq == 1);
407 OSMO_ASSERT(at->use_count == 1);
408 at = sgsn_auth_get_tuple(ctx, at->key_seq);
409 OSMO_ASSERT(at != NULL);
410 OSMO_ASSERT(at->key_seq == 2);
411 OSMO_ASSERT(at->use_count == 1);
412 at = sgsn_auth_get_tuple(ctx, at->key_seq);
413 OSMO_ASSERT(at == NULL);
414
415 /* Free MM context and subscriber */
416 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100417 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100418 s1found = gprs_subscr_get_by_imsi(imsi1);
419 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200420
421 cleanup_test();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100422}
423
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100424#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
425
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100426static int rx_gsup_message(const uint8_t *data, size_t data_len)
427{
428 struct msgb *msg;
429 int rc;
430
431 msg = msgb_alloc(1024, __func__);
432 msg->l2h = msgb_put(msg, data_len);
433 OSMO_ASSERT(msg->l2h != NULL);
434 memcpy(msg->l2h, data, data_len);
435 rc = gprs_subscr_rx_gsup_message(msg);
436 msgb_free(msg);
437
438 return rc;
439}
440
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100441static void test_subscriber_gsup(void)
442{
443 struct gsm_subscriber *s1, *s1found;
444 const char *imsi1 = "1234567890";
445 struct sgsn_mm_ctx *ctx;
446 struct gprs_ra_id raid = { 0, };
447 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100448 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100449 int rc;
450
451 static const uint8_t send_auth_info_res[] = {
452 0x0a,
453 TEST_GSUP_IMSI1_IE,
454 0x03, 0x22, /* Auth tuple */
455 0x20, 0x10,
456 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
457 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
458 0x21, 0x04,
459 0x21, 0x22, 0x23, 0x24,
460 0x22, 0x08,
461 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
462 0x03, 0x22, /* Auth tuple */
463 0x20, 0x10,
464 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
465 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
466 0x21, 0x04,
467 0xa1, 0xa2, 0xa3, 0xa4,
468 0x22, 0x08,
469 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
470 };
471
472 static const uint8_t send_auth_info_err[] = {
473 0x09,
474 TEST_GSUP_IMSI1_IE,
475 0x02, 0x01, 0x07 /* GPRS not allowed */
476 };
477
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400478#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
479
480 static const uint8_t s1_msisdn[] = { MSISDN };
481
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100482 static const uint8_t update_location_res[] = {
483 0x06,
484 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400485 0x08, 0x09, MSISDN,
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100486 0x04, 0x00, /* PDP info complete */
487 0x05, 0x12,
488 0x10, 0x01, 0x01,
489 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
490 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
491 0x05, 0x11,
492 0x10, 0x01, 0x02,
493 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
494 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
495 };
496
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400497#undef MSISDN
498
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100499 static const uint8_t update_location_err[] = {
500 0x05,
501 TEST_GSUP_IMSI1_IE,
502 0x02, 0x01, 0x07 /* GPRS not allowed */
503 };
504
505 static const uint8_t location_cancellation_req[] = {
506 0x1c,
507 TEST_GSUP_IMSI1_IE,
508 0x06, 0x01, 0x00,
509 };
510
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200511 static const uint8_t location_cancellation_req_withdraw[] = {
512 0x1c,
513 TEST_GSUP_IMSI1_IE,
514 0x06, 0x01, 0x01,
515 };
516
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100517 static const uint8_t location_cancellation_req_other[] = {
518 0x1c,
519 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
520 0x06, 0x01, 0x00,
521 };
522
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100523 static const uint8_t purge_ms_err[] = {
524 0x0d,
525 TEST_GSUP_IMSI1_IE,
526 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
527 };
528
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100529 static const uint8_t purge_ms_err_no_cause[] = {
530 0x0d,
531 TEST_GSUP_IMSI1_IE,
532 };
533
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100534 static const uint8_t purge_ms_res[] = {
535 0x0e,
536 TEST_GSUP_IMSI1_IE,
537 0x07, 0x00,
538 };
539
540
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100541 static const uint8_t insert_data_req[] = {
542 0x10,
543 TEST_GSUP_IMSI1_IE,
544 0x05, 0x11,
545 0x10, 0x01, 0x03,
546 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
547 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
548 };
549
550 static const uint8_t delete_data_req[] = {
551 0x14,
552 TEST_GSUP_IMSI1_IE,
553 0x10, 0x01, 0x03,
554 };
555
Neels Hofmeyr241bda02016-06-20 18:26:15 +0200556 printf("Testing subscriber GSUP handling\n");
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100557
558 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
559
560 /* Check for emptiness */
561 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
562
563 /* Allocate entry 1 */
564 s1 = gprs_subscr_get_or_create(imsi1);
565 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
566 s1found = gprs_subscr_get_by_imsi(imsi1);
567 OSMO_ASSERT(s1found == s1);
568 subscr_put(s1found);
569
570 /* Create a context */
571 OSMO_ASSERT(count(gprs_llme_list()) == 0);
572 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100573
574 /* Attach s1 to ctx */
575 ctx->subscr = subscr_get(s1);
576 ctx->subscr->sgsn_data->mm = ctx;
577
578 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100579 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100580 OSMO_ASSERT(rc >= 0);
581 OSMO_ASSERT(last_updated_subscr == s1);
582
583 /* Check triplets */
584 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
585 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
586 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
587
588 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100589 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100590 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100591 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100592 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100593
594 /* Check triplets */
595 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
596 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
597 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
598
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100599 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100600 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100601 OSMO_ASSERT(rc >= 0);
602 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100603 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100604 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400605 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
606 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100607 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
608 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
609 struct sgsn_subscriber_pdp_data, list);
610 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
611 pdpd = llist_entry(pdpd->list.next,
612 struct sgsn_subscriber_pdp_data, list);
613 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100614
615 /* Check authorization */
616 OSMO_ASSERT(s1->authorized == 1);
617
618 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100619 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100620 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100621 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100622 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100623
624 /* Check authorization */
625 OSMO_ASSERT(s1->authorized == 0);
626
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100627 /* Inject InsertSubscrData GSUP message */
628 last_updated_subscr = NULL;
629 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Harald Weltec346f872016-11-26 14:58:36 +0100630 OSMO_ASSERT(rc == -ENOTSUP); /* not connected */
Harald Weltecd5e5262016-05-06 13:46:21 +0200631 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100632
633 /* Inject DeleteSubscrData GSUP message */
634 last_updated_subscr = NULL;
635 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
636 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
637 OSMO_ASSERT(last_updated_subscr == NULL);
638
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100639 /* Inject wrong LocCancelReq GSUP message */
640 last_updated_subscr = NULL;
641 rc = rx_gsup_message(location_cancellation_req_other,
642 sizeof(location_cancellation_req_other));
643 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
644 OSMO_ASSERT(last_updated_subscr == NULL);
645
646 /* Check cancellation result */
647 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
648 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
649
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100650 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100651 rc = rx_gsup_message(location_cancellation_req,
652 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100653 OSMO_ASSERT(rc >= 0);
654 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100655 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100656
657 /* Check cancellation result */
658 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
659 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
660
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200661 /* Inject LocCancelReq(withdraw) GSUP message */
662 rc = rx_gsup_message(location_cancellation_req_withdraw,
663 sizeof(location_cancellation_req_withdraw));
664 OSMO_ASSERT(rc >= 0);
665 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
666
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100667 /* Inject PurgeMsRes GSUP message */
668 rc = rx_gsup_message(purge_ms_res,
669 sizeof(purge_ms_res));
670 OSMO_ASSERT(rc >= 0);
671 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
672
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100673 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100674 OSMO_ASSERT(ctx->subscr == NULL);
675 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100676 subscr_put(s1);
677 s1found = gprs_subscr_get_by_imsi(imsi1);
678 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100679
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100680 /* Inject PurgeMsRes GSUP message */
681 rc = rx_gsup_message(purge_ms_res,
682 sizeof(purge_ms_res));
683 OSMO_ASSERT(rc >= 0);
684
685 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
686 rc = rx_gsup_message(purge_ms_err,
687 sizeof(purge_ms_err));
688 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
689
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100690 /* Inject PurgeMsErr() GSUP message */
691 rc = rx_gsup_message(purge_ms_err_no_cause,
692 sizeof(purge_ms_err_no_cause));
693 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
694
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100695 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
696 last_updated_subscr = NULL;
697 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100698 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100699 OSMO_ASSERT(last_updated_subscr == NULL);
700
701 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
702 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
703 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
704 OSMO_ASSERT(last_updated_subscr == NULL);
705
706 /* Inject LocCancelReq GSUP message (unknown IMSI) */
707 rc = rx_gsup_message(location_cancellation_req,
708 sizeof(location_cancellation_req));
709 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
710 OSMO_ASSERT(last_updated_subscr == NULL);
711
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100712 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200713
714 cleanup_test();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100715}
716
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100717int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
718{
719 msgb_free(msg);
720 return 0;
721};
722
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200723/*
724 * Test that a GMM Detach will remove the MMCTX and the
725 * associated LLME.
726 */
727static void test_gmm_detach(void)
728{
729 struct gprs_ra_id raid = { 0, };
730 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200731 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200732
733 printf("Testing GMM detach\n");
734
735 /* DTAP - Detach Request (MO) */
736 /* normal detach, power_off = 0 */
737 static const unsigned char detach_req[] = {
738 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
739 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
740 };
741
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200742 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200743
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100744 /* Create a context */
745 OSMO_ASSERT(count(gprs_llme_list()) == 0);
746 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200747
748 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +0100749 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100750 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200751
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100752 /* verify that a single message (hopefully the Detach Accept) has been
753 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100754 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100755
756 /* verify that things are gone */
757 OSMO_ASSERT(count(gprs_llme_list()) == 0);
758 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
759 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200760
761 cleanup_test();
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100762}
763
764/*
765 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
766 * will not sent a Detach Accept message (power_off = 1)
767 */
768static void test_gmm_detach_power_off(void)
769{
770 struct gprs_ra_id raid = { 0, };
771 struct sgsn_mm_ctx *ctx, *ictx;
772 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100773
774 printf("Testing GMM detach (power off)\n");
775
776 /* DTAP - Detach Request (MO) */
777 /* normal detach, power_off = 1 */
778 static const unsigned char detach_req[] = {
779 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
780 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
781 };
782
783 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
784
785 /* Create a context */
786 OSMO_ASSERT(count(gprs_llme_list()) == 0);
787 ctx = alloc_mm_ctx(local_tlli, &raid);
788
789 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +0100790 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100791 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100792
793 /* verify that no message (and therefore no Detach Accept) has been
794 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100795 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100796
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200797 /* verify that things are gone */
798 OSMO_ASSERT(count(gprs_llme_list()) == 0);
799 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200800 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200801
802 cleanup_test();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200803}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200804
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200805/*
806 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
807 */
808static void test_gmm_detach_no_mmctx(void)
809{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100810 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200811 struct gprs_llc_lle *lle;
812 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200813
814 printf("Testing GMM detach (no MMCTX)\n");
815
816 /* DTAP - Detach Request (MO) */
817 /* normal detach, power_off = 0 */
818 static const unsigned char detach_req[] = {
819 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
820 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
821 };
822
823 /* Create an LLME */
824 OSMO_ASSERT(count(gprs_llme_list()) == 0);
825 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
826 lle = gprs_lle_get_or_create(local_tlli, 3);
827
828 OSMO_ASSERT(count(gprs_llme_list()) == 1);
829
830 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100831 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100832 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200833
834 /* verify that the LLME is gone */
835 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200836
837 cleanup_test();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200838}
839
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100840/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100841 * Test that a single GMM Detach Accept message will not cause the SGSN to send
842 * any message or leave an MM context at the SGSN.
843 */
844static void test_gmm_detach_accept_unexpected(void)
845{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100846 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100847 struct gprs_llc_lle *lle;
848 uint32_t local_tlli;
849
850 printf("Testing GMM detach accept (unexpected)\n");
851
852 /* DTAP - Detach Accept (MT) */
853 /* normal detach */
854 static const unsigned char detach_acc[] = {
855 0x08, 0x06
856 };
857
858 /* Create an LLME */
859 OSMO_ASSERT(count(gprs_llme_list()) == 0);
860 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
861 lle = gprs_lle_get_or_create(local_tlli, 3);
862
863 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100864 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100865 detach_acc, ARRAY_SIZE(detach_acc));
866
867 /* verify that no message (and therefore no Status or XID reset) has been
868 * sent by the SGSN */
869 OSMO_ASSERT(sgsn_tx_counter == 0);
870
871 /* verify that things are gone */
872 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200873
874 cleanup_test();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100875}
876
877/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100878 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
879 */
880static void test_gmm_status_no_mmctx(void)
881{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100882 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100883 struct gprs_llc_lle *lle;
884 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100885
886 printf("Testing GMM Status (no MMCTX)\n");
887
888 /* DTAP - GMM Status, protocol error */
889 static const unsigned char gmm_status[] = {
890 0x08, 0x20, 0x6f
891 };
892
893 /* Create an LLME */
894 OSMO_ASSERT(count(gprs_llme_list()) == 0);
895 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
896 lle = gprs_lle_get_or_create(local_tlli, 3);
897
898 OSMO_ASSERT(count(gprs_llme_list()) == 1);
899
900 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100901 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100902 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100903
904 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100905 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100906
907 /* verify that the LLME is gone */
908 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200909
910 cleanup_test();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100911}
912
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100913/*
914 * Test the GMM Attach procedure
915 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100916static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100917{
918 struct gprs_ra_id raid = { 0, };
919 struct sgsn_mm_ctx *ctx = NULL;
920 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100921 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100922 uint32_t foreign_tlli;
923 uint32_t local_tlli = 0;
924 struct gprs_llc_lle *lle;
925
926 /* DTAP - Attach Request */
927 /* The P-TMSI is not known by the SGSN */
928 static const unsigned char attach_req[] = {
929 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
930 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
931 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
932 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
933 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
934 };
935
936 /* DTAP - Identity Response IMEI */
937 static const unsigned char ident_resp_imei[] = {
938 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
939 0x56
940 };
941
942 /* DTAP - Identity Response IMSI */
943 static const unsigned char ident_resp_imsi[] = {
944 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
945 0x54
946 };
947
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100948 /* DTAP - Authentication and Ciphering Resp */
949 static const unsigned char auth_ciph_resp[] = {
950 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
951 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
952 };
953
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100954 /* DTAP - Attach Complete */
955 static const unsigned char attach_compl[] = {
956 0x08, 0x03
957 };
958
959 /* DTAP - Detach Request (MO) */
960 /* normal detach, power_off = 0 */
961 static const unsigned char detach_req[] = {
962 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
963 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
964 };
965
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100966 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100967
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100968 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
969
970 /* Create a LLE/LLME */
971 OSMO_ASSERT(count(gprs_llme_list()) == 0);
972 lle = gprs_lle_get_or_create(foreign_tlli, 3);
973 OSMO_ASSERT(count(gprs_llme_list()) == 1);
974
975 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100976 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100977 attach_req, ARRAY_SIZE(attach_req));
978
979 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
980 OSMO_ASSERT(ctx != NULL);
981 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
982
983 /* we expect an identity request (IMEI) */
984 OSMO_ASSERT(sgsn_tx_counter == 1);
985
986 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +0100987 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100988 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
989
990 /* we expect an identity request (IMSI) */
991 OSMO_ASSERT(sgsn_tx_counter == 1);
992
993 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +0100994 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100995 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
996
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100997 /* check that the MM context has not been removed due to a failed
998 * authorization */
999 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1000
Jacob Erlbeck0074a772014-10-28 16:23:46 +01001001 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001002
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001003retry_attach_req:
1004
1005 if (retry && sgsn_tx_counter == 0) {
1006 fprintf(stderr, "Retrying attach request\n");
1007 /* re-inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001008 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001009 attach_req, ARRAY_SIZE(attach_req));
1010 }
1011
1012 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
1013 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001014
1015 /* inject the auth & ciph response */
Harald Weltef97ee042015-12-25 19:12:21 +01001016 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001017 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1018
1019 /* check that the MM context has not been removed due to a
1020 * failed authorization */
1021 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001022 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1023 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001024 }
1025
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001026 if (retry && sgsn_tx_counter == 0)
1027 goto retry_attach_req;
1028
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001029 /* we expect an attach accept/reject */
1030 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001031 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1032 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001033
1034 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001035 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001036
1037 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001038 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001039 attach_compl, ARRAY_SIZE(attach_compl));
1040
1041 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1042
1043 /* we don't expect a response */
1044 OSMO_ASSERT(sgsn_tx_counter == 0);
1045
1046 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001047 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001048 detach_req, ARRAY_SIZE(detach_req));
1049
1050 /* verify that things are gone */
1051 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1052 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1053 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001054
1055 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001056}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001057
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001058static void test_gmm_attach_acl(void)
1059{
1060 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1061
1062 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1063 sgsn_acl_add("123456789012345", &sgsn->cfg);
1064 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001065 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001066 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001067
1068 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001069
1070 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001071}
1072
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001073int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001074 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001075 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001076 if (rc == -ENOTSUP) {
1077 OSMO_ASSERT(mmctx->subscr);
1078 gprs_subscr_update(mmctx->subscr);
1079 }
1080 return rc;
1081};
1082
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001083int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1084 gprs_subscr_update(mmctx->subscr);
1085 return 0;
1086};
1087
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001088static void test_gmm_attach_subscr(void)
1089{
1090 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1091 struct gsm_subscriber *subscr;
1092
1093 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001094 subscr_request_update_location_cb = my_subscr_request_update_location;
1095 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001096
1097 subscr = gprs_subscr_get_or_create("123456789012345");
1098 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001099
1100 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001101 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001102 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001103 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001104
1105 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001106 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1107 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001108
1109 cleanup_test();
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001110}
1111
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001112int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1113{
1114 /* Fake an authentication */
1115 OSMO_ASSERT(mmctx->subscr);
1116 mmctx->is_authenticated = 1;
1117 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001118
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001119 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001120};
1121
1122static void test_gmm_attach_subscr_fake_auth(void)
1123{
1124 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1125 struct gsm_subscriber *subscr;
1126
1127 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001128 subscr_request_update_location_cb = my_subscr_request_update_location;
1129 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001130
1131 subscr = gprs_subscr_get_or_create("123456789012345");
1132 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001133 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001134 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001135
1136 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001137 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001138 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001139 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001140
1141 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001142 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1143 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001144
1145 cleanup_test();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001146}
1147
1148int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1149{
1150 struct gsm_auth_tuple at = {
Harald Welte121e9a42016-04-20 13:13:19 +02001151 .vec.sres = {0x51, 0xe5, 0x51, 0xe5},
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001152 .key_seq = 0
1153 };
1154
1155 /* Fake an authentication */
1156 OSMO_ASSERT(mmctx->subscr);
1157 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1158
1159 gprs_subscr_update_auth_info(mmctx->subscr);
1160
1161 return 0;
1162};
1163
1164static void test_gmm_attach_subscr_real_auth(void)
1165{
1166 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1167 struct gsm_subscriber *subscr;
1168
1169 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1170 subscr_request_update_location_cb = my_subscr_request_update_location;
1171 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1172
1173 subscr = gprs_subscr_get_or_create("123456789012345");
1174 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001175 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001176 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001177
1178 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001179
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001180 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001181 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001182 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001183
1184 sgsn->cfg.auth_policy = saved_auth_policy;
1185 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1186 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001187
1188 cleanup_test();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001189}
1190
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001191#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1192 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1193
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001194static int auth_info_skip = 0;
1195static int upd_loc_skip = 0;
1196
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001197int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1198{
1199 static const uint8_t send_auth_info_res[] = {
1200 0x0a,
1201 TEST_GSUP_IMSI_LONG_IE,
1202 0x03, 0x22, /* Auth tuple */
1203 0x20, 0x10,
1204 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1205 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1206 0x21, 0x04,
1207 0x51, 0xe5, 0x51, 0xe5,
1208 0x22, 0x08,
1209 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1210 };
1211
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001212 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001213
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001214 if (auth_info_skip > 0) {
1215 auth_info_skip -= 1;
1216 return -EAGAIN;
1217 }
1218
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001219 /* Fake an SendAuthInfoRes */
1220 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1221
1222 return 0;
1223};
1224
1225int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1226 static const uint8_t update_location_res[] = {
1227 0x06,
1228 TEST_GSUP_IMSI_LONG_IE,
1229 0x04, 0x00, /* PDP info complete */
1230 0x05, 0x12,
1231 0x10, 0x01, 0x01,
1232 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1233 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001234 0x08, 0x07, /* MSISDN 49166213323 encoded */
1235 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freyther10c0f562015-05-17 20:58:40 +02001236 0x09, 0x07, /* MSISDN 38166213323 encoded */
1237 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001238 };
1239
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001240 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001241
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001242 if (upd_loc_skip > 0) {
1243 upd_loc_skip -= 1;
1244 return -EAGAIN;
1245 }
1246
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001247 /* Fake an UpdateLocRes */
1248 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1249};
1250
1251
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001252static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001253{
1254 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1255 struct gsm_subscriber *subscr;
1256
1257 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1258 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1259 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001260 if (retry) {
1261 upd_loc_skip = 3;
1262 auth_info_skip = 3;
1263 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001264
1265 subscr = gprs_subscr_get_or_create("123456789012345");
1266 subscr->authorized = 1;
1267 sgsn->cfg.require_authentication = 1;
1268 sgsn->cfg.require_update_location = 1;
1269 subscr_put(subscr);
1270
1271 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001272 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001273 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001274
1275 sgsn->cfg.auth_policy = saved_auth_policy;
1276 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1277 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001278 upd_loc_skip = 0;
1279 auth_info_skip = 0;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001280
1281 cleanup_test();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001282}
1283
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001284int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1285{
Harald Welte23d77d52016-04-25 19:07:34 +02001286 struct osmo_gsup_message to_peer = {0};
1287 struct osmo_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001288 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001289 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001290
1291 /* Simulate the GSUP peer */
Harald Welte23d77d52016-04-25 19:07:34 +02001292 rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001293 OSMO_ASSERT(rc >= 0);
1294 OSMO_ASSERT(to_peer.imsi[0] != 0);
1295 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001296
1297 /* This invalidates the pointers in to_peer */
1298 msgb_free(msg);
1299
1300 switch (to_peer.message_type) {
Harald Welte23d77d52016-04-25 19:07:34 +02001301 case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001302 /* Send UPDATE_LOCATION_RESULT */
1303 return my_subscr_request_update_gsup_auth(NULL);
1304
Harald Welte23d77d52016-04-25 19:07:34 +02001305 case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001306 /* Send SEND_AUTH_INFO_RESULT */
1307 return my_subscr_request_auth_info_gsup_auth(NULL);
1308
Harald Welte23d77d52016-04-25 19:07:34 +02001309 case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
1310 from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001311 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001312
1313 default:
1314 if ((to_peer.message_type & 0b00000011) == 0) {
1315 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001316 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001317 from_peer.message_type = to_peer.message_type + 1;
1318 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1319 break;
1320 }
1321
1322 /* Ignore it */
1323 return 0;
1324 }
1325
1326 reply_msg = gprs_gsup_msgb_alloc();
1327 reply_msg->l2h = reply_msg->data;
Harald Welte23d77d52016-04-25 19:07:34 +02001328 osmo_gsup_encode(reply_msg, &from_peer);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001329 gprs_subscr_rx_gsup_message(reply_msg);
1330 msgb_free(reply_msg);
1331
1332 return 0;
1333};
1334
1335static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1336{
1337 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1338 struct gsm_subscriber *subscr;
1339
1340 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001341 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1342
1343 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1344
1345 if (retry) {
1346 upd_loc_skip = 3;
1347 auth_info_skip = 3;
1348 }
1349
1350 printf("Auth policy 'remote', real GSUP based auth: ");
1351 test_gmm_attach(retry);
1352
1353 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001354 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001355 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001356
1357 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001358 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1359 upd_loc_skip = 0;
1360 auth_info_skip = 0;
1361 talloc_free(sgsn->gsup_client);
1362 sgsn->gsup_client = NULL;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001363
1364 cleanup_test();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001365}
1366
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001367/*
1368 * Test the GMM Rejects
1369 */
1370static void test_gmm_reject(void)
1371{
1372 struct gprs_ra_id raid = { 0, };
1373 struct sgsn_mm_ctx *ctx = NULL;
1374 uint32_t foreign_tlli;
1375 struct gprs_llc_lle *lle;
1376 int idx;
1377
1378 /* DTAP - Attach Request */
1379 /* Invalid MI length */
1380 static const unsigned char attach_req_inv_mi_len[] = {
1381 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1382 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1383 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1384 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1385 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1386 };
1387
1388 /* DTAP - Attach Request */
1389 /* Invalid MI type (IMEI) */
1390 static const unsigned char attach_req_inv_mi_type[] = {
1391 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1392 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1393 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1394 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1395 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1396 };
1397
1398 /* DTAP - Routing Area Update Request */
1399 static const unsigned char dtap_ra_upd_req[] = {
1400 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1401 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1402 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1403 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1404 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1405 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1406 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1407 };
1408
1409 /* DTAP - Routing Area Update Request */
1410 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1411 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1412 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1413 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1414 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1415 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1416 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1417 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1418 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1419 };
1420
1421 /* DTAP - Routing Area Update Request */
1422 /* Invalid cap length */
1423 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1424 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1425 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1426 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1427 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1428 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1429 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1430 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1431 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1432 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1433 };
1434
1435 struct test {
1436 const char *title;
1437 const unsigned char *msg;
1438 unsigned msg_len;
1439 unsigned num_resp;
1440
1441 };
1442 static struct test tests[] = {
1443 {
1444 .title = "Attach Request (invalid MI length)",
1445 .msg = attach_req_inv_mi_len,
1446 .msg_len = sizeof(attach_req_inv_mi_len),
1447 .num_resp = 1 /* Reject */
1448
1449 },
1450 {
1451 .title = "Attach Request (invalid MI type)",
1452 .msg = attach_req_inv_mi_type,
1453 .msg_len = sizeof(attach_req_inv_mi_type),
1454 .num_resp = 1 /* Reject */
1455 },
1456 {
1457 .title = "Routing Area Update Request (valid)",
1458 .msg = dtap_ra_upd_req,
1459 .msg_len = sizeof(dtap_ra_upd_req),
1460 .num_resp = 2 /* XID Reset + Reject */
1461 },
1462 {
1463 .title = "Routing Area Update Request (invalid type)",
1464 .msg = dtap_ra_upd_req_inv_type,
1465 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1466 .num_resp = 1 /* Reject */
1467 },
1468 {
1469 .title = "Routing Area Update Request (invalid CAP length)",
1470 .msg = dtap_ra_upd_req_inv_cap_len,
1471 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1472 .num_resp = 1 /* Reject */
1473 },
1474 };
1475
1476 printf("Testing GMM reject\n");
1477
1478 /* reset the PRNG used by sgsn_alloc_ptmsi */
1479 srand(1);
1480
1481 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1482
1483 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1484
1485 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1486 const struct test *test = &tests[idx];
1487 printf(" - %s\n", test->title);
1488
1489 /* Create a LLE/LLME */
1490 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1491 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1492
1493 /* Inject the Request message */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001494 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001495 test->msg, test->msg_len);
1496
1497 /* We expect a Reject message */
1498 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1499 sgsn_tx_counter, test->num_resp);
1500 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1501
1502 /* verify that LLME/MM are removed */
1503 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1504 OSMO_ASSERT(ctx == NULL);
1505 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1506 }
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001507
1508 cleanup_test();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001509}
1510
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001511/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001512 * Test cancellation of attached MM contexts
1513 */
1514static void test_gmm_cancel(void)
1515{
1516 struct gprs_ra_id raid = { 0, };
1517 struct sgsn_mm_ctx *ctx = NULL;
1518 struct sgsn_mm_ctx *ictx;
1519 uint32_t ptmsi1;
1520 uint32_t foreign_tlli;
1521 uint32_t local_tlli = 0;
1522 struct gprs_llc_lle *lle;
1523 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1524
1525 /* DTAP - Attach Request */
1526 /* The P-TMSI is not known by the SGSN */
1527 static const unsigned char attach_req[] = {
1528 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1529 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1530 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1531 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1532 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1533 };
1534
1535 /* DTAP - Identity Response IMEI */
1536 static const unsigned char ident_resp_imei[] = {
1537 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1538 0x56
1539 };
1540
1541 /* DTAP - Identity Response IMSI */
1542 static const unsigned char ident_resp_imsi[] = {
1543 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1544 0x54
1545 };
1546
1547 /* DTAP - Attach Complete */
1548 static const unsigned char attach_compl[] = {
1549 0x08, 0x03
1550 };
1551
1552 printf("Testing cancellation\n");
1553
1554 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1555
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001556 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1557
1558 /* Create a LLE/LLME */
1559 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1560 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1561 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1562
1563 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001564 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001565 attach_req, ARRAY_SIZE(attach_req));
1566
1567 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1568 OSMO_ASSERT(ctx != NULL);
1569 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1570
1571 /* we expect an identity request (IMEI) */
1572 OSMO_ASSERT(sgsn_tx_counter == 1);
1573
1574 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001575 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001576 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1577
1578 /* we expect an identity request (IMSI) */
1579 OSMO_ASSERT(sgsn_tx_counter == 1);
1580
1581 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001582 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001583 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1584
1585 /* check that the MM context has not been removed due to a failed
1586 * authorization */
1587 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1588
1589 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1590
1591 /* we expect an attach accept/reject */
1592 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001593 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1594 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001595
1596 /* this has been randomly assigned by the SGSN */
1597 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1598
1599 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001600 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001601 attach_compl, ARRAY_SIZE(attach_compl));
1602
1603 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1604
1605 /* we don't expect a response */
1606 OSMO_ASSERT(sgsn_tx_counter == 0);
1607
1608 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001609 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001610
1611 /* verify that things are gone */
1612 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1613 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1614 OSMO_ASSERT(!ictx);
1615
1616 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001617
1618 cleanup_test();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001619}
1620
1621/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001622 * Test the dynamic allocation of P-TMSIs
1623 */
1624static void test_gmm_ptmsi_allocation(void)
1625{
Jacob Erlbeckd58c0332016-01-04 18:43:35 +01001626 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001627 struct sgsn_mm_ctx *ctx = NULL;
1628 struct sgsn_mm_ctx *ictx;
1629 uint32_t foreign_tlli;
1630 uint32_t ptmsi1;
1631 uint32_t ptmsi2;
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001632 uint32_t received_ptmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001633 uint32_t old_ptmsi;
1634 uint32_t local_tlli = 0;
1635 struct gprs_llc_lle *lle;
1636 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1637
1638 /* DTAP - Attach Request (IMSI 12131415161718) */
1639 static const unsigned char attach_req[] = {
1640 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1641 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1642 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1643 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1644 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1645 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1646 0x00,
1647 };
1648
1649 /* DTAP - Identity Response IMEI */
1650 static const unsigned char ident_resp_imei[] = {
1651 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1652 0x56
1653 };
1654
1655 /* DTAP - Attach Complete */
1656 static const unsigned char attach_compl[] = {
1657 0x08, 0x03
1658 };
1659
1660 /* DTAP - Routing Area Update Request */
1661 static const unsigned char ra_upd_req[] = {
1662 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1663 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1664 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1665 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1666 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1667 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1668 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1669 };
1670
1671 /* DTAP - Routing Area Update Complete */
1672 static const unsigned char ra_upd_complete[] = {
1673 0x08, 0x0a
1674 };
1675
1676 /* DTAP - Detach Request (MO) */
1677 /* normal detach, power_off = 1 */
1678 static const unsigned char detach_req[] = {
1679 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1680 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1681 };
1682
1683 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1684
1685 printf("Testing P-TMSI allocation\n");
1686
1687 printf(" - sgsn_alloc_ptmsi\n");
1688
1689 /* reset the PRNG used by sgsn_alloc_ptmsi */
1690 srand(1);
1691
1692 ptmsi1 = sgsn_alloc_ptmsi();
1693 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1694
1695 ptmsi2 = sgsn_alloc_ptmsi();
1696 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1697
1698 OSMO_ASSERT(ptmsi1 != ptmsi2);
1699
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001700 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001701
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001702 printf(" - Repeated Attach Request\n");
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001703
1704 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1705
1706 /* Create a LLE/LLME */
1707 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1708 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1709 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1710
1711 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001712 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001713 attach_req, ARRAY_SIZE(attach_req));
1714
1715 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1716 OSMO_ASSERT(ctx != NULL);
1717 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001718 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1719 ptmsi1 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001720
1721 old_ptmsi = ctx->p_tmsi_old;
1722
1723 /* we expect an identity request (IMEI) */
1724 OSMO_ASSERT(sgsn_tx_counter == 1);
1725
1726 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001727 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001728 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1729
1730 /* check that the MM context has not been removed due to a failed
1731 * authorization */
1732 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1733
1734 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1735 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1736
1737 /* we expect an attach accept */
1738 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001739 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1740 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001741
1742 /* we ignore this and send the attach again */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001743 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001744 attach_req, ARRAY_SIZE(attach_req));
1745
1746 /* the allocated P-TMSI should be the same */
1747 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1748 OSMO_ASSERT(ctx != NULL);
1749 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1750 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1751 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1752
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001753 /* we expect an attach accept */
1754 OSMO_ASSERT(sgsn_tx_counter == 1);
1755 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1756 OSMO_ASSERT(received_ptmsi == ptmsi1);
1757
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001758 /* inject the attach complete */
1759 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001760 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001761 attach_compl, ARRAY_SIZE(attach_compl));
1762
1763 /* we don't expect a response */
1764 OSMO_ASSERT(sgsn_tx_counter == 0);
1765
1766 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1767 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1768 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1769
1770 printf(" - Repeated RA Update Request\n");
1771
1772 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001773 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001774 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1775
1776 /* we expect an RA update accept */
1777 OSMO_ASSERT(sgsn_tx_counter == 1);
1778
1779 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1780 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001781 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1782 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1783 ptmsi2 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001784
1785 /* repeat the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001786 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001787 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1788
1789 /* we expect an RA update accept */
1790 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001791 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1792 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001793
1794 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1795 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1796 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1797
1798 /* inject the RA update complete */
1799 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001800 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001801 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1802
1803 /* we don't expect a response */
1804 OSMO_ASSERT(sgsn_tx_counter == 0);
1805
1806 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1807 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1808 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1809
1810 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001811 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001812 detach_req, ARRAY_SIZE(detach_req));
1813
1814 /* verify that things are gone */
1815 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1816 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1817 OSMO_ASSERT(!ictx);
1818
1819 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001820
1821 cleanup_test();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001822}
1823
Jacob Erlbeck13304782016-01-04 18:43:37 +01001824/*
1825 * Test changing of routing areas
1826 */
1827static void test_gmm_routing_areas(void)
1828{
1829 struct gprs_ra_id raid1 = {332, 112, 16464, 96};
1830 struct gprs_ra_id raid2 = {332, 112, 16464, 97};
1831 struct sgsn_mm_ctx *ctx = NULL;
1832 struct sgsn_mm_ctx *ictx;
1833 uint32_t ptmsi1;
1834 uint32_t received_ptmsi;
1835 uint32_t ms_tlli = 0;
1836 struct gprs_llc_lle *lle;
1837 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1838
1839 /* DTAP - Attach Request (IMSI 12131415161718) */
1840 static const unsigned char attach_req[] = {
1841 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1842 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1843 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1844 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1845 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1846 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1847 0x00,
1848 };
1849
1850 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1851 static const unsigned char attach_req2[] = {
1852 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1853 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1854 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1855 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1856 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1857 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1858 0x00,
1859 };
1860
1861 /* DTAP - Identity Response IMEI */
1862 static const unsigned char ident_resp_imei[] = {
1863 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1864 0x56
1865 };
1866
1867 /* DTAP - Attach Complete */
1868 static const unsigned char attach_compl[] = {
1869 0x08, 0x03
1870 };
1871
1872 /* DTAP - Routing Area Update Request (coming from RA 1) */
1873 static const unsigned char ra_upd_req1[] = {
1874 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1875 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1876 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1877 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1878 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1879 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1880 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1881 };
1882
1883 /* DTAP - Routing Area Update Request (coming from RA 2) */
1884 static const unsigned char ra_upd_req2[] = {
1885 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1886 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1887 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1888 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1889 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1890 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1891 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1892 };
1893
1894 /* DTAP - Routing Area Update Request (coming from RA other) */
1895 /* raid_other = {443, 223, 16464, 98}; */
1896 static const unsigned char ra_upd_req_other[] = {
1897 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1898 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1899 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1900 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1901 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1902 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1903 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1904 };
1905
1906 /* DTAP - Routing Area Update Complete */
1907 static const unsigned char ra_upd_complete[] = {
1908 0x08, 0x0a
1909 };
1910
1911 /* DTAP - Detach Request (MO) */
1912 /* normal detach, power_off = 1 */
1913 static const unsigned char detach_req[] = {
1914 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1915 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1916 };
1917
1918 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1919
1920 printf("Testing routing area changes\n");
1921
1922 /* reset the PRNG used by sgsn_alloc_ptmsi */
1923 srand(1);
1924
1925 ptmsi1 = GSM_RESERVED_TMSI;
1926
1927 printf(" - Attach Request (RA 1)\n");
1928
1929 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1930
1931 /* Create a LLE/LLME */
1932 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1933 lle = gprs_lle_get_or_create(ms_tlli, 3);
1934 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1935
1936 /* inject the attach request */
1937 send_0408_message(lle->llme, ms_tlli, &raid1,
1938 attach_req, ARRAY_SIZE(attach_req));
1939
1940 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1941 OSMO_ASSERT(ctx != NULL);
1942 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1943 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1944
1945 /* we expect an identity request (IMEI) */
1946 OSMO_ASSERT(sgsn_tx_counter == 1);
1947 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1948 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1949
1950 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001951 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001952 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1953
1954 /* check that the MM context has not been removed due to a failed
1955 * authorization */
1956 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1957
1958 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1959
1960 /* we expect an attach accept */
1961 OSMO_ASSERT(sgsn_tx_counter == 1);
1962 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1963 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1964
1965 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1966 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1967 ptmsi1 = received_ptmsi;
1968
1969 /* inject the attach complete */
1970 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001971 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001972 attach_compl, ARRAY_SIZE(attach_compl));
1973
1974 /* we don't expect a response */
1975 OSMO_ASSERT(sgsn_tx_counter == 0);
1976
1977 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1978 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1979 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1980
1981 printf(" - RA Update Request (RA 1 -> RA 1)\n");
1982
1983 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001984 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001985 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
1986
1987 /* we expect an RA update accept */
1988 OSMO_ASSERT(sgsn_tx_counter == 1);
1989 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
1990 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1991
1992 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1993 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1994 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1995 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1996
1997 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1998 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1999 ptmsi1 = received_ptmsi;
2000
2001 /* inject the RA update complete */
2002 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002003 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002004 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2005
2006 /* we don't expect a response */
2007 OSMO_ASSERT(sgsn_tx_counter == 0);
2008
2009 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2010 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2011 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002012 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002013
Jacob Erlbeck13304782016-01-04 18:43:37 +01002014 printf(" - RA Update Request (RA 1 -> RA 2)\n");
2015
2016 /* inject the RA update request */
2017 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2018
2019 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002020 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002021 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2022
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002023 /* we expect an RA update accept */
Jacob Erlbeck13304782016-01-04 18:43:37 +01002024 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002025 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002026
2027 printf(" - RA Update Request (RA other -> RA 2)\n");
2028
2029 /* inject the RA update request */
2030 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2031
2032 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002033 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002034 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2035
2036 /* we expect an RA update reject (and a LLC XID RESET) */
2037 OSMO_ASSERT(sgsn_tx_counter == 2);
2038 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2039 /* this has killed the LLE/LLME */
2040
2041 printf(" - Attach Request (RA 2)\n");
2042
2043 /* Create a LLE/LLME */
2044 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2045 lle = gprs_lle_get_or_create(ms_tlli, 3);
2046 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2047
2048 /* inject the attach request */
2049 send_0408_message(lle->llme, ms_tlli, &raid2,
2050 attach_req2, ARRAY_SIZE(attach_req2));
2051
2052 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2053 OSMO_ASSERT(ctx != NULL);
2054 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2055 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2056
2057 /* we expect an attach accept */
2058 OSMO_ASSERT(sgsn_tx_counter == 1);
2059 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2060
2061 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2062 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2063 ptmsi1 = received_ptmsi;
2064
2065 /* inject the attach complete */
2066 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2067 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2068 OSMO_ASSERT(ictx != NULL);
2069 OSMO_ASSERT(ictx == ctx);
2070
Harald Weltef97ee042015-12-25 19:12:21 +01002071 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002072 attach_compl, ARRAY_SIZE(attach_compl));
2073
2074 /* we don't expect a response */
2075 OSMO_ASSERT(sgsn_tx_counter == 0);
2076
2077 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2078 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2079 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2080
2081 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2082
2083 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01002084 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002085 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2086
2087 /* we expect an RA update accept */
2088 OSMO_ASSERT(sgsn_tx_counter == 1);
2089 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2090
2091 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2092 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2093 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2094 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2095
2096 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2097 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2098 ptmsi1 = received_ptmsi;
2099
2100 /* inject the RA update complete */
2101 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002102 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002103 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2104
2105 /* we don't expect a response */
2106 OSMO_ASSERT(sgsn_tx_counter == 0);
2107
2108 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2109 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2110 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002111 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002112
2113
2114 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01002115 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002116 detach_req, ARRAY_SIZE(detach_req));
2117
2118 /* verify that things are gone */
2119 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2120 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2121 OSMO_ASSERT(!ictx);
2122
2123 sgsn->cfg.auth_policy = saved_auth_policy;
2124
2125 cleanup_test();
2126}
2127
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002128static void test_apn_matching(void)
2129{
2130 struct apn_ctx *actx, *actxs[9];
2131
2132 printf("Testing APN matching\n");
2133
2134 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2135 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2136 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2137 actxs[3] = NULL;
2138
2139 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2140 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2141 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2142 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2143
2144 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2145
2146 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2147 OSMO_ASSERT(actx == actxs[2]);
2148 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2149 OSMO_ASSERT(actx == actxs[2]);
2150 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2151 OSMO_ASSERT(actx == actxs[1]);
2152 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2153 OSMO_ASSERT(actx == actxs[1]);
2154 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2155 OSMO_ASSERT(actx == actxs[0]);
2156 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2157 OSMO_ASSERT(actx == NULL);
2158
2159 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2160 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2161 OSMO_ASSERT(actx == actxs[3]);
2162
2163 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2164 OSMO_ASSERT(actx == actxs[4]);
2165
2166 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2167 OSMO_ASSERT(actx == actxs[6]);
2168
2169 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2170 OSMO_ASSERT(actx == actxs[5]);
2171
2172 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2173 OSMO_ASSERT(actx == actxs[7]);
2174
2175 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2176 OSMO_ASSERT(actx == actxs[8]);
2177
2178 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2179 OSMO_ASSERT(actx == actxs[7]);
2180
2181 /* Free APN contexts and check how the matching changes */
2182
2183 sgsn_apn_ctx_free(actxs[7]);
2184 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2185 OSMO_ASSERT(actx == actxs[8]);
2186
2187 sgsn_apn_ctx_free(actxs[8]);
2188 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2189 OSMO_ASSERT(actx == actxs[6]);
2190
2191 sgsn_apn_ctx_free(actxs[6]);
2192 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2193 OSMO_ASSERT(actx == actxs[1]);
2194
2195 sgsn_apn_ctx_free(actxs[5]);
2196 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2197 OSMO_ASSERT(actx == actxs[4]);
2198
2199 sgsn_apn_ctx_free(actxs[4]);
2200 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2201 OSMO_ASSERT(actx == actxs[2]);
2202
2203 sgsn_apn_ctx_free(actxs[2]);
2204 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2205 OSMO_ASSERT(actx == actxs[1]);
2206
2207 sgsn_apn_ctx_free(actxs[1]);
2208 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2209 OSMO_ASSERT(actx == actxs[0]);
2210
2211 sgsn_apn_ctx_free(actxs[0]);
2212 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2213 OSMO_ASSERT(actx == actxs[3]);
2214
2215 sgsn_apn_ctx_free(actxs[3]);
2216 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2217 OSMO_ASSERT(actx == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002218
2219 cleanup_test();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002220}
2221
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002222struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2223 struct sgsn_subscriber_data *sdata);
2224
2225static void test_ggsn_selection(void)
2226{
2227 struct apn_ctx *actxs[4];
2228 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
2229 struct gsm_subscriber *s1;
2230 const char *imsi1 = "1234567890";
2231 struct sgsn_mm_ctx *ctx;
2232 struct gprs_ra_id raid = { 0, };
2233 uint32_t local_tlli = 0xffeeddcc;
2234 enum gsm48_gsm_cause gsm_cause;
2235 struct tlv_parsed tp;
2236 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2237 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002238 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002239
2240 printf("Testing GGSN selection\n");
2241
2242 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
2243
2244 /* Check for emptiness */
2245 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2246
2247 /* Create a context */
2248 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2249 ctx = alloc_mm_ctx(local_tlli, &raid);
2250 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
2251
2252 /* Allocate and attach a subscriber */
2253 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2254 assert_subscr(s1, imsi1);
2255
2256 tp.lv[GSM48_IE_GSM_APN].len = 0;
2257 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2258
2259 /* TODO: Add PDP info entries to s1 */
2260
2261 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2262 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2263 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2264
2265 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2266 actxs[0]->ggsn = ggcs[0];
2267 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2268 actxs[1]->ggsn = ggcs[1];
2269 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2270 actxs[2]->ggsn = ggcs[2];
2271
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002272 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2273 pdp_data->context_id = 1;
2274 pdp_data->pdp_type = 0x0121;
2275 strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
2276
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002277 /* Resolve GGSNs */
2278
2279 tp.lv[GSM48_IE_GSM_APN].len =
2280 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2281
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002282 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002283 OSMO_ASSERT(ggc != NULL);
2284 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002285 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002286
2287 tp.lv[GSM48_IE_GSM_APN].len =
2288 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2289
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002290 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002291 OSMO_ASSERT(ggc != NULL);
2292 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002293 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002294
2295 tp.lv[GSM48_IE_GSM_APN].len = 0;
2296 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2297
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002298 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002299 OSMO_ASSERT(ggc != NULL);
2300 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002301 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002302
2303 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2304 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002305 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002306 OSMO_ASSERT(ggc != NULL);
2307 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002308 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002309
2310 sgsn_apn_ctx_free(actxs[3]);
2311 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2312
2313 tp.lv[GSM48_IE_GSM_APN].len =
2314 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2315
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002316 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002317 OSMO_ASSERT(ggc == NULL);
2318 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002319 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002320
2321 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002322 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002323 OSMO_ASSERT(ggc == NULL);
2324 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2325
2326 /* Add PDP data entry to subscriber */
2327
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002328 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
2329
2330 tp.lv[GSM48_IE_GSM_APN].len =
2331 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2332
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002333 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002334 OSMO_ASSERT(ggc != NULL);
2335 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002336 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002337
2338 tp.lv[GSM48_IE_GSM_APN].len =
2339 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2340
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002341 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002342 OSMO_ASSERT(ggc == NULL);
2343 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002344 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002345
2346 /* Cleanup */
2347
2348 subscr_put(s1);
2349 sgsn_mm_ctx_cleanup_free(ctx);
2350
2351 assert_no_subscrs();
2352
2353 sgsn_apn_ctx_free(actxs[0]);
2354 sgsn_apn_ctx_free(actxs[1]);
2355 sgsn_apn_ctx_free(actxs[2]);
2356
2357 sgsn_ggsn_ctx_free(ggcs[0]);
2358 sgsn_ggsn_ctx_free(ggcs[1]);
2359 sgsn_ggsn_ctx_free(ggcs[2]);
2360
2361 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002362
2363 cleanup_test();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002364}
2365
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002366static struct log_info_cat gprs_categories[] = {
2367 [DMM] = {
2368 .name = "DMM",
2369 .description = "Layer3 Mobility Management (MM)",
2370 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002371 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002372 },
2373 [DPAG] = {
2374 .name = "DPAG",
2375 .description = "Paging Subsystem",
2376 .color = "\033[1;38m",
2377 .enabled = 1, .loglevel = LOGL_NOTICE,
2378 },
2379 [DMEAS] = {
2380 .name = "DMEAS",
2381 .description = "Radio Measurement Processing",
2382 .enabled = 0, .loglevel = LOGL_NOTICE,
2383 },
2384 [DREF] = {
2385 .name = "DREF",
2386 .description = "Reference Counting",
2387 .enabled = 0, .loglevel = LOGL_NOTICE,
2388 },
2389 [DGPRS] = {
2390 .name = "DGPRS",
2391 .description = "GPRS Packet Service",
2392 .enabled = 1, .loglevel = LOGL_DEBUG,
2393 },
2394 [DNS] = {
2395 .name = "DNS",
2396 .description = "GPRS Network Service (NS)",
2397 .enabled = 1, .loglevel = LOGL_INFO,
2398 },
2399 [DBSSGP] = {
2400 .name = "DBSSGP",
2401 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2402 .enabled = 1, .loglevel = LOGL_DEBUG,
2403 },
2404 [DLLC] = {
2405 .name = "DLLC",
2406 .description = "GPRS Logical Link Control Protocol (LLC)",
2407 .enabled = 1, .loglevel = LOGL_DEBUG,
2408 },
2409 [DSNDCP] = {
2410 .name = "DSNDCP",
2411 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2412 .enabled = 1, .loglevel = LOGL_DEBUG,
2413 },
2414};
2415
2416static struct log_info info = {
2417 .cat = gprs_categories,
2418 .num_cat = ARRAY_SIZE(gprs_categories),
2419};
2420
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002421int main(int argc, char **argv)
2422{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002423 void *osmo_sgsn_ctx;
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002424 void *msgb_ctx;
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002425
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002426 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002427 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2428 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002429 msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002430
Alexander Couzens14314bd2016-07-05 09:52:52 +02002431 sgsn_rate_ctr_init();
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01002432 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002433 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002434
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002435 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002436 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002437 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002438 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002439 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002440 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002441 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002442 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002443 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002444 test_gmm_attach_acl();
2445 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002446 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002447 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002448 test_gmm_attach_subscr_gsup_auth(0);
2449 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002450 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002451 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002452 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002453 test_gmm_ptmsi_allocation();
Jacob Erlbeck13304782016-01-04 18:43:37 +01002454 test_gmm_routing_areas();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002455 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002456 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002457 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002458
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002459 talloc_report_full(osmo_sgsn_ctx, stderr);
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002460 OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);
Alexander Couzens14314bd2016-07-05 09:52:52 +02002461 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 2);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002462 return 0;
2463}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002464
2465
2466/* stubs */
2467struct osmo_prim_hdr;
2468int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2469{
2470 abort();
2471}