blob: 6eabddefdee36d439b34e246e49b8a7bd4ec2aee [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},
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001167 .key_seq = 0
1168 };
1169
1170 /* Fake an authentication */
1171 OSMO_ASSERT(mmctx->subscr);
1172 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1173
1174 gprs_subscr_update_auth_info(mmctx->subscr);
1175
1176 return 0;
1177};
1178
1179static void test_gmm_attach_subscr_real_auth(void)
1180{
1181 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001182 struct gprs_subscr *subscr;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001183
1184 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1185 subscr_request_update_location_cb = my_subscr_request_update_location;
1186 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1187
1188 subscr = gprs_subscr_get_or_create("123456789012345");
1189 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001190 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001191 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001192
1193 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001194
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001195 test_gmm_attach(0);
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001196 gprs_subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001197 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001198
1199 sgsn->cfg.auth_policy = saved_auth_policy;
1200 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1201 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001202
1203 cleanup_test();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001204}
1205
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001206#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1207 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1208
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001209static int auth_info_skip = 0;
1210static int upd_loc_skip = 0;
1211
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001212int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1213{
1214 static const uint8_t send_auth_info_res[] = {
1215 0x0a,
1216 TEST_GSUP_IMSI_LONG_IE,
1217 0x03, 0x22, /* Auth tuple */
1218 0x20, 0x10,
1219 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1220 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1221 0x21, 0x04,
1222 0x51, 0xe5, 0x51, 0xe5,
1223 0x22, 0x08,
1224 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1225 };
1226
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001227 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001228
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001229 if (auth_info_skip > 0) {
1230 auth_info_skip -= 1;
1231 return -EAGAIN;
1232 }
1233
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001234 /* Fake an SendAuthInfoRes */
1235 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1236
1237 return 0;
1238};
1239
1240int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1241 static const uint8_t update_location_res[] = {
1242 0x06,
1243 TEST_GSUP_IMSI_LONG_IE,
1244 0x04, 0x00, /* PDP info complete */
1245 0x05, 0x12,
1246 0x10, 0x01, 0x01,
1247 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1248 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freyther20de3ae2015-05-05 22:52:40 +02001249 0x08, 0x07, /* MSISDN 49166213323 encoded */
1250 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freyther10c0f562015-05-17 20:58:40 +02001251 0x09, 0x07, /* MSISDN 38166213323 encoded */
1252 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001253 };
1254
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001255 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001256
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001257 if (upd_loc_skip > 0) {
1258 upd_loc_skip -= 1;
1259 return -EAGAIN;
1260 }
1261
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001262 /* Fake an UpdateLocRes */
1263 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1264};
1265
1266
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001267static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001268{
1269 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001270 struct gprs_subscr *subscr;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001271
1272 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1273 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1274 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001275 if (retry) {
1276 upd_loc_skip = 3;
1277 auth_info_skip = 3;
1278 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001279
1280 subscr = gprs_subscr_get_or_create("123456789012345");
1281 subscr->authorized = 1;
1282 sgsn->cfg.require_authentication = 1;
1283 sgsn->cfg.require_update_location = 1;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001284 gprs_subscr_put(subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001285
1286 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001287 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001288 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001289
1290 sgsn->cfg.auth_policy = saved_auth_policy;
1291 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1292 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001293 upd_loc_skip = 0;
1294 auth_info_skip = 0;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001295
1296 cleanup_test();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001297}
1298
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001299int my_gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001300{
Harald Welte23d77d52016-04-25 19:07:34 +02001301 struct osmo_gsup_message to_peer = {0};
1302 struct osmo_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001303 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001304 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001305
1306 /* Simulate the GSUP peer */
Harald Welte23d77d52016-04-25 19:07:34 +02001307 rc = osmo_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001308 OSMO_ASSERT(rc >= 0);
1309 OSMO_ASSERT(to_peer.imsi[0] != 0);
Neels Hofmeyr59504dc2017-01-13 03:10:54 +01001310 osmo_strlcpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001311
1312 /* This invalidates the pointers in to_peer */
1313 msgb_free(msg);
1314
1315 switch (to_peer.message_type) {
Harald Welte23d77d52016-04-25 19:07:34 +02001316 case OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001317 /* Send UPDATE_LOCATION_RESULT */
1318 return my_subscr_request_update_gsup_auth(NULL);
1319
Harald Welte23d77d52016-04-25 19:07:34 +02001320 case OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001321 /* Send SEND_AUTH_INFO_RESULT */
1322 return my_subscr_request_auth_info_gsup_auth(NULL);
1323
Harald Welte23d77d52016-04-25 19:07:34 +02001324 case OSMO_GSUP_MSGT_PURGE_MS_REQUEST:
1325 from_peer.message_type = OSMO_GSUP_MSGT_PURGE_MS_RESULT;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001326 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001327
1328 default:
1329 if ((to_peer.message_type & 0b00000011) == 0) {
1330 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001331 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001332 from_peer.message_type = to_peer.message_type + 1;
1333 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1334 break;
1335 }
1336
1337 /* Ignore it */
1338 return 0;
1339 }
1340
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001341 reply_msg = gsup_client_msgb_alloc();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001342 reply_msg->l2h = reply_msg->data;
Harald Welte23d77d52016-04-25 19:07:34 +02001343 osmo_gsup_encode(reply_msg, &from_peer);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001344 gprs_subscr_rx_gsup_message(reply_msg);
1345 msgb_free(reply_msg);
1346
1347 return 0;
1348};
1349
1350static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1351{
1352 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01001353 struct gprs_subscr *subscr;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001354
1355 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001356 gsup_client_send_cb = my_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001357
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001358 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gsup_client);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001359
1360 if (retry) {
1361 upd_loc_skip = 3;
1362 auth_info_skip = 3;
1363 }
1364
1365 printf("Auth policy 'remote', real GSUP based auth: ");
1366 test_gmm_attach(retry);
1367
1368 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001369 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001370 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001371
1372 sgsn->cfg.auth_policy = saved_auth_policy;
Neels Hofmeyr814fef02016-12-08 21:19:57 +01001373 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001374 upd_loc_skip = 0;
1375 auth_info_skip = 0;
1376 talloc_free(sgsn->gsup_client);
1377 sgsn->gsup_client = NULL;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001378
1379 cleanup_test();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001380}
1381
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001382/*
1383 * Test the GMM Rejects
1384 */
1385static void test_gmm_reject(void)
1386{
1387 struct gprs_ra_id raid = { 0, };
1388 struct sgsn_mm_ctx *ctx = NULL;
1389 uint32_t foreign_tlli;
1390 struct gprs_llc_lle *lle;
1391 int idx;
1392
1393 /* DTAP - Attach Request */
1394 /* Invalid MI length */
1395 static const unsigned char attach_req_inv_mi_len[] = {
1396 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1397 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1398 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1399 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1400 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1401 };
1402
1403 /* DTAP - Attach Request */
1404 /* Invalid MI type (IMEI) */
1405 static const unsigned char attach_req_inv_mi_type[] = {
1406 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1407 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1408 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1409 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1410 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1411 };
1412
1413 /* DTAP - Routing Area Update Request */
1414 static const unsigned char dtap_ra_upd_req[] = {
1415 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1416 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1417 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1418 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1419 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1420 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1421 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1422 };
1423
1424 /* DTAP - Routing Area Update Request */
1425 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1426 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1427 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1428 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1429 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1430 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1431 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1432 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1433 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1434 };
1435
1436 /* DTAP - Routing Area Update Request */
1437 /* Invalid cap length */
1438 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1439 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1440 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1441 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1442 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1443 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1444 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1445 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1446 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1447 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1448 };
1449
1450 struct test {
1451 const char *title;
1452 const unsigned char *msg;
1453 unsigned msg_len;
1454 unsigned num_resp;
1455
1456 };
1457 static struct test tests[] = {
1458 {
1459 .title = "Attach Request (invalid MI length)",
1460 .msg = attach_req_inv_mi_len,
1461 .msg_len = sizeof(attach_req_inv_mi_len),
1462 .num_resp = 1 /* Reject */
1463
1464 },
1465 {
1466 .title = "Attach Request (invalid MI type)",
1467 .msg = attach_req_inv_mi_type,
1468 .msg_len = sizeof(attach_req_inv_mi_type),
1469 .num_resp = 1 /* Reject */
1470 },
1471 {
1472 .title = "Routing Area Update Request (valid)",
1473 .msg = dtap_ra_upd_req,
1474 .msg_len = sizeof(dtap_ra_upd_req),
1475 .num_resp = 2 /* XID Reset + Reject */
1476 },
1477 {
1478 .title = "Routing Area Update Request (invalid type)",
1479 .msg = dtap_ra_upd_req_inv_type,
1480 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1481 .num_resp = 1 /* Reject */
1482 },
1483 {
1484 .title = "Routing Area Update Request (invalid CAP length)",
1485 .msg = dtap_ra_upd_req_inv_cap_len,
1486 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1487 .num_resp = 1 /* Reject */
1488 },
1489 };
1490
1491 printf("Testing GMM reject\n");
1492
1493 /* reset the PRNG used by sgsn_alloc_ptmsi */
1494 srand(1);
1495
1496 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1497
1498 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1499
1500 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1501 const struct test *test = &tests[idx];
1502 printf(" - %s\n", test->title);
1503
1504 /* Create a LLE/LLME */
1505 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1506 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1507
1508 /* Inject the Request message */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001509 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001510 test->msg, test->msg_len);
1511
1512 /* We expect a Reject message */
1513 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1514 sgsn_tx_counter, test->num_resp);
1515 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1516
1517 /* verify that LLME/MM are removed */
1518 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1519 OSMO_ASSERT(ctx == NULL);
1520 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1521 }
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001522
1523 cleanup_test();
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001524}
1525
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001526/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001527 * Test cancellation of attached MM contexts
1528 */
1529static void test_gmm_cancel(void)
1530{
1531 struct gprs_ra_id raid = { 0, };
1532 struct sgsn_mm_ctx *ctx = NULL;
1533 struct sgsn_mm_ctx *ictx;
1534 uint32_t ptmsi1;
1535 uint32_t foreign_tlli;
1536 uint32_t local_tlli = 0;
1537 struct gprs_llc_lle *lle;
1538 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1539
1540 /* DTAP - Attach Request */
1541 /* The P-TMSI is not known by the SGSN */
1542 static const unsigned char attach_req[] = {
1543 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1544 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1545 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1546 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1547 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1548 };
1549
1550 /* DTAP - Identity Response IMEI */
1551 static const unsigned char ident_resp_imei[] = {
1552 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1553 0x56
1554 };
1555
1556 /* DTAP - Identity Response IMSI */
1557 static const unsigned char ident_resp_imsi[] = {
1558 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1559 0x54
1560 };
1561
1562 /* DTAP - Attach Complete */
1563 static const unsigned char attach_compl[] = {
1564 0x08, 0x03
1565 };
1566
1567 printf("Testing cancellation\n");
1568
1569 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1570
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001571 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1572
1573 /* Create a LLE/LLME */
1574 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1575 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1576 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1577
1578 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001579 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001580 attach_req, ARRAY_SIZE(attach_req));
1581
1582 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1583 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001584 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001585
1586 /* we expect an identity request (IMEI) */
1587 OSMO_ASSERT(sgsn_tx_counter == 1);
1588
1589 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001590 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001591 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1592
1593 /* we expect an identity request (IMSI) */
1594 OSMO_ASSERT(sgsn_tx_counter == 1);
1595
1596 /* inject the identity response (IMSI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001597 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001598 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1599
1600 /* check that the MM context has not been removed due to a failed
1601 * authorization */
1602 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1603
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001604 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001605
1606 /* we expect an attach accept/reject */
1607 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001608 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1609 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001610
1611 /* this has been randomly assigned by the SGSN */
1612 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1613
1614 /* inject the attach complete */
Harald Weltef97ee042015-12-25 19:12:21 +01001615 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001616 attach_compl, ARRAY_SIZE(attach_compl));
1617
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001618 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001619
1620 /* we don't expect a response */
1621 OSMO_ASSERT(sgsn_tx_counter == 0);
1622
1623 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001624 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001625
1626 /* verify that things are gone */
1627 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1628 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1629 OSMO_ASSERT(!ictx);
1630
1631 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001632
1633 cleanup_test();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001634}
1635
1636/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001637 * Test the dynamic allocation of P-TMSIs
1638 */
1639static void test_gmm_ptmsi_allocation(void)
1640{
Jacob Erlbeckd58c0332016-01-04 18:43:35 +01001641 struct gprs_ra_id raid = {332, 112, 16464, 96};
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001642 struct sgsn_mm_ctx *ctx = NULL;
1643 struct sgsn_mm_ctx *ictx;
1644 uint32_t foreign_tlli;
1645 uint32_t ptmsi1;
1646 uint32_t ptmsi2;
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001647 uint32_t received_ptmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001648 uint32_t old_ptmsi;
1649 uint32_t local_tlli = 0;
1650 struct gprs_llc_lle *lle;
1651 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1652
1653 /* DTAP - Attach Request (IMSI 12131415161718) */
1654 static const unsigned char attach_req[] = {
1655 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1656 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1657 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1658 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1659 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1660 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1661 0x00,
1662 };
1663
1664 /* DTAP - Identity Response IMEI */
1665 static const unsigned char ident_resp_imei[] = {
1666 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1667 0x56
1668 };
1669
1670 /* DTAP - Attach Complete */
1671 static const unsigned char attach_compl[] = {
1672 0x08, 0x03
1673 };
1674
1675 /* DTAP - Routing Area Update Request */
1676 static const unsigned char ra_upd_req[] = {
1677 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1678 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1679 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1680 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1681 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1682 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1683 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1684 };
1685
1686 /* DTAP - Routing Area Update Complete */
1687 static const unsigned char ra_upd_complete[] = {
1688 0x08, 0x0a
1689 };
1690
1691 /* DTAP - Detach Request (MO) */
1692 /* normal detach, power_off = 1 */
1693 static const unsigned char detach_req[] = {
1694 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1695 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1696 };
1697
1698 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1699
1700 printf("Testing P-TMSI allocation\n");
1701
1702 printf(" - sgsn_alloc_ptmsi\n");
1703
1704 /* reset the PRNG used by sgsn_alloc_ptmsi */
1705 srand(1);
1706
1707 ptmsi1 = sgsn_alloc_ptmsi();
1708 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1709
1710 ptmsi2 = sgsn_alloc_ptmsi();
1711 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1712
1713 OSMO_ASSERT(ptmsi1 != ptmsi2);
1714
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001715 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001716
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001717 printf(" - Repeated Attach Request\n");
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001718
1719 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1720
1721 /* Create a LLE/LLME */
1722 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1723 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1724 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1725
1726 /* inject the attach request */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001727 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001728 attach_req, ARRAY_SIZE(attach_req));
1729
1730 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1731 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001732 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001733 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1734 ptmsi1 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001735
1736 old_ptmsi = ctx->p_tmsi_old;
1737
1738 /* we expect an identity request (IMEI) */
1739 OSMO_ASSERT(sgsn_tx_counter == 1);
1740
1741 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001742 send_0408_message(ctx->gb.llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001743 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1744
1745 /* check that the MM context has not been removed due to a failed
1746 * authorization */
1747 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1748
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001749 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001750 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1751
1752 /* we expect an attach accept */
1753 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001754 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1755 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001756
1757 /* we ignore this and send the attach again */
Jacob Erlbeck91580892016-01-04 18:43:33 +01001758 send_0408_message(lle->llme, foreign_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001759 attach_req, ARRAY_SIZE(attach_req));
1760
1761 /* the allocated P-TMSI should be the same */
1762 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1763 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001764 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001765 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1766 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1767
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001768 /* we expect an attach accept */
1769 OSMO_ASSERT(sgsn_tx_counter == 1);
1770 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1771 OSMO_ASSERT(received_ptmsi == ptmsi1);
1772
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001773 /* inject the attach complete */
1774 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001775 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001776 attach_compl, ARRAY_SIZE(attach_compl));
1777
1778 /* we don't expect a response */
1779 OSMO_ASSERT(sgsn_tx_counter == 0);
1780
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001781 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001782 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1783 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1784
1785 printf(" - Repeated RA Update Request\n");
1786
1787 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001788 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001789 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1790
1791 /* we expect an RA update accept */
1792 OSMO_ASSERT(sgsn_tx_counter == 1);
1793
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001794 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001795 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001796 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1797 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1798 ptmsi2 = ctx->p_tmsi;
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001799
1800 /* repeat the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001801 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001802 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1803
1804 /* we expect an RA update accept */
1805 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck133e8622015-10-12 19:36:32 +02001806 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1807 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001808
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001809 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001810 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1811 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1812
1813 /* inject the RA update complete */
1814 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001815 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001816 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1817
1818 /* we don't expect a response */
1819 OSMO_ASSERT(sgsn_tx_counter == 0);
1820
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001821 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001822 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1823 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1824
1825 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01001826 send_0408_message(ctx->gb.llme, local_tlli, &raid,
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001827 detach_req, ARRAY_SIZE(detach_req));
1828
1829 /* verify that things are gone */
1830 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1831 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1832 OSMO_ASSERT(!ictx);
1833
1834 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02001835
1836 cleanup_test();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001837}
1838
Jacob Erlbeck13304782016-01-04 18:43:37 +01001839/*
1840 * Test changing of routing areas
1841 */
1842static void test_gmm_routing_areas(void)
1843{
1844 struct gprs_ra_id raid1 = {332, 112, 16464, 96};
1845 struct gprs_ra_id raid2 = {332, 112, 16464, 97};
1846 struct sgsn_mm_ctx *ctx = NULL;
1847 struct sgsn_mm_ctx *ictx;
1848 uint32_t ptmsi1;
1849 uint32_t received_ptmsi;
1850 uint32_t ms_tlli = 0;
1851 struct gprs_llc_lle *lle;
1852 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1853
1854 /* DTAP - Attach Request (IMSI 12131415161718) */
1855 static const unsigned char attach_req[] = {
1856 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1857 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1858 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1859 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1860 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1861 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1862 0x00,
1863 };
1864
1865 /* DTAP - Attach Request (IMSI 12131415161718) (RA 2) */
1866 static const unsigned char attach_req2[] = {
1867 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1868 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1869 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x61, 0x19,
1870 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1871 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1872 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1873 0x00,
1874 };
1875
1876 /* DTAP - Identity Response IMEI */
1877 static const unsigned char ident_resp_imei[] = {
1878 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1879 0x56
1880 };
1881
1882 /* DTAP - Attach Complete */
1883 static const unsigned char attach_compl[] = {
1884 0x08, 0x03
1885 };
1886
1887 /* DTAP - Routing Area Update Request (coming from RA 1) */
1888 static const unsigned char ra_upd_req1[] = {
1889 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1890 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1891 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1892 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1893 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1894 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1895 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1896 };
1897
1898 /* DTAP - Routing Area Update Request (coming from RA 2) */
1899 static const unsigned char ra_upd_req2[] = {
1900 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1901 0x61, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1902 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1903 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1904 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1905 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1906 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1907 };
1908
1909 /* DTAP - Routing Area Update Request (coming from RA other) */
1910 /* raid_other = {443, 223, 16464, 98}; */
1911 static const unsigned char ra_upd_req_other[] = {
1912 0x08, 0x08, 0x10, 0x22, 0x33, 0x44, 0x40, 0x50,
1913 0x62, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1914 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1915 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1916 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1917 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1918 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1919 };
1920
1921 /* DTAP - Routing Area Update Complete */
1922 static const unsigned char ra_upd_complete[] = {
1923 0x08, 0x0a
1924 };
1925
1926 /* DTAP - Detach Request (MO) */
1927 /* normal detach, power_off = 1 */
1928 static const unsigned char detach_req[] = {
1929 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1930 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1931 };
1932
1933 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1934
1935 printf("Testing routing area changes\n");
1936
1937 /* reset the PRNG used by sgsn_alloc_ptmsi */
1938 srand(1);
1939
1940 ptmsi1 = GSM_RESERVED_TMSI;
1941
1942 printf(" - Attach Request (RA 1)\n");
1943
1944 ms_tlli = gprs_tmsi2tlli(0x00000023, TLLI_RANDOM);
1945
1946 /* Create a LLE/LLME */
1947 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1948 lle = gprs_lle_get_or_create(ms_tlli, 3);
1949 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1950
1951 /* inject the attach request */
1952 send_0408_message(lle->llme, ms_tlli, &raid1,
1953 attach_req, ARRAY_SIZE(attach_req));
1954
1955 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid1);
1956 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001957 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01001958 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1959
1960 /* we expect an identity request (IMEI) */
1961 OSMO_ASSERT(sgsn_tx_counter == 1);
1962 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ID_REQ);
1963 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1964
1965 /* inject the identity response (IMEI) */
Harald Weltef97ee042015-12-25 19:12:21 +01001966 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001967 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1968
1969 /* check that the MM context has not been removed due to a failed
1970 * authorization */
1971 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(ms_tlli, &raid1));
1972
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001973 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01001974
1975 /* we expect an attach accept */
1976 OSMO_ASSERT(sgsn_tx_counter == 1);
1977 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
1978 OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
1979
1980 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1981 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
1982 ptmsi1 = received_ptmsi;
1983
1984 /* inject the attach complete */
1985 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01001986 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01001987 attach_compl, ARRAY_SIZE(attach_compl));
1988
1989 /* we don't expect a response */
1990 OSMO_ASSERT(sgsn_tx_counter == 0);
1991
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01001992 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01001993 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1994 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1995
1996 printf(" - RA Update Request (RA 1 -> RA 1)\n");
1997
1998 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01001999 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002000 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2001
2002 /* we expect an RA update accept */
2003 OSMO_ASSERT(sgsn_tx_counter == 1);
2004 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2005 // OSMO_ASSERT(last_dl_parse_ctx.tlli == ms_tlli);
2006
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002007 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002008 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2009 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2010 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2011
2012 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2013 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2014 ptmsi1 = received_ptmsi;
2015
2016 /* inject the RA update complete */
2017 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002018 send_0408_message(ctx->gb.llme, ms_tlli, &raid1,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002019 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2020
2021 /* we don't expect a response */
2022 OSMO_ASSERT(sgsn_tx_counter == 0);
2023
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002024 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002025 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2026 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002027 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002028
Jacob Erlbeck13304782016-01-04 18:43:37 +01002029 printf(" - RA Update Request (RA 1 -> RA 2)\n");
2030
2031 /* inject the RA update request */
2032 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_FOREIGN);
2033
2034 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002035 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002036 ra_upd_req1, ARRAY_SIZE(ra_upd_req1));
2037
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002038 /* we expect an RA update accept */
Jacob Erlbeck13304782016-01-04 18:43:37 +01002039 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck5ac4aad2016-01-04 18:43:38 +01002040 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002041
2042 printf(" - RA Update Request (RA other -> RA 2)\n");
2043
2044 /* inject the RA update request */
2045 ms_tlli = gprs_tmsi2tlli(0x12345678, TLLI_FOREIGN);
2046
2047 /* It is coming from RA 1 => ra_upd_req1 */
Harald Weltef97ee042015-12-25 19:12:21 +01002048 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002049 ra_upd_req_other, ARRAY_SIZE(ra_upd_req_other));
2050
2051 /* we expect an RA update reject (and a LLC XID RESET) */
2052 OSMO_ASSERT(sgsn_tx_counter == 2);
2053 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_REJ);
2054 /* this has killed the LLE/LLME */
2055
2056 printf(" - Attach Request (RA 2)\n");
2057
2058 /* Create a LLE/LLME */
2059 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2060 lle = gprs_lle_get_or_create(ms_tlli, 3);
2061 OSMO_ASSERT(count(gprs_llme_list()) == 1);
2062
2063 /* inject the attach request */
2064 send_0408_message(lle->llme, ms_tlli, &raid2,
2065 attach_req2, ARRAY_SIZE(attach_req2));
2066
2067 ctx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2068 OSMO_ASSERT(ctx != NULL);
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002069 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002070 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2071
2072 /* we expect an attach accept */
2073 OSMO_ASSERT(sgsn_tx_counter == 1);
2074 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_ATTACH_ACK);
2075
2076 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2077 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2078 ptmsi1 = received_ptmsi;
2079
2080 /* inject the attach complete */
2081 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
2082 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2083 OSMO_ASSERT(ictx != NULL);
2084 OSMO_ASSERT(ictx == ctx);
2085
Harald Weltef97ee042015-12-25 19:12:21 +01002086 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002087 attach_compl, ARRAY_SIZE(attach_compl));
2088
2089 /* we don't expect a response */
2090 OSMO_ASSERT(sgsn_tx_counter == 0);
2091
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002092 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002093 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2094 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
2095
2096 printf(" - RA Update Request (RA 2 -> RA 2)\n");
2097
2098 /* inject the RA update request */
Harald Weltef97ee042015-12-25 19:12:21 +01002099 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002100 ra_upd_req2, ARRAY_SIZE(ra_upd_req2));
2101
2102 /* we expect an RA update accept */
2103 OSMO_ASSERT(sgsn_tx_counter == 1);
2104 OSMO_ASSERT(last_dl_parse_ctx.g48_hdr->msg_type == GSM48_MT_GMM_RA_UPD_ACK);
2105
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002106 OSMO_ASSERT(ctx->gmm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002107 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
2108 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
2109 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
2110
2111 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
2112 OSMO_ASSERT(received_ptmsi == ctx->p_tmsi);
2113 ptmsi1 = received_ptmsi;
2114
2115 /* inject the RA update complete */
2116 ms_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Harald Weltef97ee042015-12-25 19:12:21 +01002117 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002118 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
2119
2120 /* we don't expect a response */
2121 OSMO_ASSERT(sgsn_tx_counter == 0);
2122
Alexander Couzens4f8da6d2017-01-31 15:34:26 +01002123 OSMO_ASSERT(ctx->gmm_state == GMM_REGISTERED_NORMAL);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002124 OSMO_ASSERT(ctx->p_tmsi_old == 0);
2125 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
Harald Weltef97ee042015-12-25 19:12:21 +01002126 OSMO_ASSERT(ctx->gb.tlli == ms_tlli);
Jacob Erlbeck13304782016-01-04 18:43:37 +01002127
2128
2129 /* inject the detach */
Harald Weltef97ee042015-12-25 19:12:21 +01002130 send_0408_message(ctx->gb.llme, ms_tlli, &raid2,
Jacob Erlbeck13304782016-01-04 18:43:37 +01002131 detach_req, ARRAY_SIZE(detach_req));
2132
2133 /* verify that things are gone */
2134 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2135 ictx = sgsn_mm_ctx_by_tlli(ms_tlli, &raid2);
2136 OSMO_ASSERT(!ictx);
2137
2138 sgsn->cfg.auth_policy = saved_auth_policy;
2139
2140 cleanup_test();
2141}
2142
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002143static void test_apn_matching(void)
2144{
2145 struct apn_ctx *actx, *actxs[9];
2146
2147 printf("Testing APN matching\n");
2148
2149 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
2150 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
2151 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
2152 actxs[3] = NULL;
2153
2154 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
2155 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
2156 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
2157 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
2158
2159 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
2160
2161 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2162 OSMO_ASSERT(actx == actxs[2]);
2163 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
2164 OSMO_ASSERT(actx == actxs[2]);
2165 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
2166 OSMO_ASSERT(actx == actxs[1]);
2167 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
2168 OSMO_ASSERT(actx == actxs[1]);
2169 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
2170 OSMO_ASSERT(actx == actxs[0]);
2171 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2172 OSMO_ASSERT(actx == NULL);
2173
2174 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
2175 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
2176 OSMO_ASSERT(actx == actxs[3]);
2177
2178 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
2179 OSMO_ASSERT(actx == actxs[4]);
2180
2181 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
2182 OSMO_ASSERT(actx == actxs[6]);
2183
2184 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2185 OSMO_ASSERT(actx == actxs[5]);
2186
2187 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
2188 OSMO_ASSERT(actx == actxs[7]);
2189
2190 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
2191 OSMO_ASSERT(actx == actxs[8]);
2192
2193 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2194 OSMO_ASSERT(actx == actxs[7]);
2195
2196 /* Free APN contexts and check how the matching changes */
2197
2198 sgsn_apn_ctx_free(actxs[7]);
2199 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2200 OSMO_ASSERT(actx == actxs[8]);
2201
2202 sgsn_apn_ctx_free(actxs[8]);
2203 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2204 OSMO_ASSERT(actx == actxs[6]);
2205
2206 sgsn_apn_ctx_free(actxs[6]);
2207 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
2208 OSMO_ASSERT(actx == actxs[1]);
2209
2210 sgsn_apn_ctx_free(actxs[5]);
2211 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2212 OSMO_ASSERT(actx == actxs[4]);
2213
2214 sgsn_apn_ctx_free(actxs[4]);
2215 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
2216 OSMO_ASSERT(actx == actxs[2]);
2217
2218 sgsn_apn_ctx_free(actxs[2]);
2219 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2220 OSMO_ASSERT(actx == actxs[1]);
2221
2222 sgsn_apn_ctx_free(actxs[1]);
2223 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2224 OSMO_ASSERT(actx == actxs[0]);
2225
2226 sgsn_apn_ctx_free(actxs[0]);
2227 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2228 OSMO_ASSERT(actx == actxs[3]);
2229
2230 sgsn_apn_ctx_free(actxs[3]);
2231 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
2232 OSMO_ASSERT(actx == NULL);
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002233
2234 cleanup_test();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002235}
2236
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002237struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
2238 struct sgsn_subscriber_data *sdata);
2239
2240static void test_ggsn_selection(void)
2241{
2242 struct apn_ctx *actxs[4];
2243 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01002244 struct gprs_subscr *s1;
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002245 const char *imsi1 = "1234567890";
2246 struct sgsn_mm_ctx *ctx;
2247 struct gprs_ra_id raid = { 0, };
2248 uint32_t local_tlli = 0xffeeddcc;
2249 enum gsm48_gsm_cause gsm_cause;
2250 struct tlv_parsed tp;
2251 uint8_t apn_enc[GSM_APN_LENGTH + 10];
2252 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002253 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002254
2255 printf("Testing GGSN selection\n");
2256
Neels Hofmeyr814fef02016-12-08 21:19:57 +01002257 gsup_client_send_cb = my_gsup_client_send_dummy;
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002258
2259 /* Check for emptiness */
2260 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
2261
2262 /* Create a context */
2263 OSMO_ASSERT(count(gprs_llme_list()) == 0);
2264 ctx = alloc_mm_ctx(local_tlli, &raid);
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002265 osmo_strlcpy(ctx->imsi, imsi1, sizeof(ctx->imsi));
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002266
2267 /* Allocate and attach a subscriber */
2268 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
2269 assert_subscr(s1, imsi1);
2270
2271 tp.lv[GSM48_IE_GSM_APN].len = 0;
2272 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2273
2274 /* TODO: Add PDP info entries to s1 */
2275
2276 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
2277 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
2278 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
2279
2280 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
2281 actxs[0]->ggsn = ggcs[0];
2282 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
2283 actxs[1]->ggsn = ggcs[1];
2284 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
2285 actxs[2]->ggsn = ggcs[2];
2286
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002287 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
2288 pdp_data->context_id = 1;
2289 pdp_data->pdp_type = 0x0121;
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002290 osmo_strlcpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str));
Holger Hans Peter Freyther9270d992015-05-24 20:51:17 +08002291
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002292 /* Resolve GGSNs */
2293
2294 tp.lv[GSM48_IE_GSM_APN].len =
2295 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2296
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002297 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002298 OSMO_ASSERT(ggc != NULL);
2299 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002300 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002301
2302 tp.lv[GSM48_IE_GSM_APN].len =
2303 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2304
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002305 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002306 OSMO_ASSERT(ggc != NULL);
2307 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002308 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002309
2310 tp.lv[GSM48_IE_GSM_APN].len = 0;
2311 tp.lv[GSM48_IE_GSM_APN].val = NULL;
2312
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002313 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002314 OSMO_ASSERT(ggc != NULL);
2315 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002316 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002317
2318 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
2319 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002320 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002321 OSMO_ASSERT(ggc != NULL);
2322 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002323 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002324
2325 sgsn_apn_ctx_free(actxs[3]);
2326 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
2327
2328 tp.lv[GSM48_IE_GSM_APN].len =
2329 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
2330
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002331 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002332 OSMO_ASSERT(ggc == NULL);
2333 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002334 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002335
2336 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002337 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002338 OSMO_ASSERT(ggc == NULL);
2339 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2340
2341 /* Add PDP data entry to subscriber */
2342
Neels Hofmeyr93bafb62017-01-13 03:12:08 +01002343 osmo_strlcpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str));
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002344
2345 tp.lv[GSM48_IE_GSM_APN].len =
2346 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2347
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002348 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002349 OSMO_ASSERT(ggc != NULL);
2350 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002351 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002352
2353 tp.lv[GSM48_IE_GSM_APN].len =
2354 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2355
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002356 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002357 OSMO_ASSERT(ggc == NULL);
2358 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther39c430e2015-05-25 12:26:49 +08002359 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002360
2361 /* Cleanup */
2362
Neels Hofmeyr0e5d8072017-01-10 00:49:56 +01002363 gprs_subscr_put(s1);
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002364 sgsn_mm_ctx_cleanup_free(ctx);
2365
2366 assert_no_subscrs();
2367
2368 sgsn_apn_ctx_free(actxs[0]);
2369 sgsn_apn_ctx_free(actxs[1]);
2370 sgsn_apn_ctx_free(actxs[2]);
2371
2372 sgsn_ggsn_ctx_free(ggcs[0]);
2373 sgsn_ggsn_ctx_free(ggcs[1]);
2374 sgsn_ggsn_ctx_free(ggcs[2]);
2375
Neels Hofmeyr814fef02016-12-08 21:19:57 +01002376 gsup_client_send_cb = __real_gsup_client_send;
Jacob Erlbeckcf151872015-10-12 19:36:31 +02002377
2378 cleanup_test();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002379}
2380
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002381static struct log_info_cat gprs_categories[] = {
2382 [DMM] = {
2383 .name = "DMM",
2384 .description = "Layer3 Mobility Management (MM)",
2385 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002386 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002387 },
2388 [DPAG] = {
2389 .name = "DPAG",
2390 .description = "Paging Subsystem",
2391 .color = "\033[1;38m",
2392 .enabled = 1, .loglevel = LOGL_NOTICE,
2393 },
2394 [DMEAS] = {
2395 .name = "DMEAS",
2396 .description = "Radio Measurement Processing",
2397 .enabled = 0, .loglevel = LOGL_NOTICE,
2398 },
2399 [DREF] = {
2400 .name = "DREF",
2401 .description = "Reference Counting",
2402 .enabled = 0, .loglevel = LOGL_NOTICE,
2403 },
2404 [DGPRS] = {
2405 .name = "DGPRS",
2406 .description = "GPRS Packet Service",
2407 .enabled = 1, .loglevel = LOGL_DEBUG,
2408 },
2409 [DNS] = {
2410 .name = "DNS",
2411 .description = "GPRS Network Service (NS)",
2412 .enabled = 1, .loglevel = LOGL_INFO,
2413 },
2414 [DBSSGP] = {
2415 .name = "DBSSGP",
2416 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2417 .enabled = 1, .loglevel = LOGL_DEBUG,
2418 },
2419 [DLLC] = {
2420 .name = "DLLC",
2421 .description = "GPRS Logical Link Control Protocol (LLC)",
2422 .enabled = 1, .loglevel = LOGL_DEBUG,
2423 },
2424 [DSNDCP] = {
2425 .name = "DSNDCP",
2426 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2427 .enabled = 1, .loglevel = LOGL_DEBUG,
2428 },
2429};
2430
2431static struct log_info info = {
2432 .cat = gprs_categories,
2433 .num_cat = ARRAY_SIZE(gprs_categories),
2434};
2435
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002436int main(int argc, char **argv)
2437{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002438 void *osmo_sgsn_ctx;
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002439 void *msgb_ctx;
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002440
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002441 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002442 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2443 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002444 msgb_ctx = msgb_talloc_ctx_init(osmo_sgsn_ctx, 0);
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002445
Alexander Couzens14314bd2016-07-05 09:52:52 +02002446 sgsn_rate_ctr_init();
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01002447 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002448 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01002449
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002450 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01002451 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002452 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002453 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002454 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002455 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002456 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002457 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002458 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002459 test_gmm_attach_acl();
2460 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002461 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002462 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002463 test_gmm_attach_subscr_gsup_auth(0);
2464 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002465 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002466 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002467 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002468 test_gmm_ptmsi_allocation();
Jacob Erlbeck13304782016-01-04 18:43:37 +01002469 test_gmm_routing_areas();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002470 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002471 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002472 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002473
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002474 talloc_report_full(osmo_sgsn_ctx, stderr);
Neels Hofmeyr39ae17f2016-09-16 01:49:08 +02002475 OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1);
Alexander Couzens14314bd2016-07-05 09:52:52 +02002476 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 2);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002477 return 0;
2478}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002479
2480
2481/* stubs */
2482struct osmo_prim_hdr;
2483int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2484{
2485 abort();
2486}