blob: 2098972bdd9b4c8e837593aba5d9c59bbe59f840 [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 Erlbeck9b3ca642015-02-03 13:47:53 +01001808static void test_apn_matching(void)
1809{
1810 struct apn_ctx *actx, *actxs[9];
1811
1812 printf("Testing APN matching\n");
1813
1814 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
1815 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
1816 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
1817 actxs[3] = NULL;
1818
1819 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
1820 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
1821 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
1822 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
1823
1824 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
1825
1826 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1827 OSMO_ASSERT(actx == actxs[2]);
1828 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
1829 OSMO_ASSERT(actx == actxs[2]);
1830 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
1831 OSMO_ASSERT(actx == actxs[1]);
1832 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
1833 OSMO_ASSERT(actx == actxs[1]);
1834 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
1835 OSMO_ASSERT(actx == actxs[0]);
1836 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1837 OSMO_ASSERT(actx == NULL);
1838
1839 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
1840 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1841 OSMO_ASSERT(actx == actxs[3]);
1842
1843 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
1844 OSMO_ASSERT(actx == actxs[4]);
1845
1846 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
1847 OSMO_ASSERT(actx == actxs[6]);
1848
1849 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1850 OSMO_ASSERT(actx == actxs[5]);
1851
1852 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
1853 OSMO_ASSERT(actx == actxs[7]);
1854
1855 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
1856 OSMO_ASSERT(actx == actxs[8]);
1857
1858 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1859 OSMO_ASSERT(actx == actxs[7]);
1860
1861 /* Free APN contexts and check how the matching changes */
1862
1863 sgsn_apn_ctx_free(actxs[7]);
1864 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1865 OSMO_ASSERT(actx == actxs[8]);
1866
1867 sgsn_apn_ctx_free(actxs[8]);
1868 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1869 OSMO_ASSERT(actx == actxs[6]);
1870
1871 sgsn_apn_ctx_free(actxs[6]);
1872 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1873 OSMO_ASSERT(actx == actxs[1]);
1874
1875 sgsn_apn_ctx_free(actxs[5]);
1876 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1877 OSMO_ASSERT(actx == actxs[4]);
1878
1879 sgsn_apn_ctx_free(actxs[4]);
1880 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1881 OSMO_ASSERT(actx == actxs[2]);
1882
1883 sgsn_apn_ctx_free(actxs[2]);
1884 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1885 OSMO_ASSERT(actx == actxs[1]);
1886
1887 sgsn_apn_ctx_free(actxs[1]);
1888 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1889 OSMO_ASSERT(actx == actxs[0]);
1890
1891 sgsn_apn_ctx_free(actxs[0]);
1892 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1893 OSMO_ASSERT(actx == actxs[3]);
1894
1895 sgsn_apn_ctx_free(actxs[3]);
1896 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1897 OSMO_ASSERT(actx == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001898
1899 cleanup_test();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01001900}
1901
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001902struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
1903 struct sgsn_subscriber_data *sdata);
1904
1905static void test_ggsn_selection(void)
1906{
1907 struct apn_ctx *actxs[4];
1908 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
1909 struct gsm_subscriber *s1;
1910 const char *imsi1 = "1234567890";
1911 struct sgsn_mm_ctx *ctx;
1912 struct gprs_ra_id raid = { 0, };
1913 uint32_t local_tlli = 0xffeeddcc;
1914 enum gsm48_gsm_cause gsm_cause;
1915 struct tlv_parsed tp;
1916 uint8_t apn_enc[GSM_APN_LENGTH + 10];
1917 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001918 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001919
1920 printf("Testing GGSN selection\n");
1921
1922 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
1923
1924 /* Check for emptiness */
1925 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
1926
1927 /* Create a context */
1928 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1929 ctx = alloc_mm_ctx(local_tlli, &raid);
1930 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
1931
1932 /* Allocate and attach a subscriber */
1933 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
1934 assert_subscr(s1, imsi1);
1935
1936 tp.lv[GSM48_IE_GSM_APN].len = 0;
1937 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1938
1939 /* TODO: Add PDP info entries to s1 */
1940
1941 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
1942 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
1943 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
1944
1945 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
1946 actxs[0]->ggsn = ggcs[0];
1947 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
1948 actxs[1]->ggsn = ggcs[1];
1949 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
1950 actxs[2]->ggsn = ggcs[2];
1951
Holger Hans Peter Freytherab9422e2015-05-24 20:51:17 +08001952 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
1953 pdp_data->context_id = 1;
1954 pdp_data->pdp_type = 0x0121;
1955 strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
1956
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001957 /* Resolve GGSNs */
1958
1959 tp.lv[GSM48_IE_GSM_APN].len =
1960 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
1961
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001962 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001963 OSMO_ASSERT(ggc != NULL);
1964 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001965 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001966
1967 tp.lv[GSM48_IE_GSM_APN].len =
1968 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
1969
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001970 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001971 OSMO_ASSERT(ggc != NULL);
1972 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001973 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001974
1975 tp.lv[GSM48_IE_GSM_APN].len = 0;
1976 tp.lv[GSM48_IE_GSM_APN].val = NULL;
1977
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001978 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001979 OSMO_ASSERT(ggc != NULL);
1980 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001981 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001982
1983 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
1984 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001985 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001986 OSMO_ASSERT(ggc != NULL);
1987 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001988 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001989
1990 sgsn_apn_ctx_free(actxs[3]);
1991 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1992
1993 tp.lv[GSM48_IE_GSM_APN].len =
1994 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
1995
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001996 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001997 OSMO_ASSERT(ggc == NULL);
1998 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001999 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002000
2001 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002002 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002003 OSMO_ASSERT(ggc == NULL);
2004 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2005
2006 /* Add PDP data entry to subscriber */
2007
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002008 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
2009
2010 tp.lv[GSM48_IE_GSM_APN].len =
2011 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2012
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002013 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002014 OSMO_ASSERT(ggc != NULL);
2015 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002016 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002017
2018 tp.lv[GSM48_IE_GSM_APN].len =
2019 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2020
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002021 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002022 OSMO_ASSERT(ggc == NULL);
2023 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002024 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002025
2026 /* Cleanup */
2027
2028 subscr_put(s1);
2029 sgsn_mm_ctx_cleanup_free(ctx);
2030
2031 assert_no_subscrs();
2032
2033 sgsn_apn_ctx_free(actxs[0]);
2034 sgsn_apn_ctx_free(actxs[1]);
2035 sgsn_apn_ctx_free(actxs[2]);
2036
2037 sgsn_ggsn_ctx_free(ggcs[0]);
2038 sgsn_ggsn_ctx_free(ggcs[1]);
2039 sgsn_ggsn_ctx_free(ggcs[2]);
2040
2041 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02002042
2043 cleanup_test();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002044}
2045
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002046static struct log_info_cat gprs_categories[] = {
2047 [DMM] = {
2048 .name = "DMM",
2049 .description = "Layer3 Mobility Management (MM)",
2050 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002051 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002052 },
2053 [DPAG] = {
2054 .name = "DPAG",
2055 .description = "Paging Subsystem",
2056 .color = "\033[1;38m",
2057 .enabled = 1, .loglevel = LOGL_NOTICE,
2058 },
2059 [DMEAS] = {
2060 .name = "DMEAS",
2061 .description = "Radio Measurement Processing",
2062 .enabled = 0, .loglevel = LOGL_NOTICE,
2063 },
2064 [DREF] = {
2065 .name = "DREF",
2066 .description = "Reference Counting",
2067 .enabled = 0, .loglevel = LOGL_NOTICE,
2068 },
2069 [DGPRS] = {
2070 .name = "DGPRS",
2071 .description = "GPRS Packet Service",
2072 .enabled = 1, .loglevel = LOGL_DEBUG,
2073 },
2074 [DNS] = {
2075 .name = "DNS",
2076 .description = "GPRS Network Service (NS)",
2077 .enabled = 1, .loglevel = LOGL_INFO,
2078 },
2079 [DBSSGP] = {
2080 .name = "DBSSGP",
2081 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2082 .enabled = 1, .loglevel = LOGL_DEBUG,
2083 },
2084 [DLLC] = {
2085 .name = "DLLC",
2086 .description = "GPRS Logical Link Control Protocol (LLC)",
2087 .enabled = 1, .loglevel = LOGL_DEBUG,
2088 },
2089 [DSNDCP] = {
2090 .name = "DSNDCP",
2091 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2092 .enabled = 1, .loglevel = LOGL_DEBUG,
2093 },
2094};
2095
2096static struct log_info info = {
2097 .cat = gprs_categories,
2098 .num_cat = ARRAY_SIZE(gprs_categories),
2099};
2100
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002101int main(int argc, char **argv)
2102{
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002103 void *osmo_sgsn_ctx;
2104
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002105 osmo_init_logging(&info);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002106 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2107 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
2108 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002109
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01002110 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002111 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002112
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002113 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002114 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01002115 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01002116 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02002117 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01002118 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02002119 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01002120 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01002121 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01002122 test_gmm_attach_acl();
2123 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01002124 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01002125 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01002126 test_gmm_attach_subscr_gsup_auth(0);
2127 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01002128 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01002129 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01002130 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01002131 test_gmm_ptmsi_allocation();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002132 test_apn_matching();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002133 test_ggsn_selection();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002134 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01002135
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002136 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01002137 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002138 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002139 return 0;
2140}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002141
2142
2143/* stubs */
2144struct osmo_prim_hdr;
2145int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2146{
2147 abort();
2148}