blob: d27b755dbea09fdf78aea08e73431aa41c18abfe [file] [log] [blame]
Holger Hans Peter Freyther232f6212014-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 Freyther49dbcd92014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbecke8b69682014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Jacob Erlbeck3400f112015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Jacob Erlbeck28c28f92015-10-12 19:36:32 +020030#include <openbsc/gprs_gb_parse.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020031
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010032#include <osmocom/gprs/gprs_bssgp.h>
33
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020034#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck092bbc82015-01-05 18:57:32 +010035#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020036
37#include <osmocom/core/application.h>
38#include <osmocom/core/msgb.h>
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010039#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020040
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +020041#include <stdio.h>
42
Holger Hans Peter Freyther49dbcd92014-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 Erlbeckd7b77732014-11-04 10:08:37 +010050 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020051 },
52};
53struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010054unsigned sgsn_tx_counter = 0;
Jacob Erlbeck28c28f92015-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 Erlbeck0b2da872014-10-27 14:34:13 +010066
Jacob Erlbeck515fc332015-10-12 19:36:31 +020067static void cleanup_test()
68{
Jacob Erlbeck28c28f92015-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 Erlbeck515fc332015-10-12 19:36:31 +020080}
81
Jacob Erlbeck0b2da872014-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 Erlbeck28c28f92015-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 Erlbeck0b2da872014-10-27 14:34:13 +0100101 sgsn_tx_counter += 1;
102 return 0;
103}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200104
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100105/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck428f1ec2015-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 Erlbecke8b69682014-11-12 10:12:11 +0100108 &__real_sgsn_update_subscriber_data;
109
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100110void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100111{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100112 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100113}
114
Jacob Erlbeck828059f2014-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 Erlbeckd04f7cc2014-11-12 10:18:09 +0100119
Jacob Erlbeck828059f2014-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 Erlbeckd04f7cc2014-11-12 10:18:09 +0100131};
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100132
Jacob Erlbeck0d2cf602015-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 Freyther49dbcd92014-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 Freyther94246842014-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 Erlbeckf43a2992014-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 Erlbeck75488292014-10-29 10:31:18 +0100188static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100189 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100190 const uint8_t *data, size_t data_len)
191{
192 struct msgb *msg;
193
Jacob Erlbeck28c28f92015-10-12 19:36:32 +0200194 reset_last_msg();
Jacob Erlbeck75488292014-10-29 10:31:18 +0100195 sgsn_tx_counter = 0;
196
197 msg = create_msg(data, data_len);
198 msgb_tlli(msg) = tlli;
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100199 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Jacob Erlbeck75488292014-10-29 10:31:18 +0100200 gsm0408_gprs_rcvmsg(msg, llme);
201 msgb_free(msg);
202}
203
Holger Hans Peter Freyther49dbcd92014-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 Freyther49dbcd92014-10-02 21:27:24 +0200208
209 printf("Testing LLME allocations\n");
210 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther49dbcd92014-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 Freyther49dbcd92014-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 Erlbeck515fc332015-10-12 19:36:31 +0200230
231 cleanup_test();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200232}
233
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100234struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100235void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100236{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100237 OSMO_ASSERT(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100238 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100239 __func__, mmctx, mmctx->subscr);
240 last_updated_subscr = mmctx->subscr;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100241}
242
Jacob Erlbecka695d242015-01-09 11:59:50 +0100243static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
244{
245 struct gsm_subscriber *sfound;
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100246 OSMO_ASSERT(subscr);
247 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100248
249 sfound = gprs_subscr_get_by_imsi(imsi);
250 OSMO_ASSERT(sfound == subscr);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100251
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100252 subscr_put(sfound);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100253}
254
Jacob Erlbeck8768f2b2015-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 Freytherd95cb732015-01-20 21:14:03 +0100261 "use count: %d\n",
262 subscr->imsi, subscr->use_count);
Jacob Erlbeck8768f2b2015-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 Erlbecke8b69682014-11-12 10:12:11 +0100273static void test_subscriber(void)
274{
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100275 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100276 const char *imsi1 = "1234567890";
277 const char *imsi2 = "9876543210";
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100278 const char *imsi3 = "5656565656";
Jacob Erlbecke8b69682014-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 Erlbeck9bf4be92015-01-06 16:32:41 +0100287 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-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 Erlbecka695d242015-01-09 11:59:50 +0100292 assert_subscr(s1, imsi1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100293 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbecke8b69682014-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 Erlbecka695d242015-01-09 11:59:50 +0100298
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100299 /* Allocate entry 3 */
300 s3 = gprs_subscr_get_or_create(imsi3);
301
Jacob Erlbecka695d242015-01-09 11:59:50 +0100302 /* Check entries */
303 assert_subscr(s1, imsi1);
304 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100305 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100306
307 /* Update entry 1 */
308 last_updated_subscr = NULL;
309 gprs_subscr_update(s1);
Jacob Erlbeck428f1ec2015-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 Erlbecke8b69682014-11-12 10:12:11 +0100313
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100314 /* There is no subscriber cache. Verify it */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100315 gprs_subscr_cleanup(s1);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100316 subscr_put(s1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100317 s1 = NULL;
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100318 sfound = gprs_subscr_get_by_imsi(imsi1);
319 OSMO_ASSERT(sfound == NULL);
320
Jacob Erlbecka695d242015-01-09 11:59:50 +0100321 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100322 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100323
Jacob Erlbecka695d242015-01-09 11:59:50 +0100324 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100325 gprs_subscr_cleanup(s2);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100326 subscr_put(s2);
Jacob Erlbecke8b69682014-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 Erlbeck9bf4be92015-01-06 16:32:41 +0100330 assert_subscr(s3, imsi3);
331
332 /* Try to delete entry 3 */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100333 gprs_subscr_cleanup(s3);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100334 subscr_put(s3);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100335 s3 = NULL;
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100336 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-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 Erlbeck515fc332015-10-12 19:36:31 +0200341
342 cleanup_test();
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100343}
344
Jacob Erlbeckb1332b62014-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 Erlbeckb1332b62014-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 Erlbeck70c177a2015-01-26 14:43:07 +0100401 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100402 s1found = gprs_subscr_get_by_imsi(imsi1);
403 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200404
405 cleanup_test();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100406}
407
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100408#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
409
Jacob Erlbeckb5c51432014-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 Erlbeck5641cfc2014-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 Erlbeck94a346a2014-12-17 14:03:35 +0100432 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbeck5641cfc2014-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 Freyther786cfee2015-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 Erlbeck5641cfc2014-12-12 15:01:37 +0100466 static const uint8_t update_location_res[] = {
467 0x06,
468 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400469 0x08, 0x09, MSISDN,
Jacob Erlbeck5641cfc2014-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 Freyther786cfee2015-04-23 09:53:53 -0400481#undef MSISDN
482
Jacob Erlbeck5641cfc2014-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 Erlbecke7fea452015-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 Erlbeck00b8b912015-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 Erlbeck86bc8702015-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 Erlbeck9ca3ace2015-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 Erlbeck86bc8702015-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 Erlbeck4f414862015-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 Erlbeck5641cfc2014-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 Erlbeck5641cfc2014-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 Erlbeckb5c51432014-12-19 18:19:50 +0100563 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbeck5641cfc2014-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 Erlbeckb5c51432014-12-19 18:19:50 +0100573 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100574 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100575 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100576 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-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 Erlbeck94a346a2014-12-17 14:03:35 +0100583 /* Inject UpdateLocRes GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100584 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100585 OSMO_ASSERT(rc >= 0);
586 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100587 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100588 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther786cfee2015-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 Erlbeck94a346a2014-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 Erlbeck5641cfc2014-12-12 15:01:37 +0100598
599 /* Check authorization */
600 OSMO_ASSERT(s1->authorized == 1);
601
602 /* Inject UpdateLocErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100603 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100604 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100605 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100606 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100607
608 /* Check authorization */
609 OSMO_ASSERT(s1->authorized == 0);
610
Jacob Erlbeck4f414862015-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 Erlbeck00b8b912015-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 Erlbeck4f414862015-01-15 17:08:30 +0100634 /* Inject LocCancelReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100635 rc = rx_gsup_message(location_cancellation_req,
636 sizeof(location_cancellation_req));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100637 OSMO_ASSERT(rc >= 0);
638 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100639 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbeck5641cfc2014-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 Erlbecke7fea452015-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 Erlbeck86bc8702015-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 Erlbeck5641cfc2014-12-12 15:01:37 +0100657 /* Free MM context and subscriber */
Jacob Erlbeck265e7352015-01-30 11:57:25 +0100658 OSMO_ASSERT(ctx->subscr == NULL);
659 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100660 subscr_put(s1);
661 s1found = gprs_subscr_get_by_imsi(imsi1);
662 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100663
Jacob Erlbeck86bc8702015-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 Erlbeck9ca3ace2015-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 Erlbeck4f414862015-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 Erlbeck629dacc2015-01-15 17:50:16 +0100682 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck4f414862015-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 Erlbeck5641cfc2014-12-12 15:01:37 +0100696 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200697
698 cleanup_test();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100699}
700
Jacob Erlbeckfdf8ce52015-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 Freyther94246842014-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 Freyther94246842014-10-02 22:24:47 +0200715 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-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 Freyther94246842014-10-02 22:24:47 +0200726 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200727
Jacob Erlbeckf43a2992014-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 Freyther94246842014-10-02 22:24:47 +0200731
732 /* inject the detach */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100733 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100734 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200735
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100736 /* verify that a single message (hopefully the Detach Accept) has been
737 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100738 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-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 Erlbeck515fc332015-10-12 19:36:31 +0200744
745 cleanup_test();
Jacob Erlbeck0b2da872014-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 Erlbeck0b2da872014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100774 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100775 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100776
777 /* verify that no message (and therefore no Detach Accept) has been
778 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100779 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100780
Holger Hans Peter Freyther94246842014-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 Erlbeck12396bd2014-09-30 13:51:45 +0200784 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200785
786 cleanup_test();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200787}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200788
Jacob Erlbeck42d284f2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100794 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200795 struct gprs_llc_lle *lle;
796 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100815 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100816 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200817
818 /* verify that the LLME is gone */
819 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200820
821 cleanup_test();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200822}
823
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100824/*
Jacob Erlbeck021a0d12014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100830 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck021a0d12014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100848 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck021a0d12014-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 Erlbeck515fc332015-10-12 19:36:31 +0200857
858 cleanup_test();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100859}
860
861/*
Jacob Erlbeckb35ee6b2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100866 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100867 struct gprs_llc_lle *lle;
868 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100885 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100886 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100887
888 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100889 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100890
891 /* verify that the LLME is gone */
892 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200893
894 cleanup_test();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100895}
896
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100897/*
898 * Test the GMM Attach procedure
899 */
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100900static void test_gmm_attach(int retry)
Jacob Erlbeck7c24b3e2014-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 Erlbeck0a2c7912014-11-24 14:40:28 +0100905 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-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 Erlbeck828059f2014-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 Erlbeck7c24b3e2014-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 Erlbeck803ebfa2014-12-19 18:30:41 +0100950 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100951
Jacob Erlbeck7c24b3e2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100960 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7c24b3e2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100971 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck7c24b3e2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100978 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100979 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
980
Jacob Erlbeck7c24b3e2014-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 Erlbeck67318ef2014-10-28 16:23:46 +0100985 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100986
Jacob Erlbeck803ebfa2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +0100992 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck803ebfa2014-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 Erlbeck828059f2014-11-28 14:55:25 +0100998
999 /* inject the auth & ciph response */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001000 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeck828059f2014-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 Freythera9f671c2015-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 Erlbeck828059f2014-11-28 14:55:25 +01001008 }
1009
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001010 if (retry && sgsn_tx_counter == 0)
1011 goto retry_attach_req;
1012
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001013 /* we expect an attach accept/reject */
1014 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001015 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1016 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001017
1018 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +01001019 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001020
1021 /* inject the attach complete */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001022 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck7c24b3e2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001031 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeck7c24b3e2014-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 Erlbeck515fc332015-10-12 19:36:31 +02001038
1039 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001040}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001041
Jacob Erlbeckd04f7cc2014-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 Erlbeck803ebfa2014-12-19 18:30:41 +01001049 test_gmm_attach(0);
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001050 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001051
1052 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001053
1054 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001055}
1056
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001057int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001058 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001059 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-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 Erlbeck828059f2014-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 Erlbeckd04f7cc2014-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 Erlbeck828059f2014-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 Erlbeckd04f7cc2014-11-12 10:18:09 +01001080
1081 subscr = gprs_subscr_get_or_create("123456789012345");
1082 subscr->authorized = 1;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001083
1084 printf("Auth policy 'remote': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001085 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001086 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001087 assert_no_subscrs();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001088
1089 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-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 Erlbeck515fc332015-10-12 19:36:31 +02001092
1093 cleanup_test();
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001094}
1095
Jacob Erlbeck828059f2014-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 Erlbeckd8126992014-12-08 15:26:47 +01001102
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001103 return 0;
Jacob Erlbeckd8126992014-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 Erlbeck828059f2014-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 Erlbeckd8126992014-12-08 15:26:47 +01001114
1115 subscr = gprs_subscr_get_or_create("123456789012345");
1116 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001117 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001118 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001119
1120 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001121 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001122 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001123 assert_no_subscrs();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001124
1125 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-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 Erlbeck515fc332015-10-12 19:36:31 +02001128
1129 cleanup_test();
Jacob Erlbeck828059f2014-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 Erlbeck16b17ed2014-12-17 13:20:08 +01001159 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001160 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001161
1162 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001163
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001164 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001165 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001166 assert_no_subscrs();
Jacob Erlbeck828059f2014-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 Erlbeck515fc332015-10-12 19:36:31 +02001171
1172 cleanup_test();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001173}
1174
Jacob Erlbeckdebbdd72014-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 Erlbeck803ebfa2014-12-19 18:30:41 +01001178static int auth_info_skip = 0;
1179static int upd_loc_skip = 0;
1180
Jacob Erlbeckdebbdd72014-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 Erlbeck0d2cf602015-01-09 15:07:16 +01001196 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001197
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001198 if (auth_info_skip > 0) {
1199 auth_info_skip -= 1;
1200 return -EAGAIN;
1201 }
1202
Jacob Erlbeckdebbdd72014-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 Freythera9f671c2015-05-05 22:52:40 +02001218 0x08, 0x07, /* MSISDN 49166213323 encoded */
1219 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freytherfe4a9f62015-05-17 20:58:40 +02001220 0x09, 0x07, /* MSISDN 38166213323 encoded */
1221 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001222 };
1223
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001224 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001225
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001226 if (upd_loc_skip > 0) {
1227 upd_loc_skip -= 1;
1228 return -EAGAIN;
1229 }
1230
Jacob Erlbeckdebbdd72014-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 Erlbeck803ebfa2014-12-19 18:30:41 +01001236static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeckdebbdd72014-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 Erlbeck803ebfa2014-12-19 18:30:41 +01001244 if (retry) {
1245 upd_loc_skip = 3;
1246 auth_info_skip = 3;
1247 }
Jacob Erlbeckdebbdd72014-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 Erlbeck803ebfa2014-12-19 18:30:41 +01001256 test_gmm_attach(retry);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001257 assert_no_subscrs();
Jacob Erlbeckdebbdd72014-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 Erlbeck803ebfa2014-12-19 18:30:41 +01001262 upd_loc_skip = 0;
1263 auth_info_skip = 0;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001264
1265 cleanup_test();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001266}
1267
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001268int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1269{
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001270 struct gprs_gsup_message to_peer = {0};
1271 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001272 struct msgb *reply_msg;
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001273 int rc;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001274
1275 /* Simulate the GSUP peer */
Jacob Erlbeckb3982c12015-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 Erlbeck0d2cf602015-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 Erlbeckb3982c12015-01-06 16:32:41 +01001294 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1295 break;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001296
1297 default:
1298 if ((to_peer.message_type & 0b00000011) == 0) {
1299 /* Unhandled request */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001300 /* Send error(NOT_IMPL) */
Jacob Erlbeck0d2cf602015-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 Erlbeck0d2cf602015-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 Freytherd95cb732015-01-20 21:14:03 +01001338 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001339 assert_no_subscrs();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001340
1341 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck0d2cf602015-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 Erlbeck515fc332015-10-12 19:36:31 +02001347
1348 cleanup_test();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001349}
1350
Jacob Erlbeck6f4bbd42014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001478 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck6f4bbd42014-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 Erlbeck515fc332015-10-12 19:36:31 +02001491
1492 cleanup_test();
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001493}
1494
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001495/*
Jacob Erlbeckbf0b8742014-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 Erlbeckbf0b8742014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001548 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001559 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001566 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-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 Erlbeck28c28f92015-10-12 19:36:32 +02001577 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1578 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeckbf0b8742014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001584 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbeckbf0b8742014-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 Erlbeck41010082015-01-05 17:51:17 +01001593 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeckbf0b8742014-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 Erlbeck515fc332015-10-12 19:36:31 +02001601
1602 cleanup_test();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001603}
1604
1605/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001606 * Test the dynamic allocation of P-TMSIs
1607 */
1608static void test_gmm_ptmsi_allocation(void)
1609{
Jacob Erlbeckf963e7e2016-01-04 18:43:35 +01001610 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbecke06476a2014-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 Erlbeck28c28f92015-10-12 19:36:32 +02001616 uint32_t received_ptmsi;
Jacob Erlbecke06476a2014-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 Erlbeck28c28f92015-10-12 19:36:32 +02001684 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001685
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001686 printf(" - Repeated Attach Request\n");
Jacob Erlbecke06476a2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001696 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbecke06476a2014-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 Erlbeck28c28f92015-10-12 19:36:32 +02001702 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1703 ptmsi1 = ctx->p_tmsi;
Jacob Erlbecke06476a2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001711 send_0408_message(ctx->llme, foreign_tlli, &raid,
Jacob Erlbecke06476a2014-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 Erlbeck28c28f92015-10-12 19:36:32 +02001723 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1724 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001725
1726 /* we ignore this and send the attach again */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001727 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbecke06476a2014-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 Erlbeck28c28f92015-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 Erlbecke06476a2014-11-06 15:43:10 +01001742 /* inject the attach complete */
1743 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001744 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001757 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-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 Erlbeck28c28f92015-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 Erlbecke06476a2014-11-06 15:43:10 +01001768
1769 /* repeat the RA update request */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001770 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-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 Erlbeck28c28f92015-10-12 19:36:32 +02001775 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1776 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbecke06476a2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001784 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-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 Erlbeck2d9dee92016-01-04 18:43:33 +01001795 send_0408_message(ctx->llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-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 Erlbeck515fc332015-10-12 19:36:31 +02001804
1805 cleanup_test();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001806}
1807
Jacob Erlbeckf703f152016-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
1998
1999 printf(" - RA Update Request (RA 1 -> RA 2)\n");
2000
2001 /* inject the RA update request */
2002 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2003
2004 /* It is coming from RA 1 => ra_upd_req1 */
2005 send_0408_message(ctx->llme, ms_tlli, &raid2,
2006 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2007
2008 /* we expect an RA update reject (and a LLC XID RESET) */
2009 OSMO_ASSERT(sgsn_tx_counter == 2);
2010 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2011 /* this has killed the LLE/LLME */
2012
2013 printf(" - Attach Request (RA 2)\n");
2014
2015 /* Create a LLE/LLME */
2016 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2017 lle = gprs_lle_get_or_create(ms_tlli, 3);
2018 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2019
2020 /* inject the attach request */
2021 send_0408_message(lle->llme, ms_tlli, &raid2,
2022 attach_req2, ARRAY_SIZE(attach_req2));
2023
2024 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2025 OSMO_ASSERT(ctx != NULL);
2026 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2027 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2028
2029 /* we expect an attach accept */
2030 OSMO_ASSERT(sgsn_tx_counter == 1);
2031 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2032
2033 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2034 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2035 ptmsi1 = received_ptmsi;
2036
2037 /* inject the attach complete */
2038 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2039 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2040 OSMO_ASSERT(ictx != NULL);
2041 OSMO_ASSERT(ictx == ctx);
2042
2043 send_0408_message(ctx->llme, ms_tlli, &raid2,
2044 attach_compl, ARRAY_SIZE(attach_compl));
2045
2046 /* we don't expect a response */
2047 OSMO_ASSERT(sgsn_tx_counter == 0);
2048
2049 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2050 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2051 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2052
2053 printf(" - RA Update Request (RA other -> RA 2)\n");
2054
2055 /* inject the RA update request */
2056 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2057
2058 /* It is coming from RA 1 => ra_upd_req1 */
2059 send_0408_message(ctx->llme, ms_tlli, &raid2,
2060 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2061
2062 /* we expect an RA update reject (and a LLC XID RESET) */
2063 OSMO_ASSERT(sgsn_tx_counter == 2);
2064 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2065 /* this has killed the LLE/LLME */
2066
2067 printf(" - Attach Request (RA 2)\n");
2068
2069 /* Create a LLE/LLME */
2070 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2071 lle = gprs_lle_get_or_create(ms_tlli, 3);
2072 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2073
2074 /* inject the attach request */
2075 send_0408_message(lle->llme, ms_tlli, &raid2,
2076 attach_req2, ARRAY_SIZE(attach_req2));
2077
2078 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2079 OSMO_ASSERT(ctx != NULL);
2080 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2081 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2082
2083 /* we expect an attach accept */
2084 OSMO_ASSERT(sgsn_tx_counter == 1);
2085 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2086
2087 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2088 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2089 ptmsi1 = received_ptmsi;
2090
2091 /* inject the attach complete */
2092 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2093 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2094 OSMO_ASSERT(ictx != NULL);
2095 OSMO_ASSERT(ictx == ctx);
2096
2097 send_0408_message(ctx->llme, ms_tlli, &raid2,
2098 attach_compl, ARRAY_SIZE(attach_compl));
2099
2100 /* we don't expect a response */
2101 OSMO_ASSERT(sgsn_tx_counter == 0);
2102
2103 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2104 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2105 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2106
2107 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2108
2109 /* inject the RA update request */
2110 send_0408_message(ctx->llme, ms_tlli, &raid2,
2111 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2112
2113 /* we expect an RA update accept */
2114 OSMO_ASSERT(sgsn_tx_counter == 1);
2115 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2116
2117 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
2118 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2119 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2120 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2121
2122 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2123 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2124 ptmsi1 = received_ptmsi;
2125
2126 /* inject the RA update complete */
2127 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2128 send_0408_message(ctx->llme, ms_tlli, &raid2,
2129 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2130
2131 /* we don't expect a response */
2132 OSMO_ASSERT(sgsn_tx_counter == 0);
2133
2134 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
2135 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2136 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2137 OSMO_ASSERT(ctx->tlli == ms_tlli);
2138
2139
2140 /* inject the detach */
2141 send_0408_message(ctx->llme, ms_tlli, &raid2,
2142 detach_req, ARRAY_SIZE(detach_req));
2143
2144 /* verify that things are gone */
2145 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2146 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2147 OSMO_ASSERT(!ictx);
2148
2149 sgsn->cfg.auth_policy = saved_auth_policy;
2150
2151 cleanup_test();
2152}
2153
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002154static void test_apn_matching(void)
2155{
2156 struct apn_ctx *actx, *actxs[9];
2157
2158 printf("Testing APN matching\n");
2159
2160 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2161 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2162 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2163 actxs[3] = NULL;
2164
2165 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2166 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2167 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2168 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2169
2170 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2171
2172 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2173 OSMO_ASSERT(actx == actxs[2]);
2174 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2175 OSMO_ASSERT(actx == actxs[2]);
2176 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2177 OSMO_ASSERT(actx == actxs[1]);
2178 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2179 OSMO_ASSERT(actx == actxs[1]);
2180 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2181 OSMO_ASSERT(actx == actxs[0]);
2182 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2183 OSMO_ASSERT(actx == NULL);
2184
2185 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2186 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2187 OSMO_ASSERT(actx == actxs[3]);
2188
2189 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2190 OSMO_ASSERT(actx == actxs[4]);
2191
2192 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2193 OSMO_ASSERT(actx == actxs[6]);
2194
2195 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2196 OSMO_ASSERT(actx == actxs[5]);
2197
2198 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2199 OSMO_ASSERT(actx == actxs[7]);
2200
2201 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2202 OSMO_ASSERT(actx == actxs[8]);
2203
2204 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2205 OSMO_ASSERT(actx == actxs[7]);
2206
2207 /* Free APN contexts and check how the matching changes */
2208
2209 sgsn_apn_ctx_free(actxs[7]);
2210 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2211 OSMO_ASSERT(actx == actxs[8]);
2212
2213 sgsn_apn_ctx_free(actxs[8]);
2214 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2215 OSMO_ASSERT(actx == actxs[6]);
2216
2217 sgsn_apn_ctx_free(actxs[6]);
2218 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2219 OSMO_ASSERT(actx == actxs[1]);
2220
2221 sgsn_apn_ctx_free(actxs[5]);
2222 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2223 OSMO_ASSERT(actx == actxs[4]);
2224
2225 sgsn_apn_ctx_free(actxs[4]);
2226 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2227 OSMO_ASSERT(actx == actxs[2]);
2228
2229 sgsn_apn_ctx_free(actxs[2]);
2230 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2231 OSMO_ASSERT(actx == actxs[1]);
2232
2233 sgsn_apn_ctx_free(actxs[1]);
2234 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2235 OSMO_ASSERT(actx == actxs[0]);
2236
2237 sgsn_apn_ctx_free(actxs[0]);
2238 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2239 OSMO_ASSERT(actx == actxs[3]);
2240
2241 sgsn_apn_ctx_free(actxs[3]);
2242 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2243 OSMO_ASSERT(actx == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02002244
2245 cleanup_test();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002246}
2247
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002248struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2249 struct sgsn_subscriber_data *sdata);
2250
2251static void test_ggsn_selection(void)
2252{
2253 struct apn_ctx *actxs[4];
2254 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
2255 struct gsm_subscriber *s1;
2256 const char *imsi1 = "1234567890";
2257 struct sgsn_mm_ctx *ctx;
2258 struct gprs_ra_id raid = { 0, };
2259 uint32_t local_tlli = 0xffeeddcc;
2260 enum gsm48_gsm_cause gsm_cause;
2261 struct tlv_parsed tp;
2262 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2263 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002264 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002265
2266 printf("Testing GGSN selection\n");
2267
2268 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
2269
2270 /* Check for emptiness */
2271 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2272
2273 /* Create a context */
2274 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2275 ctx = alloc_mm_ctx(local_tlli, &raid);
2276 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
2277
2278 /* Allocate and attach a subscriber */
2279 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2280 assert_subscr(s1, imsi1);
2281
2282 tp.lv[GSM48_IE_GSM_APN].len = 0;
2283 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2284
2285 /* TODO: Add PDP info entries to s1 */
2286
2287 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2288 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2289 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2290
2291 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2292 actxs[0]->ggsn = ggcs[0];
2293 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2294 actxs[1]->ggsn = ggcs[1];
2295 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2296 actxs[2]->ggsn = ggcs[2];
2297
Holger Hans Peter Freytherab9422e2015-05-24 20:51:17 +08002298 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2299 pdp_data->context_id = 1;
2300 pdp_data->pdp_type = 0x0121;
2301 strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
2302
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002303 /* Resolve GGSNs */
2304
2305 tp.lv[GSM48_IE_GSM_APN].len =
2306 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2307
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002308 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002309 OSMO_ASSERT(ggc != NULL);
2310 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002311 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002312
2313 tp.lv[GSM48_IE_GSM_APN].len =
2314 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2315
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002316 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002317 OSMO_ASSERT(ggc != NULL);
2318 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002319 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002320
2321 tp.lv[GSM48_IE_GSM_APN].len = 0;
2322 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2323
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002324 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002325 OSMO_ASSERT(ggc != NULL);
2326 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002327 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002328
2329 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2330 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002331 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002332 OSMO_ASSERT(ggc != NULL);
2333 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002334 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002335
2336 sgsn_apn_ctx_free(actxs[3]);
2337 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2338
2339 tp.lv[GSM48_IE_GSM_APN].len =
2340 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2341
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002342 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002343 OSMO_ASSERT(ggc == NULL);
2344 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002345 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002346
2347 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002348 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002349 OSMO_ASSERT(ggc == NULL);
2350 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2351
2352 /* Add PDP data entry to subscriber */
2353
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002354 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
2355
2356 tp.lv[GSM48_IE_GSM_APN].len =
2357 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2358
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002359 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002360 OSMO_ASSERT(ggc != NULL);
2361 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002362 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002363
2364 tp.lv[GSM48_IE_GSM_APN].len =
2365 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2366
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002367 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002368 OSMO_ASSERT(ggc == NULL);
2369 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002370 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002371
2372 /* Cleanup */
2373
2374 subscr_put(s1);
2375 sgsn_mm_ctx_cleanup_free(ctx);
2376
2377 assert_no_subscrs();
2378
2379 sgsn_apn_ctx_free(actxs[0]);
2380 sgsn_apn_ctx_free(actxs[1]);
2381 sgsn_apn_ctx_free(actxs[2]);
2382
2383 sgsn_ggsn_ctx_free(ggcs[0]);
2384 sgsn_ggsn_ctx_free(ggcs[1]);
2385 sgsn_ggsn_ctx_free(ggcs[2]);
2386
2387 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02002388
2389 cleanup_test();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002390}
2391
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002392static struct log_info_cat gprs_categories[] = {
2393 [DMM] = {
2394 .name = "DMM",
2395 .description = "Layer3 Mobility Management (MM)",
2396 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002397 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002398 },
2399 [DPAG] = {
2400 .name = "DPAG",
2401 .description = "Paging Subsystem",
2402 .color = "\033[1;38m",
2403 .enabled = 1, .loglevel = LOGL_NOTICE,
2404 },
2405 [DMEAS] = {
2406 .name = "DMEAS",
2407 .description = "Radio Measurement Processing",
2408 .enabled = 0, .loglevel = LOGL_NOTICE,
2409 },
2410 [DREF] = {
2411 .name = "DREF",
2412 .description = "Reference Counting",
2413 .enabled = 0, .loglevel = LOGL_NOTICE,
2414 },
2415 [DGPRS] = {
2416 .name = "DGPRS",
2417 .description = "GPRS Packet Service",
2418 .enabled = 1, .loglevel = LOGL_DEBUG,
2419 },
2420 [DNS] = {
2421 .name = "DNS",
2422 .description = "GPRS Network Service (NS)",
2423 .enabled = 1, .loglevel = LOGL_INFO,
2424 },
2425 [DBSSGP] = {
2426 .name = "DBSSGP",
2427 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2428 .enabled = 1, .loglevel = LOGL_DEBUG,
2429 },
2430 [DLLC] = {
2431 .name = "DLLC",
2432 .description = "GPRS Logical Link Control Protocol (LLC)",
2433 .enabled = 1, .loglevel = LOGL_DEBUG,
2434 },
2435 [DSNDCP] = {
2436 .name = "DSNDCP",
2437 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2438 .enabled = 1, .loglevel = LOGL_DEBUG,
2439 },
2440};
2441
2442static struct log_info info = {
2443 .cat = gprs_categories,
2444 .num_cat = ARRAY_SIZE(gprs_categories),
2445};
2446
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002447int main(int argc, char **argv)
2448{
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002449 void *osmo_sgsn_ctx;
2450
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002451 osmo_init_logging(&info);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002452 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2453 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
2454 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002455
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01002456 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002457 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002458
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002459 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002460 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01002461 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01002462 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02002463 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01002464 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02002465 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01002466 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01002467 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01002468 test_gmm_attach_acl();
2469 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01002470 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01002471 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01002472 test_gmm_attach_subscr_gsup_auth(0);
2473 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01002474 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01002475 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01002476 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01002477 test_gmm_ptmsi_allocation();
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002478 test_gmm_routing_areas();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002479 test_apn_matching();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002480 test_ggsn_selection();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002481 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01002482
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002483 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01002484 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002485 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002486 return 0;
2487}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002488
2489
2490/* stubs */
2491struct osmo_prim_hdr;
2492int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2493{
2494 abort();
2495}