blob: 01e94c72d59d58351f54faf7bfaded1519a19af4 [file] [log] [blame]
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
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>
Jacob Erlbeckbce20612015-01-05 18:57:32 +010035#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020036
37#include <osmocom/core/application.h>
38#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010039#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020040
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020041#include <stdio.h>
42
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020043extern void *tall_msgb_ctx;
44
45void *tall_bsc_ctx;
46static struct sgsn_instance sgsn_inst = {
47 .config_file = "osmo_sgsn.cfg",
48 .cfg = {
49 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010050 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020051 },
52};
53struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010054unsigned sgsn_tx_counter = 0;
Jacob Erlbeck133e8622015-10-12 19:36:32 +020055struct msgb *last_msg = NULL;
56struct gprs_gb_parse_context last_dl_parse_ctx;
57
58static void reset_last_msg()
59{
60 if (last_msg)
61 msgb_free(last_msg);
62
63 last_msg = NULL;
64 memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx));
65}
Jacob Erlbeck189999d2014-10-27 14:34:13 +010066
Jacob Erlbeckcf151872015-10-12 19:36:31 +020067static void cleanup_test()
68{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020069 reset_last_msg();
70}
71
72static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
73{
74 uint32_t new_ptmsi = GSM_RESERVED_TMSI;
75
76 if (parse_ctx->new_ptmsi_enc)
77 gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
78
79 return new_ptmsi;
Jacob Erlbeckcf151872015-10-12 19:36:31 +020080}
81
Jacob Erlbeck189999d2014-10-27 14:34:13 +010082/* override */
83int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
84 struct bssgp_dl_ud_par *dup)
85{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020086 int rc;
87
88 reset_last_msg();
89
90 last_msg = msg;
91 OSMO_ASSERT(msgb_data(last_msg) != NULL);
92
93 rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg),
94 &last_dl_parse_ctx);
95
96 fprintf(stderr, "Got DL LLC message: %s\n",
97 gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN"));
98
99 OSMO_ASSERT(rc > 0);
100
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100101 sgsn_tx_counter += 1;
102 return 0;
103}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200104
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100105/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100106void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
107void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100108 &__real_sgsn_update_subscriber_data;
109
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100110void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100111{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100112 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100113}
114
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100115/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
116int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
117int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
118 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100119
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100120int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
121 return (*subscr_request_update_location_cb)(mmctx);
122};
123
124/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
125int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
126int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
127 &__real_gprs_subscr_request_auth_info;
128
129int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
130 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100131};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100132
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100133/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
134int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
135int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
136 &__real_gprs_gsup_client_send;
137
138int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
139{
140 return (*gprs_gsup_client_send_cb)(gsupc, msg);
141};
142
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200143static int count(struct llist_head *head)
144{
145 struct llist_head *cur;
146 int count = 0;
147
148 llist_for_each(cur, head)
149 count += 1;
150
151 return count;
152}
153
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200154static struct msgb *create_msg(const uint8_t *data, size_t len)
155{
156 struct msgb *msg = msgb_alloc(len + 8, "test message");
157 msg->l1h = msgb_put(msg, 8);
158 msg->l2h = msgb_put(msg, len);
159 memcpy(msg->l2h, data, len);
160
161 msgb_bcid(msg) = msg->l1h;
162 msgb_gmmh(msg) = msg->l2h;
163 return msg;
164}
165
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100166/*
167 * Create a context and search for it
168 */
169static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
170{
171 struct sgsn_mm_ctx *ctx, *ictx;
172 struct gprs_llc_lle *lle;
173 int old_count = count(gprs_llme_list());
174
175 lle = gprs_lle_get_or_create(tlli, 3);
176 ctx = sgsn_mm_ctx_alloc(tlli, raid);
177 ctx->mm_state = GMM_REGISTERED_NORMAL;
178 ctx->llme = lle->llme;
179
180 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
181 OSMO_ASSERT(ictx == ctx);
182
183 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
184
185 return ctx;
186}
187
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100188static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
189 const uint8_t *data, size_t data_len)
190{
191 struct msgb *msg;
192
Jacob Erlbeck133e8622015-10-12 19:36:32 +0200193 reset_last_msg();
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100194 sgsn_tx_counter = 0;
195
196 msg = create_msg(data, data_len);
197 msgb_tlli(msg) = tlli;
198 gsm0408_gprs_rcvmsg(msg, llme);
199 msgb_free(msg);
200}
201
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200202static void test_llme(void)
203{
204 struct gprs_llc_lle *lle, *lle_copy;
205 uint32_t local_tlli;
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200206
207 printf("Testing LLME allocations\n");
208 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200209
210 /* initial state */
211 OSMO_ASSERT(count(gprs_llme_list()) == 0);
212
213 /* Create a new entry */
214 lle = gprs_lle_get_or_create(local_tlli, 3);
215 OSMO_ASSERT(lle);
216 OSMO_ASSERT(count(gprs_llme_list()) == 1);
217
218 /* No new entry is created */
219 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
220 OSMO_ASSERT(lle == lle_copy);
221 OSMO_ASSERT(count(gprs_llme_list()) == 1);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200222
223 /* unassign which should delete it*/
224 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
225
226 /* Check that everything was cleaned up */
227 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200228
229 cleanup_test();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200230}
231
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100232struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100233void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100234{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100235 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100236 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100237 __func__, mmctx, mmctx->subscr);
238 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100239}
240
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100241static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
242{
243 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100244 OSMO_ASSERT(subscr);
245 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100246
247 sfound = gprs_subscr_get_by_imsi(imsi);
248 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100249
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100250 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100251}
252
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100253static void show_subscrs(FILE *out)
254{
255 struct gsm_subscriber *subscr;
256
257 llist_for_each_entry(subscr, &active_subscribers, entry) {
258 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100259 "use count: %d\n",
260 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100261 }
262}
263
264static void assert_no_subscrs()
265{
266 show_subscrs(stdout);
267 fflush(stdout);
268 OSMO_ASSERT(llist_empty(&active_subscribers));
269}
270
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100271static void test_subscriber(void)
272{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100273 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100274 const char *imsi1 = "1234567890";
275 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100276 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100277
278 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
279
280 printf("Testing core subscriber data API\n");
281
282 /* Check for emptiness */
283 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
284 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100285 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100286
287 /* Allocate entry 1 */
288 s1 = gprs_subscr_get_or_create(imsi1);
289 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100290 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100291 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100292
293 /* Allocate entry 2 */
294 s2 = gprs_subscr_get_or_create(imsi2);
295 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100296
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100297 /* Allocate entry 3 */
298 s3 = gprs_subscr_get_or_create(imsi3);
299
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100300 /* Check entries */
301 assert_subscr(s1, imsi1);
302 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100303 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100304
305 /* Update entry 1 */
306 last_updated_subscr = NULL;
307 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100308 OSMO_ASSERT(last_updated_subscr == NULL);
309 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
310 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100311
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100312 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100313 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100314 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100315 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100316 sfound = gprs_subscr_get_by_imsi(imsi1);
317 OSMO_ASSERT(sfound == NULL);
318
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100319 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100320 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100321
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100322 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100323 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100324 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100325 s2 = NULL;
326 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
327 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100328 assert_subscr(s3, imsi3);
329
330 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100331 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100332 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100333 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100334 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100335
336 OSMO_ASSERT(llist_empty(&active_subscribers));
337
338 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200339
340 cleanup_test();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100341}
342
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100343static void test_auth_triplets(void)
344{
345 struct gsm_subscriber *s1, *s1found;
346 const char *imsi1 = "1234567890";
347 struct gsm_auth_tuple *at;
348 struct sgsn_mm_ctx *ctx;
349 struct gprs_ra_id raid = { 0, };
350 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100351
352 printf("Testing authentication triplet handling\n");
353
354 /* Check for emptiness */
355 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
356
357 /* Allocate entry 1 */
358 s1 = gprs_subscr_get_or_create(imsi1);
359 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
360 s1found = gprs_subscr_get_by_imsi(imsi1);
361 OSMO_ASSERT(s1found == s1);
362 subscr_put(s1found);
363
364 /* Create a context */
365 OSMO_ASSERT(count(gprs_llme_list()) == 0);
366 ctx = alloc_mm_ctx(local_tlli, &raid);
367
368 /* Attach s1 to ctx */
369 ctx->subscr = subscr_get(s1);
370 ctx->subscr->sgsn_data->mm = ctx;
371
372 /* Try to get auth tuple */
373 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
374 OSMO_ASSERT(at == NULL);
375
376 /* Add triplets */
377 s1->sgsn_data->auth_triplets[0].key_seq = 0;
378 s1->sgsn_data->auth_triplets[1].key_seq = 1;
379 s1->sgsn_data->auth_triplets[2].key_seq = 2;
380
381 /* Try to get auth tuple */
382 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
383 OSMO_ASSERT(at != NULL);
384 OSMO_ASSERT(at->key_seq == 0);
385 OSMO_ASSERT(at->use_count == 1);
386 at = sgsn_auth_get_tuple(ctx, at->key_seq);
387 OSMO_ASSERT(at != NULL);
388 OSMO_ASSERT(at->key_seq == 1);
389 OSMO_ASSERT(at->use_count == 1);
390 at = sgsn_auth_get_tuple(ctx, at->key_seq);
391 OSMO_ASSERT(at != NULL);
392 OSMO_ASSERT(at->key_seq == 2);
393 OSMO_ASSERT(at->use_count == 1);
394 at = sgsn_auth_get_tuple(ctx, at->key_seq);
395 OSMO_ASSERT(at == NULL);
396
397 /* Free MM context and subscriber */
398 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100399 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100400 s1found = gprs_subscr_get_by_imsi(imsi1);
401 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200402
403 cleanup_test();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100404}
405
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100406#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
407
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100408static int rx_gsup_message(const uint8_t *data, size_t data_len)
409{
410 struct msgb *msg;
411 int rc;
412
413 msg = msgb_alloc(1024, __func__);
414 msg->l2h = msgb_put(msg, data_len);
415 OSMO_ASSERT(msg->l2h != NULL);
416 memcpy(msg->l2h, data, data_len);
417 rc = gprs_subscr_rx_gsup_message(msg);
418 msgb_free(msg);
419
420 return rc;
421}
422
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100423static void test_subscriber_gsup(void)
424{
425 struct gsm_subscriber *s1, *s1found;
426 const char *imsi1 = "1234567890";
427 struct sgsn_mm_ctx *ctx;
428 struct gprs_ra_id raid = { 0, };
429 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100430 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100431 int rc;
432
433 static const uint8_t send_auth_info_res[] = {
434 0x0a,
435 TEST_GSUP_IMSI1_IE,
436 0x03, 0x22, /* Auth tuple */
437 0x20, 0x10,
438 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
439 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
440 0x21, 0x04,
441 0x21, 0x22, 0x23, 0x24,
442 0x22, 0x08,
443 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
444 0x03, 0x22, /* Auth tuple */
445 0x20, 0x10,
446 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
447 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
448 0x21, 0x04,
449 0xa1, 0xa2, 0xa3, 0xa4,
450 0x22, 0x08,
451 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
452 };
453
454 static const uint8_t send_auth_info_err[] = {
455 0x09,
456 TEST_GSUP_IMSI1_IE,
457 0x02, 0x01, 0x07 /* GPRS not allowed */
458 };
459
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400460#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
461
462 static const uint8_t s1_msisdn[] = { MSISDN };
463
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100464 static const uint8_t update_location_res[] = {
465 0x06,
466 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400467 0x08, 0x09, MSISDN,
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100468 0x04, 0x00, /* PDP info complete */
469 0x05, 0x12,
470 0x10, 0x01, 0x01,
471 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
472 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
473 0x05, 0x11,
474 0x10, 0x01, 0x02,
475 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
476 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
477 };
478
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400479#undef MSISDN
480
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100481 static const uint8_t update_location_err[] = {
482 0x05,
483 TEST_GSUP_IMSI1_IE,
484 0x02, 0x01, 0x07 /* GPRS not allowed */
485 };
486
487 static const uint8_t location_cancellation_req[] = {
488 0x1c,
489 TEST_GSUP_IMSI1_IE,
490 0x06, 0x01, 0x00,
491 };
492
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200493 static const uint8_t location_cancellation_req_withdraw[] = {
494 0x1c,
495 TEST_GSUP_IMSI1_IE,
496 0x06, 0x01, 0x01,
497 };
498
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100499 static const uint8_t location_cancellation_req_other[] = {
500 0x1c,
501 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
502 0x06, 0x01, 0x00,
503 };
504
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100505 static const uint8_t purge_ms_err[] = {
506 0x0d,
507 TEST_GSUP_IMSI1_IE,
508 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
509 };
510
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100511 static const uint8_t purge_ms_err_no_cause[] = {
512 0x0d,
513 TEST_GSUP_IMSI1_IE,
514 };
515
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100516 static const uint8_t purge_ms_res[] = {
517 0x0e,
518 TEST_GSUP_IMSI1_IE,
519 0x07, 0x00,
520 };
521
522
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100523 static const uint8_t insert_data_req[] = {
524 0x10,
525 TEST_GSUP_IMSI1_IE,
526 0x05, 0x11,
527 0x10, 0x01, 0x03,
528 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
529 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
530 };
531
532 static const uint8_t delete_data_req[] = {
533 0x14,
534 TEST_GSUP_IMSI1_IE,
535 0x10, 0x01, 0x03,
536 };
537
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100538 printf("Testing subcriber GSUP handling\n");
539
540 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
541
542 /* Check for emptiness */
543 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
544
545 /* Allocate entry 1 */
546 s1 = gprs_subscr_get_or_create(imsi1);
547 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
548 s1found = gprs_subscr_get_by_imsi(imsi1);
549 OSMO_ASSERT(s1found == s1);
550 subscr_put(s1found);
551
552 /* Create a context */
553 OSMO_ASSERT(count(gprs_llme_list()) == 0);
554 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100555
556 /* Attach s1 to ctx */
557 ctx->subscr = subscr_get(s1);
558 ctx->subscr->sgsn_data->mm = ctx;
559
560 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100561 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100562 OSMO_ASSERT(rc >= 0);
563 OSMO_ASSERT(last_updated_subscr == s1);
564
565 /* Check triplets */
566 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
567 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
568 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
569
570 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100571 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100572 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100573 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100574 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100575
576 /* Check triplets */
577 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
578 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
579 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
580
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100581 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100582 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100583 OSMO_ASSERT(rc >= 0);
584 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100585 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100586 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400587 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
588 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100589 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
590 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
591 struct sgsn_subscriber_pdp_data, list);
592 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
593 pdpd = llist_entry(pdpd->list.next,
594 struct sgsn_subscriber_pdp_data, list);
595 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100596
597 /* Check authorization */
598 OSMO_ASSERT(s1->authorized == 1);
599
600 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100601 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100602 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100603 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100604 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100605
606 /* Check authorization */
607 OSMO_ASSERT(s1->authorized == 0);
608
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100609 /* Inject InsertSubscrData GSUP message */
610 last_updated_subscr = NULL;
611 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
612 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
613 OSMO_ASSERT(last_updated_subscr == NULL);
614
615 /* Inject DeleteSubscrData GSUP message */
616 last_updated_subscr = NULL;
617 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
618 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
619 OSMO_ASSERT(last_updated_subscr == NULL);
620
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100621 /* Inject wrong LocCancelReq GSUP message */
622 last_updated_subscr = NULL;
623 rc = rx_gsup_message(location_cancellation_req_other,
624 sizeof(location_cancellation_req_other));
625 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
626 OSMO_ASSERT(last_updated_subscr == NULL);
627
628 /* Check cancellation result */
629 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
630 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
631
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100632 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100633 rc = rx_gsup_message(location_cancellation_req,
634 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100635 OSMO_ASSERT(rc >= 0);
636 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100637 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100638
639 /* Check cancellation result */
640 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
641 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
642
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200643 /* Inject LocCancelReq(withdraw) GSUP message */
644 rc = rx_gsup_message(location_cancellation_req_withdraw,
645 sizeof(location_cancellation_req_withdraw));
646 OSMO_ASSERT(rc >= 0);
647 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
648
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100649 /* Inject PurgeMsRes GSUP message */
650 rc = rx_gsup_message(purge_ms_res,
651 sizeof(purge_ms_res));
652 OSMO_ASSERT(rc >= 0);
653 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
654
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100655 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100656 OSMO_ASSERT(ctx->subscr == NULL);
657 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100658 subscr_put(s1);
659 s1found = gprs_subscr_get_by_imsi(imsi1);
660 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100661
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100662 /* Inject PurgeMsRes GSUP message */
663 rc = rx_gsup_message(purge_ms_res,
664 sizeof(purge_ms_res));
665 OSMO_ASSERT(rc >= 0);
666
667 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
668 rc = rx_gsup_message(purge_ms_err,
669 sizeof(purge_ms_err));
670 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
671
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100672 /* Inject PurgeMsErr() GSUP message */
673 rc = rx_gsup_message(purge_ms_err_no_cause,
674 sizeof(purge_ms_err_no_cause));
675 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
676
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100677 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
678 last_updated_subscr = NULL;
679 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100680 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100681 OSMO_ASSERT(last_updated_subscr == NULL);
682
683 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
684 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
685 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
686 OSMO_ASSERT(last_updated_subscr == NULL);
687
688 /* Inject LocCancelReq GSUP message (unknown IMSI) */
689 rc = rx_gsup_message(location_cancellation_req,
690 sizeof(location_cancellation_req));
691 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
692 OSMO_ASSERT(last_updated_subscr == NULL);
693
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100694 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200695
696 cleanup_test();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100697}
698
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100699int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
700{
701 msgb_free(msg);
702 return 0;
703};
704
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200705/*
706 * Test that a GMM Detach will remove the MMCTX and the
707 * associated LLME.
708 */
709static void test_gmm_detach(void)
710{
711 struct gprs_ra_id raid = { 0, };
712 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200713 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200714
715 printf("Testing GMM detach\n");
716
717 /* DTAP - Detach Request (MO) */
718 /* normal detach, power_off = 0 */
719 static const unsigned char detach_req[] = {
720 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
721 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
722 };
723
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200724 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200725
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100726 /* Create a context */
727 OSMO_ASSERT(count(gprs_llme_list()) == 0);
728 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200729
730 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100731 send_0408_message(ctx->llme, local_tlli,
732 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200733
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100734 /* verify that a single message (hopefully the Detach Accept) has been
735 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100736 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100737
738 /* verify that things are gone */
739 OSMO_ASSERT(count(gprs_llme_list()) == 0);
740 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
741 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200742
743 cleanup_test();
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100744}
745
746/*
747 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
748 * will not sent a Detach Accept message (power_off = 1)
749 */
750static void test_gmm_detach_power_off(void)
751{
752 struct gprs_ra_id raid = { 0, };
753 struct sgsn_mm_ctx *ctx, *ictx;
754 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100755
756 printf("Testing GMM detach (power off)\n");
757
758 /* DTAP - Detach Request (MO) */
759 /* normal detach, power_off = 1 */
760 static const unsigned char detach_req[] = {
761 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
762 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
763 };
764
765 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
766
767 /* Create a context */
768 OSMO_ASSERT(count(gprs_llme_list()) == 0);
769 ctx = alloc_mm_ctx(local_tlli, &raid);
770
771 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100772 send_0408_message(ctx->llme, local_tlli,
773 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100774
775 /* verify that no message (and therefore no Detach Accept) has been
776 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100777 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100778
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200779 /* verify that things are gone */
780 OSMO_ASSERT(count(gprs_llme_list()) == 0);
781 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200782 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200783
784 cleanup_test();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200785}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200786
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200787/*
788 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
789 */
790static void test_gmm_detach_no_mmctx(void)
791{
792 struct gprs_llc_lle *lle;
793 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200794
795 printf("Testing GMM detach (no MMCTX)\n");
796
797 /* DTAP - Detach Request (MO) */
798 /* normal detach, power_off = 0 */
799 static const unsigned char detach_req[] = {
800 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
801 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
802 };
803
804 /* Create an LLME */
805 OSMO_ASSERT(count(gprs_llme_list()) == 0);
806 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
807 lle = gprs_lle_get_or_create(local_tlli, 3);
808
809 OSMO_ASSERT(count(gprs_llme_list()) == 1);
810
811 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100812 send_0408_message(lle->llme, local_tlli,
813 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200814
815 /* verify that the LLME is gone */
816 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200817
818 cleanup_test();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200819}
820
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100821/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100822 * Test that a single GMM Detach Accept message will not cause the SGSN to send
823 * any message or leave an MM context at the SGSN.
824 */
825static void test_gmm_detach_accept_unexpected(void)
826{
827 struct gprs_llc_lle *lle;
828 uint32_t local_tlli;
829
830 printf("Testing GMM detach accept (unexpected)\n");
831
832 /* DTAP - Detach Accept (MT) */
833 /* normal detach */
834 static const unsigned char detach_acc[] = {
835 0x08, 0x06
836 };
837
838 /* Create an LLME */
839 OSMO_ASSERT(count(gprs_llme_list()) == 0);
840 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
841 lle = gprs_lle_get_or_create(local_tlli, 3);
842
843 /* inject the detach */
844 send_0408_message(lle->llme, local_tlli,
845 detach_acc, ARRAY_SIZE(detach_acc));
846
847 /* verify that no message (and therefore no Status or XID reset) has been
848 * sent by the SGSN */
849 OSMO_ASSERT(sgsn_tx_counter == 0);
850
851 /* verify that things are gone */
852 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200853
854 cleanup_test();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100855}
856
857/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100858 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
859 */
860static void test_gmm_status_no_mmctx(void)
861{
862 struct gprs_llc_lle *lle;
863 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100864
865 printf("Testing GMM Status (no MMCTX)\n");
866
867 /* DTAP - GMM Status, protocol error */
868 static const unsigned char gmm_status[] = {
869 0x08, 0x20, 0x6f
870 };
871
872 /* Create an LLME */
873 OSMO_ASSERT(count(gprs_llme_list()) == 0);
874 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
875 lle = gprs_lle_get_or_create(local_tlli, 3);
876
877 OSMO_ASSERT(count(gprs_llme_list()) == 1);
878
879 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100880 send_0408_message(lle->llme, local_tlli,
881 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100882
883 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100884 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100885
886 /* verify that the LLME is gone */
887 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200888
889 cleanup_test();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100890}
891
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100892/*
893 * Test the GMM Attach procedure
894 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100895static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100896{
897 struct gprs_ra_id raid = { 0, };
898 struct sgsn_mm_ctx *ctx = NULL;
899 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100900 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100901 uint32_t foreign_tlli;
902 uint32_t local_tlli = 0;
903 struct gprs_llc_lle *lle;
904
905 /* DTAP - Attach Request */
906 /* The P-TMSI is not known by the SGSN */
907 static const unsigned char attach_req[] = {
908 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
909 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
910 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
911 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
912 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
913 };
914
915 /* DTAP - Identity Response IMEI */
916 static const unsigned char ident_resp_imei[] = {
917 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
918 0x56
919 };
920
921 /* DTAP - Identity Response IMSI */
922 static const unsigned char ident_resp_imsi[] = {
923 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
924 0x54
925 };
926
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100927 /* DTAP - Authentication and Ciphering Resp */
928 static const unsigned char auth_ciph_resp[] = {
929 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
930 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
931 };
932
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100933 /* DTAP - Attach Complete */
934 static const unsigned char attach_compl[] = {
935 0x08, 0x03
936 };
937
938 /* DTAP - Detach Request (MO) */
939 /* normal detach, power_off = 0 */
940 static const unsigned char detach_req[] = {
941 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
942 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
943 };
944
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100945 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100946
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100947 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
948
949 /* Create a LLE/LLME */
950 OSMO_ASSERT(count(gprs_llme_list()) == 0);
951 lle = gprs_lle_get_or_create(foreign_tlli, 3);
952 OSMO_ASSERT(count(gprs_llme_list()) == 1);
953
954 /* inject the attach request */
955 send_0408_message(lle->llme, foreign_tlli,
956 attach_req, ARRAY_SIZE(attach_req));
957
958 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
959 OSMO_ASSERT(ctx != NULL);
960 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
961
962 /* we expect an identity request (IMEI) */
963 OSMO_ASSERT(sgsn_tx_counter == 1);
964
965 /* inject the identity response (IMEI) */
966 send_0408_message(ctx->llme, foreign_tlli,
967 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
968
969 /* we expect an identity request (IMSI) */
970 OSMO_ASSERT(sgsn_tx_counter == 1);
971
972 /* inject the identity response (IMSI) */
973 send_0408_message(ctx->llme, foreign_tlli,
974 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
975
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100976 /* check that the MM context has not been removed due to a failed
977 * authorization */
978 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
979
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100980 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100981
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100982retry_attach_req:
983
984 if (retry && sgsn_tx_counter == 0) {
985 fprintf(stderr, "Retrying attach request\n");
986 /* re-inject the attach request */
987 send_0408_message(lle->llme, foreign_tlli,
988 attach_req, ARRAY_SIZE(attach_req));
989 }
990
991 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
992 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100993
994 /* inject the auth & ciph response */
995 send_0408_message(ctx->llme, foreign_tlli,
996 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
997
998 /* check that the MM context has not been removed due to a
999 * failed authorization */
1000 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001001 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1002 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001003 }
1004
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001005 if (retry && sgsn_tx_counter == 0)
1006 goto retry_attach_req;
1007
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001008 /* we expect an attach accept/reject */
1009 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001010 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1011 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001012
1013 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001014 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001015
1016 /* inject the attach complete */
1017 send_0408_message(ctx->llme, local_tlli,
1018 attach_compl, ARRAY_SIZE(attach_compl));
1019
1020 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1021
1022 /* we don't expect a response */
1023 OSMO_ASSERT(sgsn_tx_counter == 0);
1024
1025 /* inject the detach */
1026 send_0408_message(ctx->llme, local_tlli,
1027 detach_req, ARRAY_SIZE(detach_req));
1028
1029 /* verify that things are gone */
1030 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1031 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1032 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001033
1034 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001035}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001036
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001037static void test_gmm_attach_acl(void)
1038{
1039 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1040
1041 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1042 sgsn_acl_add("123456789012345", &sgsn->cfg);
1043 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001044 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001045 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001046
1047 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001048
1049 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001050}
1051
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001052int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001053 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001054 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001055 if (rc == -ENOTSUP) {
1056 OSMO_ASSERT(mmctx->subscr);
1057 gprs_subscr_update(mmctx->subscr);
1058 }
1059 return rc;
1060};
1061
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001062int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1063 gprs_subscr_update(mmctx->subscr);
1064 return 0;
1065};
1066
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001067static void test_gmm_attach_subscr(void)
1068{
1069 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1070 struct gsm_subscriber *subscr;
1071
1072 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001073 subscr_request_update_location_cb = my_subscr_request_update_location;
1074 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001075
1076 subscr = gprs_subscr_get_or_create("123456789012345");
1077 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001078
1079 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001080 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001081 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001082 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001083
1084 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001085 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1086 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001087
1088 cleanup_test();
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001089}
1090
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001091int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1092{
1093 /* Fake an authentication */
1094 OSMO_ASSERT(mmctx->subscr);
1095 mmctx->is_authenticated = 1;
1096 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001097
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001098 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001099};
1100
1101static void test_gmm_attach_subscr_fake_auth(void)
1102{
1103 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1104 struct gsm_subscriber *subscr;
1105
1106 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001107 subscr_request_update_location_cb = my_subscr_request_update_location;
1108 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001109
1110 subscr = gprs_subscr_get_or_create("123456789012345");
1111 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001112 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001113 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001114
1115 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001116 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001117 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001118 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001119
1120 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001121 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1122 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001123
1124 cleanup_test();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001125}
1126
1127int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1128{
1129 struct gsm_auth_tuple at = {
1130 .sres = {0x51, 0xe5, 0x51, 0xe5},
1131 .key_seq = 0
1132 };
1133
1134 /* Fake an authentication */
1135 OSMO_ASSERT(mmctx->subscr);
1136 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1137
1138 gprs_subscr_update_auth_info(mmctx->subscr);
1139
1140 return 0;
1141};
1142
1143static void test_gmm_attach_subscr_real_auth(void)
1144{
1145 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1146 struct gsm_subscriber *subscr;
1147
1148 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1149 subscr_request_update_location_cb = my_subscr_request_update_location;
1150 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1151
1152 subscr = gprs_subscr_get_or_create("123456789012345");
1153 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001154 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001155 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001156
1157 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001158
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001159 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001160 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001161 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001162
1163 sgsn->cfg.auth_policy = saved_auth_policy;
1164 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1165 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001166
1167 cleanup_test();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001168}
1169
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001170#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1171 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1172
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001173static int auth_info_skip = 0;
1174static int upd_loc_skip = 0;
1175
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001176int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1177{
1178 static const uint8_t send_auth_info_res[] = {
1179 0x0a,
1180 TEST_GSUP_IMSI_LONG_IE,
1181 0x03, 0x22, /* Auth tuple */
1182 0x20, 0x10,
1183 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1184 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1185 0x21, 0x04,
1186 0x51, 0xe5, 0x51, 0xe5,
1187 0x22, 0x08,
1188 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1189 };
1190
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001191 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001192
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001193 if (auth_info_skip > 0) {
1194 auth_info_skip -= 1;
1195 return -EAGAIN;
1196 }
1197
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001198 /* Fake an SendAuthInfoRes */
1199 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1200
1201 return 0;
1202};
1203
1204int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1205 static const uint8_t update_location_res[] = {
1206 0x06,
1207 TEST_GSUP_IMSI_LONG_IE,
1208 0x04, 0x00, /* PDP info complete */
1209 0x05, 0x12,
1210 0x10, 0x01, 0x01,
1211 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1212 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001213 0x08, 0x07, /* MSISDN 49166213323 encoded */
1214 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freyther10c0f562015-05-17 20:58:40 +02001215 0x09, 0x07, /* MSISDN 38166213323 encoded */
1216 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001217 };
1218
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001219 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001220
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001221 if (upd_loc_skip > 0) {
1222 upd_loc_skip -= 1;
1223 return -EAGAIN;
1224 }
1225
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001226 /* Fake an UpdateLocRes */
1227 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1228};
1229
1230
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001231static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001232{
1233 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1234 struct gsm_subscriber *subscr;
1235
1236 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1237 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1238 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001239 if (retry) {
1240 upd_loc_skip = 3;
1241 auth_info_skip = 3;
1242 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001243
1244 subscr = gprs_subscr_get_or_create("123456789012345");
1245 subscr->authorized = 1;
1246 sgsn->cfg.require_authentication = 1;
1247 sgsn->cfg.require_update_location = 1;
1248 subscr_put(subscr);
1249
1250 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001251 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001252 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001253
1254 sgsn->cfg.auth_policy = saved_auth_policy;
1255 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1256 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001257 upd_loc_skip = 0;
1258 auth_info_skip = 0;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001259
1260 cleanup_test();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001261}
1262
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001263int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1264{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001265 struct gprs_gsup_message to_peer = {0};
1266 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001267 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001268 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001269
1270 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001271 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1272 OSMO_ASSERT(rc >= 0);
1273 OSMO_ASSERT(to_peer.imsi[0] != 0);
1274 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001275
1276 /* This invalidates the pointers in to_peer */
1277 msgb_free(msg);
1278
1279 switch (to_peer.message_type) {
1280 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1281 /* Send UPDATE_LOCATION_RESULT */
1282 return my_subscr_request_update_gsup_auth(NULL);
1283
1284 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1285 /* Send SEND_AUTH_INFO_RESULT */
1286 return my_subscr_request_auth_info_gsup_auth(NULL);
1287
1288 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001289 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1290 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001291
1292 default:
1293 if ((to_peer.message_type & 0b00000011) == 0) {
1294 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001295 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001296 from_peer.message_type = to_peer.message_type + 1;
1297 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1298 break;
1299 }
1300
1301 /* Ignore it */
1302 return 0;
1303 }
1304
1305 reply_msg = gprs_gsup_msgb_alloc();
1306 reply_msg->l2h = reply_msg->data;
1307 gprs_gsup_encode(reply_msg, &from_peer);
1308 gprs_subscr_rx_gsup_message(reply_msg);
1309 msgb_free(reply_msg);
1310
1311 return 0;
1312};
1313
1314static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1315{
1316 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1317 struct gsm_subscriber *subscr;
1318
1319 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001320 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1321
1322 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1323
1324 if (retry) {
1325 upd_loc_skip = 3;
1326 auth_info_skip = 3;
1327 }
1328
1329 printf("Auth policy 'remote', real GSUP based auth: ");
1330 test_gmm_attach(retry);
1331
1332 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001333 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001334 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001335
1336 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001337 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1338 upd_loc_skip = 0;
1339 auth_info_skip = 0;
1340 talloc_free(sgsn->gsup_client);
1341 sgsn->gsup_client = NULL;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001342
1343 cleanup_test();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001344}
1345
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001346/*
1347 * Test the GMM Rejects
1348 */
1349static void test_gmm_reject(void)
1350{
1351 struct gprs_ra_id raid = { 0, };
1352 struct sgsn_mm_ctx *ctx = NULL;
1353 uint32_t foreign_tlli;
1354 struct gprs_llc_lle *lle;
1355 int idx;
1356
1357 /* DTAP - Attach Request */
1358 /* Invalid MI length */
1359 static const unsigned char attach_req_inv_mi_len[] = {
1360 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1361 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1362 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1363 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1364 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1365 };
1366
1367 /* DTAP - Attach Request */
1368 /* Invalid MI type (IMEI) */
1369 static const unsigned char attach_req_inv_mi_type[] = {
1370 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1371 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1372 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1373 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1374 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1375 };
1376
1377 /* DTAP - Routing Area Update Request */
1378 static const unsigned char dtap_ra_upd_req[] = {
1379 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1380 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1381 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1382 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1383 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1384 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1385 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1386 };
1387
1388 /* DTAP - Routing Area Update Request */
1389 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1390 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1391 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1392 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1393 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1394 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1395 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1396 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1397 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1398 };
1399
1400 /* DTAP - Routing Area Update Request */
1401 /* Invalid cap length */
1402 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1403 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1404 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1405 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1406 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1407 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1408 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1409 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1410 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1411 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1412 };
1413
1414 struct test {
1415 const char *title;
1416 const unsigned char *msg;
1417 unsigned msg_len;
1418 unsigned num_resp;
1419
1420 };
1421 static struct test tests[] = {
1422 {
1423 .title = "Attach Request (invalid MI length)",
1424 .msg = attach_req_inv_mi_len,
1425 .msg_len = sizeof(attach_req_inv_mi_len),
1426 .num_resp = 1 /* Reject */
1427
1428 },
1429 {
1430 .title = "Attach Request (invalid MI type)",
1431 .msg = attach_req_inv_mi_type,
1432 .msg_len = sizeof(attach_req_inv_mi_type),
1433 .num_resp = 1 /* Reject */
1434 },
1435 {
1436 .title = "Routing Area Update Request (valid)",
1437 .msg = dtap_ra_upd_req,
1438 .msg_len = sizeof(dtap_ra_upd_req),
1439 .num_resp = 2 /* XID Reset + Reject */
1440 },
1441 {
1442 .title = "Routing Area Update Request (invalid type)",
1443 .msg = dtap_ra_upd_req_inv_type,
1444 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1445 .num_resp = 1 /* Reject */
1446 },
1447 {
1448 .title = "Routing Area Update Request (invalid CAP length)",
1449 .msg = dtap_ra_upd_req_inv_cap_len,
1450 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1451 .num_resp = 1 /* Reject */
1452 },
1453 };
1454
1455 printf("Testing GMM reject\n");
1456
1457 /* reset the PRNG used by sgsn_alloc_ptmsi */
1458 srand(1);
1459
1460 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1461
1462 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1463
1464 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1465 const struct test *test = &tests[idx];
1466 printf(" - %s\n", test->title);
1467
1468 /* Create a LLE/LLME */
1469 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1470 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1471
1472 /* Inject the Request message */
1473 send_0408_message(lle->llme, foreign_tlli,
1474 test->msg, test->msg_len);
1475
1476 /* We expect a Reject message */
1477 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1478 sgsn_tx_counter, test->num_resp);
1479 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1480
1481 /* verify that LLME/MM are removed */
1482 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1483 OSMO_ASSERT(ctx == NULL);
1484 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1485 }
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001486
1487 cleanup_test();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001488}
1489
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001490/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001491 * Test cancellation of attached MM contexts
1492 */
1493static void test_gmm_cancel(void)
1494{
1495 struct gprs_ra_id raid = { 0, };
1496 struct sgsn_mm_ctx *ctx = NULL;
1497 struct sgsn_mm_ctx *ictx;
1498 uint32_t ptmsi1;
1499 uint32_t foreign_tlli;
1500 uint32_t local_tlli = 0;
1501 struct gprs_llc_lle *lle;
1502 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1503
1504 /* DTAP - Attach Request */
1505 /* The P-TMSI is not known by the SGSN */
1506 static const unsigned char attach_req[] = {
1507 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1508 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1509 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1510 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1511 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1512 };
1513
1514 /* DTAP - Identity Response IMEI */
1515 static const unsigned char ident_resp_imei[] = {
1516 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1517 0x56
1518 };
1519
1520 /* DTAP - Identity Response IMSI */
1521 static const unsigned char ident_resp_imsi[] = {
1522 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1523 0x54
1524 };
1525
1526 /* DTAP - Attach Complete */
1527 static const unsigned char attach_compl[] = {
1528 0x08, 0x03
1529 };
1530
1531 printf("Testing cancellation\n");
1532
1533 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1534
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001535 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1536
1537 /* Create a LLE/LLME */
1538 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1539 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1540 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1541
1542 /* inject the attach request */
1543 send_0408_message(lle->llme, foreign_tlli,
1544 attach_req, ARRAY_SIZE(attach_req));
1545
1546 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1547 OSMO_ASSERT(ctx != NULL);
1548 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1549
1550 /* we expect an identity request (IMEI) */
1551 OSMO_ASSERT(sgsn_tx_counter == 1);
1552
1553 /* inject the identity response (IMEI) */
1554 send_0408_message(ctx->llme, foreign_tlli,
1555 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1556
1557 /* we expect an identity request (IMSI) */
1558 OSMO_ASSERT(sgsn_tx_counter == 1);
1559
1560 /* inject the identity response (IMSI) */
1561 send_0408_message(ctx->llme, foreign_tlli,
1562 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1563
1564 /* check that the MM context has not been removed due to a failed
1565 * authorization */
1566 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1567
1568 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1569
1570 /* we expect an attach accept/reject */
1571 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001572 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1573 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001574
1575 /* this has been randomly assigned by the SGSN */
1576 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1577
1578 /* inject the attach complete */
1579 send_0408_message(ctx->llme, local_tlli,
1580 attach_compl, ARRAY_SIZE(attach_compl));
1581
1582 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1583
1584 /* we don't expect a response */
1585 OSMO_ASSERT(sgsn_tx_counter == 0);
1586
1587 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001588 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001589
1590 /* verify that things are gone */
1591 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1592 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1593 OSMO_ASSERT(!ictx);
1594
1595 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001596
1597 cleanup_test();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001598}
1599
1600/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001601 * Test the dynamic allocation of P-TMSIs
1602 */
1603static void test_gmm_ptmsi_allocation(void)
1604{
1605 struct gprs_ra_id raid = { 0, };
1606 struct sgsn_mm_ctx *ctx = NULL;
1607 struct sgsn_mm_ctx *ictx;
1608 uint32_t foreign_tlli;
1609 uint32_t ptmsi1;
1610 uint32_t ptmsi2;
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001611 uint32_t received_ptmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001612 uint32_t old_ptmsi;
1613 uint32_t local_tlli = 0;
1614 struct gprs_llc_lle *lle;
1615 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1616
1617 /* DTAP - Attach Request (IMSI 12131415161718) */
1618 static const unsigned char attach_req[] = {
1619 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1620 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1621 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1622 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1623 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1624 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1625 0x00,
1626 };
1627
1628 /* DTAP - Identity Response IMEI */
1629 static const unsigned char ident_resp_imei[] = {
1630 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1631 0x56
1632 };
1633
1634 /* DTAP - Attach Complete */
1635 static const unsigned char attach_compl[] = {
1636 0x08, 0x03
1637 };
1638
1639 /* DTAP - Routing Area Update Request */
1640 static const unsigned char ra_upd_req[] = {
1641 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1642 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1643 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1644 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1645 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1646 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1647 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1648 };
1649
1650 /* DTAP - Routing Area Update Complete */
1651 static const unsigned char ra_upd_complete[] = {
1652 0x08, 0x0a
1653 };
1654
1655 /* DTAP - Detach Request (MO) */
1656 /* normal detach, power_off = 1 */
1657 static const unsigned char detach_req[] = {
1658 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1659 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1660 };
1661
1662 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1663
1664 printf("Testing P-TMSI allocation\n");
1665
1666 printf(" - sgsn_alloc_ptmsi\n");
1667
1668 /* reset the PRNG used by sgsn_alloc_ptmsi */
1669 srand(1);
1670
1671 ptmsi1 = sgsn_alloc_ptmsi();
1672 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1673
1674 ptmsi2 = sgsn_alloc_ptmsi();
1675 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1676
1677 OSMO_ASSERT(ptmsi1 != ptmsi2);
1678
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001679 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001680
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001681 printf(" - Repeated Attach Request\n");
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001682
1683 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1684
1685 /* Create a LLE/LLME */
1686 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1687 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1688 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1689
1690 /* inject the attach request */
1691 send_0408_message(lle->llme, foreign_tlli,
1692 attach_req, ARRAY_SIZE(attach_req));
1693
1694 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1695 OSMO_ASSERT(ctx != NULL);
1696 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001697 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1698 ptmsi1 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001699
1700 old_ptmsi = ctx->p_tmsi_old;
1701
1702 /* we expect an identity request (IMEI) */
1703 OSMO_ASSERT(sgsn_tx_counter == 1);
1704
1705 /* inject the identity response (IMEI) */
1706 send_0408_message(ctx->llme, foreign_tlli,
1707 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1708
1709 /* check that the MM context has not been removed due to a failed
1710 * authorization */
1711 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1712
1713 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1714 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1715
1716 /* we expect an attach accept */
1717 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001718 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1719 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001720
1721 /* we ignore this and send the attach again */
1722 send_0408_message(lle->llme, foreign_tlli,
1723 attach_req, ARRAY_SIZE(attach_req));
1724
1725 /* the allocated P-TMSI should be the same */
1726 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1727 OSMO_ASSERT(ctx != NULL);
1728 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1729 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1730 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1731
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001732 /* we expect an attach accept */
1733 OSMO_ASSERT(sgsn_tx_counter == 1);
1734 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1735 OSMO_ASSERT(received_ptmsi == ptmsi1);
1736
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001737 /* inject the attach complete */
1738 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1739 send_0408_message(ctx->llme, local_tlli,
1740 attach_compl, ARRAY_SIZE(attach_compl));
1741
1742 /* we don't expect a response */
1743 OSMO_ASSERT(sgsn_tx_counter == 0);
1744
1745 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1746 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1747 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1748
1749 printf(" - Repeated RA Update Request\n");
1750
1751 /* inject the RA update request */
1752 send_0408_message(ctx->llme, local_tlli,
1753 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1754
1755 /* we expect an RA update accept */
1756 OSMO_ASSERT(sgsn_tx_counter == 1);
1757
1758 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1759 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001760 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1761 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1762 ptmsi2 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001763
1764 /* repeat the RA update request */
1765 send_0408_message(ctx->llme, local_tlli,
1766 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1767
1768 /* we expect an RA update accept */
1769 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001770 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1771 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001772
1773 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1774 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1775 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1776
1777 /* inject the RA update complete */
1778 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1779 send_0408_message(ctx->llme, local_tlli,
1780 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1781
1782 /* we don't expect a response */
1783 OSMO_ASSERT(sgsn_tx_counter == 0);
1784
1785 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1786 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1787 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1788
1789 /* inject the detach */
1790 send_0408_message(ctx->llme, local_tlli,
1791 detach_req, ARRAY_SIZE(detach_req));
1792
1793 /* verify that things are gone */
1794 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1795 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1796 OSMO_ASSERT(!ictx);
1797
1798 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001799
1800 cleanup_test();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001801}
1802
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01001803static void test_apn_matching(void)
1804{
1805 struct apn_ctx *actx, *actxs[9];
1806
1807 printf("Testing APN matching\n");
1808
1809 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
1810 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
1811 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
1812 actxs[3] = NULL;
1813
1814 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
1815 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
1816 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
1817 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
1818
1819 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
1820
1821 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1822 OSMO_ASSERT(actx == actxs[2]);
1823 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
1824 OSMO_ASSERT(actx == actxs[2]);
1825 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
1826 OSMO_ASSERT(actx == actxs[1]);
1827 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
1828 OSMO_ASSERT(actx == actxs[1]);
1829 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
1830 OSMO_ASSERT(actx == actxs[0]);
1831 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1832 OSMO_ASSERT(actx == NULL);
1833
1834 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
1835 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1836 OSMO_ASSERT(actx == actxs[3]);
1837
1838 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
1839 OSMO_ASSERT(actx == actxs[4]);
1840
1841 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
1842 OSMO_ASSERT(actx == actxs[6]);
1843
1844 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1845 OSMO_ASSERT(actx == actxs[5]);
1846
1847 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
1848 OSMO_ASSERT(actx == actxs[7]);
1849
1850 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
1851 OSMO_ASSERT(actx == actxs[8]);
1852
1853 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1854 OSMO_ASSERT(actx == actxs[7]);
1855
1856 /* Free APN contexts and check how the matching changes */
1857
1858 sgsn_apn_ctx_free(actxs[7]);
1859 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1860 OSMO_ASSERT(actx == actxs[8]);
1861
1862 sgsn_apn_ctx_free(actxs[8]);
1863 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1864 OSMO_ASSERT(actx == actxs[6]);
1865
1866 sgsn_apn_ctx_free(actxs[6]);
1867 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1868 OSMO_ASSERT(actx == actxs[1]);
1869
1870 sgsn_apn_ctx_free(actxs[5]);
1871 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1872 OSMO_ASSERT(actx == actxs[4]);
1873
1874 sgsn_apn_ctx_free(actxs[4]);
1875 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1876 OSMO_ASSERT(actx == actxs[2]);
1877
1878 sgsn_apn_ctx_free(actxs[2]);
1879 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1880 OSMO_ASSERT(actx == actxs[1]);
1881
1882 sgsn_apn_ctx_free(actxs[1]);
1883 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1884 OSMO_ASSERT(actx == actxs[0]);
1885
1886 sgsn_apn_ctx_free(actxs[0]);
1887 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1888 OSMO_ASSERT(actx == actxs[3]);
1889
1890 sgsn_apn_ctx_free(actxs[3]);
1891 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1892 OSMO_ASSERT(actx == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001893
1894 cleanup_test();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01001895}
1896
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001897struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
1898 struct sgsn_subscriber_data *sdata);
1899
1900static void test_ggsn_selection(void)
1901{
1902 struct apn_ctx *actxs[4];
1903 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
1904 struct gsm_subscriber *s1;
1905 const char *imsi1 = "1234567890";
1906 struct sgsn_mm_ctx *ctx;
1907 struct gprs_ra_id raid = { 0, };
1908 uint32_t local_tlli = 0xffeeddcc;
1909 enum gsm48_gsm_cause gsm_cause;
1910 struct tlv_parsed tp;
1911 uint8_t apn_enc[GSM_APN_LENGTH + 10];
1912 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001913 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001914
1915 printf("Testing GGSN selection\n");
1916
1917 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
1918
1919 /* Check for emptiness */
1920 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
1921
1922 /* Create a context */
1923 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1924 ctx = alloc_mm_ctx(local_tlli, &raid);
1925 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
1926
1927 /* Allocate and attach a subscriber */
1928 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
1929 assert_subscr(s1, imsi1);
1930
1931 tp.lv[GSM48_IE_GSM_APN].len = 0;
1932 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1933
1934 /* TODO: Add PDP info entries to s1 */
1935
1936 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
1937 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
1938 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
1939
1940 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
1941 actxs[0]->ggsn = ggcs[0];
1942 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
1943 actxs[1]->ggsn = ggcs[1];
1944 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
1945 actxs[2]->ggsn = ggcs[2];
1946
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08001947 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
1948 pdp_data->context_id = 1;
1949 pdp_data->pdp_type = 0x0121;
1950 strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
1951
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001952 /* Resolve GGSNs */
1953
1954 tp.lv[GSM48_IE_GSM_APN].len =
1955 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
1956
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001957 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001958 OSMO_ASSERT(ggc != NULL);
1959 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001960 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001961
1962 tp.lv[GSM48_IE_GSM_APN].len =
1963 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
1964
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001965 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001966 OSMO_ASSERT(ggc != NULL);
1967 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001968 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001969
1970 tp.lv[GSM48_IE_GSM_APN].len = 0;
1971 tp.lv[GSM48_IE_GSM_APN].val = NULL;
1972
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001973 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001974 OSMO_ASSERT(ggc != NULL);
1975 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001976 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001977
1978 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
1979 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001980 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001981 OSMO_ASSERT(ggc != NULL);
1982 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001983 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001984
1985 sgsn_apn_ctx_free(actxs[3]);
1986 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1987
1988 tp.lv[GSM48_IE_GSM_APN].len =
1989 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
1990
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001991 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001992 OSMO_ASSERT(ggc == NULL);
1993 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001994 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001995
1996 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08001997 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001998 OSMO_ASSERT(ggc == NULL);
1999 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2000
2001 /* Add PDP data entry to subscriber */
2002
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002003 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
2004
2005 tp.lv[GSM48_IE_GSM_APN].len =
2006 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2007
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002008 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002009 OSMO_ASSERT(ggc != NULL);
2010 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002011 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002012
2013 tp.lv[GSM48_IE_GSM_APN].len =
2014 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2015
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002016 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002017 OSMO_ASSERT(ggc == NULL);
2018 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002019 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002020
2021 /* Cleanup */
2022
2023 subscr_put(s1);
2024 sgsn_mm_ctx_cleanup_free(ctx);
2025
2026 assert_no_subscrs();
2027
2028 sgsn_apn_ctx_free(actxs[0]);
2029 sgsn_apn_ctx_free(actxs[1]);
2030 sgsn_apn_ctx_free(actxs[2]);
2031
2032 sgsn_ggsn_ctx_free(ggcs[0]);
2033 sgsn_ggsn_ctx_free(ggcs[1]);
2034 sgsn_ggsn_ctx_free(ggcs[2]);
2035
2036 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002037
2038 cleanup_test();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002039}
2040
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002041static struct log_info_cat gprs_categories[] = {
2042 [DMM] = {
2043 .name = "DMM",
2044 .description = "Layer3 Mobility Management (MM)",
2045 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002046 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002047 },
2048 [DPAG] = {
2049 .name = "DPAG",
2050 .description = "Paging Subsystem",
2051 .color = "\033[1;38m",
2052 .enabled = 1, .loglevel = LOGL_NOTICE,
2053 },
2054 [DMEAS] = {
2055 .name = "DMEAS",
2056 .description = "Radio Measurement Processing",
2057 .enabled = 0, .loglevel = LOGL_NOTICE,
2058 },
2059 [DREF] = {
2060 .name = "DREF",
2061 .description = "Reference Counting",
2062 .enabled = 0, .loglevel = LOGL_NOTICE,
2063 },
2064 [DGPRS] = {
2065 .name = "DGPRS",
2066 .description = "GPRS Packet Service",
2067 .enabled = 1, .loglevel = LOGL_DEBUG,
2068 },
2069 [DNS] = {
2070 .name = "DNS",
2071 .description = "GPRS Network Service (NS)",
2072 .enabled = 1, .loglevel = LOGL_INFO,
2073 },
2074 [DBSSGP] = {
2075 .name = "DBSSGP",
2076 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2077 .enabled = 1, .loglevel = LOGL_DEBUG,
2078 },
2079 [DLLC] = {
2080 .name = "DLLC",
2081 .description = "GPRS Logical Link Control Protocol (LLC)",
2082 .enabled = 1, .loglevel = LOGL_DEBUG,
2083 },
2084 [DSNDCP] = {
2085 .name = "DSNDCP",
2086 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2087 .enabled = 1, .loglevel = LOGL_DEBUG,
2088 },
2089};
2090
2091static struct log_info info = {
2092 .cat = gprs_categories,
2093 .num_cat = ARRAY_SIZE(gprs_categories),
2094};
2095
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002096int main(int argc, char **argv)
2097{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002098 void *osmo_sgsn_ctx;
2099
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002100 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002101 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2102 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
2103 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002104
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01002105 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002106 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002107
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002108 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002109 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002110 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002111 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002112 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002113 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002114 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002115 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002116 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002117 test_gmm_attach_acl();
2118 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002119 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002120 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002121 test_gmm_attach_subscr_gsup_auth(0);
2122 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002123 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002124 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002125 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002126 test_gmm_ptmsi_allocation();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002127 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002128 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002129 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002130
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002131 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01002132 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002133 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002134 return 0;
2135}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002136
2137
2138/* stubs */
2139struct osmo_prim_hdr;
2140int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2141{
2142 abort();
2143}