blob: 5cffff28947d15b9e1cd8f558a13c36a8cef830f [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 +020042extern void *tall_msgb_ctx;
43
44void *tall_bsc_ctx;
45static struct sgsn_instance sgsn_inst = {
46 .config_file = "osmo_sgsn.cfg",
47 .cfg = {
48 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010049 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020050 },
51};
52struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010053unsigned sgsn_tx_counter = 0;
Jacob Erlbeck133e8622015-10-12 19:36:32 +020054struct msgb *last_msg = NULL;
55struct gprs_gb_parse_context last_dl_parse_ctx;
56
57static void reset_last_msg()
58{
59 if (last_msg)
60 msgb_free(last_msg);
61
62 last_msg = NULL;
63 memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx));
64}
Jacob Erlbeck189999d2014-10-27 14:34:13 +010065
Jacob Erlbeckcf151872015-10-12 19:36:31 +020066static void cleanup_test()
67{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020068 reset_last_msg();
69}
70
71static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
72{
73 uint32_t new_ptmsi = GSM_RESERVED_TMSI;
74
75 if (parse_ctx->new_ptmsi_enc)
76 gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
77
78 return new_ptmsi;
Jacob Erlbeckcf151872015-10-12 19:36:31 +020079}
80
Jacob Erlbeck189999d2014-10-27 14:34:13 +010081/* override */
82int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
83 struct bssgp_dl_ud_par *dup)
84{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020085 int rc;
86
87 reset_last_msg();
88
89 last_msg = msg;
90 OSMO_ASSERT(msgb_data(last_msg) != NULL);
91
92 rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg),
93 &last_dl_parse_ctx);
94
95 fprintf(stderr, "Got DL LLC message: %s\n",
96 gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN"));
97
98 OSMO_ASSERT(rc > 0);
99
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100100 sgsn_tx_counter += 1;
101 return 0;
102}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200103
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100104/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100105void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
106void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100107 &__real_sgsn_update_subscriber_data;
108
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100109void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100110{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100111 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100112}
113
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100114/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
115int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
116int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
117 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100118
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100119int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
120 return (*subscr_request_update_location_cb)(mmctx);
121};
122
123/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
124int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
125int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
126 &__real_gprs_subscr_request_auth_info;
127
128int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
129 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100130};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100131
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100132/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
133int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
134int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
135 &__real_gprs_gsup_client_send;
136
137int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
138{
139 return (*gprs_gsup_client_send_cb)(gsupc, msg);
140};
141
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200142static int count(struct llist_head *head)
143{
144 struct llist_head *cur;
145 int count = 0;
146
147 llist_for_each(cur, head)
148 count += 1;
149
150 return count;
151}
152
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200153static struct msgb *create_msg(const uint8_t *data, size_t len)
154{
155 struct msgb *msg = msgb_alloc(len + 8, "test message");
156 msg->l1h = msgb_put(msg, 8);
157 msg->l2h = msgb_put(msg, len);
158 memcpy(msg->l2h, data, len);
159
160 msgb_bcid(msg) = msg->l1h;
161 msgb_gmmh(msg) = msg->l2h;
162 return msg;
163}
164
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100165/*
166 * Create a context and search for it
167 */
168static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
169{
170 struct sgsn_mm_ctx *ctx, *ictx;
171 struct gprs_llc_lle *lle;
172 int old_count = count(gprs_llme_list());
173
174 lle = gprs_lle_get_or_create(tlli, 3);
175 ctx = sgsn_mm_ctx_alloc(tlli, raid);
176 ctx->mm_state = GMM_REGISTERED_NORMAL;
177 ctx->llme = lle->llme;
178
179 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
180 OSMO_ASSERT(ictx == ctx);
181
182 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
183
184 return ctx;
185}
186
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100187static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck91580892016-01-04 18:43:33 +0100188 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100189 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;
Jacob Erlbeck91580892016-01-04 18:43:33 +0100198 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100199 gsm0408_gprs_rcvmsg(msg, llme);
200 msgb_free(msg);
201}
202
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200203static void test_llme(void)
204{
205 struct gprs_llc_lle *lle, *lle_copy;
206 uint32_t local_tlli;
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200207
208 printf("Testing LLME allocations\n");
209 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200210
211 /* initial state */
212 OSMO_ASSERT(count(gprs_llme_list()) == 0);
213
214 /* Create a new entry */
215 lle = gprs_lle_get_or_create(local_tlli, 3);
216 OSMO_ASSERT(lle);
217 OSMO_ASSERT(count(gprs_llme_list()) == 1);
218
219 /* No new entry is created */
220 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
221 OSMO_ASSERT(lle == lle_copy);
222 OSMO_ASSERT(count(gprs_llme_list()) == 1);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200223
224 /* unassign which should delete it*/
225 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
226
227 /* Check that everything was cleaned up */
228 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200229
230 cleanup_test();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200231}
232
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100233struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100234void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100235{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100236 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100237 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100238 __func__, mmctx, mmctx->subscr);
239 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100240}
241
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100242static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
243{
244 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100245 OSMO_ASSERT(subscr);
246 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100247
248 sfound = gprs_subscr_get_by_imsi(imsi);
249 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100250
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100251 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100252}
253
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100254static void show_subscrs(FILE *out)
255{
256 struct gsm_subscriber *subscr;
257
258 llist_for_each_entry(subscr, &active_subscribers, entry) {
259 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100260 "use count: %d\n",
261 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100262 }
263}
264
265static void assert_no_subscrs()
266{
267 show_subscrs(stdout);
268 fflush(stdout);
269 OSMO_ASSERT(llist_empty(&active_subscribers));
270}
271
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100272static void test_subscriber(void)
273{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100274 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100275 const char *imsi1 = "1234567890";
276 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100277 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100278
279 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
280
281 printf("Testing core subscriber data API\n");
282
283 /* Check for emptiness */
284 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
285 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100286 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100287
288 /* Allocate entry 1 */
289 s1 = gprs_subscr_get_or_create(imsi1);
290 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100291 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100292 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100293
294 /* Allocate entry 2 */
295 s2 = gprs_subscr_get_or_create(imsi2);
296 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100297
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100298 /* Allocate entry 3 */
299 s3 = gprs_subscr_get_or_create(imsi3);
300
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100301 /* Check entries */
302 assert_subscr(s1, imsi1);
303 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100304 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100305
306 /* Update entry 1 */
307 last_updated_subscr = NULL;
308 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100309 OSMO_ASSERT(last_updated_subscr == NULL);
310 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
311 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100312
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100313 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100314 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100315 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100316 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100317 sfound = gprs_subscr_get_by_imsi(imsi1);
318 OSMO_ASSERT(sfound == NULL);
319
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100320 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100321 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100322
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100323 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100324 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100325 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100326 s2 = NULL;
327 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
328 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100329 assert_subscr(s3, imsi3);
330
331 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100332 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100333 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100334 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100335 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100336
337 OSMO_ASSERT(llist_empty(&active_subscribers));
338
339 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200340
341 cleanup_test();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100342}
343
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100344static void test_auth_triplets(void)
345{
346 struct gsm_subscriber *s1, *s1found;
347 const char *imsi1 = "1234567890";
348 struct gsm_auth_tuple *at;
349 struct sgsn_mm_ctx *ctx;
350 struct gprs_ra_id raid = { 0, };
351 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100352
353 printf("Testing authentication triplet handling\n");
354
355 /* Check for emptiness */
356 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
357
358 /* Allocate entry 1 */
359 s1 = gprs_subscr_get_or_create(imsi1);
360 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
361 s1found = gprs_subscr_get_by_imsi(imsi1);
362 OSMO_ASSERT(s1found == s1);
363 subscr_put(s1found);
364
365 /* Create a context */
366 OSMO_ASSERT(count(gprs_llme_list()) == 0);
367 ctx = alloc_mm_ctx(local_tlli, &raid);
368
369 /* Attach s1 to ctx */
370 ctx->subscr = subscr_get(s1);
371 ctx->subscr->sgsn_data->mm = ctx;
372
373 /* Try to get auth tuple */
374 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
375 OSMO_ASSERT(at == NULL);
376
377 /* Add triplets */
378 s1->sgsn_data->auth_triplets[0].key_seq = 0;
379 s1->sgsn_data->auth_triplets[1].key_seq = 1;
380 s1->sgsn_data->auth_triplets[2].key_seq = 2;
381
382 /* Try to get auth tuple */
383 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
384 OSMO_ASSERT(at != NULL);
385 OSMO_ASSERT(at->key_seq == 0);
386 OSMO_ASSERT(at->use_count == 1);
387 at = sgsn_auth_get_tuple(ctx, at->key_seq);
388 OSMO_ASSERT(at != NULL);
389 OSMO_ASSERT(at->key_seq == 1);
390 OSMO_ASSERT(at->use_count == 1);
391 at = sgsn_auth_get_tuple(ctx, at->key_seq);
392 OSMO_ASSERT(at != NULL);
393 OSMO_ASSERT(at->key_seq == 2);
394 OSMO_ASSERT(at->use_count == 1);
395 at = sgsn_auth_get_tuple(ctx, at->key_seq);
396 OSMO_ASSERT(at == NULL);
397
398 /* Free MM context and subscriber */
399 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100400 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100401 s1found = gprs_subscr_get_by_imsi(imsi1);
402 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200403
404 cleanup_test();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100405}
406
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100407#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
408
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100409static int rx_gsup_message(const uint8_t *data, size_t data_len)
410{
411 struct msgb *msg;
412 int rc;
413
414 msg = msgb_alloc(1024, __func__);
415 msg->l2h = msgb_put(msg, data_len);
416 OSMO_ASSERT(msg->l2h != NULL);
417 memcpy(msg->l2h, data, data_len);
418 rc = gprs_subscr_rx_gsup_message(msg);
419 msgb_free(msg);
420
421 return rc;
422}
423
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100424static void test_subscriber_gsup(void)
425{
426 struct gsm_subscriber *s1, *s1found;
427 const char *imsi1 = "1234567890";
428 struct sgsn_mm_ctx *ctx;
429 struct gprs_ra_id raid = { 0, };
430 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100431 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100432 int rc;
433
434 static const uint8_t send_auth_info_res[] = {
435 0x0a,
436 TEST_GSUP_IMSI1_IE,
437 0x03, 0x22, /* Auth tuple */
438 0x20, 0x10,
439 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
440 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
441 0x21, 0x04,
442 0x21, 0x22, 0x23, 0x24,
443 0x22, 0x08,
444 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
445 0x03, 0x22, /* Auth tuple */
446 0x20, 0x10,
447 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
448 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
449 0x21, 0x04,
450 0xa1, 0xa2, 0xa3, 0xa4,
451 0x22, 0x08,
452 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
453 };
454
455 static const uint8_t send_auth_info_err[] = {
456 0x09,
457 TEST_GSUP_IMSI1_IE,
458 0x02, 0x01, 0x07 /* GPRS not allowed */
459 };
460
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400461#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
462
463 static const uint8_t s1_msisdn[] = { MSISDN };
464
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100465 static const uint8_t update_location_res[] = {
466 0x06,
467 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400468 0x08, 0x09, MSISDN,
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100469 0x04, 0x00, /* PDP info complete */
470 0x05, 0x12,
471 0x10, 0x01, 0x01,
472 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
473 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
474 0x05, 0x11,
475 0x10, 0x01, 0x02,
476 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
477 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
478 };
479
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400480#undef MSISDN
481
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100482 static const uint8_t update_location_err[] = {
483 0x05,
484 TEST_GSUP_IMSI1_IE,
485 0x02, 0x01, 0x07 /* GPRS not allowed */
486 };
487
488 static const uint8_t location_cancellation_req[] = {
489 0x1c,
490 TEST_GSUP_IMSI1_IE,
491 0x06, 0x01, 0x00,
492 };
493
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200494 static const uint8_t location_cancellation_req_withdraw[] = {
495 0x1c,
496 TEST_GSUP_IMSI1_IE,
497 0x06, 0x01, 0x01,
498 };
499
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100500 static const uint8_t location_cancellation_req_other[] = {
501 0x1c,
502 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
503 0x06, 0x01, 0x00,
504 };
505
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100506 static const uint8_t purge_ms_err[] = {
507 0x0d,
508 TEST_GSUP_IMSI1_IE,
509 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
510 };
511
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100512 static const uint8_t purge_ms_err_no_cause[] = {
513 0x0d,
514 TEST_GSUP_IMSI1_IE,
515 };
516
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100517 static const uint8_t purge_ms_res[] = {
518 0x0e,
519 TEST_GSUP_IMSI1_IE,
520 0x07, 0x00,
521 };
522
523
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100524 static const uint8_t insert_data_req[] = {
525 0x10,
526 TEST_GSUP_IMSI1_IE,
527 0x05, 0x11,
528 0x10, 0x01, 0x03,
529 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
530 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
531 };
532
533 static const uint8_t delete_data_req[] = {
534 0x14,
535 TEST_GSUP_IMSI1_IE,
536 0x10, 0x01, 0x03,
537 };
538
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100539 printf("Testing subcriber GSUP handling\n");
540
541 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
542
543 /* Check for emptiness */
544 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
545
546 /* Allocate entry 1 */
547 s1 = gprs_subscr_get_or_create(imsi1);
548 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
549 s1found = gprs_subscr_get_by_imsi(imsi1);
550 OSMO_ASSERT(s1found == s1);
551 subscr_put(s1found);
552
553 /* Create a context */
554 OSMO_ASSERT(count(gprs_llme_list()) == 0);
555 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100556
557 /* Attach s1 to ctx */
558 ctx->subscr = subscr_get(s1);
559 ctx->subscr->sgsn_data->mm = ctx;
560
561 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100562 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100563 OSMO_ASSERT(rc >= 0);
564 OSMO_ASSERT(last_updated_subscr == s1);
565
566 /* Check triplets */
567 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
568 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
569 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
570
571 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100572 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100573 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100574 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100575 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100576
577 /* Check triplets */
578 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
579 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
580 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
581
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100582 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100583 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100584 OSMO_ASSERT(rc >= 0);
585 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100586 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100587 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400588 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
589 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100590 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
591 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
592 struct sgsn_subscriber_pdp_data, list);
593 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
594 pdpd = llist_entry(pdpd->list.next,
595 struct sgsn_subscriber_pdp_data, list);
596 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100597
598 /* Check authorization */
599 OSMO_ASSERT(s1->authorized == 1);
600
601 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100602 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100603 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100604 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100605 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100606
607 /* Check authorization */
608 OSMO_ASSERT(s1->authorized == 0);
609
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100610 /* Inject InsertSubscrData GSUP message */
611 last_updated_subscr = NULL;
612 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
613 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
614 OSMO_ASSERT(last_updated_subscr == NULL);
615
616 /* Inject DeleteSubscrData GSUP message */
617 last_updated_subscr = NULL;
618 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
619 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
620 OSMO_ASSERT(last_updated_subscr == NULL);
621
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100622 /* Inject wrong LocCancelReq GSUP message */
623 last_updated_subscr = NULL;
624 rc = rx_gsup_message(location_cancellation_req_other,
625 sizeof(location_cancellation_req_other));
626 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
627 OSMO_ASSERT(last_updated_subscr == NULL);
628
629 /* Check cancellation result */
630 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
631 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
632
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100633 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100634 rc = rx_gsup_message(location_cancellation_req,
635 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100636 OSMO_ASSERT(rc >= 0);
637 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100638 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100639
640 /* Check cancellation result */
641 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
642 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
643
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200644 /* Inject LocCancelReq(withdraw) GSUP message */
645 rc = rx_gsup_message(location_cancellation_req_withdraw,
646 sizeof(location_cancellation_req_withdraw));
647 OSMO_ASSERT(rc >= 0);
648 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
649
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100650 /* Inject PurgeMsRes GSUP message */
651 rc = rx_gsup_message(purge_ms_res,
652 sizeof(purge_ms_res));
653 OSMO_ASSERT(rc >= 0);
654 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
655
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100656 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100657 OSMO_ASSERT(ctx->subscr == NULL);
658 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100659 subscr_put(s1);
660 s1found = gprs_subscr_get_by_imsi(imsi1);
661 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100662
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100663 /* Inject PurgeMsRes GSUP message */
664 rc = rx_gsup_message(purge_ms_res,
665 sizeof(purge_ms_res));
666 OSMO_ASSERT(rc >= 0);
667
668 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
669 rc = rx_gsup_message(purge_ms_err,
670 sizeof(purge_ms_err));
671 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
672
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100673 /* Inject PurgeMsErr() GSUP message */
674 rc = rx_gsup_message(purge_ms_err_no_cause,
675 sizeof(purge_ms_err_no_cause));
676 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
677
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100678 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
679 last_updated_subscr = NULL;
680 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100681 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100682 OSMO_ASSERT(last_updated_subscr == NULL);
683
684 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
685 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
686 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
687 OSMO_ASSERT(last_updated_subscr == NULL);
688
689 /* Inject LocCancelReq GSUP message (unknown IMSI) */
690 rc = rx_gsup_message(location_cancellation_req,
691 sizeof(location_cancellation_req));
692 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
693 OSMO_ASSERT(last_updated_subscr == NULL);
694
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100695 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200696
697 cleanup_test();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100698}
699
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100700int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
701{
702 msgb_free(msg);
703 return 0;
704};
705
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200706/*
707 * Test that a GMM Detach will remove the MMCTX and the
708 * associated LLME.
709 */
710static void test_gmm_detach(void)
711{
712 struct gprs_ra_id raid = { 0, };
713 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200714 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200715
716 printf("Testing GMM detach\n");
717
718 /* DTAP - Detach Request (MO) */
719 /* normal detach, power_off = 0 */
720 static const unsigned char detach_req[] = {
721 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
722 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
723 };
724
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200725 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200726
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100727 /* Create a context */
728 OSMO_ASSERT(count(gprs_llme_list()) == 0);
729 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200730
731 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100732 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100733 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200734
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100735 /* verify that a single message (hopefully the Detach Accept) has been
736 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100737 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100738
739 /* verify that things are gone */
740 OSMO_ASSERT(count(gprs_llme_list()) == 0);
741 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
742 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200743
744 cleanup_test();
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100745}
746
747/*
748 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
749 * will not sent a Detach Accept message (power_off = 1)
750 */
751static void test_gmm_detach_power_off(void)
752{
753 struct gprs_ra_id raid = { 0, };
754 struct sgsn_mm_ctx *ctx, *ictx;
755 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100756
757 printf("Testing GMM detach (power off)\n");
758
759 /* DTAP - Detach Request (MO) */
760 /* normal detach, power_off = 1 */
761 static const unsigned char detach_req[] = {
762 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
763 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
764 };
765
766 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
767
768 /* Create a context */
769 OSMO_ASSERT(count(gprs_llme_list()) == 0);
770 ctx = alloc_mm_ctx(local_tlli, &raid);
771
772 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100773 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100774 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100775
776 /* verify that no message (and therefore no Detach Accept) has been
777 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100778 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100779
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200780 /* verify that things are gone */
781 OSMO_ASSERT(count(gprs_llme_list()) == 0);
782 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200783 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200784
785 cleanup_test();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200786}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200787
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200788/*
789 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
790 */
791static void test_gmm_detach_no_mmctx(void)
792{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100793 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200794 struct gprs_llc_lle *lle;
795 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200796
797 printf("Testing GMM detach (no MMCTX)\n");
798
799 /* DTAP - Detach Request (MO) */
800 /* normal detach, power_off = 0 */
801 static const unsigned char detach_req[] = {
802 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
803 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
804 };
805
806 /* Create an LLME */
807 OSMO_ASSERT(count(gprs_llme_list()) == 0);
808 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
809 lle = gprs_lle_get_or_create(local_tlli, 3);
810
811 OSMO_ASSERT(count(gprs_llme_list()) == 1);
812
813 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100814 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100815 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200816
817 /* verify that the LLME is gone */
818 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200819
820 cleanup_test();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200821}
822
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100823/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100824 * Test that a single GMM Detach Accept message will not cause the SGSN to send
825 * any message or leave an MM context at the SGSN.
826 */
827static void test_gmm_detach_accept_unexpected(void)
828{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100829 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100830 struct gprs_llc_lle *lle;
831 uint32_t local_tlli;
832
833 printf("Testing GMM detach accept (unexpected)\n");
834
835 /* DTAP - Detach Accept (MT) */
836 /* normal detach */
837 static const unsigned char detach_acc[] = {
838 0x08, 0x06
839 };
840
841 /* Create an LLME */
842 OSMO_ASSERT(count(gprs_llme_list()) == 0);
843 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
844 lle = gprs_lle_get_or_create(local_tlli, 3);
845
846 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100847 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100848 detach_acc, ARRAY_SIZE(detach_acc));
849
850 /* verify that no message (and therefore no Status or XID reset) has been
851 * sent by the SGSN */
852 OSMO_ASSERT(sgsn_tx_counter == 0);
853
854 /* verify that things are gone */
855 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200856
857 cleanup_test();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100858}
859
860/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100861 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
862 */
863static void test_gmm_status_no_mmctx(void)
864{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100865 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100866 struct gprs_llc_lle *lle;
867 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100868
869 printf("Testing GMM Status (no MMCTX)\n");
870
871 /* DTAP - GMM Status, protocol error */
872 static const unsigned char gmm_status[] = {
873 0x08, 0x20, 0x6f
874 };
875
876 /* Create an LLME */
877 OSMO_ASSERT(count(gprs_llme_list()) == 0);
878 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
879 lle = gprs_lle_get_or_create(local_tlli, 3);
880
881 OSMO_ASSERT(count(gprs_llme_list()) == 1);
882
883 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100884 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100885 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100886
887 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100888 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100889
890 /* verify that the LLME is gone */
891 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200892
893 cleanup_test();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100894}
895
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100896/*
897 * Test the GMM Attach procedure
898 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100899static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100900{
901 struct gprs_ra_id raid = { 0, };
902 struct sgsn_mm_ctx *ctx = NULL;
903 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100904 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100905 uint32_t foreign_tlli;
906 uint32_t local_tlli = 0;
907 struct gprs_llc_lle *lle;
908
909 /* DTAP - Attach Request */
910 /* The P-TMSI is not known by the SGSN */
911 static const unsigned char attach_req[] = {
912 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
913 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
914 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
915 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
916 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
917 };
918
919 /* DTAP - Identity Response IMEI */
920 static const unsigned char ident_resp_imei[] = {
921 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
922 0x56
923 };
924
925 /* DTAP - Identity Response IMSI */
926 static const unsigned char ident_resp_imsi[] = {
927 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
928 0x54
929 };
930
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100931 /* DTAP - Authentication and Ciphering Resp */
932 static const unsigned char auth_ciph_resp[] = {
933 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
934 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
935 };
936
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100937 /* DTAP - Attach Complete */
938 static const unsigned char attach_compl[] = {
939 0x08, 0x03
940 };
941
942 /* DTAP - Detach Request (MO) */
943 /* normal detach, power_off = 0 */
944 static const unsigned char detach_req[] = {
945 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
946 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
947 };
948
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100949 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100950
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100951 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
952
953 /* Create a LLE/LLME */
954 OSMO_ASSERT(count(gprs_llme_list()) == 0);
955 lle = gprs_lle_get_or_create(foreign_tlli, 3);
956 OSMO_ASSERT(count(gprs_llme_list()) == 1);
957
958 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100959 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100960 attach_req, ARRAY_SIZE(attach_req));
961
962 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
963 OSMO_ASSERT(ctx != NULL);
964 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
965
966 /* we expect an identity request (IMEI) */
967 OSMO_ASSERT(sgsn_tx_counter == 1);
968
969 /* inject the identity response (IMEI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100970 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100971 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
972
973 /* we expect an identity request (IMSI) */
974 OSMO_ASSERT(sgsn_tx_counter == 1);
975
976 /* inject the identity response (IMSI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100977 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100978 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
979
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100980 /* check that the MM context has not been removed due to a failed
981 * authorization */
982 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
983
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100984 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100985
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100986retry_attach_req:
987
988 if (retry && sgsn_tx_counter == 0) {
989 fprintf(stderr, "Retrying attach request\n");
990 /* re-inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100991 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100992 attach_req, ARRAY_SIZE(attach_req));
993 }
994
995 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
996 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100997
998 /* inject the auth & ciph response */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100999 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001000 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1001
1002 /* check that the MM context has not been removed due to a
1003 * failed authorization */
1004 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001005 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1006 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001007 }
1008
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001009 if (retry && sgsn_tx_counter == 0)
1010 goto retry_attach_req;
1011
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001012 /* we expect an attach accept/reject */
1013 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001014 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1015 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001016
1017 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001018 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001019
1020 /* inject the attach complete */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001021 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001022 attach_compl, ARRAY_SIZE(attach_compl));
1023
1024 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1025
1026 /* we don't expect a response */
1027 OSMO_ASSERT(sgsn_tx_counter == 0);
1028
1029 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001030 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001031 detach_req, ARRAY_SIZE(detach_req));
1032
1033 /* verify that things are gone */
1034 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1035 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1036 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001037
1038 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001039}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001040
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001041static void test_gmm_attach_acl(void)
1042{
1043 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1044
1045 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1046 sgsn_acl_add("123456789012345", &sgsn->cfg);
1047 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001048 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001049 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001050
1051 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001052
1053 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001054}
1055
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001056int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001057 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001058 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001059 if (rc == -ENOTSUP) {
1060 OSMO_ASSERT(mmctx->subscr);
1061 gprs_subscr_update(mmctx->subscr);
1062 }
1063 return rc;
1064};
1065
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001066int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1067 gprs_subscr_update(mmctx->subscr);
1068 return 0;
1069};
1070
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001071static void test_gmm_attach_subscr(void)
1072{
1073 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1074 struct gsm_subscriber *subscr;
1075
1076 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001077 subscr_request_update_location_cb = my_subscr_request_update_location;
1078 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001079
1080 subscr = gprs_subscr_get_or_create("123456789012345");
1081 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001082
1083 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001084 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001085 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001086 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001087
1088 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001089 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1090 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001091
1092 cleanup_test();
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001093}
1094
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001095int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1096{
1097 /* Fake an authentication */
1098 OSMO_ASSERT(mmctx->subscr);
1099 mmctx->is_authenticated = 1;
1100 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001101
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001102 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001103};
1104
1105static void test_gmm_attach_subscr_fake_auth(void)
1106{
1107 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1108 struct gsm_subscriber *subscr;
1109
1110 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001111 subscr_request_update_location_cb = my_subscr_request_update_location;
1112 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001113
1114 subscr = gprs_subscr_get_or_create("123456789012345");
1115 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001116 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001117 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001118
1119 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001120 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001121 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001122 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001123
1124 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001125 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1126 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001127
1128 cleanup_test();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001129}
1130
1131int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1132{
1133 struct gsm_auth_tuple at = {
Harald Welte121e9a42016-04-20 13:13:19 +02001134 .vec.sres = {0x51, 0xe5, 0x51, 0xe5},
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001135 .key_seq = 0
1136 };
1137
1138 /* Fake an authentication */
1139 OSMO_ASSERT(mmctx->subscr);
1140 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1141
1142 gprs_subscr_update_auth_info(mmctx->subscr);
1143
1144 return 0;
1145};
1146
1147static void test_gmm_attach_subscr_real_auth(void)
1148{
1149 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1150 struct gsm_subscriber *subscr;
1151
1152 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1153 subscr_request_update_location_cb = my_subscr_request_update_location;
1154 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1155
1156 subscr = gprs_subscr_get_or_create("123456789012345");
1157 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001158 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001159 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001160
1161 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001162
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001163 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001164 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001165 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001166
1167 sgsn->cfg.auth_policy = saved_auth_policy;
1168 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1169 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001170
1171 cleanup_test();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001172}
1173
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001174#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1175 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1176
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001177static int auth_info_skip = 0;
1178static int upd_loc_skip = 0;
1179
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001180int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1181{
1182 static const uint8_t send_auth_info_res[] = {
1183 0x0a,
1184 TEST_GSUP_IMSI_LONG_IE,
1185 0x03, 0x22, /* Auth tuple */
1186 0x20, 0x10,
1187 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1188 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1189 0x21, 0x04,
1190 0x51, 0xe5, 0x51, 0xe5,
1191 0x22, 0x08,
1192 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1193 };
1194
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001195 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001196
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001197 if (auth_info_skip > 0) {
1198 auth_info_skip -= 1;
1199 return -EAGAIN;
1200 }
1201
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001202 /* Fake an SendAuthInfoRes */
1203 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1204
1205 return 0;
1206};
1207
1208int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1209 static const uint8_t update_location_res[] = {
1210 0x06,
1211 TEST_GSUP_IMSI_LONG_IE,
1212 0x04, 0x00, /* PDP info complete */
1213 0x05, 0x12,
1214 0x10, 0x01, 0x01,
1215 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1216 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001217 0x08, 0x07, /* MSISDN 49166213323 encoded */
1218 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freyther10c0f562015-05-17 20:58:40 +02001219 0x09, 0x07, /* MSISDN 38166213323 encoded */
1220 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001221 };
1222
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001223 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001224
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001225 if (upd_loc_skip > 0) {
1226 upd_loc_skip -= 1;
1227 return -EAGAIN;
1228 }
1229
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001230 /* Fake an UpdateLocRes */
1231 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1232};
1233
1234
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001235static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001236{
1237 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1238 struct gsm_subscriber *subscr;
1239
1240 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1241 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1242 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001243 if (retry) {
1244 upd_loc_skip = 3;
1245 auth_info_skip = 3;
1246 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001247
1248 subscr = gprs_subscr_get_or_create("123456789012345");
1249 subscr->authorized = 1;
1250 sgsn->cfg.require_authentication = 1;
1251 sgsn->cfg.require_update_location = 1;
1252 subscr_put(subscr);
1253
1254 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001255 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001256 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001257
1258 sgsn->cfg.auth_policy = saved_auth_policy;
1259 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1260 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001261 upd_loc_skip = 0;
1262 auth_info_skip = 0;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001263
1264 cleanup_test();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001265}
1266
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001267int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1268{
Harald Welte23d77d52016-04-25 19:07:34 +02001269 struct osmo_gsup_message to_peer = {0};
1270 struct osmo_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001271 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001272 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001273
1274 /* Simulate the GSUP peer */
Harald Welte23d77d52016-04-25 19:07:34 +02001275 rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001276 OSMO_ASSERT(rc >= 0);
1277 OSMO_ASSERT(to_peer.imsi[0] != 0);
1278 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001279
1280 /* This invalidates the pointers in to_peer */
1281 msgb_free(msg);
1282
1283 switch (to_peer.message_type) {
Harald Welte23d77d52016-04-25 19:07:34 +02001284 case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001285 /* Send UPDATE_LOCATION_RESULT */
1286 return my_subscr_request_update_gsup_auth(NULL);
1287
Harald Welte23d77d52016-04-25 19:07:34 +02001288 case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001289 /* Send SEND_AUTH_INFO_RESULT */
1290 return my_subscr_request_auth_info_gsup_auth(NULL);
1291
Harald Welte23d77d52016-04-25 19:07:34 +02001292 case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
1293 from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001294 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001295
1296 default:
1297 if ((to_peer.message_type & 0b00000011) == 0) {
1298 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001299 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001300 from_peer.message_type = to_peer.message_type + 1;
1301 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1302 break;
1303 }
1304
1305 /* Ignore it */
1306 return 0;
1307 }
1308
1309 reply_msg = gprs_gsup_msgb_alloc();
1310 reply_msg->l2h = reply_msg->data;
Harald Welte23d77d52016-04-25 19:07:34 +02001311 osmo_gsup_encode(reply_msg, &from_peer);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001312 gprs_subscr_rx_gsup_message(reply_msg);
1313 msgb_free(reply_msg);
1314
1315 return 0;
1316};
1317
1318static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1319{
1320 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1321 struct gsm_subscriber *subscr;
1322
1323 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001324 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1325
1326 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1327
1328 if (retry) {
1329 upd_loc_skip = 3;
1330 auth_info_skip = 3;
1331 }
1332
1333 printf("Auth policy 'remote', real GSUP based auth: ");
1334 test_gmm_attach(retry);
1335
1336 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001337 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001338 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001339
1340 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001341 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1342 upd_loc_skip = 0;
1343 auth_info_skip = 0;
1344 talloc_free(sgsn->gsup_client);
1345 sgsn->gsup_client = NULL;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001346
1347 cleanup_test();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001348}
1349
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001350/*
1351 * Test the GMM Rejects
1352 */
1353static void test_gmm_reject(void)
1354{
1355 struct gprs_ra_id raid = { 0, };
1356 struct sgsn_mm_ctx *ctx = NULL;
1357 uint32_t foreign_tlli;
1358 struct gprs_llc_lle *lle;
1359 int idx;
1360
1361 /* DTAP - Attach Request */
1362 /* Invalid MI length */
1363 static const unsigned char attach_req_inv_mi_len[] = {
1364 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1365 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1366 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1367 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1368 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1369 };
1370
1371 /* DTAP - Attach Request */
1372 /* Invalid MI type (IMEI) */
1373 static const unsigned char attach_req_inv_mi_type[] = {
1374 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1375 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1376 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1377 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1378 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1379 };
1380
1381 /* DTAP - Routing Area Update Request */
1382 static const unsigned char dtap_ra_upd_req[] = {
1383 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1384 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1385 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1386 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1387 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1388 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1389 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1390 };
1391
1392 /* DTAP - Routing Area Update Request */
1393 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1394 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1395 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1396 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1397 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1398 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1399 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1400 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1401 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1402 };
1403
1404 /* DTAP - Routing Area Update Request */
1405 /* Invalid cap length */
1406 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1407 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1408 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1409 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1410 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1411 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1412 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1413 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1414 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1415 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1416 };
1417
1418 struct test {
1419 const char *title;
1420 const unsigned char *msg;
1421 unsigned msg_len;
1422 unsigned num_resp;
1423
1424 };
1425 static struct test tests[] = {
1426 {
1427 .title = "Attach Request (invalid MI length)",
1428 .msg = attach_req_inv_mi_len,
1429 .msg_len = sizeof(attach_req_inv_mi_len),
1430 .num_resp = 1 /* Reject */
1431
1432 },
1433 {
1434 .title = "Attach Request (invalid MI type)",
1435 .msg = attach_req_inv_mi_type,
1436 .msg_len = sizeof(attach_req_inv_mi_type),
1437 .num_resp = 1 /* Reject */
1438 },
1439 {
1440 .title = "Routing Area Update Request (valid)",
1441 .msg = dtap_ra_upd_req,
1442 .msg_len = sizeof(dtap_ra_upd_req),
1443 .num_resp = 2 /* XID Reset + Reject */
1444 },
1445 {
1446 .title = "Routing Area Update Request (invalid type)",
1447 .msg = dtap_ra_upd_req_inv_type,
1448 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1449 .num_resp = 1 /* Reject */
1450 },
1451 {
1452 .title = "Routing Area Update Request (invalid CAP length)",
1453 .msg = dtap_ra_upd_req_inv_cap_len,
1454 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1455 .num_resp = 1 /* Reject */
1456 },
1457 };
1458
1459 printf("Testing GMM reject\n");
1460
1461 /* reset the PRNG used by sgsn_alloc_ptmsi */
1462 srand(1);
1463
1464 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1465
1466 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1467
1468 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1469 const struct test *test = &tests[idx];
1470 printf(" - %s\n", test->title);
1471
1472 /* Create a LLE/LLME */
1473 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1474 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1475
1476 /* Inject the Request message */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001477 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001478 test->msg, test->msg_len);
1479
1480 /* We expect a Reject message */
1481 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1482 sgsn_tx_counter, test->num_resp);
1483 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1484
1485 /* verify that LLME/MM are removed */
1486 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1487 OSMO_ASSERT(ctx == NULL);
1488 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1489 }
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001490
1491 cleanup_test();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001492}
1493
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001494/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001495 * Test cancellation of attached MM contexts
1496 */
1497static void test_gmm_cancel(void)
1498{
1499 struct gprs_ra_id raid = { 0, };
1500 struct sgsn_mm_ctx *ctx = NULL;
1501 struct sgsn_mm_ctx *ictx;
1502 uint32_t ptmsi1;
1503 uint32_t foreign_tlli;
1504 uint32_t local_tlli = 0;
1505 struct gprs_llc_lle *lle;
1506 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1507
1508 /* DTAP - Attach Request */
1509 /* The P-TMSI is not known by the SGSN */
1510 static const unsigned char attach_req[] = {
1511 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1512 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1513 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1514 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1515 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1516 };
1517
1518 /* DTAP - Identity Response IMEI */
1519 static const unsigned char ident_resp_imei[] = {
1520 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1521 0x56
1522 };
1523
1524 /* DTAP - Identity Response IMSI */
1525 static const unsigned char ident_resp_imsi[] = {
1526 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1527 0x54
1528 };
1529
1530 /* DTAP - Attach Complete */
1531 static const unsigned char attach_compl[] = {
1532 0x08, 0x03
1533 };
1534
1535 printf("Testing cancellation\n");
1536
1537 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1538
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001539 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1540
1541 /* Create a LLE/LLME */
1542 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1543 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1544 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1545
1546 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001547 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001548 attach_req, ARRAY_SIZE(attach_req));
1549
1550 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1551 OSMO_ASSERT(ctx != NULL);
1552 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1553
1554 /* we expect an identity request (IMEI) */
1555 OSMO_ASSERT(sgsn_tx_counter == 1);
1556
1557 /* inject the identity response (IMEI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001558 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001559 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1560
1561 /* we expect an identity request (IMSI) */
1562 OSMO_ASSERT(sgsn_tx_counter == 1);
1563
1564 /* inject the identity response (IMSI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001565 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001566 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1567
1568 /* check that the MM context has not been removed due to a failed
1569 * authorization */
1570 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1571
1572 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1573
1574 /* we expect an attach accept/reject */
1575 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001576 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1577 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001578
1579 /* this has been randomly assigned by the SGSN */
1580 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1581
1582 /* inject the attach complete */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001583 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001584 attach_compl, ARRAY_SIZE(attach_compl));
1585
1586 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1587
1588 /* we don't expect a response */
1589 OSMO_ASSERT(sgsn_tx_counter == 0);
1590
1591 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001592 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001593
1594 /* verify that things are gone */
1595 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1596 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1597 OSMO_ASSERT(!ictx);
1598
1599 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001600
1601 cleanup_test();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001602}
1603
1604/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001605 * Test the dynamic allocation of P-TMSIs
1606 */
1607static void test_gmm_ptmsi_allocation(void)
1608{
Jacob Erlbeckd58c0332016-01-04 18:43:35 +01001609 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001610 struct sgsn_mm_ctx *ctx = NULL;
1611 struct sgsn_mm_ctx *ictx;
1612 uint32_t foreign_tlli;
1613 uint32_t ptmsi1;
1614 uint32_t ptmsi2;
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001615 uint32_t received_ptmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001616 uint32_t old_ptmsi;
1617 uint32_t local_tlli = 0;
1618 struct gprs_llc_lle *lle;
1619 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1620
1621 /* DTAP - Attach Request (IMSI 12131415161718) */
1622 static const unsigned char attach_req[] = {
1623 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1624 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1625 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1626 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1627 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1628 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1629 0x00,
1630 };
1631
1632 /* DTAP - Identity Response IMEI */
1633 static const unsigned char ident_resp_imei[] = {
1634 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1635 0x56
1636 };
1637
1638 /* DTAP - Attach Complete */
1639 static const unsigned char attach_compl[] = {
1640 0x08, 0x03
1641 };
1642
1643 /* DTAP - Routing Area Update Request */
1644 static const unsigned char ra_upd_req[] = {
1645 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1646 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1647 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1648 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1649 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1650 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1651 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1652 };
1653
1654 /* DTAP - Routing Area Update Complete */
1655 static const unsigned char ra_upd_complete[] = {
1656 0x08, 0x0a
1657 };
1658
1659 /* DTAP - Detach Request (MO) */
1660 /* normal detach, power_off = 1 */
1661 static const unsigned char detach_req[] = {
1662 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1663 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1664 };
1665
1666 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1667
1668 printf("Testing P-TMSI allocation\n");
1669
1670 printf(" - sgsn_alloc_ptmsi\n");
1671
1672 /* reset the PRNG used by sgsn_alloc_ptmsi */
1673 srand(1);
1674
1675 ptmsi1 = sgsn_alloc_ptmsi();
1676 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1677
1678 ptmsi2 = sgsn_alloc_ptmsi();
1679 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1680
1681 OSMO_ASSERT(ptmsi1 != ptmsi2);
1682
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001683 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001684
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001685 printf(" - Repeated Attach Request\n");
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001686
1687 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1688
1689 /* Create a LLE/LLME */
1690 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1691 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1692 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1693
1694 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001695 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001696 attach_req, ARRAY_SIZE(attach_req));
1697
1698 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1699 OSMO_ASSERT(ctx != NULL);
1700 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001701 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1702 ptmsi1 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001703
1704 old_ptmsi = ctx->p_tmsi_old;
1705
1706 /* we expect an identity request (IMEI) */
1707 OSMO_ASSERT(sgsn_tx_counter == 1);
1708
1709 /* inject the identity response (IMEI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001710 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001711 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1712
1713 /* check that the MM context has not been removed due to a failed
1714 * authorization */
1715 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1716
1717 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1718 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1719
1720 /* we expect an attach accept */
1721 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001722 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1723 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001724
1725 /* we ignore this and send the attach again */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001726 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001727 attach_req, ARRAY_SIZE(attach_req));
1728
1729 /* the allocated P-TMSI should be the same */
1730 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1731 OSMO_ASSERT(ctx != NULL);
1732 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1733 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1734 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1735
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001736 /* we expect an attach accept */
1737 OSMO_ASSERT(sgsn_tx_counter == 1);
1738 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1739 OSMO_ASSERT(received_ptmsi == ptmsi1);
1740
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001741 /* inject the attach complete */
1742 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck91580892016-01-04 18:43:33 +01001743 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001744 attach_compl, ARRAY_SIZE(attach_compl));
1745
1746 /* we don't expect a response */
1747 OSMO_ASSERT(sgsn_tx_counter == 0);
1748
1749 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1750 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1751 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1752
1753 printf(" - Repeated RA Update Request\n");
1754
1755 /* inject the RA update request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001756 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001757 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1758
1759 /* we expect an RA update accept */
1760 OSMO_ASSERT(sgsn_tx_counter == 1);
1761
1762 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1763 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001764 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1765 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1766 ptmsi2 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001767
1768 /* repeat the RA update request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001769 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001770 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1771
1772 /* we expect an RA update accept */
1773 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001774 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1775 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001776
1777 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1778 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1779 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1780
1781 /* inject the RA update complete */
1782 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Jacob Erlbeck91580892016-01-04 18:43:33 +01001783 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001784 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1785
1786 /* we don't expect a response */
1787 OSMO_ASSERT(sgsn_tx_counter == 0);
1788
1789 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1790 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1791 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1792
1793 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001794 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001795 detach_req, ARRAY_SIZE(detach_req));
1796
1797 /* verify that things are gone */
1798 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1799 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1800 OSMO_ASSERT(!ictx);
1801
1802 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001803
1804 cleanup_test();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001805}
1806
Jacob Erlbeck13304782016-01-04 18:43:37 +01001807/*
1808 * Test changing of routing areas
1809 */
1810static void test_gmm_routing_areas(void)
1811{
1812 struct gprs_ra_id raid1 = {332, 112, 16464, 96};
1813 struct gprs_ra_id raid2 = {332, 112, 16464, 97};
1814 struct sgsn_mm_ctx *ctx = NULL;
1815 struct sgsn_mm_ctx *ictx;
1816 uint32_t ptmsi1;
1817 uint32_t received_ptmsi;
1818 uint32_t ms_tlli = 0;
1819 struct gprs_llc_lle *lle;
1820 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1821
1822 /* DTAP - Attach Request (IMSI 12131415161718) */
1823 static const unsigned char attach_req[] = {
1824 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1825 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1826 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1827 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1828 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1829 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1830 0x00,
1831 };
1832
1833 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1834 static const unsigned char attach_req2[] = {
1835 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1836 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1837 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1838 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1839 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1840 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1841 0x00,
1842 };
1843
1844 /* DTAP - Identity Response IMEI */
1845 static const unsigned char ident_resp_imei[] = {
1846 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1847 0x56
1848 };
1849
1850 /* DTAP - Attach Complete */
1851 static const unsigned char attach_compl[] = {
1852 0x08, 0x03
1853 };
1854
1855 /* DTAP - Routing Area Update Request (coming from RA 1) */
1856 static const unsigned char ra_upd_req1[] = {
1857 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1858 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1859 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1860 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1861 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1862 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1863 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1864 };
1865
1866 /* DTAP - Routing Area Update Request (coming from RA 2) */
1867 static const unsigned char ra_upd_req2[] = {
1868 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1869 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1870 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1871 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1872 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1873 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1874 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1875 };
1876
1877 /* DTAP - Routing Area Update Request (coming from RA other) */
1878 /* raid_other = {443, 223, 16464, 98}; */
1879 static const unsigned char ra_upd_req_other[] = {
1880 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1881 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1882 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1883 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1884 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1885 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1886 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1887 };
1888
1889 /* DTAP - Routing Area Update Complete */
1890 static const unsigned char ra_upd_complete[] = {
1891 0x08, 0x0a
1892 };
1893
1894 /* DTAP - Detach Request (MO) */
1895 /* normal detach, power_off = 1 */
1896 static const unsigned char detach_req[] = {
1897 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1898 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1899 };
1900
1901 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1902
1903 printf("Testing routing area changes\n");
1904
1905 /* reset the PRNG used by sgsn_alloc_ptmsi */
1906 srand(1);
1907
1908 ptmsi1 = GSM_RESERVED_TMSI;
1909
1910 printf(" - Attach Request (RA 1)\n");
1911
1912 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1913
1914 /* Create a LLE/LLME */
1915 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1916 lle = gprs_lle_get_or_create(ms_tlli, 3);
1917 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1918
1919 /* inject the attach request */
1920 send_0408_message(lle->llme, ms_tlli, &raid1,
1921 attach_req, ARRAY_SIZE(attach_req));
1922
1923 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1924 OSMO_ASSERT(ctx != NULL);
1925 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1926 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1927
1928 /* we expect an identity request (IMEI) */
1929 OSMO_ASSERT(sgsn_tx_counter == 1);
1930 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1931 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1932
1933 /* inject the identity response (IMEI) */
1934 send_0408_message(ctx->llme, ms_tlli, &raid1,
1935 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1936
1937 /* check that the MM context has not been removed due to a failed
1938 * authorization */
1939 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1940
1941 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1942
1943 /* we expect an attach accept */
1944 OSMO_ASSERT(sgsn_tx_counter == 1);
1945 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1946 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1947
1948 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1949 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1950 ptmsi1 = received_ptmsi;
1951
1952 /* inject the attach complete */
1953 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1954 send_0408_message(ctx->llme, ms_tlli, &raid1,
1955 attach_compl, ARRAY_SIZE(attach_compl));
1956
1957 /* we don't expect a response */
1958 OSMO_ASSERT(sgsn_tx_counter == 0);
1959
1960 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1961 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1962 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1963
1964 printf(" - RA Update Request (RA 1 -> RA 1)\n");
1965
1966 /* inject the RA update request */
1967 send_0408_message(ctx->llme, ms_tlli, &raid1,
1968 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
1969
1970 /* we expect an RA update accept */
1971 OSMO_ASSERT(sgsn_tx_counter == 1);
1972 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
1973 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1974
1975 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1976 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1977 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1978 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1979
1980 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1981 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1982 ptmsi1 = received_ptmsi;
1983
1984 /* inject the RA update complete */
1985 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1986 send_0408_message(ctx->llme, ms_tlli, &raid1,
1987 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1988
1989 /* we don't expect a response */
1990 OSMO_ASSERT(sgsn_tx_counter == 0);
1991
1992 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1993 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1994 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1995 OSMO_ASSERT(ctx->tlli == ms_tlli);
1996
Jacob Erlbeck13304782016-01-04 18:43:37 +01001997 printf(" - RA Update Request (RA 1 -> RA 2)\n");
1998
1999 /* inject the RA update request */
2000 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2001
2002 /* It is coming from RA 1 => ra_upd_req1 */
2003 send_0408_message(ctx->llme, ms_tlli, &raid2,
2004 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2005
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002006 /* we expect an RA update accept */
Jacob Erlbeck13304782016-01-04 18:43:37 +01002007 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002008 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002009
2010 printf(" - RA Update Request (RA other -> RA 2)\n");
2011
2012 /* inject the RA update request */
2013 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2014
2015 /* It is coming from RA 1 => ra_upd_req1 */
2016 send_0408_message(ctx->llme, ms_tlli, &raid2,
2017 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2018
2019 /* we expect an RA update reject (and a LLC XID RESET) */
2020 OSMO_ASSERT(sgsn_tx_counter == 2);
2021 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2022 /* this has killed the LLE/LLME */
2023
2024 printf(" - Attach Request (RA 2)\n");
2025
2026 /* Create a LLE/LLME */
2027 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2028 lle = gprs_lle_get_or_create(ms_tlli, 3);
2029 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2030
2031 /* inject the attach request */
2032 send_0408_message(lle->llme, ms_tlli, &raid2,
2033 attach_req2, ARRAY_SIZE(attach_req2));
2034
2035 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2036 OSMO_ASSERT(ctx != NULL);
2037 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2038 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2039
2040 /* we expect an attach accept */
2041 OSMO_ASSERT(sgsn_tx_counter == 1);
2042 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2043
2044 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2045 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2046 ptmsi1 = received_ptmsi;
2047
2048 /* inject the attach complete */
2049 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2050 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2051 OSMO_ASSERT(ictx != NULL);
2052 OSMO_ASSERT(ictx == ctx);
2053
2054 send_0408_message(ctx->llme, ms_tlli, &raid2,
2055 attach_compl, ARRAY_SIZE(attach_compl));
2056
2057 /* we don't expect a response */
2058 OSMO_ASSERT(sgsn_tx_counter == 0);
2059
2060 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2061 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2062 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2063
2064 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2065
2066 /* inject the RA update request */
2067 send_0408_message(ctx->llme, ms_tlli, &raid2,
2068 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2069
2070 /* we expect an RA update accept */
2071 OSMO_ASSERT(sgsn_tx_counter == 1);
2072 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2073
2074 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2075 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2076 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2077 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2078
2079 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2080 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2081 ptmsi1 = received_ptmsi;
2082
2083 /* inject the RA update complete */
2084 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2085 send_0408_message(ctx->llme, ms_tlli, &raid2,
2086 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2087
2088 /* we don't expect a response */
2089 OSMO_ASSERT(sgsn_tx_counter == 0);
2090
2091 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2092 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2093 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2094 OSMO_ASSERT(ctx->tlli == ms_tlli);
2095
2096
2097 /* inject the detach */
2098 send_0408_message(ctx->llme, ms_tlli, &raid2,
2099 detach_req, ARRAY_SIZE(detach_req));
2100
2101 /* verify that things are gone */
2102 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2103 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2104 OSMO_ASSERT(!ictx);
2105
2106 sgsn->cfg.auth_policy = saved_auth_policy;
2107
2108 cleanup_test();
2109}
2110
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002111static void test_apn_matching(void)
2112{
2113 struct apn_ctx *actx, *actxs[9];
2114
2115 printf("Testing APN matching\n");
2116
2117 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2118 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2119 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2120 actxs[3] = NULL;
2121
2122 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2123 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2124 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2125 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2126
2127 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2128
2129 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2130 OSMO_ASSERT(actx == actxs[2]);
2131 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2132 OSMO_ASSERT(actx == actxs[2]);
2133 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2134 OSMO_ASSERT(actx == actxs[1]);
2135 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2136 OSMO_ASSERT(actx == actxs[1]);
2137 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2138 OSMO_ASSERT(actx == actxs[0]);
2139 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2140 OSMO_ASSERT(actx == NULL);
2141
2142 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2143 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2144 OSMO_ASSERT(actx == actxs[3]);
2145
2146 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2147 OSMO_ASSERT(actx == actxs[4]);
2148
2149 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2150 OSMO_ASSERT(actx == actxs[6]);
2151
2152 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2153 OSMO_ASSERT(actx == actxs[5]);
2154
2155 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2156 OSMO_ASSERT(actx == actxs[7]);
2157
2158 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2159 OSMO_ASSERT(actx == actxs[8]);
2160
2161 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2162 OSMO_ASSERT(actx == actxs[7]);
2163
2164 /* Free APN contexts and check how the matching changes */
2165
2166 sgsn_apn_ctx_free(actxs[7]);
2167 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2168 OSMO_ASSERT(actx == actxs[8]);
2169
2170 sgsn_apn_ctx_free(actxs[8]);
2171 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2172 OSMO_ASSERT(actx == actxs[6]);
2173
2174 sgsn_apn_ctx_free(actxs[6]);
2175 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2176 OSMO_ASSERT(actx == actxs[1]);
2177
2178 sgsn_apn_ctx_free(actxs[5]);
2179 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2180 OSMO_ASSERT(actx == actxs[4]);
2181
2182 sgsn_apn_ctx_free(actxs[4]);
2183 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2184 OSMO_ASSERT(actx == actxs[2]);
2185
2186 sgsn_apn_ctx_free(actxs[2]);
2187 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2188 OSMO_ASSERT(actx == actxs[1]);
2189
2190 sgsn_apn_ctx_free(actxs[1]);
2191 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2192 OSMO_ASSERT(actx == actxs[0]);
2193
2194 sgsn_apn_ctx_free(actxs[0]);
2195 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2196 OSMO_ASSERT(actx == actxs[3]);
2197
2198 sgsn_apn_ctx_free(actxs[3]);
2199 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2200 OSMO_ASSERT(actx == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002201
2202 cleanup_test();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002203}
2204
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002205struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2206 struct sgsn_subscriber_data *sdata);
2207
2208static void test_ggsn_selection(void)
2209{
2210 struct apn_ctx *actxs[4];
2211 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
2212 struct gsm_subscriber *s1;
2213 const char *imsi1 = "1234567890";
2214 struct sgsn_mm_ctx *ctx;
2215 struct gprs_ra_id raid = { 0, };
2216 uint32_t local_tlli = 0xffeeddcc;
2217 enum gsm48_gsm_cause gsm_cause;
2218 struct tlv_parsed tp;
2219 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2220 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002221 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002222
2223 printf("Testing GGSN selection\n");
2224
2225 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
2226
2227 /* Check for emptiness */
2228 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2229
2230 /* Create a context */
2231 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2232 ctx = alloc_mm_ctx(local_tlli, &raid);
2233 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
2234
2235 /* Allocate and attach a subscriber */
2236 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2237 assert_subscr(s1, imsi1);
2238
2239 tp.lv[GSM48_IE_GSM_APN].len = 0;
2240 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2241
2242 /* TODO: Add PDP info entries to s1 */
2243
2244 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2245 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2246 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2247
2248 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2249 actxs[0]->ggsn = ggcs[0];
2250 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2251 actxs[1]->ggsn = ggcs[1];
2252 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2253 actxs[2]->ggsn = ggcs[2];
2254
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002255 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2256 pdp_data->context_id = 1;
2257 pdp_data->pdp_type = 0x0121;
2258 strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
2259
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002260 /* Resolve GGSNs */
2261
2262 tp.lv[GSM48_IE_GSM_APN].len =
2263 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2264
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002265 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002266 OSMO_ASSERT(ggc != NULL);
2267 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002268 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002269
2270 tp.lv[GSM48_IE_GSM_APN].len =
2271 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2272
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002273 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002274 OSMO_ASSERT(ggc != NULL);
2275 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002276 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002277
2278 tp.lv[GSM48_IE_GSM_APN].len = 0;
2279 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2280
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002281 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002282 OSMO_ASSERT(ggc != NULL);
2283 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002284 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002285
2286 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2287 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002288 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002289 OSMO_ASSERT(ggc != NULL);
2290 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002291 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002292
2293 sgsn_apn_ctx_free(actxs[3]);
2294 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2295
2296 tp.lv[GSM48_IE_GSM_APN].len =
2297 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2298
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002299 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002300 OSMO_ASSERT(ggc == NULL);
2301 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002302 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002303
2304 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
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(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2308
2309 /* Add PDP data entry to subscriber */
2310
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002311 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
2312
2313 tp.lv[GSM48_IE_GSM_APN].len =
2314 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
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(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002319 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002320
2321 tp.lv[GSM48_IE_GSM_APN].len =
2322 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2323
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002324 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002325 OSMO_ASSERT(ggc == NULL);
2326 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002327 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002328
2329 /* Cleanup */
2330
2331 subscr_put(s1);
2332 sgsn_mm_ctx_cleanup_free(ctx);
2333
2334 assert_no_subscrs();
2335
2336 sgsn_apn_ctx_free(actxs[0]);
2337 sgsn_apn_ctx_free(actxs[1]);
2338 sgsn_apn_ctx_free(actxs[2]);
2339
2340 sgsn_ggsn_ctx_free(ggcs[0]);
2341 sgsn_ggsn_ctx_free(ggcs[1]);
2342 sgsn_ggsn_ctx_free(ggcs[2]);
2343
2344 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002345
2346 cleanup_test();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002347}
2348
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002349static struct log_info_cat gprs_categories[] = {
2350 [DMM] = {
2351 .name = "DMM",
2352 .description = "Layer3 Mobility Management (MM)",
2353 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002354 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002355 },
2356 [DPAG] = {
2357 .name = "DPAG",
2358 .description = "Paging Subsystem",
2359 .color = "\033[1;38m",
2360 .enabled = 1, .loglevel = LOGL_NOTICE,
2361 },
2362 [DMEAS] = {
2363 .name = "DMEAS",
2364 .description = "Radio Measurement Processing",
2365 .enabled = 0, .loglevel = LOGL_NOTICE,
2366 },
2367 [DREF] = {
2368 .name = "DREF",
2369 .description = "Reference Counting",
2370 .enabled = 0, .loglevel = LOGL_NOTICE,
2371 },
2372 [DGPRS] = {
2373 .name = "DGPRS",
2374 .description = "GPRS Packet Service",
2375 .enabled = 1, .loglevel = LOGL_DEBUG,
2376 },
2377 [DNS] = {
2378 .name = "DNS",
2379 .description = "GPRS Network Service (NS)",
2380 .enabled = 1, .loglevel = LOGL_INFO,
2381 },
2382 [DBSSGP] = {
2383 .name = "DBSSGP",
2384 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2385 .enabled = 1, .loglevel = LOGL_DEBUG,
2386 },
2387 [DLLC] = {
2388 .name = "DLLC",
2389 .description = "GPRS Logical Link Control Protocol (LLC)",
2390 .enabled = 1, .loglevel = LOGL_DEBUG,
2391 },
2392 [DSNDCP] = {
2393 .name = "DSNDCP",
2394 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2395 .enabled = 1, .loglevel = LOGL_DEBUG,
2396 },
2397};
2398
2399static struct log_info info = {
2400 .cat = gprs_categories,
2401 .num_cat = ARRAY_SIZE(gprs_categories),
2402};
2403
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002404int main(int argc, char **argv)
2405{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002406 void *osmo_sgsn_ctx;
2407
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002408 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002409 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2410 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
2411 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002412
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01002413 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002414 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002415
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002416 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002417 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002418 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002419 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002420 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002421 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002422 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002423 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002424 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002425 test_gmm_attach_acl();
2426 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002427 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002428 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002429 test_gmm_attach_subscr_gsup_auth(0);
2430 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002431 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002432 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002433 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002434 test_gmm_ptmsi_allocation();
Jacob Erlbeck13304782016-01-04 18:43:37 +01002435 test_gmm_routing_areas();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002436 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002437 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002438 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002439
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002440 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01002441 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002442 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002443 return 0;
2444}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002445
2446
2447/* stubs */
2448struct osmo_prim_hdr;
2449int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2450{
2451 abort();
2452}