blob: 2f1513a298c9108e325482db88b9b6eba6080253 [file] [log] [blame]
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +010026#include <openbsc/gprs_subscriber.h>
Harald Welte23d77d52016-04-25 19:07:34 +020027#include <osmocom/gsm/gsup.h>
Neels Hofmeyreaaee922016-12-08 21:22:58 +010028#include <openbsc/gsup_client.h>
Jacob Erlbeck277b71e2015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Jacob Erlbeck133e8622015-10-12 19:36:32 +020030#include <openbsc/gprs_gb_parse.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020031
Jacob Erlbeck189999d2014-10-27 14:34:13 +010032#include <osmocom/gprs/gprs_bssgp.h>
33
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020034#include <osmocom/gsm/gsm_utils.h>
35
36#include <osmocom/core/application.h>
37#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010038#include <osmocom/core/rate_ctr.h>
Neels Hofmeyr59504dc2017-01-13 03:10:54 +010039#include <osmocom/core/utils.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020040
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020041#include <stdio.h>
42
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020043void *tall_bsc_ctx;
44static struct sgsn_instance sgsn_inst = {
45 .config_file = "osmo_sgsn.cfg",
46 .cfg = {
47 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010048 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020049 },
50};
51struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010052unsigned sgsn_tx_counter = 0;
Jacob Erlbeck133e8622015-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 Erlbeck189999d2014-10-27 14:34:13 +010064
Jacob Erlbeckcf151872015-10-12 19:36:31 +020065static void cleanup_test()
66{
Jacob Erlbeck133e8622015-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 Erlbeckcf151872015-10-12 19:36:31 +020078}
79
Jacob Erlbeck189999d2014-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 Erlbeck133e8622015-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 Erlbeck189999d2014-10-27 14:34:13 +010099 sgsn_tx_counter += 1;
100 return 0;
101}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200102
Max4011e722016-07-05 15:19:12 +0200103/* override, requires '-Wl,--wrap=RAND_bytes' */
104int __real_RAND_bytes(unsigned char *buf, int num);
105int mock_RAND_bytes(unsigned char *buf, int num);
106int (*RAND_bytes_cb)(unsigned char *, int) =
107 &mock_RAND_bytes;
108
109int __wrap_RAND_bytes(unsigned char *buf, int num)
110{
111 return (*RAND_bytes_cb)(buf, num);
112}
113/* make results of A&C ref predictable */
114int mock_RAND_bytes(unsigned char *buf, int num)
115{
116 if (num > 1)
117 return __real_RAND_bytes(buf, num);
118 buf[0] = 0;
119 return 1;
120}
121
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100122/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-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 Erlbeck33b6dad2014-11-12 10:12:11 +0100125 &__real_sgsn_update_subscriber_data;
126
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100127void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100128{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100129 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100130}
131
Jacob Erlbeck98a95ac2014-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 Erlbeckbe2c8d92014-11-12 10:18:09 +0100136
Jacob Erlbeck98a95ac2014-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' */
142int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
143int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
144 &__real_gprs_subscr_request_auth_info;
145
146int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
147 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100148};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100149
Neels Hofmeyr814fef02016-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 Erlbeckc157ee72015-01-09 15:07:16 +0100154
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100155int __wrap_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100156{
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100157 return (*gsup_client_send_cb)(gsupc, msg);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +0100158};
159
Holger Hans Peter Freyther4299c052014-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
168 return count;
169}
170
Holger Hans Peter Freytherfe921332014-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 Erlbeckabc16a52014-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 Couzens2b5fb8e2017-02-04 06:01:00 +0100193 ctx = sgsn_mm_ctx_alloc_gb(tlli, raid);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +0100194 ctx->gmm_state = GMM_REGISTERED_NORMAL;
Harald Weltef97ee042015-12-25 19:12:21 +0100195 ctx->gb.llme = lle->llme;
Jacob Erlbeckabc16a52014-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 Erlbeck94ef1c02014-10-29 10:31:18 +0100205static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
Jacob Erlbeck91580892016-01-04 18:43:33 +0100206 const struct gprs_ra_id *bssgp_raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100207 const uint8_t *data, size_t data_len)
208{
209 struct msgb *msg;
210
Jacob Erlbeck133e8622015-10-12 19:36:32 +0200211 reset_last_msg();
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100212 sgsn_tx_counter = 0;
213
214 msg = create_msg(data, data_len);
215 msgb_tlli(msg) = tlli;
Jacob Erlbeck91580892016-01-04 18:43:33 +0100216 bssgp_create_cell_id(msgb_bcid(msg), bssgp_raid, 0);
Max82040102016-07-06 11:59:18 +0200217 gsm0408_gprs_rcvmsg_gb(msg, llme, false);
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100218 msgb_free(msg);
219}
220
Holger Hans Peter Freyther4299c052014-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 Freyther4299c052014-10-02 21:27:24 +0200225
226 printf("Testing LLME allocations\n");
227 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
Holger Hans Peter Freyther4299c052014-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 Freyther4299c052014-10-02 21:27:24 +0200241
242 /* unassign which should delete it*/
Max39550252016-06-28 17:39:20 +0200243 gprs_llgmm_unassign(lle->llme);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200244
245 /* Check that everything was cleaned up */
246 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200247
248 cleanup_test();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200249}
250
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100251struct gprs_subscr *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100252void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100253{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100254 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100255 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100256 __func__, mmctx, mmctx->subscr);
257 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100258}
259
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100260static void assert_subscr(const struct gprs_subscr *subscr, const char *imsi)
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100261{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100262 struct gprs_subscr *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100263 OSMO_ASSERT(subscr);
264 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100265
266 sfound = gprs_subscr_get_by_imsi(imsi);
267 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100268
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100269 gprs_subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100270}
271
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100272static void show_subscrs(FILE *out)
273{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100274 struct gprs_subscr *subscr;
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100275
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100276 llist_for_each_entry(subscr, gprs_subscribers, entry) {
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100277 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100278 "use count: %d\n",
279 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100280 }
281}
282
283static void assert_no_subscrs()
284{
285 show_subscrs(stdout);
286 fflush(stdout);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100287 OSMO_ASSERT(llist_empty(gprs_subscribers));
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100288}
289
Neels Hofmeyr0e5d8072017-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 Erlbeck33b6dad2014-11-12 10:12:11 +0100296static void test_subscriber(void)
297{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100298 struct gprs_subscr *s1, *s2, *s3;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100299 const char *imsi1 = "1234567890";
300 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100301 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-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 Erlbeck0f47b8f2015-01-06 16:32:41 +0100310 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100311 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d");
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100312
313 /* Allocate entry 1 */
314 s1 = gprs_subscr_get_or_create(imsi1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100315 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
316 s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100317 assert_subscr(s1, imsi1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100318 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100319 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100320
321 /* Allocate entry 2 */
322 s2 = gprs_subscr_get_or_create(imsi2);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100323 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 2, "%d");
324 s2->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100325
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100326 /* Allocate entry 3 */
327 s3 = gprs_subscr_get_or_create(imsi3);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100328 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 3, "%d");
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100329
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100330 /* Check entries */
331 assert_subscr(s1, imsi1);
332 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100333 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100334
335 /* Update entry 1 */
336 last_updated_subscr = NULL;
337 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100338 OSMO_ASSERT(last_updated_subscr == NULL);
339 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100340 OSMO_ASSERT((s1->flags & GPRS_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100341
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100342 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100343 gprs_subscr_cleanup(s1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100344 gprs_subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100345 s1 = NULL;
Neels Hofmeyr0e5d8072017-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 Freyther1d778fd2015-01-20 21:14:03 +0100348
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100349 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100350 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100351
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100352 /* Free entry 2 (GPRS_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100353 gprs_subscr_cleanup(s2);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100354 gprs_subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100355 s2 = NULL;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100356 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 1, "%d");
Jacob Erlbeck33b6dad2014-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 Erlbeck0f47b8f2015-01-06 16:32:41 +0100359 assert_subscr(s3, imsi3);
360
361 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100362 gprs_subscr_cleanup(s3);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100363 gprs_subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100364 s3 = NULL;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100365 VERBOSE_ASSERT(llist_count(gprs_subscribers), == 0, "%d");
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100366 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100367
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100368 OSMO_ASSERT(llist_empty(gprs_subscribers));
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100369
370 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200371
372 cleanup_test();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100373}
374
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100375static void test_auth_triplets(void)
376{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100377 struct gprs_subscr *s1, *s1found;
Jacob Erlbeck7921ab12014-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 Erlbeck7921ab12014-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 Hofmeyr0e5d8072017-01-10 00:49:56 +0100391 s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100392 s1found = gprs_subscr_get_by_imsi(imsi1);
393 OSMO_ASSERT(s1found == s1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100394 gprs_subscr_put(s1found);
Jacob Erlbeck7921ab12014-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 Hofmeyr0e5d8072017-01-10 00:49:56 +0100401 ctx->subscr = gprs_subscr_get(s1);
Jacob Erlbeck7921ab12014-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 Hofmeyr0e5d8072017-01-10 00:49:56 +0100430 gprs_subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100431 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100432 s1found = gprs_subscr_get_by_imsi(imsi1);
433 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200434
435 cleanup_test();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100436}
437
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100438#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
439
Jacob Erlbecke21e1842014-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 Erlbecka6ddc2d2014-12-12 15:01:37 +0100455static void test_subscriber_gsup(void)
456{
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100457 struct gprs_subscr *s1, *s1found;
Jacob Erlbecka6ddc2d2014-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 Erlbeck0e8add62014-12-17 14:03:35 +0100462 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-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 Freyther9ba273d2015-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 Erlbecka6ddc2d2014-12-12 15:01:37 +0100496 static const uint8_t update_location_res[] = {
497 0x06,
498 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther9ba273d2015-04-23 09:53:53 -0400499 0x08, 0x09, MSISDN,
Jacob Erlbecka6ddc2d2014-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 Freyther9ba273d2015-04-23 09:53:53 -0400511#undef MSISDN
512
Jacob Erlbecka6ddc2d2014-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 Erlbeck5b512052015-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 Erlbeck87c7ffc2015-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 Erlbeck466cedd2015-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 Erlbeck9ff82892015-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 Erlbeck466cedd2015-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 Erlbeck9999fd92015-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 Hofmeyr241bda02016-06-20 18:26:15 +0200570 printf("Testing subscriber GSUP handling\n");
Jacob Erlbecka6ddc2d2014-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 Hofmeyr0e5d8072017-01-10 00:49:56 +0100579 s1->flags |= GPRS_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100580 s1found = gprs_subscr_get_by_imsi(imsi1);
581 OSMO_ASSERT(s1found == s1);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100582 gprs_subscr_put(s1found);
Jacob Erlbecka6ddc2d2014-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 Erlbecka6ddc2d2014-12-12 15:01:37 +0100587
588 /* Attach s1 to ctx */
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100589 ctx->subscr = gprs_subscr_get(s1);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100590 ctx->subscr->sgsn_data->mm = ctx;
591
592 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100593 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-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 Erlbecke21e1842014-12-19 18:19:50 +0100603 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100604 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100605 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100606 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100607
608 /* Check 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 Erlbeck0e8add62014-12-17 14:03:35 +0100613 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100614 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100615 OSMO_ASSERT(rc >= 0);
616 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100617 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100618 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther9ba273d2015-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 Erlbeck0e8add62014-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 Erlbecka6ddc2d2014-12-12 15:01:37 +0100628
629 /* Check authorization */
630 OSMO_ASSERT(s1->authorized == 1);
631
632 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100633 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100634 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100635 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100636 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100637
638 /* Check authorization */
639 OSMO_ASSERT(s1->authorized == 0);
640
Jacob Erlbeck9999fd92015-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 Weltec346f872016-11-26 14:58:36 +0100644 OSMO_ASSERT(rc == -ENOTSUP); /* not connected */
Harald Weltecd5e5262016-05-06 13:46:21 +0200645 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck9999fd92015-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));
Maxa66d8cf2017-02-15 11:43:59 +0100650 if (rc != -GMM_CAUSE_SEM_INCORR_MSG)
651 printf("Unexpected response to DSD: %d\n", rc);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100652 OSMO_ASSERT(last_updated_subscr == NULL);
653
Jacob Erlbeck87c7ffc2015-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 Erlbeck9999fd92015-01-15 17:08:30 +0100665 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100666 rc = rx_gsup_message(location_cancellation_req,
667 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100668 OSMO_ASSERT(rc >= 0);
669 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100670 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-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 Erlbeck5b512052015-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 Erlbeck466cedd2015-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 Erlbecka6ddc2d2014-12-12 15:01:37 +0100688 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100689 OSMO_ASSERT(ctx->subscr == NULL);
690 sgsn_mm_ctx_cleanup_free(ctx);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +0100691 gprs_subscr_put(s1);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100692 s1found = gprs_subscr_get_by_imsi(imsi1);
693 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100694
Jacob Erlbeck466cedd2015-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 Erlbeck9ff82892015-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 Erlbeck9999fd92015-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 Erlbeck4dedb272015-01-15 17:50:16 +0100713 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-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 Erlbecka6ddc2d2014-12-12 15:01:37 +0100727 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200728
729 cleanup_test();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100730}
731
Neels Hofmeyr814fef02016-12-08 21:19:57 +0100732int my_gsup_client_send_dummy(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100733{
734 msgb_free(msg);
735 return 0;
736};
737
Holger Hans Peter Freytherfe921332014-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 Freytherfe921332014-10-02 22:24:47 +0200746 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-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 Freytherfe921332014-10-02 22:24:47 +0200757 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200758
Jacob Erlbeckabc16a52014-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 Freytherfe921332014-10-02 22:24:47 +0200762
763 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +0100764 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100765 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200766
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100767 /* verify that a single message (hopefully the Detach Accept) has been
768 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100769 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-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 Erlbeckcf151872015-10-12 19:36:31 +0200775
776 cleanup_test();
Jacob Erlbeck189999d2014-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 Erlbeck189999d2014-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 Weltef97ee042015-12-25 19:12:21 +0100805 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100806 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100807
808 /* verify that no message (and therefore no Detach Accept) has been
809 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100810 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100811
Holger Hans Peter Freytherfe921332014-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 Erlbeck258ce3d2014-09-30 13:51:45 +0200815 OSMO_ASSERT(!ictx);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200816
817 cleanup_test();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200818}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200819
Jacob Erlbeck5a38f642014-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 Erlbeck91580892016-01-04 18:43:33 +0100825 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200826 struct gprs_llc_lle *lle;
827 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-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 Erlbeck91580892016-01-04 18:43:33 +0100846 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100847 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200848
849 /* verify that the LLME is gone */
850 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200851
852 cleanup_test();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200853}
854
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100855/*
Jacob Erlbeckde4bbc72014-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 Erlbeck91580892016-01-04 18:43:33 +0100861 struct gprs_ra_id raid = { 0, };
Jacob Erlbeckde4bbc72014-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 Erlbeck91580892016-01-04 18:43:33 +0100879 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeckde4bbc72014-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 Erlbeckcf151872015-10-12 19:36:31 +0200888
889 cleanup_test();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100890}
891
892/*
Jacob Erlbeck14ae5822014-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 Erlbeck91580892016-01-04 18:43:33 +0100897 struct gprs_ra_id raid = { 0, };
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100898 struct gprs_llc_lle *lle;
899 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-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 Erlbeck91580892016-01-04 18:43:33 +0100916 send_0408_message(lle->llme, local_tlli, &raid,
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100917 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100918
919 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100920 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100921
922 /* verify that the LLME is gone */
923 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeckcf151872015-10-12 19:36:31 +0200924
925 cleanup_test();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100926}
927
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100928/*
929 * Test the GMM Attach procedure
930 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100931static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-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 Erlbeckaec03a12014-11-24 14:40:28 +0100936 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-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 Erlbeck98a95ac2014-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 Erlbeck27cb4d52014-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 Erlbeck7660ffa2014-12-19 18:30:41 +0100981 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100982
Jacob Erlbeck27cb4d52014-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 Erlbeck91580892016-01-04 18:43:33 +0100991 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-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 Couzens4f8da6d2017-01-31 15:34:26 +0100996 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-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 Weltef97ee042015-12-25 19:12:21 +01001002 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-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 Weltef97ee042015-12-25 19:12:21 +01001009 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001010 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1011
Jacob Erlbeck27cb4d52014-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 Couzens4f8da6d2017-01-31 15:34:26 +01001016 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001017
Jacob Erlbeck7660ffa2014-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 Erlbeck91580892016-01-04 18:43:33 +01001023 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck7660ffa2014-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 Erlbeck98a95ac2014-11-28 14:55:25 +01001029
1030 /* inject the auth & ciph response */
Harald Weltef97ee042015-12-25 19:12:21 +01001031 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98a95ac2014-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 Freyther20de3ae2015-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 Erlbeck98a95ac2014-11-28 14:55:25 +01001039 }
1040
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001041 if (retry && sgsn_tx_counter == 0)
1042 goto retry_attach_req;
1043
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001044 /* we expect an attach accept/reject */
1045 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001046 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1047 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001048
1049 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001050 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001051
1052 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001053 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001054 attach_compl, ARRAY_SIZE(attach_compl));
1055
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001056 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck27cb4d52014-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 Weltef97ee042015-12-25 19:12:21 +01001062 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeck27cb4d52014-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 Erlbeckcf151872015-10-12 19:36:31 +02001069
1070 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001071}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001072
Jacob Erlbeckbe2c8d92014-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 Erlbeck7660ffa2014-12-19 18:30:41 +01001080 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001081 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001082
1083 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001084
1085 cleanup_test();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001086}
1087
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001088int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001089 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001090 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001091 if (rc == -ENOTSUP) {
1092 OSMO_ASSERT(mmctx->subscr);
1093 gprs_subscr_update(mmctx->subscr);
1094 }
1095 return rc;
1096};
1097
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001098int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1099 gprs_subscr_update(mmctx->subscr);
1100 return 0;
1101};
1102
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001103static void test_gmm_attach_subscr(void)
1104{
1105 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001106 struct gprs_subscr *subscr;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001107
1108 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001109 subscr_request_update_location_cb = my_subscr_request_update_location;
1110 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001111
1112 subscr = gprs_subscr_get_or_create("123456789012345");
1113 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001114
1115 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001116 test_gmm_attach(0);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001117 gprs_subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001118 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001119
1120 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001121 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1122 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001123
1124 cleanup_test();
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001125}
1126
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001127int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1128{
1129 /* Fake an authentication */
1130 OSMO_ASSERT(mmctx->subscr);
1131 mmctx->is_authenticated = 1;
1132 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001133
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001134 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001135};
1136
1137static void test_gmm_attach_subscr_fake_auth(void)
1138{
1139 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001140 struct gprs_subscr *subscr;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001141
1142 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001143 subscr_request_update_location_cb = my_subscr_request_update_location;
1144 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001145
1146 subscr = gprs_subscr_get_or_create("123456789012345");
1147 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001148 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001149 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001150
1151 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001152 test_gmm_attach(0);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001153 gprs_subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001154 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001155
1156 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001157 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1158 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001159
1160 cleanup_test();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001161}
1162
1163int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1164{
1165 struct gsm_auth_tuple at = {
Harald Welte121e9a42016-04-20 13:13:19 +02001166 .vec.sres = {0x51, 0xe5, 0x51, 0xe5},
Neels Hofmeyr058cd572017-02-24 06:24:45 +01001167 .vec.auth_types = OSMO_AUTH_TYPE_GSM,
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001168 .key_seq = 0
1169 };
1170
1171 /* Fake an authentication */
1172 OSMO_ASSERT(mmctx->subscr);
1173 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1174
1175 gprs_subscr_update_auth_info(mmctx->subscr);
1176
1177 return 0;
1178};
1179
1180static void test_gmm_attach_subscr_real_auth(void)
1181{
1182 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001183 struct gprs_subscr *subscr;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001184
1185 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1186 subscr_request_update_location_cb = my_subscr_request_update_location;
1187 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1188
1189 subscr = gprs_subscr_get_or_create("123456789012345");
1190 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001191 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001192 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001193
1194 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001195
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001196 test_gmm_attach(0);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001197 gprs_subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001198 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001199
1200 sgsn->cfg.auth_policy = saved_auth_policy;
1201 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1202 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001203
1204 cleanup_test();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001205}
1206
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001207#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1208 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1209
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001210static int auth_info_skip = 0;
1211static int upd_loc_skip = 0;
1212
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001213int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1214{
1215 static const uint8_t send_auth_info_res[] = {
1216 0x0a,
1217 TEST_GSUP_IMSI_LONG_IE,
1218 0x03, 0x22, /* Auth tuple */
1219 0x20, 0x10,
1220 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1221 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1222 0x21, 0x04,
1223 0x51, 0xe5, 0x51, 0xe5,
1224 0x22, 0x08,
1225 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1226 };
1227
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001228 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001229
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001230 if (auth_info_skip > 0) {
1231 auth_info_skip -= 1;
1232 return -EAGAIN;
1233 }
1234
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001235 /* Fake an SendAuthInfoRes */
1236 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1237
1238 return 0;
1239};
1240
1241int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1242 static const uint8_t update_location_res[] = {
1243 0x06,
1244 TEST_GSUP_IMSI_LONG_IE,
1245 0x04, 0x00, /* PDP info complete */
1246 0x05, 0x12,
1247 0x10, 0x01, 0x01,
1248 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1249 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001250 0x08, 0x07, /* MSISDN 49166213323 encoded */
1251 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freyther10c0f562015-05-17 20:58:40 +02001252 0x09, 0x07, /* MSISDN 38166213323 encoded */
1253 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001254 };
1255
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001256 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001257
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001258 if (upd_loc_skip > 0) {
1259 upd_loc_skip -= 1;
1260 return -EAGAIN;
1261 }
1262
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001263 /* Fake an UpdateLocRes */
1264 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1265};
1266
1267
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001268static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001269{
1270 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001271 struct gprs_subscr *subscr;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001272
1273 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1274 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1275 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001276 if (retry) {
1277 upd_loc_skip = 3;
1278 auth_info_skip = 3;
1279 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001280
1281 subscr = gprs_subscr_get_or_create("123456789012345");
1282 subscr->authorized = 1;
1283 sgsn->cfg.require_authentication = 1;
1284 sgsn->cfg.require_update_location = 1;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001285 gprs_subscr_put(subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001286
1287 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001288 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001289 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001290
1291 sgsn->cfg.auth_policy = saved_auth_policy;
1292 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1293 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001294 upd_loc_skip = 0;
1295 auth_info_skip = 0;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001296
1297 cleanup_test();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001298}
1299
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001300int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001301{
Harald Welte23d77d52016-04-25 19:07:34 +02001302 struct osmo_gsup_message to_peer = {0};
1303 struct osmo_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001304 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001305 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001306
1307 /* Simulate the GSUP peer */
Harald Welte23d77d52016-04-25 19:07:34 +02001308 rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001309 OSMO_ASSERT(rc >= 0);
1310 OSMO_ASSERT(to_peer.imsi[0] != 0);
Neels Hofmeyr59504dc2017-01-13 03:10:54 +01001311 osmo_strlcpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001312
1313 /* This invalidates the pointers in to_peer */
1314 msgb_free(msg);
1315
1316 switch (to_peer.message_type) {
Harald Welte23d77d52016-04-25 19:07:34 +02001317 case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001318 /* Send UPDATE_LOCATION_RESULT */
1319 return my_subscr_request_update_gsup_auth(NULL);
1320
Harald Welte23d77d52016-04-25 19:07:34 +02001321 case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001322 /* Send SEND_AUTH_INFO_RESULT */
1323 return my_subscr_request_auth_info_gsup_auth(NULL);
1324
Harald Welte23d77d52016-04-25 19:07:34 +02001325 case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
1326 from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001327 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001328
1329 default:
1330 if ((to_peer.message_type & 0b00000011) == 0) {
1331 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001332 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001333 from_peer.message_type = to_peer.message_type + 1;
1334 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1335 break;
1336 }
1337
1338 /* Ignore it */
1339 return 0;
1340 }
1341
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001342 reply_msg = gsup_client_msgb_alloc();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001343 reply_msg->l2h = reply_msg->data;
Harald Welte23d77d52016-04-25 19:07:34 +02001344 osmo_gsup_encode(reply_msg, &from_peer);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001345 gprs_subscr_rx_gsup_message(reply_msg);
1346 msgb_free(reply_msg);
1347
1348 return 0;
1349};
1350
1351static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1352{
1353 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001354 struct gprs_subscr *subscr;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001355
1356 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001357 gsup_client_send_cb = my_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001358
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001359 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gsup_client);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001360
1361 if (retry) {
1362 upd_loc_skip = 3;
1363 auth_info_skip = 3;
1364 }
1365
1366 printf("Auth policy 'remote', real GSUP based auth: ");
1367 test_gmm_attach(retry);
1368
1369 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001370 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001371 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001372
1373 sgsn->cfg.auth_policy = saved_auth_policy;
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001374 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001375 upd_loc_skip = 0;
1376 auth_info_skip = 0;
1377 talloc_free(sgsn->gsup_client);
1378 sgsn->gsup_client = NULL;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001379
1380 cleanup_test();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001381}
1382
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001383/*
1384 * Test the GMM Rejects
1385 */
1386static void test_gmm_reject(void)
1387{
1388 struct gprs_ra_id raid = { 0, };
1389 struct sgsn_mm_ctx *ctx = NULL;
1390 uint32_t foreign_tlli;
1391 struct gprs_llc_lle *lle;
1392 int idx;
1393
1394 /* DTAP - Attach Request */
1395 /* Invalid MI length */
1396 static const unsigned char attach_req_inv_mi_len[] = {
1397 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1398 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1399 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1400 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1401 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1402 };
1403
1404 /* DTAP - Attach Request */
1405 /* Invalid MI type (IMEI) */
1406 static const unsigned char attach_req_inv_mi_type[] = {
1407 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1408 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1409 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1410 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1411 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1412 };
1413
1414 /* DTAP - Routing Area Update Request */
1415 static const unsigned char dtap_ra_upd_req[] = {
1416 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1417 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1418 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1419 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1420 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1421 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1422 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1423 };
1424
1425 /* DTAP - Routing Area Update Request */
1426 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1427 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1428 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1429 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1430 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1431 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1432 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1433 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1434 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1435 };
1436
1437 /* DTAP - Routing Area Update Request */
1438 /* Invalid cap length */
1439 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1440 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1441 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1442 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1443 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1444 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1445 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1446 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1447 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1448 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1449 };
1450
1451 struct test {
1452 const char *title;
1453 const unsigned char *msg;
1454 unsigned msg_len;
1455 unsigned num_resp;
1456
1457 };
1458 static struct test tests[] = {
1459 {
1460 .title = "Attach Request (invalid MI length)",
1461 .msg = attach_req_inv_mi_len,
1462 .msg_len = sizeof(attach_req_inv_mi_len),
1463 .num_resp = 1 /* Reject */
1464
1465 },
1466 {
1467 .title = "Attach Request (invalid MI type)",
1468 .msg = attach_req_inv_mi_type,
1469 .msg_len = sizeof(attach_req_inv_mi_type),
1470 .num_resp = 1 /* Reject */
1471 },
1472 {
1473 .title = "Routing Area Update Request (valid)",
1474 .msg = dtap_ra_upd_req,
1475 .msg_len = sizeof(dtap_ra_upd_req),
1476 .num_resp = 2 /* XID Reset + Reject */
1477 },
1478 {
1479 .title = "Routing Area Update Request (invalid type)",
1480 .msg = dtap_ra_upd_req_inv_type,
1481 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1482 .num_resp = 1 /* Reject */
1483 },
1484 {
1485 .title = "Routing Area Update Request (invalid CAP length)",
1486 .msg = dtap_ra_upd_req_inv_cap_len,
1487 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1488 .num_resp = 1 /* Reject */
1489 },
1490 };
1491
1492 printf("Testing GMM reject\n");
1493
1494 /* reset the PRNG used by sgsn_alloc_ptmsi */
1495 srand(1);
1496
1497 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1498
1499 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1500
1501 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1502 const struct test *test = &tests[idx];
1503 printf(" - %s\n", test->title);
1504
1505 /* Create a LLE/LLME */
1506 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1507 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1508
1509 /* Inject the Request message */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001510 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001511 test->msg, test->msg_len);
1512
1513 /* We expect a Reject message */
1514 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1515 sgsn_tx_counter, test->num_resp);
1516 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1517
1518 /* verify that LLME/MM are removed */
1519 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1520 OSMO_ASSERT(ctx == NULL);
1521 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1522 }
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001523
1524 cleanup_test();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001525}
1526
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001527/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001528 * Test cancellation of attached MM contexts
1529 */
1530static void test_gmm_cancel(void)
1531{
1532 struct gprs_ra_id raid = { 0, };
1533 struct sgsn_mm_ctx *ctx = NULL;
1534 struct sgsn_mm_ctx *ictx;
1535 uint32_t ptmsi1;
1536 uint32_t foreign_tlli;
1537 uint32_t local_tlli = 0;
1538 struct gprs_llc_lle *lle;
1539 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1540
1541 /* DTAP - Attach Request */
1542 /* The P-TMSI is not known by the SGSN */
1543 static const unsigned char attach_req[] = {
1544 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1545 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1546 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1547 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1548 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1549 };
1550
1551 /* DTAP - Identity Response IMEI */
1552 static const unsigned char ident_resp_imei[] = {
1553 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1554 0x56
1555 };
1556
1557 /* DTAP - Identity Response IMSI */
1558 static const unsigned char ident_resp_imsi[] = {
1559 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1560 0x54
1561 };
1562
1563 /* DTAP - Attach Complete */
1564 static const unsigned char attach_compl[] = {
1565 0x08, 0x03
1566 };
1567
1568 printf("Testing cancellation\n");
1569
1570 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1571
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001572 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1573
1574 /* Create a LLE/LLME */
1575 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1576 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1577 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1578
1579 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001580 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001581 attach_req, ARRAY_SIZE(attach_req));
1582
1583 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1584 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001585 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001586
1587 /* we expect an identity request (IMEI) */
1588 OSMO_ASSERT(sgsn_tx_counter == 1);
1589
1590 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001591 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001592 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1593
1594 /* we expect an identity request (IMSI) */
1595 OSMO_ASSERT(sgsn_tx_counter == 1);
1596
1597 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001598 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001599 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1600
1601 /* check that the MM context has not been removed due to a failed
1602 * authorization */
1603 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1604
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001605 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001606
1607 /* we expect an attach accept/reject */
1608 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001609 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1610 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001611
1612 /* this has been randomly assigned by the SGSN */
1613 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1614
1615 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001616 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001617 attach_compl, ARRAY_SIZE(attach_compl));
1618
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001619 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001620
1621 /* we don't expect a response */
1622 OSMO_ASSERT(sgsn_tx_counter == 0);
1623
1624 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001625 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001626
1627 /* verify that things are gone */
1628 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1629 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1630 OSMO_ASSERT(!ictx);
1631
1632 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001633
1634 cleanup_test();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001635}
1636
1637/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001638 * Test the dynamic allocation of P-TMSIs
1639 */
1640static void test_gmm_ptmsi_allocation(void)
1641{
Jacob Erlbeckd58c0332016-01-04 18:43:35 +01001642 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001643 struct sgsn_mm_ctx *ctx = NULL;
1644 struct sgsn_mm_ctx *ictx;
1645 uint32_t foreign_tlli;
1646 uint32_t ptmsi1;
1647 uint32_t ptmsi2;
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001648 uint32_t received_ptmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001649 uint32_t old_ptmsi;
1650 uint32_t local_tlli = 0;
1651 struct gprs_llc_lle *lle;
1652 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1653
1654 /* DTAP - Attach Request (IMSI 12131415161718) */
1655 static const unsigned char attach_req[] = {
1656 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1657 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1658 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1659 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1660 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1661 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1662 0x00,
1663 };
1664
1665 /* DTAP - Identity Response IMEI */
1666 static const unsigned char ident_resp_imei[] = {
1667 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1668 0x56
1669 };
1670
1671 /* DTAP - Attach Complete */
1672 static const unsigned char attach_compl[] = {
1673 0x08, 0x03
1674 };
1675
1676 /* DTAP - Routing Area Update Request */
1677 static const unsigned char ra_upd_req[] = {
1678 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1679 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1680 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1681 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1682 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1683 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1684 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1685 };
1686
1687 /* DTAP - Routing Area Update Complete */
1688 static const unsigned char ra_upd_complete[] = {
1689 0x08, 0x0a
1690 };
1691
1692 /* DTAP - Detach Request (MO) */
1693 /* normal detach, power_off = 1 */
1694 static const unsigned char detach_req[] = {
1695 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1696 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1697 };
1698
1699 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1700
1701 printf("Testing P-TMSI allocation\n");
1702
1703 printf(" - sgsn_alloc_ptmsi\n");
1704
1705 /* reset the PRNG used by sgsn_alloc_ptmsi */
1706 srand(1);
1707
1708 ptmsi1 = sgsn_alloc_ptmsi();
1709 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1710
1711 ptmsi2 = sgsn_alloc_ptmsi();
1712 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1713
1714 OSMO_ASSERT(ptmsi1 != ptmsi2);
1715
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001716 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001717
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001718 printf(" - Repeated Attach Request\n");
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001719
1720 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1721
1722 /* Create a LLE/LLME */
1723 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1724 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1725 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1726
1727 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001728 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001729 attach_req, ARRAY_SIZE(attach_req));
1730
1731 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1732 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001733 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001734 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1735 ptmsi1 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001736
1737 old_ptmsi = ctx->p_tmsi_old;
1738
1739 /* we expect an identity request (IMEI) */
1740 OSMO_ASSERT(sgsn_tx_counter == 1);
1741
1742 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001743 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001744 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1745
1746 /* check that the MM context has not been removed due to a failed
1747 * authorization */
1748 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1749
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001750 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001751 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1752
1753 /* we expect an attach accept */
1754 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001755 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1756 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001757
1758 /* we ignore this and send the attach again */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001759 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001760 attach_req, ARRAY_SIZE(attach_req));
1761
1762 /* the allocated P-TMSI should be the same */
1763 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1764 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001765 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001766 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1767 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1768
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001769 /* we expect an attach accept */
1770 OSMO_ASSERT(sgsn_tx_counter == 1);
1771 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1772 OSMO_ASSERT(received_ptmsi == ptmsi1);
1773
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001774 /* inject the attach complete */
1775 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001776 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001777 attach_compl, ARRAY_SIZE(attach_compl));
1778
1779 /* we don't expect a response */
1780 OSMO_ASSERT(sgsn_tx_counter == 0);
1781
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001782 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001783 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1784 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1785
1786 printf(" - Repeated RA Update Request\n");
1787
1788 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001789 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001790 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1791
1792 /* we expect an RA update accept */
1793 OSMO_ASSERT(sgsn_tx_counter == 1);
1794
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001795 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001796 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001797 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1798 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1799 ptmsi2 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001800
1801 /* repeat the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001802 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001803 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1804
1805 /* we expect an RA update accept */
1806 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001807 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1808 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001809
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001810 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001811 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1812 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1813
1814 /* inject the RA update complete */
1815 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001816 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001817 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1818
1819 /* we don't expect a response */
1820 OSMO_ASSERT(sgsn_tx_counter == 0);
1821
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001822 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001823 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1824 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1825
1826 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001827 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001828 detach_req, ARRAY_SIZE(detach_req));
1829
1830 /* verify that things are gone */
1831 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1832 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1833 OSMO_ASSERT(!ictx);
1834
1835 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001836
1837 cleanup_test();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001838}
1839
Jacob Erlbeck13304782016-01-04 18:43:37 +01001840/*
1841 * Test changing of routing areas
1842 */
1843static void test_gmm_routing_areas(void)
1844{
1845 struct gprs_ra_id raid1 = {332, 112, 16464, 96};
1846 struct gprs_ra_id raid2 = {332, 112, 16464, 97};
1847 struct sgsn_mm_ctx *ctx = NULL;
1848 struct sgsn_mm_ctx *ictx;
1849 uint32_t ptmsi1;
1850 uint32_t received_ptmsi;
1851 uint32_t ms_tlli = 0;
1852 struct gprs_llc_lle *lle;
1853 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1854
1855 /* DTAP - Attach Request (IMSI 12131415161718) */
1856 static const unsigned char attach_req[] = {
1857 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1858 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1859 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1860 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1861 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1862 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1863 0x00,
1864 };
1865
1866 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1867 static const unsigned char attach_req2[] = {
1868 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1869 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1870 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1871 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1872 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1873 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1874 0x00,
1875 };
1876
1877 /* DTAP - Identity Response IMEI */
1878 static const unsigned char ident_resp_imei[] = {
1879 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1880 0x56
1881 };
1882
1883 /* DTAP - Attach Complete */
1884 static const unsigned char attach_compl[] = {
1885 0x08, 0x03
1886 };
1887
1888 /* DTAP - Routing Area Update Request (coming from RA 1) */
1889 static const unsigned char ra_upd_req1[] = {
1890 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1891 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1892 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1893 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1894 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1895 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1896 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1897 };
1898
1899 /* DTAP - Routing Area Update Request (coming from RA 2) */
1900 static const unsigned char ra_upd_req2[] = {
1901 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1902 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1903 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1904 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1905 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1906 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1907 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1908 };
1909
1910 /* DTAP - Routing Area Update Request (coming from RA other) */
1911 /* raid_other = {443, 223, 16464, 98}; */
1912 static const unsigned char ra_upd_req_other[] = {
1913 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1914 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1915 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1916 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1917 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1918 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1919 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1920 };
1921
1922 /* DTAP - Routing Area Update Complete */
1923 static const unsigned char ra_upd_complete[] = {
1924 0x08, 0x0a
1925 };
1926
1927 /* DTAP - Detach Request (MO) */
1928 /* normal detach, power_off = 1 */
1929 static const unsigned char detach_req[] = {
1930 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1931 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1932 };
1933
1934 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1935
1936 printf("Testing routing area changes\n");
1937
1938 /* reset the PRNG used by sgsn_alloc_ptmsi */
1939 srand(1);
1940
1941 ptmsi1 = GSM_RESERVED_TMSI;
1942
1943 printf(" - Attach Request (RA 1)\n");
1944
1945 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1946
1947 /* Create a LLE/LLME */
1948 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1949 lle = gprs_lle_get_or_create(ms_tlli, 3);
1950 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1951
1952 /* inject the attach request */
1953 send_0408_message(lle->llme, ms_tlli, &raid1,
1954 attach_req, ARRAY_SIZE(attach_req));
1955
1956 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1957 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001958 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01001959 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1960
1961 /* we expect an identity request (IMEI) */
1962 OSMO_ASSERT(sgsn_tx_counter == 1);
1963 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1964 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1965
1966 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001967 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001968 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1969
1970 /* check that the MM context has not been removed due to a failed
1971 * authorization */
1972 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1973
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001974 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01001975
1976 /* we expect an attach accept */
1977 OSMO_ASSERT(sgsn_tx_counter == 1);
1978 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1979 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1980
1981 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1982 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1983 ptmsi1 = received_ptmsi;
1984
1985 /* inject the attach complete */
1986 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001987 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001988 attach_compl, ARRAY_SIZE(attach_compl));
1989
1990 /* we don't expect a response */
1991 OSMO_ASSERT(sgsn_tx_counter == 0);
1992
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001993 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01001994 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1995 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1996
1997 printf(" - RA Update Request (RA 1 -> RA 1)\n");
1998
1999 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01002000 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002001 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2002
2003 /* we expect an RA update accept */
2004 OSMO_ASSERT(sgsn_tx_counter == 1);
2005 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2006 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
2007
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002008 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002009 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2010 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2011 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2012
2013 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2014 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2015 ptmsi1 = received_ptmsi;
2016
2017 /* inject the RA update complete */
2018 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002019 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002020 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2021
2022 /* we don't expect a response */
2023 OSMO_ASSERT(sgsn_tx_counter == 0);
2024
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002025 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002026 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2027 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002028 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002029
Jacob Erlbeck13304782016-01-04 18:43:37 +01002030 printf(" - RA Update Request (RA 1 -> RA 2)\n");
2031
2032 /* inject the RA update request */
2033 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2034
2035 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002036 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002037 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2038
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002039 /* we expect an RA update accept */
Jacob Erlbeck13304782016-01-04 18:43:37 +01002040 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002041 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002042
2043 printf(" - RA Update Request (RA other -> RA 2)\n");
2044
2045 /* inject the RA update request */
2046 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2047
2048 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002049 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002050 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2051
2052 /* we expect an RA update reject (and a LLC XID RESET) */
2053 OSMO_ASSERT(sgsn_tx_counter == 2);
2054 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2055 /* this has killed the LLE/LLME */
2056
2057 printf(" - Attach Request (RA 2)\n");
2058
2059 /* Create a LLE/LLME */
2060 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2061 lle = gprs_lle_get_or_create(ms_tlli, 3);
2062 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2063
2064 /* inject the attach request */
2065 send_0408_message(lle->llme, ms_tlli, &raid2,
2066 attach_req2, ARRAY_SIZE(attach_req2));
2067
2068 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2069 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002070 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002071 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2072
2073 /* we expect an attach accept */
2074 OSMO_ASSERT(sgsn_tx_counter == 1);
2075 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2076
2077 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2078 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2079 ptmsi1 = received_ptmsi;
2080
2081 /* inject the attach complete */
2082 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2083 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2084 OSMO_ASSERT(ictx != NULL);
2085 OSMO_ASSERT(ictx == ctx);
2086
Harald Weltef97ee042015-12-25 19:12:21 +01002087 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002088 attach_compl, ARRAY_SIZE(attach_compl));
2089
2090 /* we don't expect a response */
2091 OSMO_ASSERT(sgsn_tx_counter == 0);
2092
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002093 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002094 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2095 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2096
2097 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2098
2099 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01002100 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002101 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2102
2103 /* we expect an RA update accept */
2104 OSMO_ASSERT(sgsn_tx_counter == 1);
2105 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2106
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002107 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002108 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2109 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2110 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2111
2112 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2113 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2114 ptmsi1 = received_ptmsi;
2115
2116 /* inject the RA update complete */
2117 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002118 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002119 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2120
2121 /* we don't expect a response */
2122 OSMO_ASSERT(sgsn_tx_counter == 0);
2123
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002124 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002125 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2126 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002127 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002128
2129
2130 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01002131 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002132 detach_req, ARRAY_SIZE(detach_req));
2133
2134 /* verify that things are gone */
2135 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2136 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2137 OSMO_ASSERT(!ictx);
2138
2139 sgsn->cfg.auth_policy = saved_auth_policy;
2140
2141 cleanup_test();
2142}
2143
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002144static void test_apn_matching(void)
2145{
2146 struct apn_ctx *actx, *actxs[9];
2147
2148 printf("Testing APN matching\n");
2149
2150 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2151 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2152 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2153 actxs[3] = NULL;
2154
2155 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2156 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2157 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2158 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2159
2160 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2161
2162 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2163 OSMO_ASSERT(actx == actxs[2]);
2164 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2165 OSMO_ASSERT(actx == actxs[2]);
2166 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2167 OSMO_ASSERT(actx == actxs[1]);
2168 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2169 OSMO_ASSERT(actx == actxs[1]);
2170 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2171 OSMO_ASSERT(actx == actxs[0]);
2172 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2173 OSMO_ASSERT(actx == NULL);
2174
2175 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2176 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2177 OSMO_ASSERT(actx == actxs[3]);
2178
2179 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2180 OSMO_ASSERT(actx == actxs[4]);
2181
2182 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2183 OSMO_ASSERT(actx == actxs[6]);
2184
2185 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2186 OSMO_ASSERT(actx == actxs[5]);
2187
2188 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2189 OSMO_ASSERT(actx == actxs[7]);
2190
2191 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2192 OSMO_ASSERT(actx == actxs[8]);
2193
2194 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2195 OSMO_ASSERT(actx == actxs[7]);
2196
2197 /* Free APN contexts and check how the matching changes */
2198
2199 sgsn_apn_ctx_free(actxs[7]);
2200 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2201 OSMO_ASSERT(actx == actxs[8]);
2202
2203 sgsn_apn_ctx_free(actxs[8]);
2204 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2205 OSMO_ASSERT(actx == actxs[6]);
2206
2207 sgsn_apn_ctx_free(actxs[6]);
2208 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2209 OSMO_ASSERT(actx == actxs[1]);
2210
2211 sgsn_apn_ctx_free(actxs[5]);
2212 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2213 OSMO_ASSERT(actx == actxs[4]);
2214
2215 sgsn_apn_ctx_free(actxs[4]);
2216 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2217 OSMO_ASSERT(actx == actxs[2]);
2218
2219 sgsn_apn_ctx_free(actxs[2]);
2220 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2221 OSMO_ASSERT(actx == actxs[1]);
2222
2223 sgsn_apn_ctx_free(actxs[1]);
2224 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2225 OSMO_ASSERT(actx == actxs[0]);
2226
2227 sgsn_apn_ctx_free(actxs[0]);
2228 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2229 OSMO_ASSERT(actx == actxs[3]);
2230
2231 sgsn_apn_ctx_free(actxs[3]);
2232 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2233 OSMO_ASSERT(actx == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002234
2235 cleanup_test();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002236}
2237
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002238struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2239 struct sgsn_subscriber_data *sdata);
2240
2241static void test_ggsn_selection(void)
2242{
2243 struct apn_ctx *actxs[4];
2244 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01002245 struct gprs_subscr *s1;
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002246 const char *imsi1 = "1234567890";
2247 struct sgsn_mm_ctx *ctx;
2248 struct gprs_ra_id raid = { 0, };
2249 uint32_t local_tlli = 0xffeeddcc;
2250 enum gsm48_gsm_cause gsm_cause;
2251 struct tlv_parsed tp;
2252 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2253 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002254 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002255
2256 printf("Testing GGSN selection\n");
2257
Neels Hofmeyr814fef02016-12-08 21:19:57 +01002258 gsup_client_send_cb = my_gsup_client_send_dummy;
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002259
2260 /* Check for emptiness */
2261 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2262
2263 /* Create a context */
2264 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2265 ctx = alloc_mm_ctx(local_tlli, &raid);
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002266 osmo_strlcpy(ctx->imsi, imsi1, sizeof(ctx->imsi));
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002267
2268 /* Allocate and attach a subscriber */
2269 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2270 assert_subscr(s1, imsi1);
2271
2272 tp.lv[GSM48_IE_GSM_APN].len = 0;
2273 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2274
2275 /* TODO: Add PDP info entries to s1 */
2276
2277 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2278 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2279 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2280
2281 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2282 actxs[0]->ggsn = ggcs[0];
2283 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2284 actxs[1]->ggsn = ggcs[1];
2285 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2286 actxs[2]->ggsn = ggcs[2];
2287
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002288 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2289 pdp_data->context_id = 1;
2290 pdp_data->pdp_type = 0x0121;
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002291 osmo_strlcpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str));
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002292
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002293 /* Resolve GGSNs */
2294
2295 tp.lv[GSM48_IE_GSM_APN].len =
2296 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2297
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002298 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002299 OSMO_ASSERT(ggc != NULL);
2300 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002301 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002302
2303 tp.lv[GSM48_IE_GSM_APN].len =
2304 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2305
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002306 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002307 OSMO_ASSERT(ggc != NULL);
2308 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002309 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002310
2311 tp.lv[GSM48_IE_GSM_APN].len = 0;
2312 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2313
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002314 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002315 OSMO_ASSERT(ggc != NULL);
2316 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002317 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002318
2319 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2320 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002321 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002322 OSMO_ASSERT(ggc != NULL);
2323 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002324 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002325
2326 sgsn_apn_ctx_free(actxs[3]);
2327 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2328
2329 tp.lv[GSM48_IE_GSM_APN].len =
2330 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2331
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002332 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002333 OSMO_ASSERT(ggc == NULL);
2334 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002335 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002336
2337 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002338 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002339 OSMO_ASSERT(ggc == NULL);
2340 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2341
2342 /* Add PDP data entry to subscriber */
2343
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002344 osmo_strlcpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str));
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002345
2346 tp.lv[GSM48_IE_GSM_APN].len =
2347 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2348
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002349 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002350 OSMO_ASSERT(ggc != NULL);
2351 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002352 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002353
2354 tp.lv[GSM48_IE_GSM_APN].len =
2355 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2356
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002357 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002358 OSMO_ASSERT(ggc == NULL);
2359 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002360 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002361
2362 /* Cleanup */
2363
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01002364 gprs_subscr_put(s1);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002365 sgsn_mm_ctx_cleanup_free(ctx);
2366
2367 assert_no_subscrs();
2368
2369 sgsn_apn_ctx_free(actxs[0]);
2370 sgsn_apn_ctx_free(actxs[1]);
2371 sgsn_apn_ctx_free(actxs[2]);
2372
2373 sgsn_ggsn_ctx_free(ggcs[0]);
2374 sgsn_ggsn_ctx_free(ggcs[1]);
2375 sgsn_ggsn_ctx_free(ggcs[2]);
2376
Neels Hofmeyr814fef02016-12-08 21:19:57 +01002377 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002378
2379 cleanup_test();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002380}
2381
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002382static struct log_info_cat gprs_categories[] = {
2383 [DMM] = {
2384 .name = "DMM",
2385 .description = "Layer3 Mobility Management (MM)",
2386 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002387 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002388 },
2389 [DPAG] = {
2390 .name = "DPAG",
2391 .description = "Paging Subsystem",
2392 .color = "\033[1;38m",
2393 .enabled = 1, .loglevel = LOGL_NOTICE,
2394 },
2395 [DMEAS] = {
2396 .name = "DMEAS",
2397 .description = "Radio Measurement Processing",
2398 .enabled = 0, .loglevel = LOGL_NOTICE,
2399 },
2400 [DREF] = {
2401 .name = "DREF",
2402 .description = "Reference Counting",
2403 .enabled = 0, .loglevel = LOGL_NOTICE,
2404 },
2405 [DGPRS] = {
2406 .name = "DGPRS",
2407 .description = "GPRS Packet Service",
2408 .enabled = 1, .loglevel = LOGL_DEBUG,
2409 },
2410 [DNS] = {
2411 .name = "DNS",
2412 .description = "GPRS Network Service (NS)",
2413 .enabled = 1, .loglevel = LOGL_INFO,
2414 },
2415 [DBSSGP] = {
2416 .name = "DBSSGP",
2417 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2418 .enabled = 1, .loglevel = LOGL_DEBUG,
2419 },
2420 [DLLC] = {
2421 .name = "DLLC",
2422 .description = "GPRS Logical Link Control Protocol (LLC)",
2423 .enabled = 1, .loglevel = LOGL_DEBUG,
2424 },
2425 [DSNDCP] = {
2426 .name = "DSNDCP",
2427 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2428 .enabled = 1, .loglevel = LOGL_DEBUG,
2429 },
2430};
2431
2432static struct log_info info = {
2433 .cat = gprs_categories,
2434 .num_cat = ARRAY_SIZE(gprs_categories),
2435};
2436
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002437int main(int argc, char **argv)
2438{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002439 void *osmo_sgsn_ctx;
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002440 void *msgb_ctx;
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002441
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002442 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002443 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2444 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002445 msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002446
Alexander Couzens14314bd2016-07-05 09:52:52 +02002447 sgsn_rate_ctr_init();
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01002448 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002449 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002450
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002451 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002452 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002453 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002454 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002455 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002456 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002457 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002458 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002459 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002460 test_gmm_attach_acl();
2461 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002462 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002463 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002464 test_gmm_attach_subscr_gsup_auth(0);
2465 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002466 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002467 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002468 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002469 test_gmm_ptmsi_allocation();
Jacob Erlbeck13304782016-01-04 18:43:37 +01002470 test_gmm_routing_areas();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002471 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002472 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002473 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002474
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002475 talloc_report_full(osmo_sgsn_ctx, stderr);
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002476 OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);
Alexander Couzens14314bd2016-07-05 09:52:52 +02002477 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 2);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002478 return 0;
2479}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002480
2481
2482/* stubs */
2483struct osmo_prim_hdr;
2484int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2485{
2486 abort();
2487}