blob: 2fbd6e4fd3511c97f44d9cf35f5e176f7545a952 [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
Neels Hofmeyr4b4c5862017-09-04 15:13:25 +020022#include <osmocom/sgsn/gprs_llc.h>
23#include <osmocom/sgsn/sgsn.h>
24#include <osmocom/sgsn/gprs_gmm.h>
25#include <osmocom/sgsn/debug.h>
26#include <osmocom/sgsn/gprs_subscriber.h>
Harald Welte4e349d62016-04-25 19:07:34 +020027#include <osmocom/gsm/gsup.h>
Neels Hofmeyr4b4c5862017-09-04 15:13:25 +020028#include <osmocom/sgsn/gsup_client.h>
29#include <osmocom/sgsn/gprs_utils.h>
30#include <osmocom/sgsn/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>
35
36#include <osmocom/core/application.h>
37#include <osmocom/core/msgb.h>
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010038#include <osmocom/core/rate_ctr.h>
Neels Hofmeyr64a40bf2017-01-13 03:10:54 +010039#include <osmocom/core/utils.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 +020043void *tall_bsc_ctx;
44static struct sgsn_instance sgsn_inst = {
45 .config_file = "osmo_sgsn.cfg",
46 .cfg = {
47 .gtp_statedir = "./",
Jacob Erlbeckd7b77732014-11-04 10:08:37 +010048 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020049 },
50};
51struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010052unsigned sgsn_tx_counter = 0;
Jacob Erlbeck28c28f92015-10-12 19:36:32 +020053struct msgb *last_msg = NULL;
54struct gprs_gb_parse_context last_dl_parse_ctx;
55
56static void reset_last_msg()
57{
58 if (last_msg)
59 msgb_free(last_msg);
60
61 last_msg = NULL;
62 memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx));
63}
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010064
Jacob Erlbeck515fc332015-10-12 19:36:31 +020065static void cleanup_test()
66{
Jacob Erlbeck28c28f92015-10-12 19:36:32 +020067 reset_last_msg();
68}
69
70static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
71{
72 uint32_t new_ptmsi = GSM_RESERVED_TMSI;
73
74 if (parse_ctx->new_ptmsi_enc)
75 gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
76
77 return new_ptmsi;
Jacob Erlbeck515fc332015-10-12 19:36:31 +020078}
79
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010080/* override */
81int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
82 struct bssgp_dl_ud_par *dup)
83{
Jacob Erlbeck28c28f92015-10-12 19:36:32 +020084 int rc;
85
86 reset_last_msg();
87
88 last_msg = msg;
89 OSMO_ASSERT(msgb_data(last_msg) != NULL);
90
91 rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg),
92 &last_dl_parse_ctx);
93
94 fprintf(stderr, "Got DL LLC message: %s\n",
95 gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN"));
96
97 OSMO_ASSERT(rc > 0);
98
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010099 sgsn_tx_counter += 1;
100 return 0;
101}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200102
Maxca7be8a2017-11-01 13:28:38 +0100103/* override, requires '-Wl,--wrap=osmo_get_rand_id' */
104int __real_osmo_get_rand_id(uint8_t *data, size_t len);
105int mock_osmo_get_rand_id(uint8_t *data, size_t len);
106int (*osmo_get_rand_id_cb)(uint8_t *, size_t) =
107 &mock_osmo_get_rand_id;
Max9943d7a2016-07-05 15:19:12 +0200108
Maxca7be8a2017-11-01 13:28:38 +0100109int __wrap_osmo_get_rand_id(uint8_t *buf, size_t num)
Max9943d7a2016-07-05 15:19:12 +0200110{
Maxca7be8a2017-11-01 13:28:38 +0100111 return (*osmo_get_rand_id_cb)(buf, num);
Max9943d7a2016-07-05 15:19:12 +0200112}
113/* make results of A&C ref predictable */
Maxca7be8a2017-11-01 13:28:38 +0100114int mock_osmo_get_rand_id(uint8_t *buf, size_t num)
Max9943d7a2016-07-05 15:19:12 +0200115{
116 if (num > 1)
Maxca7be8a2017-11-01 13:28:38 +0100117 return __real_osmo_get_rand_id(buf, num);
Max9943d7a2016-07-05 15:19:12 +0200118 buf[0] = 0;
119 return 1;
120}
121
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100122/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100123void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
124void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100125 &__real_sgsn_update_subscriber_data;
126
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100127void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100128{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100129 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100130}
131
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100132/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
133int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
134int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
135 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100136
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100137int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
138 return (*subscr_request_update_location_cb)(mmctx);
139};
140
141/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
Pau Espin Pedrol78a62a52017-08-16 11:30:01 +0200142int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand);
143int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand) =
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100144 &__real_gprs_subscr_request_auth_info;
145
Pau Espin Pedrol78a62a52017-08-16 11:30:01 +0200146int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand) {
147 return (*subscr_request_auth_info_cb)(mmctx, auts, auts_rand);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100148};
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100149
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +0100150/* override, requires '-Wl,--wrap=gsup_client_send' */
151int __real_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg);
152int (*gsup_client_send_cb)(struct gsup_client *gsupc, struct msgb *msg) =
153 &__real_gsup_client_send;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +0100154
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +0100155int __wrap_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +0100156{
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +0100157 return (*gsup_client_send_cb)(gsupc, msg);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +0100158};
159
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200160static int count(struct llist_head *head)
161{
162 struct llist_head *cur;
163 int count = 0;
164
165 llist_for_each(cur, head)
166 count += 1;
167
Pau Espin Pedrol964dcb22018-01-07 18:07:17 +0100168 return count;
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200169}
170
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200171static struct msgb *create_msg(const uint8_t *data, size_t len)
172{
173 struct msgb *msg = msgb_alloc(len + 8, "test message");
174 msg->l1h = msgb_put(msg, 8);
175 msg->l2h = msgb_put(msg, len);
176 memcpy(msg->l2h, data, len);
177
178 msgb_bcid(msg) = msg->l1h;
179 msgb_gmmh(msg) = msg->l2h;
180 return msg;
181}
182
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100183/*
184 * Create a context and search for it
185 */
186static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
187{
188 struct sgsn_mm_ctx *ctx, *ictx;
189 struct gprs_llc_lle *lle;
190 int old_count = count(gprs_llme_list());
191
192 lle = gprs_lle_get_or_create(tlli, 3);
Alexander Couzens1c7869e2017-02-04 06:01:00 +0100193 ctx = sgsn_mm_ctx_alloc_gb(tlli, raid);
Alexander Couzens5e33f442017-01-31 15:34:26 +0100194 ctx->gmm_state = GMM_REGISTERED_NORMAL;
Harald Weltec28dc2f2015-12-25 19:12:21 +0100195 ctx->gb.llme = lle->llme;
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100196
197 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
198 OSMO_ASSERT(ictx == ctx);
199
200 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
201
202 return ctx;
203}
204
Jacob Erlbeck75488292014-10-29 10:31:18 +0100205static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100206 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100207 const uint8_t *data, size_t data_len)
208{
209 struct msgb *msg;
210
Jacob Erlbeck28c28f92015-10-12 19:36:32 +0200211 reset_last_msg();
Jacob Erlbeck75488292014-10-29 10:31:18 +0100212 sgsn_tx_counter = 0;
213
214 msg = create_msg(data, data_len);
215 msgb_tlli(msg) = tlli;
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100216 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Max4bc28212016-07-06 11:59:18 +0200217 gsm0408_gprs_rcvmsg_gb(msg, llme, false);
Jacob Erlbeck75488292014-10-29 10:31:18 +0100218 msgb_free(msg);
219}
220
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200221static void test_llme(void)
222{
223 struct gprs_llc_lle *lle, *lle_copy;
224 uint32_t local_tlli;
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200225
226 printf("Testing LLME allocations\n");
227 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200228
229 /* initial state */
230 OSMO_ASSERT(count(gprs_llme_list()) == 0);
231
232 /* Create a new entry */
233 lle = gprs_lle_get_or_create(local_tlli, 3);
234 OSMO_ASSERT(lle);
235 OSMO_ASSERT(count(gprs_llme_list()) == 1);
236
237 /* No new entry is created */
238 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
239 OSMO_ASSERT(lle == lle_copy);
240 OSMO_ASSERT(count(gprs_llme_list()) == 1);
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200241
242 /* unassign which should delete it*/
Maxa86f5c02016-06-28 17:39:20 +0200243 gprs_llgmm_unassign(lle->llme);
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200244
245 /* Check that everything was cleaned up */
246 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200247
248 cleanup_test();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200249}
250
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100251struct gprs_subscr *last_updated_subscr = NULL;
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100252void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100253{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100254 OSMO_ASSERT(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100255 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100256 __func__, mmctx, mmctx->subscr);
257 last_updated_subscr = mmctx->subscr;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100258}
259
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100260static void assert_subscr(const struct gprs_subscr *subscr, const char *imsi)
Jacob Erlbecka695d242015-01-09 11:59:50 +0100261{
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100262 struct gprs_subscr *sfound;
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100263 OSMO_ASSERT(subscr);
264 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100265
266 sfound = gprs_subscr_get_by_imsi(imsi);
267 OSMO_ASSERT(sfound == subscr);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100268
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100269 gprs_subscr_put(sfound);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100270}
271
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100272static void show_subscrs(FILE *out)
273{
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100274 struct gprs_subscr *subscr;
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100275
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100276 llist_for_each_entry(subscr, gprs_subscribers, entry) {
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100277 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100278 "use count: %d\n",
279 subscr->imsi, subscr->use_count);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100280 }
281}
282
283static void assert_no_subscrs()
284{
285 show_subscrs(stdout);
286 fflush(stdout);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100287 OSMO_ASSERT(llist_empty(gprs_subscribers));
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100288}
289
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100290#define VERBOSE_ASSERT(val, expect_op, fmt) \
291 do { \
292 printf(#val " == " fmt "\n", (val)); \
293 OSMO_ASSERT((val) expect_op); \
294 } while (0);
295
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100296static void test_subscriber(void)
297{
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100298 struct gprs_subscr *s1, *s2, *s3;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100299 const char *imsi1 = "1234567890";
300 const char *imsi2 = "9876543210";
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100301 const char *imsi3 = "5656565656";
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100302
303 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
304
305 printf("Testing core subscriber data API\n");
306
307 /* Check for emptiness */
308 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
309 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100310 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100311 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d");
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100312
313 /* Allocate entry 1 */
314 s1 = gprs_subscr_get_or_create(imsi1);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100315 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
316 s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100317 assert_subscr(s1, imsi1);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100318 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100319 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100320
321 /* Allocate entry 2 */
322 s2 = gprs_subscr_get_or_create(imsi2);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100323 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d");
324 s2->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100325
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100326 /* Allocate entry 3 */
327 s3 = gprs_subscr_get_or_create(imsi3);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100328 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 3, "%d");
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100329
Jacob Erlbecka695d242015-01-09 11:59:50 +0100330 /* Check entries */
331 assert_subscr(s1, imsi1);
332 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100333 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100334
335 /* Update entry 1 */
336 last_updated_subscr = NULL;
337 gprs_subscr_update(s1);
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100338 OSMO_ASSERT(last_updated_subscr == NULL);
339 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100340 OSMO_ASSERT((s1->flags & GPRS_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100341
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100342 /* There is no subscriber cache. Verify it */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100343 gprs_subscr_cleanup(s1);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100344 gprs_subscr_put(s1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100345 s1 = NULL;
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100346 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d");
347 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100348
Jacob Erlbecka695d242015-01-09 11:59:50 +0100349 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100350 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100351
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100352 /* Free entry 2 (GPRS_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100353 gprs_subscr_cleanup(s2);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100354 gprs_subscr_put(s2);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100355 s2 = NULL;
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100356 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100357 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
358 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100359 assert_subscr(s3, imsi3);
360
361 /* Try to delete entry 3 */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100362 gprs_subscr_cleanup(s3);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100363 gprs_subscr_put(s3);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100364 s3 = NULL;
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100365 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d");
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100366 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100367
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100368 OSMO_ASSERT(llist_empty(gprs_subscribers));
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100369
370 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200371
372 cleanup_test();
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100373}
374
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100375static void test_auth_triplets(void)
376{
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100377 struct gprs_subscr *s1, *s1found;
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100378 const char *imsi1 = "1234567890";
379 struct gsm_auth_tuple *at;
380 struct sgsn_mm_ctx *ctx;
381 struct gprs_ra_id raid = { 0, };
382 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100383
384 printf("Testing authentication triplet handling\n");
385
386 /* Check for emptiness */
387 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
388
389 /* Allocate entry 1 */
390 s1 = gprs_subscr_get_or_create(imsi1);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100391 s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100392 s1found = gprs_subscr_get_by_imsi(imsi1);
393 OSMO_ASSERT(s1found == s1);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100394 gprs_subscr_put(s1found);
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100395
396 /* Create a context */
397 OSMO_ASSERT(count(gprs_llme_list()) == 0);
398 ctx = alloc_mm_ctx(local_tlli, &raid);
399
400 /* Attach s1 to ctx */
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100401 ctx->subscr = gprs_subscr_get(s1);
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100402 ctx->subscr->sgsn_data->mm = ctx;
403
404 /* Try to get auth tuple */
405 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
406 OSMO_ASSERT(at == NULL);
407
408 /* Add triplets */
409 s1->sgsn_data->auth_triplets[0].key_seq = 0;
410 s1->sgsn_data->auth_triplets[1].key_seq = 1;
411 s1->sgsn_data->auth_triplets[2].key_seq = 2;
412
413 /* Try to get auth tuple */
414 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
415 OSMO_ASSERT(at != NULL);
416 OSMO_ASSERT(at->key_seq == 0);
417 OSMO_ASSERT(at->use_count == 1);
418 at = sgsn_auth_get_tuple(ctx, at->key_seq);
419 OSMO_ASSERT(at != NULL);
420 OSMO_ASSERT(at->key_seq == 1);
421 OSMO_ASSERT(at->use_count == 1);
422 at = sgsn_auth_get_tuple(ctx, at->key_seq);
423 OSMO_ASSERT(at != NULL);
424 OSMO_ASSERT(at->key_seq == 2);
425 OSMO_ASSERT(at->use_count == 1);
426 at = sgsn_auth_get_tuple(ctx, at->key_seq);
427 OSMO_ASSERT(at == NULL);
428
429 /* Free MM context and subscriber */
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100430 gprs_subscr_put(s1);
Jacob Erlbeck70c177a2015-01-26 14:43:07 +0100431 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100432 s1found = gprs_subscr_get_by_imsi(imsi1);
433 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200434
435 cleanup_test();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100436}
437
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100438#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
439
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100440static int rx_gsup_message(const uint8_t *data, size_t data_len)
441{
442 struct msgb *msg;
443 int rc;
444
445 msg = msgb_alloc(1024, __func__);
446 msg->l2h = msgb_put(msg, data_len);
447 OSMO_ASSERT(msg->l2h != NULL);
448 memcpy(msg->l2h, data, data_len);
449 rc = gprs_subscr_rx_gsup_message(msg);
450 msgb_free(msg);
451
452 return rc;
453}
454
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100455static void test_subscriber_gsup(void)
456{
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100457 struct gprs_subscr *s1, *s1found;
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100458 const char *imsi1 = "1234567890";
459 struct sgsn_mm_ctx *ctx;
460 struct gprs_ra_id raid = { 0, };
461 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100462 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100463 int rc;
464
465 static const uint8_t send_auth_info_res[] = {
466 0x0a,
467 TEST_GSUP_IMSI1_IE,
468 0x03, 0x22, /* Auth tuple */
469 0x20, 0x10,
470 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
471 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
472 0x21, 0x04,
473 0x21, 0x22, 0x23, 0x24,
474 0x22, 0x08,
475 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
476 0x03, 0x22, /* Auth tuple */
477 0x20, 0x10,
478 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
479 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
480 0x21, 0x04,
481 0xa1, 0xa2, 0xa3, 0xa4,
482 0x22, 0x08,
483 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
484 };
485
486 static const uint8_t send_auth_info_err[] = {
487 0x09,
488 TEST_GSUP_IMSI1_IE,
489 0x02, 0x01, 0x07 /* GPRS not allowed */
490 };
491
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400492#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
493
494 static const uint8_t s1_msisdn[] = { MSISDN };
495
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100496 static const uint8_t update_location_res[] = {
497 0x06,
498 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400499 0x08, 0x09, MSISDN,
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100500 0x04, 0x00, /* PDP info complete */
501 0x05, 0x12,
502 0x10, 0x01, 0x01,
503 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
504 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
505 0x05, 0x11,
506 0x10, 0x01, 0x02,
507 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
508 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
509 };
510
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400511#undef MSISDN
512
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100513 static const uint8_t update_location_err[] = {
514 0x05,
515 TEST_GSUP_IMSI1_IE,
516 0x02, 0x01, 0x07 /* GPRS not allowed */
517 };
518
519 static const uint8_t location_cancellation_req[] = {
520 0x1c,
521 TEST_GSUP_IMSI1_IE,
522 0x06, 0x01, 0x00,
523 };
524
Jacob Erlbecke7fea452015-04-07 17:49:48 +0200525 static const uint8_t location_cancellation_req_withdraw[] = {
526 0x1c,
527 TEST_GSUP_IMSI1_IE,
528 0x06, 0x01, 0x01,
529 };
530
Jacob Erlbeck00b8b912015-01-08 15:29:01 +0100531 static const uint8_t location_cancellation_req_other[] = {
532 0x1c,
533 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
534 0x06, 0x01, 0x00,
535 };
536
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100537 static const uint8_t purge_ms_err[] = {
538 0x0d,
539 TEST_GSUP_IMSI1_IE,
540 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
541 };
542
Jacob Erlbeck9ca3ace2015-01-29 14:17:51 +0100543 static const uint8_t purge_ms_err_no_cause[] = {
544 0x0d,
545 TEST_GSUP_IMSI1_IE,
546 };
547
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100548 static const uint8_t purge_ms_res[] = {
549 0x0e,
550 TEST_GSUP_IMSI1_IE,
551 0x07, 0x00,
552 };
553
554
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100555 static const uint8_t insert_data_req[] = {
556 0x10,
557 TEST_GSUP_IMSI1_IE,
558 0x05, 0x11,
559 0x10, 0x01, 0x03,
560 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
561 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
562 };
563
564 static const uint8_t delete_data_req[] = {
565 0x14,
566 TEST_GSUP_IMSI1_IE,
567 0x10, 0x01, 0x03,
568 };
569
Neels Hofmeyr2b91ce22016-06-20 18:26:15 +0200570 printf("Testing subscriber GSUP handling\n");
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100571
572 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
573
574 /* Check for emptiness */
575 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
576
577 /* Allocate entry 1 */
578 s1 = gprs_subscr_get_or_create(imsi1);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100579 s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100580 s1found = gprs_subscr_get_by_imsi(imsi1);
581 OSMO_ASSERT(s1found == s1);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100582 gprs_subscr_put(s1found);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100583
584 /* Create a context */
585 OSMO_ASSERT(count(gprs_llme_list()) == 0);
586 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100587
588 /* Attach s1 to ctx */
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100589 ctx->subscr = gprs_subscr_get(s1);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100590 ctx->subscr->sgsn_data->mm = ctx;
591
592 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100593 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100594 OSMO_ASSERT(rc >= 0);
595 OSMO_ASSERT(last_updated_subscr == s1);
596
597 /* Check triplets */
598 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
599 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
600 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
601
602 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100603 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_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 triplets */
609 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
610 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
611 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
612
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100613 /* Inject UpdateLocRes GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100614 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100615 OSMO_ASSERT(rc >= 0);
616 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100617 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100618 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400619 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
620 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100621 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
622 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
623 struct sgsn_subscriber_pdp_data, list);
624 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
625 pdpd = llist_entry(pdpd->list.next,
626 struct sgsn_subscriber_pdp_data, list);
627 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100628
629 /* Check authorization */
630 OSMO_ASSERT(s1->authorized == 1);
631
632 /* Inject UpdateLocErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100633 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100634 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100635 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100636 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100637
638 /* Check authorization */
639 OSMO_ASSERT(s1->authorized == 0);
640
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100641 /* Inject InsertSubscrData GSUP message */
642 last_updated_subscr = NULL;
643 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Harald Weltee7e3f272016-11-26 14:58:36 +0100644 OSMO_ASSERT(rc == -ENOTSUP); /* not connected */
Harald Welted3356e72016-05-06 13:46:21 +0200645 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100646
647 /* Inject DeleteSubscrData GSUP message */
648 last_updated_subscr = NULL;
649 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
Maxe405f152017-02-15 11:43:59 +0100650 if (rc != -GMM_CAUSE_SEM_INCORR_MSG)
651 printf("Unexpected response to DSD: %d\n", rc);
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100652 OSMO_ASSERT(last_updated_subscr == NULL);
653
Jacob Erlbeck00b8b912015-01-08 15:29:01 +0100654 /* Inject wrong LocCancelReq GSUP message */
655 last_updated_subscr = NULL;
656 rc = rx_gsup_message(location_cancellation_req_other,
657 sizeof(location_cancellation_req_other));
658 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
659 OSMO_ASSERT(last_updated_subscr == NULL);
660
661 /* Check cancellation result */
662 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
663 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
664
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100665 /* Inject LocCancelReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100666 rc = rx_gsup_message(location_cancellation_req,
667 sizeof(location_cancellation_req));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100668 OSMO_ASSERT(rc >= 0);
669 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100670 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100671
672 /* Check cancellation result */
673 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
674 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
675
Jacob Erlbecke7fea452015-04-07 17:49:48 +0200676 /* Inject LocCancelReq(withdraw) GSUP message */
677 rc = rx_gsup_message(location_cancellation_req_withdraw,
678 sizeof(location_cancellation_req_withdraw));
679 OSMO_ASSERT(rc >= 0);
680 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
681
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100682 /* Inject PurgeMsRes GSUP message */
683 rc = rx_gsup_message(purge_ms_res,
684 sizeof(purge_ms_res));
685 OSMO_ASSERT(rc >= 0);
686 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
687
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100688 /* Free MM context and subscriber */
Jacob Erlbeck265e7352015-01-30 11:57:25 +0100689 OSMO_ASSERT(ctx->subscr == NULL);
690 sgsn_mm_ctx_cleanup_free(ctx);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +0100691 gprs_subscr_put(s1);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100692 s1found = gprs_subscr_get_by_imsi(imsi1);
693 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100694
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100695 /* Inject PurgeMsRes GSUP message */
696 rc = rx_gsup_message(purge_ms_res,
697 sizeof(purge_ms_res));
698 OSMO_ASSERT(rc >= 0);
699
700 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
701 rc = rx_gsup_message(purge_ms_err,
702 sizeof(purge_ms_err));
703 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
704
Jacob Erlbeck9ca3ace2015-01-29 14:17:51 +0100705 /* Inject PurgeMsErr() GSUP message */
706 rc = rx_gsup_message(purge_ms_err_no_cause,
707 sizeof(purge_ms_err_no_cause));
708 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
709
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100710 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
711 last_updated_subscr = NULL;
712 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck629dacc2015-01-15 17:50:16 +0100713 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100714 OSMO_ASSERT(last_updated_subscr == NULL);
715
716 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
717 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
718 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
719 OSMO_ASSERT(last_updated_subscr == NULL);
720
721 /* Inject LocCancelReq GSUP message (unknown IMSI) */
722 rc = rx_gsup_message(location_cancellation_req,
723 sizeof(location_cancellation_req));
724 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
725 OSMO_ASSERT(last_updated_subscr == NULL);
726
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100727 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200728
729 cleanup_test();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100730}
731
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +0100732int my_gsup_client_send_dummy(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +0100733{
734 msgb_free(msg);
735 return 0;
736};
737
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200738/*
739 * Test that a GMM Detach will remove the MMCTX and the
740 * associated LLME.
741 */
742static void test_gmm_detach(void)
743{
744 struct gprs_ra_id raid = { 0, };
745 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200746 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200747
748 printf("Testing GMM detach\n");
749
750 /* DTAP - Detach Request (MO) */
751 /* normal detach, power_off = 0 */
752 static const unsigned char detach_req[] = {
753 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
754 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
755 };
756
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200757 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200758
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100759 /* Create a context */
760 OSMO_ASSERT(count(gprs_llme_list()) == 0);
761 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200762
763 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +0100764 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100765 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200766
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100767 /* verify that a single message (hopefully the Detach Accept) has been
768 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100769 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100770
771 /* verify that things are gone */
772 OSMO_ASSERT(count(gprs_llme_list()) == 0);
773 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
774 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200775
776 cleanup_test();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100777}
778
779/*
780 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
781 * will not sent a Detach Accept message (power_off = 1)
782 */
783static void test_gmm_detach_power_off(void)
784{
785 struct gprs_ra_id raid = { 0, };
786 struct sgsn_mm_ctx *ctx, *ictx;
787 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100788
789 printf("Testing GMM detach (power off)\n");
790
791 /* DTAP - Detach Request (MO) */
792 /* normal detach, power_off = 1 */
793 static const unsigned char detach_req[] = {
794 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
795 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
796 };
797
798 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
799
800 /* Create a context */
801 OSMO_ASSERT(count(gprs_llme_list()) == 0);
802 ctx = alloc_mm_ctx(local_tlli, &raid);
803
804 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +0100805 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100806 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100807
808 /* verify that no message (and therefore no Detach Accept) has been
809 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100810 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100811
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200812 /* verify that things are gone */
813 OSMO_ASSERT(count(gprs_llme_list()) == 0);
814 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200815 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200816
817 cleanup_test();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200818}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200819
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200820/*
821 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
822 */
823static void test_gmm_detach_no_mmctx(void)
824{
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100825 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200826 struct gprs_llc_lle *lle;
827 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200828
829 printf("Testing GMM detach (no MMCTX)\n");
830
831 /* DTAP - Detach Request (MO) */
832 /* normal detach, power_off = 0 */
833 static const unsigned char detach_req[] = {
834 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
835 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
836 };
837
838 /* Create an LLME */
839 OSMO_ASSERT(count(gprs_llme_list()) == 0);
840 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
841 lle = gprs_lle_get_or_create(local_tlli, 3);
842
843 OSMO_ASSERT(count(gprs_llme_list()) == 1);
844
845 /* inject the detach */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100846 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100847 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200848
849 /* verify that the LLME is gone */
850 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200851
852 cleanup_test();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200853}
854
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100855/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100856 * Test that a single GMM Detach Accept message will not cause the SGSN to send
857 * any message or leave an MM context at the SGSN.
858 */
859static void test_gmm_detach_accept_unexpected(void)
860{
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100861 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100862 struct gprs_llc_lle *lle;
863 uint32_t local_tlli;
864
865 printf("Testing GMM detach accept (unexpected)\n");
866
867 /* DTAP - Detach Accept (MT) */
868 /* normal detach */
869 static const unsigned char detach_acc[] = {
870 0x08, 0x06
871 };
872
873 /* Create an LLME */
874 OSMO_ASSERT(count(gprs_llme_list()) == 0);
875 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
876 lle = gprs_lle_get_or_create(local_tlli, 3);
877
878 /* inject the detach */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100879 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100880 detach_acc, ARRAY_SIZE(detach_acc));
881
882 /* verify that no message (and therefore no Status or XID reset) has been
883 * sent by the SGSN */
884 OSMO_ASSERT(sgsn_tx_counter == 0);
885
886 /* verify that things are gone */
887 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200888
889 cleanup_test();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100890}
891
892/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100893 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
894 */
895static void test_gmm_status_no_mmctx(void)
896{
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100897 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100898 struct gprs_llc_lle *lle;
899 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100900
901 printf("Testing GMM Status (no MMCTX)\n");
902
903 /* DTAP - GMM Status, protocol error */
904 static const unsigned char gmm_status[] = {
905 0x08, 0x20, 0x6f
906 };
907
908 /* Create an LLME */
909 OSMO_ASSERT(count(gprs_llme_list()) == 0);
910 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
911 lle = gprs_lle_get_or_create(local_tlli, 3);
912
913 OSMO_ASSERT(count(gprs_llme_list()) == 1);
914
915 /* inject the detach */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100916 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck75488292014-10-29 10:31:18 +0100917 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100918
919 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100920 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100921
922 /* verify that the LLME is gone */
923 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200924
925 cleanup_test();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100926}
927
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100928/*
929 * Test the GMM Attach procedure
930 */
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100931static void test_gmm_attach(int retry)
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100932{
933 struct gprs_ra_id raid = { 0, };
934 struct sgsn_mm_ctx *ctx = NULL;
935 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100936 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100937 uint32_t foreign_tlli;
938 uint32_t local_tlli = 0;
939 struct gprs_llc_lle *lle;
940
941 /* DTAP - Attach Request */
942 /* The P-TMSI is not known by the SGSN */
943 static const unsigned char attach_req[] = {
944 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
945 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
946 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
947 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
948 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
949 };
950
951 /* DTAP - Identity Response IMEI */
952 static const unsigned char ident_resp_imei[] = {
953 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
954 0x56
955 };
956
957 /* DTAP - Identity Response IMSI */
958 static const unsigned char ident_resp_imsi[] = {
959 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
960 0x54
961 };
962
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100963 /* DTAP - Authentication and Ciphering Resp */
964 static const unsigned char auth_ciph_resp[] = {
965 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
966 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
967 };
968
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100969 /* DTAP - Attach Complete */
970 static const unsigned char attach_compl[] = {
971 0x08, 0x03
972 };
973
974 /* DTAP - Detach Request (MO) */
975 /* normal detach, power_off = 0 */
976 static const unsigned char detach_req[] = {
977 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
978 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
979 };
980
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100981 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100982
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100983 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
984
985 /* Create a LLE/LLME */
986 OSMO_ASSERT(count(gprs_llme_list()) == 0);
987 lle = gprs_lle_get_or_create(foreign_tlli, 3);
988 OSMO_ASSERT(count(gprs_llme_list()) == 1);
989
990 /* inject the attach request */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +0100991 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100992 attach_req, ARRAY_SIZE(attach_req));
993
994 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
995 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +0100996 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100997
998 /* we expect an identity request (IMEI) */
999 OSMO_ASSERT(sgsn_tx_counter == 1);
1000
1001 /* inject the identity response (IMEI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001002 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001003 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1004
1005 /* we expect an identity request (IMSI) */
1006 OSMO_ASSERT(sgsn_tx_counter == 1);
1007
1008 /* inject the identity response (IMSI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001009 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001010 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1011
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001012 /* check that the MM context has not been removed due to a failed
1013 * authorization */
1014 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1015
Alexander Couzens5e33f442017-01-31 15:34:26 +01001016 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001017
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001018retry_attach_req:
1019
1020 if (retry && sgsn_tx_counter == 0) {
1021 fprintf(stderr, "Retrying attach request\n");
1022 /* re-inject the attach request */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001023 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001024 attach_req, ARRAY_SIZE(attach_req));
1025 }
1026
1027 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
1028 /* we got an auth & ciph request */
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001029
1030 /* inject the auth & ciph response */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001031 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001032 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1033
1034 /* check that the MM context has not been removed due to a
1035 * failed authorization */
1036 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freythera9f671c2015-05-05 22:52:40 +02001037 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1038 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001039 }
1040
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001041 if (retry && sgsn_tx_counter == 0)
1042 goto retry_attach_req;
1043
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001044 /* we expect an attach accept/reject */
1045 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001046 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1047 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001048
1049 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +01001050 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001051
1052 /* inject the attach complete */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001053 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001054 attach_compl, ARRAY_SIZE(attach_compl));
1055
Alexander Couzens5e33f442017-01-31 15:34:26 +01001056 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001057
1058 /* we don't expect a response */
1059 OSMO_ASSERT(sgsn_tx_counter == 0);
1060
1061 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001062 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001063 detach_req, ARRAY_SIZE(detach_req));
1064
1065 /* verify that things are gone */
1066 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1067 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1068 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001069
1070 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001071}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001072
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001073static void test_gmm_attach_acl(void)
1074{
1075 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1076
1077 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1078 sgsn_acl_add("123456789012345", &sgsn->cfg);
1079 printf("Auth policy 'closed': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001080 test_gmm_attach(0);
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001081 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001082
1083 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001084
1085 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001086}
1087
Pau Espin Pedrol964dcb22018-01-07 18:07:17 +01001088int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx)
1089{
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001090 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001091 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001092 if (rc == -ENOTSUP) {
1093 OSMO_ASSERT(mmctx->subscr);
1094 gprs_subscr_update(mmctx->subscr);
1095 }
1096 return rc;
Pau Espin Pedrol964dcb22018-01-07 18:07:17 +01001097}
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001098
Pau Espin Pedrold17d6212018-01-07 18:05:22 +01001099int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx, const uint8_t *auts,
1100 const uint8_t *auts_rand)
1101{
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001102 gprs_subscr_update(mmctx->subscr);
1103 return 0;
Pau Espin Pedrol964dcb22018-01-07 18:07:17 +01001104}
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001105
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001106static void test_gmm_attach_subscr(void)
1107{
1108 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01001109 struct gprs_subscr *subscr;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001110
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;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001114
1115 subscr = gprs_subscr_get_or_create("123456789012345");
1116 subscr->authorized = 1;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001117
1118 printf("Auth policy 'remote': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001119 test_gmm_attach(0);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01001120 gprs_subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001121 assert_no_subscrs();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001122
1123 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001124 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1125 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001126
1127 cleanup_test();
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001128}
1129
Pau Espin Pedrold17d6212018-01-07 18:05:22 +01001130int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts,
1131 const uint8_t *auts_rand)
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001132{
1133 /* Fake an authentication */
1134 OSMO_ASSERT(mmctx->subscr);
1135 mmctx->is_authenticated = 1;
1136 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001137
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001138 return 0;
Pau Espin Pedrol964dcb22018-01-07 18:07:17 +01001139}
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001140
1141static void test_gmm_attach_subscr_fake_auth(void)
1142{
1143 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01001144 struct gprs_subscr *subscr;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001145
1146 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001147 subscr_request_update_location_cb = my_subscr_request_update_location;
1148 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001149
1150 subscr = gprs_subscr_get_or_create("123456789012345");
1151 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001152 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001153 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001154
1155 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001156 test_gmm_attach(0);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01001157 gprs_subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001158 assert_no_subscrs();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001159
1160 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001161 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1162 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001163
1164 cleanup_test();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001165}
1166
Pau Espin Pedrol78a62a52017-08-16 11:30:01 +02001167int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts, const uint8_t *auts_rand)
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001168{
1169 struct gsm_auth_tuple at = {
Harald Welte34ef4c52016-04-20 13:13:19 +02001170 .vec.sres = {0x51, 0xe5, 0x51, 0xe5},
Neels Hofmeyr4eec3df2017-02-24 06:24:45 +01001171 .vec.auth_types = OSMO_AUTH_TYPE_GSM,
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001172 .key_seq = 0
1173 };
1174
1175 /* Fake an authentication */
1176 OSMO_ASSERT(mmctx->subscr);
1177 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1178
1179 gprs_subscr_update_auth_info(mmctx->subscr);
1180
1181 return 0;
Pau Espin Pedrol964dcb22018-01-07 18:07:17 +01001182}
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001183
1184static void test_gmm_attach_subscr_real_auth(void)
1185{
1186 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01001187 struct gprs_subscr *subscr;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001188
1189 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1190 subscr_request_update_location_cb = my_subscr_request_update_location;
1191 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1192
1193 subscr = gprs_subscr_get_or_create("123456789012345");
1194 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001195 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001196 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001197
1198 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001199
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001200 test_gmm_attach(0);
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01001201 gprs_subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001202 assert_no_subscrs();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001203
1204 sgsn->cfg.auth_policy = saved_auth_policy;
1205 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1206 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001207
1208 cleanup_test();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001209}
1210
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001211#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1212 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1213
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001214static int auth_info_skip = 0;
1215static int upd_loc_skip = 0;
1216
Pau Espin Pedrold17d6212018-01-07 18:05:22 +01001217int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx, const uint8_t *auts,
1218 const uint8_t *auts_rand)
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001219{
1220 static const uint8_t send_auth_info_res[] = {
1221 0x0a,
1222 TEST_GSUP_IMSI_LONG_IE,
1223 0x03, 0x22, /* Auth tuple */
1224 0x20, 0x10,
1225 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1226 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1227 0x21, 0x04,
1228 0x51, 0xe5, 0x51, 0xe5,
1229 0x22, 0x08,
1230 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1231 };
1232
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001233 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001234
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001235 if (auth_info_skip > 0) {
1236 auth_info_skip -= 1;
1237 return -EAGAIN;
1238 }
1239
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001240 /* Fake an SendAuthInfoRes */
1241 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1242
1243 return 0;
1244};
1245
1246int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1247 static const uint8_t update_location_res[] = {
1248 0x06,
1249 TEST_GSUP_IMSI_LONG_IE,
1250 0x04, 0x00, /* PDP info complete */
1251 0x05, 0x12,
1252 0x10, 0x01, 0x01,
1253 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1254 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freythera9f671c2015-05-05 22:52:40 +02001255 0x08, 0x07, /* MSISDN 49166213323 encoded */
1256 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freytherfe4a9f62015-05-17 20:58:40 +02001257 0x09, 0x07, /* MSISDN 38166213323 encoded */
1258 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001259 };
1260
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001261 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001262
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001263 if (upd_loc_skip > 0) {
1264 upd_loc_skip -= 1;
1265 return -EAGAIN;
1266 }
1267
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001268 /* Fake an UpdateLocRes */
1269 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1270};
1271
1272
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001273static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001274{
1275 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01001276 struct gprs_subscr *subscr;
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001277
1278 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1279 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1280 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001281 if (retry) {
1282 upd_loc_skip = 3;
1283 auth_info_skip = 3;
1284 }
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001285
1286 subscr = gprs_subscr_get_or_create("123456789012345");
1287 subscr->authorized = 1;
1288 sgsn->cfg.require_authentication = 1;
1289 sgsn->cfg.require_update_location = 1;
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01001290 gprs_subscr_put(subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001291
1292 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001293 test_gmm_attach(retry);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001294 assert_no_subscrs();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001295
1296 sgsn->cfg.auth_policy = saved_auth_policy;
1297 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1298 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001299 upd_loc_skip = 0;
1300 auth_info_skip = 0;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001301
1302 cleanup_test();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001303}
1304
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001305int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001306{
Harald Welte4e349d62016-04-25 19:07:34 +02001307 struct osmo_gsup_message to_peer = {0};
1308 struct osmo_gsup_message from_peer = {0};
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001309 struct msgb *reply_msg;
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001310 int rc;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001311
1312 /* Simulate the GSUP peer */
Harald Welte4e349d62016-04-25 19:07:34 +02001313 rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001314 OSMO_ASSERT(rc >= 0);
1315 OSMO_ASSERT(to_peer.imsi[0] != 0);
Neels Hofmeyr64a40bf2017-01-13 03:10:54 +01001316 osmo_strlcpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001317
1318 /* This invalidates the pointers in to_peer */
1319 msgb_free(msg);
1320
1321 switch (to_peer.message_type) {
Harald Welte4e349d62016-04-25 19:07:34 +02001322 case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001323 /* Send UPDATE_LOCATION_RESULT */
1324 return my_subscr_request_update_gsup_auth(NULL);
1325
Harald Welte4e349d62016-04-25 19:07:34 +02001326 case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001327 /* Send SEND_AUTH_INFO_RESULT */
Pau Espin Pedrold17d6212018-01-07 18:05:22 +01001328 return my_subscr_request_auth_info_gsup_auth(NULL, NULL, NULL);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001329
Harald Welte4e349d62016-04-25 19:07:34 +02001330 case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
1331 from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001332 break;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001333
1334 default:
1335 if ((to_peer.message_type & 0b00000011) == 0) {
1336 /* Unhandled request */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001337 /* Send error(NOT_IMPL) */
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001338 from_peer.message_type = to_peer.message_type + 1;
1339 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1340 break;
1341 }
1342
1343 /* Ignore it */
1344 return 0;
1345 }
1346
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001347 reply_msg = gsup_client_msgb_alloc();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001348 reply_msg->l2h = reply_msg->data;
Harald Welte4e349d62016-04-25 19:07:34 +02001349 osmo_gsup_encode(reply_msg, &from_peer);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001350 gprs_subscr_rx_gsup_message(reply_msg);
1351 msgb_free(reply_msg);
1352
1353 return 0;
1354};
1355
1356static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1357{
1358 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01001359 struct gprs_subscr *subscr;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001360
1361 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001362 gsup_client_send_cb = my_gsup_client_send;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001363
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001364 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gsup_client);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001365
1366 if (retry) {
1367 upd_loc_skip = 3;
1368 auth_info_skip = 3;
1369 }
1370
1371 printf("Auth policy 'remote', real GSUP based auth: ");
1372 test_gmm_attach(retry);
1373
1374 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001375 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001376 assert_no_subscrs();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001377
1378 sgsn->cfg.auth_policy = saved_auth_policy;
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01001379 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001380 upd_loc_skip = 0;
1381 auth_info_skip = 0;
1382 talloc_free(sgsn->gsup_client);
1383 sgsn->gsup_client = NULL;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001384
1385 cleanup_test();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001386}
1387
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001388/*
1389 * Test the GMM Rejects
1390 */
1391static void test_gmm_reject(void)
1392{
1393 struct gprs_ra_id raid = { 0, };
1394 struct sgsn_mm_ctx *ctx = NULL;
1395 uint32_t foreign_tlli;
1396 struct gprs_llc_lle *lle;
1397 int idx;
1398
1399 /* DTAP - Attach Request */
1400 /* Invalid MI length */
1401 static const unsigned char attach_req_inv_mi_len[] = {
1402 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1403 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1404 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1405 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1406 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1407 };
1408
1409 /* DTAP - Attach Request */
1410 /* Invalid MI type (IMEI) */
1411 static const unsigned char attach_req_inv_mi_type[] = {
1412 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1413 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1414 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1415 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1416 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1417 };
1418
1419 /* DTAP - Routing Area Update Request */
1420 static const unsigned char dtap_ra_upd_req[] = {
1421 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1422 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1423 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1424 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1425 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1426 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1427 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1428 };
1429
1430 /* DTAP - Routing Area Update Request */
1431 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1432 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1433 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1434 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1435 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1436 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1437 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1438 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1439 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1440 };
1441
1442 /* DTAP - Routing Area Update Request */
1443 /* Invalid cap length */
1444 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1445 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1446 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1447 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1448 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1449 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1450 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1451 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1452 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1453 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1454 };
1455
1456 struct test {
1457 const char *title;
1458 const unsigned char *msg;
1459 unsigned msg_len;
1460 unsigned num_resp;
1461
1462 };
1463 static struct test tests[] = {
1464 {
1465 .title = "Attach Request (invalid MI length)",
1466 .msg = attach_req_inv_mi_len,
1467 .msg_len = sizeof(attach_req_inv_mi_len),
1468 .num_resp = 1 /* Reject */
1469
1470 },
1471 {
1472 .title = "Attach Request (invalid MI type)",
1473 .msg = attach_req_inv_mi_type,
1474 .msg_len = sizeof(attach_req_inv_mi_type),
1475 .num_resp = 1 /* Reject */
1476 },
1477 {
1478 .title = "Routing Area Update Request (valid)",
1479 .msg = dtap_ra_upd_req,
1480 .msg_len = sizeof(dtap_ra_upd_req),
1481 .num_resp = 2 /* XID Reset + Reject */
1482 },
1483 {
1484 .title = "Routing Area Update Request (invalid type)",
1485 .msg = dtap_ra_upd_req_inv_type,
1486 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1487 .num_resp = 1 /* Reject */
1488 },
1489 {
1490 .title = "Routing Area Update Request (invalid CAP length)",
1491 .msg = dtap_ra_upd_req_inv_cap_len,
1492 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1493 .num_resp = 1 /* Reject */
1494 },
1495 };
1496
1497 printf("Testing GMM reject\n");
1498
1499 /* reset the PRNG used by sgsn_alloc_ptmsi */
1500 srand(1);
1501
1502 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1503
1504 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1505
1506 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1507 const struct test *test = &tests[idx];
1508 printf(" - %s\n", test->title);
1509
1510 /* Create a LLE/LLME */
1511 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1512 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1513
1514 /* Inject the Request message */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001515 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001516 test->msg, test->msg_len);
1517
1518 /* We expect a Reject message */
1519 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1520 sgsn_tx_counter, test->num_resp);
1521 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1522
1523 /* verify that LLME/MM are removed */
1524 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1525 OSMO_ASSERT(ctx == NULL);
1526 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1527 }
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001528
1529 cleanup_test();
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001530}
1531
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001532/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001533 * Test cancellation of attached MM contexts
1534 */
1535static void test_gmm_cancel(void)
1536{
1537 struct gprs_ra_id raid = { 0, };
1538 struct sgsn_mm_ctx *ctx = NULL;
1539 struct sgsn_mm_ctx *ictx;
1540 uint32_t ptmsi1;
1541 uint32_t foreign_tlli;
1542 uint32_t local_tlli = 0;
1543 struct gprs_llc_lle *lle;
1544 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1545
1546 /* DTAP - Attach Request */
1547 /* The P-TMSI is not known by the SGSN */
1548 static const unsigned char attach_req[] = {
1549 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1550 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1551 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1552 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1553 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1554 };
1555
1556 /* DTAP - Identity Response IMEI */
1557 static const unsigned char ident_resp_imei[] = {
1558 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1559 0x56
1560 };
1561
1562 /* DTAP - Identity Response IMSI */
1563 static const unsigned char ident_resp_imsi[] = {
1564 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1565 0x54
1566 };
1567
1568 /* DTAP - Attach Complete */
1569 static const unsigned char attach_compl[] = {
1570 0x08, 0x03
1571 };
1572
1573 printf("Testing cancellation\n");
1574
1575 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1576
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001577 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1578
1579 /* Create a LLE/LLME */
1580 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1581 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1582 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1583
1584 /* inject the attach request */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001585 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001586 attach_req, ARRAY_SIZE(attach_req));
1587
1588 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1589 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01001590 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001591
1592 /* we expect an identity request (IMEI) */
1593 OSMO_ASSERT(sgsn_tx_counter == 1);
1594
1595 /* inject the identity response (IMEI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001596 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001597 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1598
1599 /* we expect an identity request (IMSI) */
1600 OSMO_ASSERT(sgsn_tx_counter == 1);
1601
1602 /* inject the identity response (IMSI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001603 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001604 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1605
1606 /* check that the MM context has not been removed due to a failed
1607 * authorization */
1608 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1609
Alexander Couzens5e33f442017-01-31 15:34:26 +01001610 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001611
1612 /* we expect an attach accept/reject */
1613 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001614 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1615 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001616
1617 /* this has been randomly assigned by the SGSN */
1618 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1619
1620 /* inject the attach complete */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001621 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001622 attach_compl, ARRAY_SIZE(attach_compl));
1623
Alexander Couzens5e33f442017-01-31 15:34:26 +01001624 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001625
1626 /* we don't expect a response */
1627 OSMO_ASSERT(sgsn_tx_counter == 0);
1628
1629 /* cancel */
Jacob Erlbeck41010082015-01-05 17:51:17 +01001630 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001631
1632 /* verify that things are gone */
1633 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1634 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1635 OSMO_ASSERT(!ictx);
1636
1637 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001638
1639 cleanup_test();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001640}
1641
1642/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001643 * Test the dynamic allocation of P-TMSIs
1644 */
1645static void test_gmm_ptmsi_allocation(void)
1646{
Neels Hofmeyr3ab28a22018-02-21 18:30:19 +01001647 struct gprs_ra_id raid = { .mnc=332, .mcc=112, .lac=16464, .rac=96};
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001648 struct sgsn_mm_ctx *ctx = NULL;
1649 struct sgsn_mm_ctx *ictx;
1650 uint32_t foreign_tlli;
1651 uint32_t ptmsi1;
1652 uint32_t ptmsi2;
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001653 uint32_t received_ptmsi;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001654 uint32_t old_ptmsi;
1655 uint32_t local_tlli = 0;
1656 struct gprs_llc_lle *lle;
1657 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1658
1659 /* DTAP - Attach Request (IMSI 12131415161718) */
1660 static const unsigned char attach_req[] = {
1661 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1662 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1663 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1664 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1665 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1666 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1667 0x00,
1668 };
1669
1670 /* DTAP - Identity Response IMEI */
1671 static const unsigned char ident_resp_imei[] = {
1672 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1673 0x56
1674 };
1675
1676 /* DTAP - Attach Complete */
1677 static const unsigned char attach_compl[] = {
1678 0x08, 0x03
1679 };
1680
1681 /* DTAP - Routing Area Update Request */
1682 static const unsigned char ra_upd_req[] = {
1683 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1684 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1685 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1686 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1687 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1688 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1689 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1690 };
1691
1692 /* DTAP - Routing Area Update Complete */
1693 static const unsigned char ra_upd_complete[] = {
1694 0x08, 0x0a
1695 };
1696
1697 /* DTAP - Detach Request (MO) */
1698 /* normal detach, power_off = 1 */
1699 static const unsigned char detach_req[] = {
1700 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1701 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1702 };
1703
1704 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1705
1706 printf("Testing P-TMSI allocation\n");
1707
1708 printf(" - sgsn_alloc_ptmsi\n");
1709
1710 /* reset the PRNG used by sgsn_alloc_ptmsi */
1711 srand(1);
1712
1713 ptmsi1 = sgsn_alloc_ptmsi();
1714 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1715
1716 ptmsi2 = sgsn_alloc_ptmsi();
1717 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1718
1719 OSMO_ASSERT(ptmsi1 != ptmsi2);
1720
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001721 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001722
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001723 printf(" - Repeated Attach Request\n");
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001724
1725 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1726
1727 /* Create a LLE/LLME */
1728 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1729 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1730 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1731
1732 /* inject the attach request */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001733 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001734 attach_req, ARRAY_SIZE(attach_req));
1735
1736 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1737 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01001738 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001739 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1740 ptmsi1 = ctx->p_tmsi;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001741
1742 old_ptmsi = ctx->p_tmsi_old;
1743
1744 /* we expect an identity request (IMEI) */
1745 OSMO_ASSERT(sgsn_tx_counter == 1);
1746
1747 /* inject the identity response (IMEI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001748 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001749 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1750
1751 /* check that the MM context has not been removed due to a failed
1752 * authorization */
1753 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1754
Alexander Couzens5e33f442017-01-31 15:34:26 +01001755 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001756 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1757
1758 /* we expect an attach accept */
1759 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001760 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1761 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001762
1763 /* we ignore this and send the attach again */
Jacob Erlbeck2d9dee92016-01-04 18:43:33 +01001764 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001765 attach_req, ARRAY_SIZE(attach_req));
1766
1767 /* the allocated P-TMSI should be the same */
1768 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1769 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01001770 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001771 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1772 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1773
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001774 /* we expect an attach accept */
1775 OSMO_ASSERT(sgsn_tx_counter == 1);
1776 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1777 OSMO_ASSERT(received_ptmsi == ptmsi1);
1778
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001779 /* inject the attach complete */
1780 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01001781 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001782 attach_compl, ARRAY_SIZE(attach_compl));
1783
1784 /* we don't expect a response */
1785 OSMO_ASSERT(sgsn_tx_counter == 0);
1786
Alexander Couzens5e33f442017-01-31 15:34:26 +01001787 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001788 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1789 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1790
1791 printf(" - Repeated RA Update Request\n");
1792
1793 /* inject the RA update request */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001794 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001795 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1796
1797 /* we expect an RA update accept */
1798 OSMO_ASSERT(sgsn_tx_counter == 1);
1799
Alexander Couzens5e33f442017-01-31 15:34:26 +01001800 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001801 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001802 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1803 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1804 ptmsi2 = ctx->p_tmsi;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001805
1806 /* repeat the RA update request */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001807 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001808 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1809
1810 /* we expect an RA update accept */
1811 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001812 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1813 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001814
Alexander Couzens5e33f442017-01-31 15:34:26 +01001815 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001816 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1817 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1818
1819 /* inject the RA update complete */
1820 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01001821 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001822 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1823
1824 /* we don't expect a response */
1825 OSMO_ASSERT(sgsn_tx_counter == 0);
1826
Alexander Couzens5e33f442017-01-31 15:34:26 +01001827 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001828 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1829 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1830
1831 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001832 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001833 detach_req, ARRAY_SIZE(detach_req));
1834
1835 /* verify that things are gone */
1836 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1837 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1838 OSMO_ASSERT(!ictx);
1839
1840 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001841
1842 cleanup_test();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001843}
1844
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001845/*
1846 * Test changing of routing areas
1847 */
1848static void test_gmm_routing_areas(void)
1849{
Neels Hofmeyr3ab28a22018-02-21 18:30:19 +01001850 struct gprs_ra_id raid1 = { .mnc=332, .mcc=112, .lac=16464, .rac=96};
1851 struct gprs_ra_id raid2 = { .mnc=332, .mcc=112, .lac=16464, .rac=97};
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001852 struct sgsn_mm_ctx *ctx = NULL;
1853 struct sgsn_mm_ctx *ictx;
1854 uint32_t ptmsi1;
1855 uint32_t received_ptmsi;
1856 uint32_t ms_tlli = 0;
1857 struct gprs_llc_lle *lle;
1858 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1859
1860 /* DTAP - Attach Request (IMSI 12131415161718) */
1861 static const unsigned char attach_req[] = {
1862 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1863 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1864 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1865 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1866 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1867 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1868 0x00,
1869 };
1870
1871 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1872 static const unsigned char attach_req2[] = {
1873 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1874 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1875 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1876 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1877 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1878 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1879 0x00,
1880 };
1881
1882 /* DTAP - Identity Response IMEI */
1883 static const unsigned char ident_resp_imei[] = {
1884 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1885 0x56
1886 };
1887
1888 /* DTAP - Attach Complete */
1889 static const unsigned char attach_compl[] = {
1890 0x08, 0x03
1891 };
1892
1893 /* DTAP - Routing Area Update Request (coming from RA 1) */
1894 static const unsigned char ra_upd_req1[] = {
1895 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1896 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1897 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1898 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1899 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1900 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1901 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1902 };
1903
1904 /* DTAP - Routing Area Update Request (coming from RA 2) */
1905 static const unsigned char ra_upd_req2[] = {
1906 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1907 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1908 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1909 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1910 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1911 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1912 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1913 };
1914
1915 /* DTAP - Routing Area Update Request (coming from RA other) */
1916 /* raid_other = {443, 223, 16464, 98}; */
1917 static const unsigned char ra_upd_req_other[] = {
1918 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1919 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1920 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1921 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1922 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1923 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1924 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1925 };
1926
1927 /* DTAP - Routing Area Update Complete */
1928 static const unsigned char ra_upd_complete[] = {
1929 0x08, 0x0a
1930 };
1931
1932 /* DTAP - Detach Request (MO) */
1933 /* normal detach, power_off = 1 */
1934 static const unsigned char detach_req[] = {
1935 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1936 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1937 };
1938
1939 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1940
1941 printf("Testing routing area changes\n");
1942
1943 /* reset the PRNG used by sgsn_alloc_ptmsi */
1944 srand(1);
1945
1946 ptmsi1 = GSM_RESERVED_TMSI;
1947
1948 printf(" - Attach Request (RA 1)\n");
1949
1950 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1951
1952 /* Create a LLE/LLME */
1953 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1954 lle = gprs_lle_get_or_create(ms_tlli, 3);
1955 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1956
1957 /* inject the attach request */
1958 send_0408_message(lle->llme, ms_tlli, &raid1,
1959 attach_req, ARRAY_SIZE(attach_req));
1960
1961 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1962 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01001963 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001964 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1965
1966 /* we expect an identity request (IMEI) */
1967 OSMO_ASSERT(sgsn_tx_counter == 1);
1968 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1969 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1970
1971 /* inject the identity response (IMEI) */
Harald Weltec28dc2f2015-12-25 19:12:21 +01001972 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001973 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1974
1975 /* check that the MM context has not been removed due to a failed
1976 * authorization */
1977 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1978
Alexander Couzens5e33f442017-01-31 15:34:26 +01001979 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001980
1981 /* we expect an attach accept */
1982 OSMO_ASSERT(sgsn_tx_counter == 1);
1983 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1984 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1985
1986 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1987 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1988 ptmsi1 = received_ptmsi;
1989
1990 /* inject the attach complete */
1991 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01001992 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001993 attach_compl, ARRAY_SIZE(attach_compl));
1994
1995 /* we don't expect a response */
1996 OSMO_ASSERT(sgsn_tx_counter == 0);
1997
Alexander Couzens5e33f442017-01-31 15:34:26 +01001998 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01001999 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2000 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2001
2002 printf(" - RA Update Request (RA 1 -> RA 1)\n");
2003
2004 /* inject the RA update request */
Harald Weltec28dc2f2015-12-25 19:12:21 +01002005 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002006 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2007
2008 /* we expect an RA update accept */
2009 OSMO_ASSERT(sgsn_tx_counter == 1);
2010 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2011 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
2012
Alexander Couzens5e33f442017-01-31 15:34:26 +01002013 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002014 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2015 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2016 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2017
2018 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2019 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2020 ptmsi1 = received_ptmsi;
2021
2022 /* inject the RA update complete */
2023 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01002024 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002025 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2026
2027 /* we don't expect a response */
2028 OSMO_ASSERT(sgsn_tx_counter == 0);
2029
Alexander Couzens5e33f442017-01-31 15:34:26 +01002030 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002031 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2032 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltec28dc2f2015-12-25 19:12:21 +01002033 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002034
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002035 printf(" - RA Update Request (RA 1 -> RA 2)\n");
2036
2037 /* inject the RA update request */
2038 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2039
2040 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltec28dc2f2015-12-25 19:12:21 +01002041 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002042 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2043
Jacob Erlbeck556aa912016-01-04 18:43:38 +01002044 /* we expect an RA update accept */
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002045 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck556aa912016-01-04 18:43:38 +01002046 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002047
2048 printf(" - RA Update Request (RA other -> RA 2)\n");
2049
2050 /* inject the RA update request */
2051 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2052
2053 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltec28dc2f2015-12-25 19:12:21 +01002054 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002055 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2056
2057 /* we expect an RA update reject (and a LLC XID RESET) */
2058 OSMO_ASSERT(sgsn_tx_counter == 2);
2059 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2060 /* this has killed the LLE/LLME */
2061
2062 printf(" - Attach Request (RA 2)\n");
2063
2064 /* Create a LLE/LLME */
2065 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2066 lle = gprs_lle_get_or_create(ms_tlli, 3);
2067 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2068
2069 /* inject the attach request */
2070 send_0408_message(lle->llme, ms_tlli, &raid2,
2071 attach_req2, ARRAY_SIZE(attach_req2));
2072
2073 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2074 OSMO_ASSERT(ctx != NULL);
Alexander Couzens5e33f442017-01-31 15:34:26 +01002075 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002076 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2077
2078 /* we expect an attach accept */
2079 OSMO_ASSERT(sgsn_tx_counter == 1);
2080 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2081
2082 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2083 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2084 ptmsi1 = received_ptmsi;
2085
2086 /* inject the attach complete */
2087 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2088 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2089 OSMO_ASSERT(ictx != NULL);
2090 OSMO_ASSERT(ictx == ctx);
2091
Harald Weltec28dc2f2015-12-25 19:12:21 +01002092 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002093 attach_compl, ARRAY_SIZE(attach_compl));
2094
2095 /* we don't expect a response */
2096 OSMO_ASSERT(sgsn_tx_counter == 0);
2097
Alexander Couzens5e33f442017-01-31 15:34:26 +01002098 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002099 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2100 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2101
2102 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2103
2104 /* inject the RA update request */
Harald Weltec28dc2f2015-12-25 19:12:21 +01002105 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002106 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2107
2108 /* we expect an RA update accept */
2109 OSMO_ASSERT(sgsn_tx_counter == 1);
2110 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2111
Alexander Couzens5e33f442017-01-31 15:34:26 +01002112 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002113 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2114 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2115 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2116
2117 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2118 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2119 ptmsi1 = received_ptmsi;
2120
2121 /* inject the RA update complete */
2122 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltec28dc2f2015-12-25 19:12:21 +01002123 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002124 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2125
2126 /* we don't expect a response */
2127 OSMO_ASSERT(sgsn_tx_counter == 0);
2128
Alexander Couzens5e33f442017-01-31 15:34:26 +01002129 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002130 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2131 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltec28dc2f2015-12-25 19:12:21 +01002132 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002133
2134
2135 /* inject the detach */
Harald Weltec28dc2f2015-12-25 19:12:21 +01002136 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002137 detach_req, ARRAY_SIZE(detach_req));
2138
2139 /* verify that things are gone */
2140 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2141 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2142 OSMO_ASSERT(!ictx);
2143
2144 sgsn->cfg.auth_policy = saved_auth_policy;
2145
2146 cleanup_test();
2147}
2148
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002149static void test_apn_matching(void)
2150{
2151 struct apn_ctx *actx, *actxs[9];
2152
2153 printf("Testing APN matching\n");
2154
2155 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2156 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2157 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2158 actxs[3] = NULL;
2159
2160 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2161 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2162 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2163 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2164
2165 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2166
2167 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2168 OSMO_ASSERT(actx == actxs[2]);
2169 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2170 OSMO_ASSERT(actx == actxs[2]);
2171 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2172 OSMO_ASSERT(actx == actxs[1]);
2173 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2174 OSMO_ASSERT(actx == actxs[1]);
2175 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2176 OSMO_ASSERT(actx == actxs[0]);
2177 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2178 OSMO_ASSERT(actx == NULL);
2179
2180 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2181 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2182 OSMO_ASSERT(actx == actxs[3]);
2183
2184 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2185 OSMO_ASSERT(actx == actxs[4]);
2186
2187 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2188 OSMO_ASSERT(actx == actxs[6]);
2189
2190 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2191 OSMO_ASSERT(actx == actxs[5]);
2192
2193 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2194 OSMO_ASSERT(actx == actxs[7]);
2195
2196 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2197 OSMO_ASSERT(actx == actxs[8]);
2198
2199 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2200 OSMO_ASSERT(actx == actxs[7]);
2201
2202 /* Free APN contexts and check how the matching changes */
2203
2204 sgsn_apn_ctx_free(actxs[7]);
2205 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2206 OSMO_ASSERT(actx == actxs[8]);
2207
2208 sgsn_apn_ctx_free(actxs[8]);
2209 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2210 OSMO_ASSERT(actx == actxs[6]);
2211
2212 sgsn_apn_ctx_free(actxs[6]);
2213 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2214 OSMO_ASSERT(actx == actxs[1]);
2215
2216 sgsn_apn_ctx_free(actxs[5]);
2217 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2218 OSMO_ASSERT(actx == actxs[4]);
2219
2220 sgsn_apn_ctx_free(actxs[4]);
2221 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2222 OSMO_ASSERT(actx == actxs[2]);
2223
2224 sgsn_apn_ctx_free(actxs[2]);
2225 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2226 OSMO_ASSERT(actx == actxs[1]);
2227
2228 sgsn_apn_ctx_free(actxs[1]);
2229 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2230 OSMO_ASSERT(actx == actxs[0]);
2231
2232 sgsn_apn_ctx_free(actxs[0]);
2233 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2234 OSMO_ASSERT(actx == actxs[3]);
2235
2236 sgsn_apn_ctx_free(actxs[3]);
2237 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2238 OSMO_ASSERT(actx == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02002239
2240 cleanup_test();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002241}
2242
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002243struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2244 struct sgsn_subscriber_data *sdata);
2245
2246static void test_ggsn_selection(void)
2247{
2248 struct apn_ctx *actxs[4];
2249 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01002250 struct gprs_subscr *s1;
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002251 const char *imsi1 = "1234567890";
2252 struct sgsn_mm_ctx *ctx;
2253 struct gprs_ra_id raid = { 0, };
2254 uint32_t local_tlli = 0xffeeddcc;
2255 enum gsm48_gsm_cause gsm_cause;
2256 struct tlv_parsed tp;
2257 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2258 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002259 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002260
2261 printf("Testing GGSN selection\n");
2262
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01002263 gsup_client_send_cb = my_gsup_client_send_dummy;
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002264
2265 /* Check for emptiness */
2266 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2267
2268 /* Create a context */
2269 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2270 ctx = alloc_mm_ctx(local_tlli, &raid);
Neels Hofmeyr5644c2b2017-01-13 03:12:08 +01002271 osmo_strlcpy(ctx->imsi, imsi1, sizeof(ctx->imsi));
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002272
2273 /* Allocate and attach a subscriber */
2274 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2275 assert_subscr(s1, imsi1);
2276
2277 tp.lv[GSM48_IE_GSM_APN].len = 0;
2278 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2279
2280 /* TODO: Add PDP info entries to s1 */
2281
2282 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2283 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2284 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2285
2286 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2287 actxs[0]->ggsn = ggcs[0];
2288 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2289 actxs[1]->ggsn = ggcs[1];
2290 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2291 actxs[2]->ggsn = ggcs[2];
2292
Holger Hans Peter Freytherab9422e2015-05-24 20:51:17 +08002293 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2294 pdp_data->context_id = 1;
2295 pdp_data->pdp_type = 0x0121;
Neels Hofmeyr5644c2b2017-01-13 03:12:08 +01002296 osmo_strlcpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str));
Holger Hans Peter Freytherab9422e2015-05-24 20:51:17 +08002297
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002298 /* Resolve GGSNs */
2299
2300 tp.lv[GSM48_IE_GSM_APN].len =
2301 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2302
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002303 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002304 OSMO_ASSERT(ggc != NULL);
2305 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002306 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002307
2308 tp.lv[GSM48_IE_GSM_APN].len =
2309 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2310
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002311 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002312 OSMO_ASSERT(ggc != NULL);
2313 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002314 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002315
2316 tp.lv[GSM48_IE_GSM_APN].len = 0;
2317 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2318
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002319 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002320 OSMO_ASSERT(ggc != NULL);
2321 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002322 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002323
2324 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2325 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002326 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002327 OSMO_ASSERT(ggc != NULL);
2328 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002329 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002330
2331 sgsn_apn_ctx_free(actxs[3]);
2332 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2333
2334 tp.lv[GSM48_IE_GSM_APN].len =
2335 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2336
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002337 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002338 OSMO_ASSERT(ggc == NULL);
2339 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002340 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002341
2342 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002343 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002344 OSMO_ASSERT(ggc == NULL);
2345 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2346
2347 /* Add PDP data entry to subscriber */
2348
Neels Hofmeyr5644c2b2017-01-13 03:12:08 +01002349 osmo_strlcpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str));
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002350
2351 tp.lv[GSM48_IE_GSM_APN].len =
2352 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2353
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002354 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002355 OSMO_ASSERT(ggc != NULL);
2356 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002357 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002358
2359 tp.lv[GSM48_IE_GSM_APN].len =
2360 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2361
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002362 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002363 OSMO_ASSERT(ggc == NULL);
2364 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002365 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002366
2367 /* Cleanup */
2368
Neels Hofmeyre2c94d62017-01-10 00:49:56 +01002369 gprs_subscr_put(s1);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002370 sgsn_mm_ctx_cleanup_free(ctx);
2371
2372 assert_no_subscrs();
2373
2374 sgsn_apn_ctx_free(actxs[0]);
2375 sgsn_apn_ctx_free(actxs[1]);
2376 sgsn_apn_ctx_free(actxs[2]);
2377
2378 sgsn_ggsn_ctx_free(ggcs[0]);
2379 sgsn_ggsn_ctx_free(ggcs[1]);
2380 sgsn_ggsn_ctx_free(ggcs[2]);
2381
Neels Hofmeyr0e5c1e12016-12-08 21:19:57 +01002382 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02002383
2384 cleanup_test();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002385}
2386
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002387static struct log_info_cat gprs_categories[] = {
2388 [DMM] = {
2389 .name = "DMM",
2390 .description = "Layer3 Mobility Management (MM)",
2391 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002392 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002393 },
2394 [DPAG] = {
2395 .name = "DPAG",
2396 .description = "Paging Subsystem",
2397 .color = "\033[1;38m",
2398 .enabled = 1, .loglevel = LOGL_NOTICE,
2399 },
2400 [DMEAS] = {
2401 .name = "DMEAS",
2402 .description = "Radio Measurement Processing",
2403 .enabled = 0, .loglevel = LOGL_NOTICE,
2404 },
2405 [DREF] = {
2406 .name = "DREF",
2407 .description = "Reference Counting",
2408 .enabled = 0, .loglevel = LOGL_NOTICE,
2409 },
2410 [DGPRS] = {
2411 .name = "DGPRS",
2412 .description = "GPRS Packet Service",
2413 .enabled = 1, .loglevel = LOGL_DEBUG,
2414 },
2415 [DNS] = {
2416 .name = "DNS",
2417 .description = "GPRS Network Service (NS)",
2418 .enabled = 1, .loglevel = LOGL_INFO,
2419 },
2420 [DBSSGP] = {
2421 .name = "DBSSGP",
2422 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2423 .enabled = 1, .loglevel = LOGL_DEBUG,
2424 },
2425 [DLLC] = {
2426 .name = "DLLC",
2427 .description = "GPRS Logical Link Control Protocol (LLC)",
2428 .enabled = 1, .loglevel = LOGL_DEBUG,
2429 },
2430 [DSNDCP] = {
2431 .name = "DSNDCP",
2432 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2433 .enabled = 1, .loglevel = LOGL_DEBUG,
2434 },
2435};
2436
2437static struct log_info info = {
2438 .cat = gprs_categories,
2439 .num_cat = ARRAY_SIZE(gprs_categories),
2440};
2441
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002442int main(int argc, char **argv)
2443{
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002444 void *osmo_sgsn_ctx;
Neels Hofmeyra73e5f12016-09-16 01:49:08 +02002445 void *msgb_ctx;
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002446
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002447 osmo_init_logging(&info);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002448 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2449 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
Neels Hofmeyra73e5f12016-09-16 01:49:08 +02002450 msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0);
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002451
Alexander Couzens32fdba02016-07-05 09:52:52 +02002452 sgsn_rate_ctr_init();
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01002453 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002454 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002455
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002456 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002457 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01002458 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01002459 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02002460 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01002461 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02002462 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01002463 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01002464 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01002465 test_gmm_attach_acl();
2466 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01002467 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01002468 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01002469 test_gmm_attach_subscr_gsup_auth(0);
2470 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01002471 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01002472 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01002473 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01002474 test_gmm_ptmsi_allocation();
Jacob Erlbeckf703f152016-01-04 18:43:37 +01002475 test_gmm_routing_areas();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002476 test_apn_matching();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002477 test_ggsn_selection();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002478 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01002479
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002480 talloc_report_full(osmo_sgsn_ctx, stderr);
Neels Hofmeyra73e5f12016-09-16 01:49:08 +02002481 OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);
Alexander Couzens32fdba02016-07-05 09:52:52 +02002482 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 2);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002483 return 0;
2484}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002485
2486
2487/* stubs */
2488struct osmo_prim_hdr;
2489int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2490{
2491 abort();
2492}