blob: 1acd6f2f85c5f4cc00a61eb03a3352bcc91dba40 [file] [log] [blame]
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Jacob Erlbeck277b71e2015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Jacob Erlbeck133e8622015-10-12 19:36:32 +020030#include <openbsc/gprs_gb_parse.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020031
Jacob Erlbeck189999d2014-10-27 14:34:13 +010032#include <osmocom/gprs/gprs_bssgp.h>
33
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020034#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeckbce20612015-01-05 18:57:32 +010035#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020036
37#include <osmocom/core/application.h>
38#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010039#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020040
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020041#include <stdio.h>
42
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020043extern void *tall_msgb_ctx;
44
45void *tall_bsc_ctx;
46static struct sgsn_instance sgsn_inst = {
47 .config_file = "osmo_sgsn.cfg",
48 .cfg = {
49 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010050 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020051 },
52};
53struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010054unsigned sgsn_tx_counter = 0;
Jacob Erlbeck133e8622015-10-12 19:36:32 +020055struct msgb *last_msg = NULL;
56struct gprs_gb_parse_context last_dl_parse_ctx;
57
58static void reset_last_msg()
59{
60 if (last_msg)
61 msgb_free(last_msg);
62
63 last_msg = NULL;
64 memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx));
65}
Jacob Erlbeck189999d2014-10-27 14:34:13 +010066
Jacob Erlbeckcf151872015-10-12 19:36:31 +020067static void cleanup_test()
68{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020069 reset_last_msg();
70}
71
72static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
73{
74 uint32_t new_ptmsi = GSM_RESERVED_TMSI;
75
76 if (parse_ctx->new_ptmsi_enc)
77 gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
78
79 return new_ptmsi;
Jacob Erlbeckcf151872015-10-12 19:36:31 +020080}
81
Jacob Erlbeck189999d2014-10-27 14:34:13 +010082/* override */
83int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
84 struct bssgp_dl_ud_par *dup)
85{
Jacob Erlbeck133e8622015-10-12 19:36:32 +020086 int rc;
87
88 reset_last_msg();
89
90 last_msg = msg;
91 OSMO_ASSERT(msgb_data(last_msg) != NULL);
92
93 rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg),
94 &last_dl_parse_ctx);
95
96 fprintf(stderr, "Got DL LLC message: %s\n",
97 gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN"));
98
99 OSMO_ASSERT(rc > 0);
100
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100101 sgsn_tx_counter += 1;
102 return 0;
103}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200104
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100105/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100106void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
107void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100108 &__real_sgsn_update_subscriber_data;
109
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100110void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100111{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100112 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100113}
114
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100115/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
116int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
117int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
118 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100119
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100120int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
121 return (*subscr_request_update_location_cb)(mmctx);
122};
123
124/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
125int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
126int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
127 &__real_gprs_subscr_request_auth_info;
128
129int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
130 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100131};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100132
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100133/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
134int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
135int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
136 &__real_gprs_gsup_client_send;
137
138int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
139{
140 return (*gprs_gsup_client_send_cb)(gsupc, msg);
141};
142
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200143static int count(struct llist_head *head)
144{
145 struct llist_head *cur;
146 int count = 0;
147
148 llist_for_each(cur, head)
149 count += 1;
150
151 return count;
152}
153
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200154static struct msgb *create_msg(const uint8_t *data, size_t len)
155{
156 struct msgb *msg = msgb_alloc(len + 8, "test message");
157 msg->l1h = msgb_put(msg, 8);
158 msg->l2h = msgb_put(msg, len);
159 memcpy(msg->l2h, data, len);
160
161 msgb_bcid(msg) = msg->l1h;
162 msgb_gmmh(msg) = msg->l2h;
163 return msg;
164}
165
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100166/*
167 * Create a context and search for it
168 */
169static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
170{
171 struct sgsn_mm_ctx *ctx, *ictx;
172 struct gprs_llc_lle *lle;
173 int old_count = count(gprs_llme_list());
174
175 lle = gprs_lle_get_or_create(tlli, 3);
176 ctx = sgsn_mm_ctx_alloc(tlli, raid);
177 ctx->mm_state = GMM_REGISTERED_NORMAL;
178 ctx->llme = lle->llme;
179
180 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
181 OSMO_ASSERT(ictx == ctx);
182
183 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
184
185 return ctx;
186}
187
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100188static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck91580892016-01-04 18:43:33 +0100189 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100190 const uint8_t *data, size_t data_len)
191{
192 struct msgb *msg;
193
Jacob Erlbeck133e8622015-10-12 19:36:32 +0200194 reset_last_msg();
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100195 sgsn_tx_counter = 0;
196
197 msg = create_msg(data, data_len);
198 msgb_tlli(msg) = tlli;
Jacob Erlbeck91580892016-01-04 18:43:33 +0100199 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100200 gsm0408_gprs_rcvmsg(msg, llme);
201 msgb_free(msg);
202}
203
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200204static void test_llme(void)
205{
206 struct gprs_llc_lle *lle, *lle_copy;
207 uint32_t local_tlli;
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200208
209 printf("Testing LLME allocations\n");
210 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200211
212 /* initial state */
213 OSMO_ASSERT(count(gprs_llme_list()) == 0);
214
215 /* Create a new entry */
216 lle = gprs_lle_get_or_create(local_tlli, 3);
217 OSMO_ASSERT(lle);
218 OSMO_ASSERT(count(gprs_llme_list()) == 1);
219
220 /* No new entry is created */
221 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
222 OSMO_ASSERT(lle == lle_copy);
223 OSMO_ASSERT(count(gprs_llme_list()) == 1);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200224
225 /* unassign which should delete it*/
226 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
227
228 /* Check that everything was cleaned up */
229 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200230
231 cleanup_test();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200232}
233
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100234struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100235void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100236{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100237 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100238 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100239 __func__, mmctx, mmctx->subscr);
240 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100241}
242
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100243static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
244{
245 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100246 OSMO_ASSERT(subscr);
247 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100248
249 sfound = gprs_subscr_get_by_imsi(imsi);
250 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100251
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100252 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100253}
254
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100255static void show_subscrs(FILE *out)
256{
257 struct gsm_subscriber *subscr;
258
259 llist_for_each_entry(subscr, &active_subscribers, entry) {
260 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100261 "use count: %d\n",
262 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100263 }
264}
265
266static void assert_no_subscrs()
267{
268 show_subscrs(stdout);
269 fflush(stdout);
270 OSMO_ASSERT(llist_empty(&active_subscribers));
271}
272
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100273static void test_subscriber(void)
274{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100275 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100276 const char *imsi1 = "1234567890";
277 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100278 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100279
280 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
281
282 printf("Testing core subscriber data API\n");
283
284 /* Check for emptiness */
285 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
286 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100287 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100288
289 /* Allocate entry 1 */
290 s1 = gprs_subscr_get_or_create(imsi1);
291 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100292 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100293 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100294
295 /* Allocate entry 2 */
296 s2 = gprs_subscr_get_or_create(imsi2);
297 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100298
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100299 /* Allocate entry 3 */
300 s3 = gprs_subscr_get_or_create(imsi3);
301
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100302 /* Check entries */
303 assert_subscr(s1, imsi1);
304 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100305 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100306
307 /* Update entry 1 */
308 last_updated_subscr = NULL;
309 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100310 OSMO_ASSERT(last_updated_subscr == NULL);
311 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
312 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100313
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100314 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100315 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100316 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100317 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100318 sfound = gprs_subscr_get_by_imsi(imsi1);
319 OSMO_ASSERT(sfound == NULL);
320
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100321 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100322 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100323
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100324 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100325 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100326 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100327 s2 = NULL;
328 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
329 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100330 assert_subscr(s3, imsi3);
331
332 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100333 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100334 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100335 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100336 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100337
338 OSMO_ASSERT(llist_empty(&active_subscribers));
339
340 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200341
342 cleanup_test();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100343}
344
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100345static void test_auth_triplets(void)
346{
347 struct gsm_subscriber *s1, *s1found;
348 const char *imsi1 = "1234567890";
349 struct gsm_auth_tuple *at;
350 struct sgsn_mm_ctx *ctx;
351 struct gprs_ra_id raid = { 0, };
352 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100353
354 printf("Testing authentication triplet handling\n");
355
356 /* Check for emptiness */
357 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
358
359 /* Allocate entry 1 */
360 s1 = gprs_subscr_get_or_create(imsi1);
361 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
362 s1found = gprs_subscr_get_by_imsi(imsi1);
363 OSMO_ASSERT(s1found == s1);
364 subscr_put(s1found);
365
366 /* Create a context */
367 OSMO_ASSERT(count(gprs_llme_list()) == 0);
368 ctx = alloc_mm_ctx(local_tlli, &raid);
369
370 /* Attach s1 to ctx */
371 ctx->subscr = subscr_get(s1);
372 ctx->subscr->sgsn_data->mm = ctx;
373
374 /* Try to get auth tuple */
375 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
376 OSMO_ASSERT(at == NULL);
377
378 /* Add triplets */
379 s1->sgsn_data->auth_triplets[0].key_seq = 0;
380 s1->sgsn_data->auth_triplets[1].key_seq = 1;
381 s1->sgsn_data->auth_triplets[2].key_seq = 2;
382
383 /* Try to get auth tuple */
384 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
385 OSMO_ASSERT(at != NULL);
386 OSMO_ASSERT(at->key_seq == 0);
387 OSMO_ASSERT(at->use_count == 1);
388 at = sgsn_auth_get_tuple(ctx, at->key_seq);
389 OSMO_ASSERT(at != NULL);
390 OSMO_ASSERT(at->key_seq == 1);
391 OSMO_ASSERT(at->use_count == 1);
392 at = sgsn_auth_get_tuple(ctx, at->key_seq);
393 OSMO_ASSERT(at != NULL);
394 OSMO_ASSERT(at->key_seq == 2);
395 OSMO_ASSERT(at->use_count == 1);
396 at = sgsn_auth_get_tuple(ctx, at->key_seq);
397 OSMO_ASSERT(at == NULL);
398
399 /* Free MM context and subscriber */
400 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100401 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100402 s1found = gprs_subscr_get_by_imsi(imsi1);
403 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200404
405 cleanup_test();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100406}
407
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100408#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
409
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100410static int rx_gsup_message(const uint8_t *data, size_t data_len)
411{
412 struct msgb *msg;
413 int rc;
414
415 msg = msgb_alloc(1024, __func__);
416 msg->l2h = msgb_put(msg, data_len);
417 OSMO_ASSERT(msg->l2h != NULL);
418 memcpy(msg->l2h, data, data_len);
419 rc = gprs_subscr_rx_gsup_message(msg);
420 msgb_free(msg);
421
422 return rc;
423}
424
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100425static void test_subscriber_gsup(void)
426{
427 struct gsm_subscriber *s1, *s1found;
428 const char *imsi1 = "1234567890";
429 struct sgsn_mm_ctx *ctx;
430 struct gprs_ra_id raid = { 0, };
431 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100432 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100433 int rc;
434
435 static const uint8_t send_auth_info_res[] = {
436 0x0a,
437 TEST_GSUP_IMSI1_IE,
438 0x03, 0x22, /* Auth tuple */
439 0x20, 0x10,
440 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
441 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
442 0x21, 0x04,
443 0x21, 0x22, 0x23, 0x24,
444 0x22, 0x08,
445 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
446 0x03, 0x22, /* Auth tuple */
447 0x20, 0x10,
448 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
449 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
450 0x21, 0x04,
451 0xa1, 0xa2, 0xa3, 0xa4,
452 0x22, 0x08,
453 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
454 };
455
456 static const uint8_t send_auth_info_err[] = {
457 0x09,
458 TEST_GSUP_IMSI1_IE,
459 0x02, 0x01, 0x07 /* GPRS not allowed */
460 };
461
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400462#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
463
464 static const uint8_t s1_msisdn[] = { MSISDN };
465
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100466 static const uint8_t update_location_res[] = {
467 0x06,
468 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400469 0x08, 0x09, MSISDN,
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100470 0x04, 0x00, /* PDP info complete */
471 0x05, 0x12,
472 0x10, 0x01, 0x01,
473 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
474 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
475 0x05, 0x11,
476 0x10, 0x01, 0x02,
477 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
478 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
479 };
480
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400481#undef MSISDN
482
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100483 static const uint8_t update_location_err[] = {
484 0x05,
485 TEST_GSUP_IMSI1_IE,
486 0x02, 0x01, 0x07 /* GPRS not allowed */
487 };
488
489 static const uint8_t location_cancellation_req[] = {
490 0x1c,
491 TEST_GSUP_IMSI1_IE,
492 0x06, 0x01, 0x00,
493 };
494
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200495 static const uint8_t location_cancellation_req_withdraw[] = {
496 0x1c,
497 TEST_GSUP_IMSI1_IE,
498 0x06, 0x01, 0x01,
499 };
500
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100501 static const uint8_t location_cancellation_req_other[] = {
502 0x1c,
503 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
504 0x06, 0x01, 0x00,
505 };
506
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100507 static const uint8_t purge_ms_err[] = {
508 0x0d,
509 TEST_GSUP_IMSI1_IE,
510 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
511 };
512
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100513 static const uint8_t purge_ms_err_no_cause[] = {
514 0x0d,
515 TEST_GSUP_IMSI1_IE,
516 };
517
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100518 static const uint8_t purge_ms_res[] = {
519 0x0e,
520 TEST_GSUP_IMSI1_IE,
521 0x07, 0x00,
522 };
523
524
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100525 static const uint8_t insert_data_req[] = {
526 0x10,
527 TEST_GSUP_IMSI1_IE,
528 0x05, 0x11,
529 0x10, 0x01, 0x03,
530 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
531 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
532 };
533
534 static const uint8_t delete_data_req[] = {
535 0x14,
536 TEST_GSUP_IMSI1_IE,
537 0x10, 0x01, 0x03,
538 };
539
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100540 printf("Testing subcriber GSUP handling\n");
541
542 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
543
544 /* Check for emptiness */
545 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
546
547 /* Allocate entry 1 */
548 s1 = gprs_subscr_get_or_create(imsi1);
549 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
550 s1found = gprs_subscr_get_by_imsi(imsi1);
551 OSMO_ASSERT(s1found == s1);
552 subscr_put(s1found);
553
554 /* Create a context */
555 OSMO_ASSERT(count(gprs_llme_list()) == 0);
556 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100557
558 /* Attach s1 to ctx */
559 ctx->subscr = subscr_get(s1);
560 ctx->subscr->sgsn_data->mm = ctx;
561
562 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100563 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100564 OSMO_ASSERT(rc >= 0);
565 OSMO_ASSERT(last_updated_subscr == s1);
566
567 /* Check triplets */
568 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
569 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
570 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
571
572 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100573 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100574 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100575 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100576 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100577
578 /* Check triplets */
579 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
580 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
581 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
582
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100583 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100584 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100585 OSMO_ASSERT(rc >= 0);
586 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100587 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100588 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400589 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
590 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100591 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
592 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
593 struct sgsn_subscriber_pdp_data, list);
594 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
595 pdpd = llist_entry(pdpd->list.next,
596 struct sgsn_subscriber_pdp_data, list);
597 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100598
599 /* Check authorization */
600 OSMO_ASSERT(s1->authorized == 1);
601
602 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100603 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100604 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100605 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100606 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100607
608 /* Check authorization */
609 OSMO_ASSERT(s1->authorized == 0);
610
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100611 /* Inject InsertSubscrData GSUP message */
612 last_updated_subscr = NULL;
613 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
614 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
615 OSMO_ASSERT(last_updated_subscr == NULL);
616
617 /* Inject DeleteSubscrData GSUP message */
618 last_updated_subscr = NULL;
619 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
620 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
621 OSMO_ASSERT(last_updated_subscr == NULL);
622
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100623 /* Inject wrong LocCancelReq GSUP message */
624 last_updated_subscr = NULL;
625 rc = rx_gsup_message(location_cancellation_req_other,
626 sizeof(location_cancellation_req_other));
627 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
628 OSMO_ASSERT(last_updated_subscr == NULL);
629
630 /* Check cancellation result */
631 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
632 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
633
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100634 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100635 rc = rx_gsup_message(location_cancellation_req,
636 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100637 OSMO_ASSERT(rc >= 0);
638 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100639 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100640
641 /* Check cancellation result */
642 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
643 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
644
Jacob Erlbeck5b512052015-04-07 17:49:48 +0200645 /* Inject LocCancelReq(withdraw) GSUP message */
646 rc = rx_gsup_message(location_cancellation_req_withdraw,
647 sizeof(location_cancellation_req_withdraw));
648 OSMO_ASSERT(rc >= 0);
649 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
650
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100651 /* Inject PurgeMsRes GSUP message */
652 rc = rx_gsup_message(purge_ms_res,
653 sizeof(purge_ms_res));
654 OSMO_ASSERT(rc >= 0);
655 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
656
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100657 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100658 OSMO_ASSERT(ctx->subscr == NULL);
659 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100660 subscr_put(s1);
661 s1found = gprs_subscr_get_by_imsi(imsi1);
662 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100663
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100664 /* Inject PurgeMsRes GSUP message */
665 rc = rx_gsup_message(purge_ms_res,
666 sizeof(purge_ms_res));
667 OSMO_ASSERT(rc >= 0);
668
669 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
670 rc = rx_gsup_message(purge_ms_err,
671 sizeof(purge_ms_err));
672 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
673
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100674 /* Inject PurgeMsErr() GSUP message */
675 rc = rx_gsup_message(purge_ms_err_no_cause,
676 sizeof(purge_ms_err_no_cause));
677 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
678
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100679 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
680 last_updated_subscr = NULL;
681 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100682 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100683 OSMO_ASSERT(last_updated_subscr == NULL);
684
685 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
686 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
687 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
688 OSMO_ASSERT(last_updated_subscr == NULL);
689
690 /* Inject LocCancelReq GSUP message (unknown IMSI) */
691 rc = rx_gsup_message(location_cancellation_req,
692 sizeof(location_cancellation_req));
693 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
694 OSMO_ASSERT(last_updated_subscr == NULL);
695
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100696 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200697
698 cleanup_test();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100699}
700
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100701int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
702{
703 msgb_free(msg);
704 return 0;
705};
706
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200707/*
708 * Test that a GMM Detach will remove the MMCTX and the
709 * associated LLME.
710 */
711static void test_gmm_detach(void)
712{
713 struct gprs_ra_id raid = { 0, };
714 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200715 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200716
717 printf("Testing GMM detach\n");
718
719 /* DTAP - Detach Request (MO) */
720 /* normal detach, power_off = 0 */
721 static const unsigned char detach_req[] = {
722 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
723 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
724 };
725
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200726 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200727
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100728 /* Create a context */
729 OSMO_ASSERT(count(gprs_llme_list()) == 0);
730 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200731
732 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100733 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100734 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200735
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100736 /* verify that a single message (hopefully the Detach Accept) has been
737 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100738 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100739
740 /* verify that things are gone */
741 OSMO_ASSERT(count(gprs_llme_list()) == 0);
742 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
743 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200744
745 cleanup_test();
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100746}
747
748/*
749 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
750 * will not sent a Detach Accept message (power_off = 1)
751 */
752static void test_gmm_detach_power_off(void)
753{
754 struct gprs_ra_id raid = { 0, };
755 struct sgsn_mm_ctx *ctx, *ictx;
756 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100757
758 printf("Testing GMM detach (power off)\n");
759
760 /* DTAP - Detach Request (MO) */
761 /* normal detach, power_off = 1 */
762 static const unsigned char detach_req[] = {
763 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
764 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
765 };
766
767 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
768
769 /* Create a context */
770 OSMO_ASSERT(count(gprs_llme_list()) == 0);
771 ctx = alloc_mm_ctx(local_tlli, &raid);
772
773 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100774 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100775 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100776
777 /* verify that no message (and therefore no Detach Accept) has been
778 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100779 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100780
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200781 /* verify that things are gone */
782 OSMO_ASSERT(count(gprs_llme_list()) == 0);
783 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200784 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200785
786 cleanup_test();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200787}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200788
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200789/*
790 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
791 */
792static void test_gmm_detach_no_mmctx(void)
793{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100794 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200795 struct gprs_llc_lle *lle;
796 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200797
798 printf("Testing GMM detach (no MMCTX)\n");
799
800 /* DTAP - Detach Request (MO) */
801 /* normal detach, power_off = 0 */
802 static const unsigned char detach_req[] = {
803 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
804 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
805 };
806
807 /* Create an LLME */
808 OSMO_ASSERT(count(gprs_llme_list()) == 0);
809 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
810 lle = gprs_lle_get_or_create(local_tlli, 3);
811
812 OSMO_ASSERT(count(gprs_llme_list()) == 1);
813
814 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100815 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100816 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200817
818 /* verify that the LLME is gone */
819 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200820
821 cleanup_test();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200822}
823
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100824/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100825 * Test that a single GMM Detach Accept message will not cause the SGSN to send
826 * any message or leave an MM context at the SGSN.
827 */
828static void test_gmm_detach_accept_unexpected(void)
829{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100830 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100831 struct gprs_llc_lle *lle;
832 uint32_t local_tlli;
833
834 printf("Testing GMM detach accept (unexpected)\n");
835
836 /* DTAP - Detach Accept (MT) */
837 /* normal detach */
838 static const unsigned char detach_acc[] = {
839 0x08, 0x06
840 };
841
842 /* Create an LLME */
843 OSMO_ASSERT(count(gprs_llme_list()) == 0);
844 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
845 lle = gprs_lle_get_or_create(local_tlli, 3);
846
847 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100848 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100849 detach_acc, ARRAY_SIZE(detach_acc));
850
851 /* verify that no message (and therefore no Status or XID reset) has been
852 * sent by the SGSN */
853 OSMO_ASSERT(sgsn_tx_counter == 0);
854
855 /* verify that things are gone */
856 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200857
858 cleanup_test();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100859}
860
861/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100862 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
863 */
864static void test_gmm_status_no_mmctx(void)
865{
Jacob Erlbeck91580892016-01-04 18:43:33 +0100866 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100867 struct gprs_llc_lle *lle;
868 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100869
870 printf("Testing GMM Status (no MMCTX)\n");
871
872 /* DTAP - GMM Status, protocol error */
873 static const unsigned char gmm_status[] = {
874 0x08, 0x20, 0x6f
875 };
876
877 /* Create an LLME */
878 OSMO_ASSERT(count(gprs_llme_list()) == 0);
879 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
880 lle = gprs_lle_get_or_create(local_tlli, 3);
881
882 OSMO_ASSERT(count(gprs_llme_list()) == 1);
883
884 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100885 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100886 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100887
888 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100889 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100890
891 /* verify that the LLME is gone */
892 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200893
894 cleanup_test();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100895}
896
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100897/*
898 * Test the GMM Attach procedure
899 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100900static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100901{
902 struct gprs_ra_id raid = { 0, };
903 struct sgsn_mm_ctx *ctx = NULL;
904 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100905 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100906 uint32_t foreign_tlli;
907 uint32_t local_tlli = 0;
908 struct gprs_llc_lle *lle;
909
910 /* DTAP - Attach Request */
911 /* The P-TMSI is not known by the SGSN */
912 static const unsigned char attach_req[] = {
913 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
914 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
915 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
916 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
917 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
918 };
919
920 /* DTAP - Identity Response IMEI */
921 static const unsigned char ident_resp_imei[] = {
922 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
923 0x56
924 };
925
926 /* DTAP - Identity Response IMSI */
927 static const unsigned char ident_resp_imsi[] = {
928 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
929 0x54
930 };
931
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100932 /* DTAP - Authentication and Ciphering Resp */
933 static const unsigned char auth_ciph_resp[] = {
934 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
935 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
936 };
937
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100938 /* DTAP - Attach Complete */
939 static const unsigned char attach_compl[] = {
940 0x08, 0x03
941 };
942
943 /* DTAP - Detach Request (MO) */
944 /* normal detach, power_off = 0 */
945 static const unsigned char detach_req[] = {
946 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
947 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
948 };
949
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100950 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100951
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100952 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
953
954 /* Create a LLE/LLME */
955 OSMO_ASSERT(count(gprs_llme_list()) == 0);
956 lle = gprs_lle_get_or_create(foreign_tlli, 3);
957 OSMO_ASSERT(count(gprs_llme_list()) == 1);
958
959 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100960 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100961 attach_req, ARRAY_SIZE(attach_req));
962
963 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
964 OSMO_ASSERT(ctx != NULL);
965 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
966
967 /* we expect an identity request (IMEI) */
968 OSMO_ASSERT(sgsn_tx_counter == 1);
969
970 /* inject the identity response (IMEI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100971 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100972 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
973
974 /* we expect an identity request (IMSI) */
975 OSMO_ASSERT(sgsn_tx_counter == 1);
976
977 /* inject the identity response (IMSI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100978 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100979 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
980
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100981 /* check that the MM context has not been removed due to a failed
982 * authorization */
983 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
984
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100985 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100986
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100987retry_attach_req:
988
989 if (retry && sgsn_tx_counter == 0) {
990 fprintf(stderr, "Retrying attach request\n");
991 /* re-inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +0100992 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100993 attach_req, ARRAY_SIZE(attach_req));
994 }
995
996 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
997 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100998
999 /* inject the auth & ciph response */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001000 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001001 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1002
1003 /* check that the MM context has not been removed due to a
1004 * failed authorization */
1005 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001006 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1007 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001008 }
1009
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001010 if (retry && sgsn_tx_counter == 0)
1011 goto retry_attach_req;
1012
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001013 /* we expect an attach accept/reject */
1014 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001015 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1016 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001017
1018 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001019 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001020
1021 /* inject the attach complete */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001022 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001023 attach_compl, ARRAY_SIZE(attach_compl));
1024
1025 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1026
1027 /* we don't expect a response */
1028 OSMO_ASSERT(sgsn_tx_counter == 0);
1029
1030 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001031 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001032 detach_req, ARRAY_SIZE(detach_req));
1033
1034 /* verify that things are gone */
1035 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1036 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1037 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001038
1039 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001040}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001041
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001042static void test_gmm_attach_acl(void)
1043{
1044 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1045
1046 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1047 sgsn_acl_add("123456789012345", &sgsn->cfg);
1048 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001049 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001050 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001051
1052 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001053
1054 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001055}
1056
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001057int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001058 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001059 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001060 if (rc == -ENOTSUP) {
1061 OSMO_ASSERT(mmctx->subscr);
1062 gprs_subscr_update(mmctx->subscr);
1063 }
1064 return rc;
1065};
1066
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001067int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1068 gprs_subscr_update(mmctx->subscr);
1069 return 0;
1070};
1071
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001072static void test_gmm_attach_subscr(void)
1073{
1074 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1075 struct gsm_subscriber *subscr;
1076
1077 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001078 subscr_request_update_location_cb = my_subscr_request_update_location;
1079 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001080
1081 subscr = gprs_subscr_get_or_create("123456789012345");
1082 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001083
1084 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001085 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001086 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001087 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001088
1089 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001090 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1091 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001092
1093 cleanup_test();
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001094}
1095
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001096int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1097{
1098 /* Fake an authentication */
1099 OSMO_ASSERT(mmctx->subscr);
1100 mmctx->is_authenticated = 1;
1101 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001102
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001103 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001104};
1105
1106static void test_gmm_attach_subscr_fake_auth(void)
1107{
1108 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1109 struct gsm_subscriber *subscr;
1110
1111 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001112 subscr_request_update_location_cb = my_subscr_request_update_location;
1113 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001114
1115 subscr = gprs_subscr_get_or_create("123456789012345");
1116 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001117 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001118 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001119
1120 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001121 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001122 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001123 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001124
1125 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001126 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1127 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001128
1129 cleanup_test();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001130}
1131
1132int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1133{
1134 struct gsm_auth_tuple at = {
1135 .sres = {0x51, 0xe5, 0x51, 0xe5},
1136 .key_seq = 0
1137 };
1138
1139 /* Fake an authentication */
1140 OSMO_ASSERT(mmctx->subscr);
1141 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1142
1143 gprs_subscr_update_auth_info(mmctx->subscr);
1144
1145 return 0;
1146};
1147
1148static void test_gmm_attach_subscr_real_auth(void)
1149{
1150 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1151 struct gsm_subscriber *subscr;
1152
1153 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1154 subscr_request_update_location_cb = my_subscr_request_update_location;
1155 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1156
1157 subscr = gprs_subscr_get_or_create("123456789012345");
1158 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001159 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001160 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001161
1162 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001163
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001164 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001165 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001166 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001167
1168 sgsn->cfg.auth_policy = saved_auth_policy;
1169 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1170 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001171
1172 cleanup_test();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001173}
1174
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001175#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1176 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1177
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001178static int auth_info_skip = 0;
1179static int upd_loc_skip = 0;
1180
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001181int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1182{
1183 static const uint8_t send_auth_info_res[] = {
1184 0x0a,
1185 TEST_GSUP_IMSI_LONG_IE,
1186 0x03, 0x22, /* Auth tuple */
1187 0x20, 0x10,
1188 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1189 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1190 0x21, 0x04,
1191 0x51, 0xe5, 0x51, 0xe5,
1192 0x22, 0x08,
1193 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1194 };
1195
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001196 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001197
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001198 if (auth_info_skip > 0) {
1199 auth_info_skip -= 1;
1200 return -EAGAIN;
1201 }
1202
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001203 /* Fake an SendAuthInfoRes */
1204 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1205
1206 return 0;
1207};
1208
1209int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1210 static const uint8_t update_location_res[] = {
1211 0x06,
1212 TEST_GSUP_IMSI_LONG_IE,
1213 0x04, 0x00, /* PDP info complete */
1214 0x05, 0x12,
1215 0x10, 0x01, 0x01,
1216 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1217 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001218 0x08, 0x07, /* MSISDN 49166213323 encoded */
1219 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freyther10c0f562015-05-17 20:58:40 +02001220 0x09, 0x07, /* MSISDN 38166213323 encoded */
1221 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001222 };
1223
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001224 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001225
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001226 if (upd_loc_skip > 0) {
1227 upd_loc_skip -= 1;
1228 return -EAGAIN;
1229 }
1230
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001231 /* Fake an UpdateLocRes */
1232 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1233};
1234
1235
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001236static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001237{
1238 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1239 struct gsm_subscriber *subscr;
1240
1241 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1242 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1243 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001244 if (retry) {
1245 upd_loc_skip = 3;
1246 auth_info_skip = 3;
1247 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001248
1249 subscr = gprs_subscr_get_or_create("123456789012345");
1250 subscr->authorized = 1;
1251 sgsn->cfg.require_authentication = 1;
1252 sgsn->cfg.require_update_location = 1;
1253 subscr_put(subscr);
1254
1255 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001256 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001257 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001258
1259 sgsn->cfg.auth_policy = saved_auth_policy;
1260 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1261 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001262 upd_loc_skip = 0;
1263 auth_info_skip = 0;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001264
1265 cleanup_test();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001266}
1267
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001268int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1269{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001270 struct gprs_gsup_message to_peer = {0};
1271 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001272 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001273 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001274
1275 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001276 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1277 OSMO_ASSERT(rc >= 0);
1278 OSMO_ASSERT(to_peer.imsi[0] != 0);
1279 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001280
1281 /* This invalidates the pointers in to_peer */
1282 msgb_free(msg);
1283
1284 switch (to_peer.message_type) {
1285 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1286 /* Send UPDATE_LOCATION_RESULT */
1287 return my_subscr_request_update_gsup_auth(NULL);
1288
1289 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1290 /* Send SEND_AUTH_INFO_RESULT */
1291 return my_subscr_request_auth_info_gsup_auth(NULL);
1292
1293 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001294 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1295 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001296
1297 default:
1298 if ((to_peer.message_type & 0b00000011) == 0) {
1299 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001300 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001301 from_peer.message_type = to_peer.message_type + 1;
1302 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1303 break;
1304 }
1305
1306 /* Ignore it */
1307 return 0;
1308 }
1309
1310 reply_msg = gprs_gsup_msgb_alloc();
1311 reply_msg->l2h = reply_msg->data;
1312 gprs_gsup_encode(reply_msg, &from_peer);
1313 gprs_subscr_rx_gsup_message(reply_msg);
1314 msgb_free(reply_msg);
1315
1316 return 0;
1317};
1318
1319static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1320{
1321 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1322 struct gsm_subscriber *subscr;
1323
1324 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001325 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1326
1327 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1328
1329 if (retry) {
1330 upd_loc_skip = 3;
1331 auth_info_skip = 3;
1332 }
1333
1334 printf("Auth policy 'remote', real GSUP based auth: ");
1335 test_gmm_attach(retry);
1336
1337 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001338 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001339 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001340
1341 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001342 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1343 upd_loc_skip = 0;
1344 auth_info_skip = 0;
1345 talloc_free(sgsn->gsup_client);
1346 sgsn->gsup_client = NULL;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001347
1348 cleanup_test();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001349}
1350
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001351/*
1352 * Test the GMM Rejects
1353 */
1354static void test_gmm_reject(void)
1355{
1356 struct gprs_ra_id raid = { 0, };
1357 struct sgsn_mm_ctx *ctx = NULL;
1358 uint32_t foreign_tlli;
1359 struct gprs_llc_lle *lle;
1360 int idx;
1361
1362 /* DTAP - Attach Request */
1363 /* Invalid MI length */
1364 static const unsigned char attach_req_inv_mi_len[] = {
1365 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1366 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1367 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1368 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1369 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1370 };
1371
1372 /* DTAP - Attach Request */
1373 /* Invalid MI type (IMEI) */
1374 static const unsigned char attach_req_inv_mi_type[] = {
1375 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1376 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1377 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1378 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1379 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1380 };
1381
1382 /* DTAP - Routing Area Update Request */
1383 static const unsigned char dtap_ra_upd_req[] = {
1384 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1385 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1386 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1387 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1388 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1389 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1390 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1391 };
1392
1393 /* DTAP - Routing Area Update Request */
1394 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1395 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1396 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1397 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1398 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1399 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1400 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1401 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1402 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1403 };
1404
1405 /* DTAP - Routing Area Update Request */
1406 /* Invalid cap length */
1407 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1408 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1409 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1410 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1411 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1412 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1413 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1414 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1415 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1416 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1417 };
1418
1419 struct test {
1420 const char *title;
1421 const unsigned char *msg;
1422 unsigned msg_len;
1423 unsigned num_resp;
1424
1425 };
1426 static struct test tests[] = {
1427 {
1428 .title = "Attach Request (invalid MI length)",
1429 .msg = attach_req_inv_mi_len,
1430 .msg_len = sizeof(attach_req_inv_mi_len),
1431 .num_resp = 1 /* Reject */
1432
1433 },
1434 {
1435 .title = "Attach Request (invalid MI type)",
1436 .msg = attach_req_inv_mi_type,
1437 .msg_len = sizeof(attach_req_inv_mi_type),
1438 .num_resp = 1 /* Reject */
1439 },
1440 {
1441 .title = "Routing Area Update Request (valid)",
1442 .msg = dtap_ra_upd_req,
1443 .msg_len = sizeof(dtap_ra_upd_req),
1444 .num_resp = 2 /* XID Reset + Reject */
1445 },
1446 {
1447 .title = "Routing Area Update Request (invalid type)",
1448 .msg = dtap_ra_upd_req_inv_type,
1449 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1450 .num_resp = 1 /* Reject */
1451 },
1452 {
1453 .title = "Routing Area Update Request (invalid CAP length)",
1454 .msg = dtap_ra_upd_req_inv_cap_len,
1455 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1456 .num_resp = 1 /* Reject */
1457 },
1458 };
1459
1460 printf("Testing GMM reject\n");
1461
1462 /* reset the PRNG used by sgsn_alloc_ptmsi */
1463 srand(1);
1464
1465 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1466
1467 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1468
1469 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1470 const struct test *test = &tests[idx];
1471 printf(" - %s\n", test->title);
1472
1473 /* Create a LLE/LLME */
1474 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1475 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1476
1477 /* Inject the Request message */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001478 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001479 test->msg, test->msg_len);
1480
1481 /* We expect a Reject message */
1482 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1483 sgsn_tx_counter, test->num_resp);
1484 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1485
1486 /* verify that LLME/MM are removed */
1487 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1488 OSMO_ASSERT(ctx == NULL);
1489 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1490 }
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001491
1492 cleanup_test();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001493}
1494
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001495/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001496 * Test cancellation of attached MM contexts
1497 */
1498static void test_gmm_cancel(void)
1499{
1500 struct gprs_ra_id raid = { 0, };
1501 struct sgsn_mm_ctx *ctx = NULL;
1502 struct sgsn_mm_ctx *ictx;
1503 uint32_t ptmsi1;
1504 uint32_t foreign_tlli;
1505 uint32_t local_tlli = 0;
1506 struct gprs_llc_lle *lle;
1507 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1508
1509 /* DTAP - Attach Request */
1510 /* The P-TMSI is not known by the SGSN */
1511 static const unsigned char attach_req[] = {
1512 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1513 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1514 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1515 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1516 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1517 };
1518
1519 /* DTAP - Identity Response IMEI */
1520 static const unsigned char ident_resp_imei[] = {
1521 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1522 0x56
1523 };
1524
1525 /* DTAP - Identity Response IMSI */
1526 static const unsigned char ident_resp_imsi[] = {
1527 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1528 0x54
1529 };
1530
1531 /* DTAP - Attach Complete */
1532 static const unsigned char attach_compl[] = {
1533 0x08, 0x03
1534 };
1535
1536 printf("Testing cancellation\n");
1537
1538 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1539
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001540 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1541
1542 /* Create a LLE/LLME */
1543 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1544 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1545 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1546
1547 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001548 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001549 attach_req, ARRAY_SIZE(attach_req));
1550
1551 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1552 OSMO_ASSERT(ctx != NULL);
1553 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1554
1555 /* we expect an identity request (IMEI) */
1556 OSMO_ASSERT(sgsn_tx_counter == 1);
1557
1558 /* inject the identity response (IMEI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001559 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001560 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1561
1562 /* we expect an identity request (IMSI) */
1563 OSMO_ASSERT(sgsn_tx_counter == 1);
1564
1565 /* inject the identity response (IMSI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001566 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001567 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1568
1569 /* check that the MM context has not been removed due to a failed
1570 * authorization */
1571 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1572
1573 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1574
1575 /* we expect an attach accept/reject */
1576 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001577 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1578 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001579
1580 /* this has been randomly assigned by the SGSN */
1581 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1582
1583 /* inject the attach complete */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001584 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001585 attach_compl, ARRAY_SIZE(attach_compl));
1586
1587 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1588
1589 /* we don't expect a response */
1590 OSMO_ASSERT(sgsn_tx_counter == 0);
1591
1592 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001593 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001594
1595 /* verify that things are gone */
1596 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1597 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1598 OSMO_ASSERT(!ictx);
1599
1600 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001601
1602 cleanup_test();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001603}
1604
1605/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001606 * Test the dynamic allocation of P-TMSIs
1607 */
1608static void test_gmm_ptmsi_allocation(void)
1609{
Jacob Erlbeckd58c0332016-01-04 18:43:35 +01001610 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001611 struct sgsn_mm_ctx *ctx = NULL;
1612 struct sgsn_mm_ctx *ictx;
1613 uint32_t foreign_tlli;
1614 uint32_t ptmsi1;
1615 uint32_t ptmsi2;
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001616 uint32_t received_ptmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001617 uint32_t old_ptmsi;
1618 uint32_t local_tlli = 0;
1619 struct gprs_llc_lle *lle;
1620 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1621
1622 /* DTAP - Attach Request (IMSI 12131415161718) */
1623 static const unsigned char attach_req[] = {
1624 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1625 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1626 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1627 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1628 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1629 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1630 0x00,
1631 };
1632
1633 /* DTAP - Identity Response IMEI */
1634 static const unsigned char ident_resp_imei[] = {
1635 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1636 0x56
1637 };
1638
1639 /* DTAP - Attach Complete */
1640 static const unsigned char attach_compl[] = {
1641 0x08, 0x03
1642 };
1643
1644 /* DTAP - Routing Area Update Request */
1645 static const unsigned char ra_upd_req[] = {
1646 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1647 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1648 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1649 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1650 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1651 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1652 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1653 };
1654
1655 /* DTAP - Routing Area Update Complete */
1656 static const unsigned char ra_upd_complete[] = {
1657 0x08, 0x0a
1658 };
1659
1660 /* DTAP - Detach Request (MO) */
1661 /* normal detach, power_off = 1 */
1662 static const unsigned char detach_req[] = {
1663 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1664 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1665 };
1666
1667 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1668
1669 printf("Testing P-TMSI allocation\n");
1670
1671 printf(" - sgsn_alloc_ptmsi\n");
1672
1673 /* reset the PRNG used by sgsn_alloc_ptmsi */
1674 srand(1);
1675
1676 ptmsi1 = sgsn_alloc_ptmsi();
1677 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1678
1679 ptmsi2 = sgsn_alloc_ptmsi();
1680 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1681
1682 OSMO_ASSERT(ptmsi1 != ptmsi2);
1683
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001684 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001685
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001686 printf(" - Repeated Attach Request\n");
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001687
1688 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1689
1690 /* Create a LLE/LLME */
1691 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1692 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1693 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1694
1695 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001696 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001697 attach_req, ARRAY_SIZE(attach_req));
1698
1699 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1700 OSMO_ASSERT(ctx != NULL);
1701 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001702 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1703 ptmsi1 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001704
1705 old_ptmsi = ctx->p_tmsi_old;
1706
1707 /* we expect an identity request (IMEI) */
1708 OSMO_ASSERT(sgsn_tx_counter == 1);
1709
1710 /* inject the identity response (IMEI) */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001711 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001712 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1713
1714 /* check that the MM context has not been removed due to a failed
1715 * authorization */
1716 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1717
1718 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1719 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1720
1721 /* we expect an attach accept */
1722 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001723 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1724 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001725
1726 /* we ignore this and send the attach again */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001727 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001728 attach_req, ARRAY_SIZE(attach_req));
1729
1730 /* the allocated P-TMSI should be the same */
1731 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1732 OSMO_ASSERT(ctx != NULL);
1733 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1734 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1735 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1736
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001737 /* we expect an attach accept */
1738 OSMO_ASSERT(sgsn_tx_counter == 1);
1739 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1740 OSMO_ASSERT(received_ptmsi == ptmsi1);
1741
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001742 /* inject the attach complete */
1743 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck91580892016-01-04 18:43:33 +01001744 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001745 attach_compl, ARRAY_SIZE(attach_compl));
1746
1747 /* we don't expect a response */
1748 OSMO_ASSERT(sgsn_tx_counter == 0);
1749
1750 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1751 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1752 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1753
1754 printf(" - Repeated RA Update Request\n");
1755
1756 /* inject the RA update request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001757 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001758 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1759
1760 /* we expect an RA update accept */
1761 OSMO_ASSERT(sgsn_tx_counter == 1);
1762
1763 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1764 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001765 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1766 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1767 ptmsi2 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001768
1769 /* repeat the RA update request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001770 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001771 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1772
1773 /* we expect an RA update accept */
1774 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001775 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1776 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001777
1778 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1779 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1780 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1781
1782 /* inject the RA update complete */
1783 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Jacob Erlbeck91580892016-01-04 18:43:33 +01001784 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001785 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1786
1787 /* we don't expect a response */
1788 OSMO_ASSERT(sgsn_tx_counter == 0);
1789
1790 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1791 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1792 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1793
1794 /* inject the detach */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001795 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001796 detach_req, ARRAY_SIZE(detach_req));
1797
1798 /* verify that things are gone */
1799 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1800 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1801 OSMO_ASSERT(!ictx);
1802
1803 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001804
1805 cleanup_test();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001806}
1807
Jacob Erlbeck13304782016-01-04 18:43:37 +01001808/*
1809 * Test changing of routing areas
1810 */
1811static void test_gmm_routing_areas(void)
1812{
1813 struct gprs_ra_id raid1 = {332, 112, 16464, 96};
1814 struct gprs_ra_id raid2 = {332, 112, 16464, 97};
1815 struct sgsn_mm_ctx *ctx = NULL;
1816 struct sgsn_mm_ctx *ictx;
1817 uint32_t ptmsi1;
1818 uint32_t received_ptmsi;
1819 uint32_t ms_tlli = 0;
1820 struct gprs_llc_lle *lle;
1821 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1822
1823 /* DTAP - Attach Request (IMSI 12131415161718) */
1824 static const unsigned char attach_req[] = {
1825 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1826 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1827 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1828 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1829 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1830 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1831 0x00,
1832 };
1833
1834 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1835 static const unsigned char attach_req2[] = {
1836 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1837 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1838 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1839 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1840 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1841 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1842 0x00,
1843 };
1844
1845 /* DTAP - Identity Response IMEI */
1846 static const unsigned char ident_resp_imei[] = {
1847 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1848 0x56
1849 };
1850
1851 /* DTAP - Attach Complete */
1852 static const unsigned char attach_compl[] = {
1853 0x08, 0x03
1854 };
1855
1856 /* DTAP - Routing Area Update Request (coming from RA 1) */
1857 static const unsigned char ra_upd_req1[] = {
1858 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1859 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1860 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1861 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1862 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1863 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1864 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1865 };
1866
1867 /* DTAP - Routing Area Update Request (coming from RA 2) */
1868 static const unsigned char ra_upd_req2[] = {
1869 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1870 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1871 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1872 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1873 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1874 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1875 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1876 };
1877
1878 /* DTAP - Routing Area Update Request (coming from RA other) */
1879 /* raid_other = {443, 223, 16464, 98}; */
1880 static const unsigned char ra_upd_req_other[] = {
1881 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1882 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1883 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1884 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1885 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1886 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1887 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1888 };
1889
1890 /* DTAP - Routing Area Update Complete */
1891 static const unsigned char ra_upd_complete[] = {
1892 0x08, 0x0a
1893 };
1894
1895 /* DTAP - Detach Request (MO) */
1896 /* normal detach, power_off = 1 */
1897 static const unsigned char detach_req[] = {
1898 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1899 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1900 };
1901
1902 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1903
1904 printf("Testing routing area changes\n");
1905
1906 /* reset the PRNG used by sgsn_alloc_ptmsi */
1907 srand(1);
1908
1909 ptmsi1 = GSM_RESERVED_TMSI;
1910
1911 printf(" - Attach Request (RA 1)\n");
1912
1913 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1914
1915 /* Create a LLE/LLME */
1916 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1917 lle = gprs_lle_get_or_create(ms_tlli, 3);
1918 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1919
1920 /* inject the attach request */
1921 send_0408_message(lle->llme, ms_tlli, &raid1,
1922 attach_req, ARRAY_SIZE(attach_req));
1923
1924 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1925 OSMO_ASSERT(ctx != NULL);
1926 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1927 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1928
1929 /* we expect an identity request (IMEI) */
1930 OSMO_ASSERT(sgsn_tx_counter == 1);
1931 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1932 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1933
1934 /* inject the identity response (IMEI) */
1935 send_0408_message(ctx->llme, ms_tlli, &raid1,
1936 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1937
1938 /* check that the MM context has not been removed due to a failed
1939 * authorization */
1940 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1941
1942 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1943
1944 /* we expect an attach accept */
1945 OSMO_ASSERT(sgsn_tx_counter == 1);
1946 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1947 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1948
1949 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1950 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1951 ptmsi1 = received_ptmsi;
1952
1953 /* inject the attach complete */
1954 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1955 send_0408_message(ctx->llme, ms_tlli, &raid1,
1956 attach_compl, ARRAY_SIZE(attach_compl));
1957
1958 /* we don't expect a response */
1959 OSMO_ASSERT(sgsn_tx_counter == 0);
1960
1961 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1962 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1963 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1964
1965 printf(" - RA Update Request (RA 1 -> RA 1)\n");
1966
1967 /* inject the RA update request */
1968 send_0408_message(ctx->llme, ms_tlli, &raid1,
1969 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
1970
1971 /* we expect an RA update accept */
1972 OSMO_ASSERT(sgsn_tx_counter == 1);
1973 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
1974 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1975
1976 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1977 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1978 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1979 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1980
1981 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1982 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1983 ptmsi1 = received_ptmsi;
1984
1985 /* inject the RA update complete */
1986 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1987 send_0408_message(ctx->llme, ms_tlli, &raid1,
1988 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1989
1990 /* we don't expect a response */
1991 OSMO_ASSERT(sgsn_tx_counter == 0);
1992
1993 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1994 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1995 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1996 OSMO_ASSERT(ctx->tlli == ms_tlli);
1997
Jacob Erlbeck13304782016-01-04 18:43:37 +01001998 printf(" - RA Update Request (RA 1 -> RA 2)\n");
1999
2000 /* inject the RA update request */
2001 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2002
2003 /* It is coming from RA 1 => ra_upd_req1 */
2004 send_0408_message(ctx->llme, ms_tlli, &raid2,
2005 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2006
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002007 /* we expect an RA update accept */
Jacob Erlbeck13304782016-01-04 18:43:37 +01002008 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002009 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002010
2011 printf(" - RA Update Request (RA other -> RA 2)\n");
2012
2013 /* inject the RA update request */
2014 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2015
2016 /* It is coming from RA 1 => ra_upd_req1 */
2017 send_0408_message(ctx->llme, ms_tlli, &raid2,
2018 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2019
2020 /* we expect an RA update reject (and a LLC XID RESET) */
2021 OSMO_ASSERT(sgsn_tx_counter == 2);
2022 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2023 /* this has killed the LLE/LLME */
2024
2025 printf(" - Attach Request (RA 2)\n");
2026
2027 /* Create a LLE/LLME */
2028 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2029 lle = gprs_lle_get_or_create(ms_tlli, 3);
2030 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2031
2032 /* inject the attach request */
2033 send_0408_message(lle->llme, ms_tlli, &raid2,
2034 attach_req2, ARRAY_SIZE(attach_req2));
2035
2036 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2037 OSMO_ASSERT(ctx != NULL);
2038 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2039 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2040
2041 /* we expect an attach accept */
2042 OSMO_ASSERT(sgsn_tx_counter == 1);
2043 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2044
2045 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2046 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2047 ptmsi1 = received_ptmsi;
2048
2049 /* inject the attach complete */
2050 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2051 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2052 OSMO_ASSERT(ictx != NULL);
2053 OSMO_ASSERT(ictx == ctx);
2054
2055 send_0408_message(ctx->llme, ms_tlli, &raid2,
2056 attach_compl, ARRAY_SIZE(attach_compl));
2057
2058 /* we don't expect a response */
2059 OSMO_ASSERT(sgsn_tx_counter == 0);
2060
2061 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2062 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2063 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2064
2065 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2066
2067 /* inject the RA update request */
2068 send_0408_message(ctx->llme, ms_tlli, &raid2,
2069 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2070
2071 /* we expect an RA update accept */
2072 OSMO_ASSERT(sgsn_tx_counter == 1);
2073 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2074
2075 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2076 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2077 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2078 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2079
2080 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2081 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2082 ptmsi1 = received_ptmsi;
2083
2084 /* inject the RA update complete */
2085 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2086 send_0408_message(ctx->llme, ms_tlli, &raid2,
2087 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2088
2089 /* we don't expect a response */
2090 OSMO_ASSERT(sgsn_tx_counter == 0);
2091
2092 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2093 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2094 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2095 OSMO_ASSERT(ctx->tlli == ms_tlli);
2096
2097
2098 /* inject the detach */
2099 send_0408_message(ctx->llme, ms_tlli, &raid2,
2100 detach_req, ARRAY_SIZE(detach_req));
2101
2102 /* verify that things are gone */
2103 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2104 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2105 OSMO_ASSERT(!ictx);
2106
2107 sgsn->cfg.auth_policy = saved_auth_policy;
2108
2109 cleanup_test();
2110}
2111
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002112static void test_apn_matching(void)
2113{
2114 struct apn_ctx *actx, *actxs[9];
2115
2116 printf("Testing APN matching\n");
2117
2118 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2119 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2120 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2121 actxs[3] = NULL;
2122
2123 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2124 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2125 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2126 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2127
2128 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2129
2130 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2131 OSMO_ASSERT(actx == actxs[2]);
2132 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2133 OSMO_ASSERT(actx == actxs[2]);
2134 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2135 OSMO_ASSERT(actx == actxs[1]);
2136 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2137 OSMO_ASSERT(actx == actxs[1]);
2138 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2139 OSMO_ASSERT(actx == actxs[0]);
2140 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2141 OSMO_ASSERT(actx == NULL);
2142
2143 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2144 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2145 OSMO_ASSERT(actx == actxs[3]);
2146
2147 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2148 OSMO_ASSERT(actx == actxs[4]);
2149
2150 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2151 OSMO_ASSERT(actx == actxs[6]);
2152
2153 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2154 OSMO_ASSERT(actx == actxs[5]);
2155
2156 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2157 OSMO_ASSERT(actx == actxs[7]);
2158
2159 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2160 OSMO_ASSERT(actx == actxs[8]);
2161
2162 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2163 OSMO_ASSERT(actx == actxs[7]);
2164
2165 /* Free APN contexts and check how the matching changes */
2166
2167 sgsn_apn_ctx_free(actxs[7]);
2168 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2169 OSMO_ASSERT(actx == actxs[8]);
2170
2171 sgsn_apn_ctx_free(actxs[8]);
2172 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2173 OSMO_ASSERT(actx == actxs[6]);
2174
2175 sgsn_apn_ctx_free(actxs[6]);
2176 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2177 OSMO_ASSERT(actx == actxs[1]);
2178
2179 sgsn_apn_ctx_free(actxs[5]);
2180 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2181 OSMO_ASSERT(actx == actxs[4]);
2182
2183 sgsn_apn_ctx_free(actxs[4]);
2184 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2185 OSMO_ASSERT(actx == actxs[2]);
2186
2187 sgsn_apn_ctx_free(actxs[2]);
2188 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2189 OSMO_ASSERT(actx == actxs[1]);
2190
2191 sgsn_apn_ctx_free(actxs[1]);
2192 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2193 OSMO_ASSERT(actx == actxs[0]);
2194
2195 sgsn_apn_ctx_free(actxs[0]);
2196 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2197 OSMO_ASSERT(actx == actxs[3]);
2198
2199 sgsn_apn_ctx_free(actxs[3]);
2200 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2201 OSMO_ASSERT(actx == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002202
2203 cleanup_test();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002204}
2205
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002206struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2207 struct sgsn_subscriber_data *sdata);
2208
2209static void test_ggsn_selection(void)
2210{
2211 struct apn_ctx *actxs[4];
2212 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
2213 struct gsm_subscriber *s1;
2214 const char *imsi1 = "1234567890";
2215 struct sgsn_mm_ctx *ctx;
2216 struct gprs_ra_id raid = { 0, };
2217 uint32_t local_tlli = 0xffeeddcc;
2218 enum gsm48_gsm_cause gsm_cause;
2219 struct tlv_parsed tp;
2220 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2221 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002222 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002223
2224 printf("Testing GGSN selection\n");
2225
2226 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
2227
2228 /* Check for emptiness */
2229 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2230
2231 /* Create a context */
2232 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2233 ctx = alloc_mm_ctx(local_tlli, &raid);
2234 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
2235
2236 /* Allocate and attach a subscriber */
2237 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2238 assert_subscr(s1, imsi1);
2239
2240 tp.lv[GSM48_IE_GSM_APN].len = 0;
2241 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2242
2243 /* TODO: Add PDP info entries to s1 */
2244
2245 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2246 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2247 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2248
2249 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2250 actxs[0]->ggsn = ggcs[0];
2251 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2252 actxs[1]->ggsn = ggcs[1];
2253 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2254 actxs[2]->ggsn = ggcs[2];
2255
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002256 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2257 pdp_data->context_id = 1;
2258 pdp_data->pdp_type = 0x0121;
2259 strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
2260
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002261 /* Resolve GGSNs */
2262
2263 tp.lv[GSM48_IE_GSM_APN].len =
2264 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2265
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002266 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002267 OSMO_ASSERT(ggc != NULL);
2268 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002269 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002270
2271 tp.lv[GSM48_IE_GSM_APN].len =
2272 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2273
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002274 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002275 OSMO_ASSERT(ggc != NULL);
2276 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002277 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002278
2279 tp.lv[GSM48_IE_GSM_APN].len = 0;
2280 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2281
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002282 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002283 OSMO_ASSERT(ggc != NULL);
2284 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002285 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002286
2287 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2288 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002289 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002290 OSMO_ASSERT(ggc != NULL);
2291 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002292 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002293
2294 sgsn_apn_ctx_free(actxs[3]);
2295 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2296
2297 tp.lv[GSM48_IE_GSM_APN].len =
2298 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2299
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002300 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002301 OSMO_ASSERT(ggc == NULL);
2302 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002303 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002304
2305 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002306 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002307 OSMO_ASSERT(ggc == NULL);
2308 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2309
2310 /* Add PDP data entry to subscriber */
2311
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002312 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
2313
2314 tp.lv[GSM48_IE_GSM_APN].len =
2315 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2316
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002317 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002318 OSMO_ASSERT(ggc != NULL);
2319 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002320 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002321
2322 tp.lv[GSM48_IE_GSM_APN].len =
2323 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2324
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002325 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002326 OSMO_ASSERT(ggc == NULL);
2327 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002328 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002329
2330 /* Cleanup */
2331
2332 subscr_put(s1);
2333 sgsn_mm_ctx_cleanup_free(ctx);
2334
2335 assert_no_subscrs();
2336
2337 sgsn_apn_ctx_free(actxs[0]);
2338 sgsn_apn_ctx_free(actxs[1]);
2339 sgsn_apn_ctx_free(actxs[2]);
2340
2341 sgsn_ggsn_ctx_free(ggcs[0]);
2342 sgsn_ggsn_ctx_free(ggcs[1]);
2343 sgsn_ggsn_ctx_free(ggcs[2]);
2344
2345 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002346
2347 cleanup_test();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002348}
2349
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002350static struct log_info_cat gprs_categories[] = {
2351 [DMM] = {
2352 .name = "DMM",
2353 .description = "Layer3 Mobility Management (MM)",
2354 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002355 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002356 },
2357 [DPAG] = {
2358 .name = "DPAG",
2359 .description = "Paging Subsystem",
2360 .color = "\033[1;38m",
2361 .enabled = 1, .loglevel = LOGL_NOTICE,
2362 },
2363 [DMEAS] = {
2364 .name = "DMEAS",
2365 .description = "Radio Measurement Processing",
2366 .enabled = 0, .loglevel = LOGL_NOTICE,
2367 },
2368 [DREF] = {
2369 .name = "DREF",
2370 .description = "Reference Counting",
2371 .enabled = 0, .loglevel = LOGL_NOTICE,
2372 },
2373 [DGPRS] = {
2374 .name = "DGPRS",
2375 .description = "GPRS Packet Service",
2376 .enabled = 1, .loglevel = LOGL_DEBUG,
2377 },
2378 [DNS] = {
2379 .name = "DNS",
2380 .description = "GPRS Network Service (NS)",
2381 .enabled = 1, .loglevel = LOGL_INFO,
2382 },
2383 [DBSSGP] = {
2384 .name = "DBSSGP",
2385 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2386 .enabled = 1, .loglevel = LOGL_DEBUG,
2387 },
2388 [DLLC] = {
2389 .name = "DLLC",
2390 .description = "GPRS Logical Link Control Protocol (LLC)",
2391 .enabled = 1, .loglevel = LOGL_DEBUG,
2392 },
2393 [DSNDCP] = {
2394 .name = "DSNDCP",
2395 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2396 .enabled = 1, .loglevel = LOGL_DEBUG,
2397 },
2398};
2399
2400static struct log_info info = {
2401 .cat = gprs_categories,
2402 .num_cat = ARRAY_SIZE(gprs_categories),
2403};
2404
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002405int main(int argc, char **argv)
2406{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002407 void *osmo_sgsn_ctx;
2408
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002409 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002410 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2411 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
2412 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002413
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01002414 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002415 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002416
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002417 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002418 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002419 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002420 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002421 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002422 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002423 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002424 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002425 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002426 test_gmm_attach_acl();
2427 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002428 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002429 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002430 test_gmm_attach_subscr_gsup_auth(0);
2431 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002432 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002433 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002434 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002435 test_gmm_ptmsi_allocation();
Jacob Erlbeck13304782016-01-04 18:43:37 +01002436 test_gmm_routing_areas();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002437 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002438 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002439 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002440
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002441 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01002442 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002443 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002444 return 0;
2445}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002446
2447
2448/* stubs */
2449struct osmo_prim_hdr;
2450int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2451{
2452 abort();
2453}