blob: 859223f7aa937e4746b8dc9b2bf1670fe456ee35 [file] [log] [blame]
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbecke8b69682014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Jacob Erlbeck3400f112015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Jacob Erlbeck28c28f92015-10-12 19:36:32 +020030#include <openbsc/gprs_gb_parse.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020031
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010032#include <osmocom/gprs/gprs_bssgp.h>
33
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020034#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck092bbc82015-01-05 18:57:32 +010035#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020036
37#include <osmocom/core/application.h>
38#include <osmocom/core/msgb.h>
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010039#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020040
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +020041#include <stdio.h>
42
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020043extern void *tall_msgb_ctx;
44
45void *tall_bsc_ctx;
46static struct sgsn_instance sgsn_inst = {
47 .config_file = "osmo_sgsn.cfg",
48 .cfg = {
49 .gtp_statedir = "./",
Jacob Erlbeckd7b77732014-11-04 10:08:37 +010050 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020051 },
52};
53struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010054unsigned sgsn_tx_counter = 0;
Jacob Erlbeck28c28f92015-10-12 19:36:32 +020055struct msgb *last_msg = NULL;
56struct gprs_gb_parse_context last_dl_parse_ctx;
57
58static void reset_last_msg()
59{
60 if (last_msg)
61 msgb_free(last_msg);
62
63 last_msg = NULL;
64 memset(&last_dl_parse_ctx, 0, sizeof(last_dl_parse_ctx));
65}
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010066
Jacob Erlbeck515fc332015-10-12 19:36:31 +020067static void cleanup_test()
68{
Jacob Erlbeck28c28f92015-10-12 19:36:32 +020069 reset_last_msg();
70}
71
72static uint32_t get_new_ptmsi(const struct gprs_gb_parse_context *parse_ctx)
73{
74 uint32_t new_ptmsi = GSM_RESERVED_TMSI;
75
76 if (parse_ctx->new_ptmsi_enc)
77 gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
78
79 return new_ptmsi;
Jacob Erlbeck515fc332015-10-12 19:36:31 +020080}
81
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010082/* override */
83int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
84 struct bssgp_dl_ud_par *dup)
85{
Jacob Erlbeck28c28f92015-10-12 19:36:32 +020086 int rc;
87
88 reset_last_msg();
89
90 last_msg = msg;
91 OSMO_ASSERT(msgb_data(last_msg) != NULL);
92
93 rc = gprs_gb_parse_llc(msgb_data(last_msg), msgb_length(last_msg),
94 &last_dl_parse_ctx);
95
96 fprintf(stderr, "Got DL LLC message: %s\n",
97 gprs_gb_message_name(&last_dl_parse_ctx, "UNKNOWN"));
98
99 OSMO_ASSERT(rc > 0);
100
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100101 sgsn_tx_counter += 1;
102 return 0;
103}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200104
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100105/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100106void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
107void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100108 &__real_sgsn_update_subscriber_data;
109
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100110void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100111{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100112 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100113}
114
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100115/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
116int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
117int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
118 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100119
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100120int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
121 return (*subscr_request_update_location_cb)(mmctx);
122};
123
124/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
125int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
126int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
127 &__real_gprs_subscr_request_auth_info;
128
129int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
130 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +0100131};
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100132
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +0100133/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
134int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
135int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
136 &__real_gprs_gsup_client_send;
137
138int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
139{
140 return (*gprs_gsup_client_send_cb)(gsupc, msg);
141};
142
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200143static int count(struct llist_head *head)
144{
145 struct llist_head *cur;
146 int count = 0;
147
148 llist_for_each(cur, head)
149 count += 1;
150
151 return count;
152}
153
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200154static struct msgb *create_msg(const uint8_t *data, size_t len)
155{
156 struct msgb *msg = msgb_alloc(len + 8, "test message");
157 msg->l1h = msgb_put(msg, 8);
158 msg->l2h = msgb_put(msg, len);
159 memcpy(msg->l2h, data, len);
160
161 msgb_bcid(msg) = msg->l1h;
162 msgb_gmmh(msg) = msg->l2h;
163 return msg;
164}
165
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100166/*
167 * Create a context and search for it
168 */
169static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
170{
171 struct sgsn_mm_ctx *ctx, *ictx;
172 struct gprs_llc_lle *lle;
173 int old_count = count(gprs_llme_list());
174
175 lle = gprs_lle_get_or_create(tlli, 3);
176 ctx = sgsn_mm_ctx_alloc(tlli, raid);
177 ctx->mm_state = GMM_REGISTERED_NORMAL;
178 ctx->llme = lle->llme;
179
180 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
181 OSMO_ASSERT(ictx == ctx);
182
183 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
184
185 return ctx;
186}
187
Jacob Erlbeck75488292014-10-29 10:31:18 +0100188static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
189 const uint8_t *data, size_t data_len)
190{
191 struct msgb *msg;
192
Jacob Erlbeck28c28f92015-10-12 19:36:32 +0200193 reset_last_msg();
Jacob Erlbeck75488292014-10-29 10:31:18 +0100194 sgsn_tx_counter = 0;
195
196 msg = create_msg(data, data_len);
197 msgb_tlli(msg) = tlli;
198 gsm0408_gprs_rcvmsg(msg, llme);
199 msgb_free(msg);
200}
201
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200202static void test_llme(void)
203{
204 struct gprs_llc_lle *lle, *lle_copy;
205 uint32_t local_tlli;
206 uint32_t foreign_tlli;
207
208 printf("Testing LLME allocations\n");
209 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
210 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
211
212 /* initial state */
213 OSMO_ASSERT(count(gprs_llme_list()) == 0);
214
215 /* Create a new entry */
216 lle = gprs_lle_get_or_create(local_tlli, 3);
217 OSMO_ASSERT(lle);
218 OSMO_ASSERT(count(gprs_llme_list()) == 1);
219
220 /* No new entry is created */
221 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
222 OSMO_ASSERT(lle == lle_copy);
223 OSMO_ASSERT(count(gprs_llme_list()) == 1);
224 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
225 OSMO_ASSERT(lle == lle_copy);
226 OSMO_ASSERT(count(gprs_llme_list()) == 1);
227
228 /* unassign which should delete it*/
229 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
230
231 /* Check that everything was cleaned up */
232 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200233
234 cleanup_test();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200235}
236
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100237struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100238void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100239{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100240 OSMO_ASSERT(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100241 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100242 __func__, mmctx, mmctx->subscr);
243 last_updated_subscr = mmctx->subscr;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100244}
245
Jacob Erlbecka695d242015-01-09 11:59:50 +0100246static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
247{
248 struct gsm_subscriber *sfound;
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100249 OSMO_ASSERT(subscr);
250 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100251
252 sfound = gprs_subscr_get_by_imsi(imsi);
253 OSMO_ASSERT(sfound == subscr);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100254
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100255 subscr_put(sfound);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100256}
257
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100258static void show_subscrs(FILE *out)
259{
260 struct gsm_subscriber *subscr;
261
262 llist_for_each_entry(subscr, &active_subscribers, entry) {
263 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100264 "use count: %d\n",
265 subscr->imsi, subscr->use_count);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +0100266 }
267}
268
269static void assert_no_subscrs()
270{
271 show_subscrs(stdout);
272 fflush(stdout);
273 OSMO_ASSERT(llist_empty(&active_subscribers));
274}
275
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100276static void test_subscriber(void)
277{
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100278 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100279 const char *imsi1 = "1234567890";
280 const char *imsi2 = "9876543210";
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100281 const char *imsi3 = "5656565656";
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100282
283 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
284
285 printf("Testing core subscriber data API\n");
286
287 /* Check for emptiness */
288 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
289 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100290 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100291
292 /* Allocate entry 1 */
293 s1 = gprs_subscr_get_or_create(imsi1);
294 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100295 assert_subscr(s1, imsi1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100296 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100297
298 /* Allocate entry 2 */
299 s2 = gprs_subscr_get_or_create(imsi2);
300 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbecka695d242015-01-09 11:59:50 +0100301
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100302 /* Allocate entry 3 */
303 s3 = gprs_subscr_get_or_create(imsi3);
304
Jacob Erlbecka695d242015-01-09 11:59:50 +0100305 /* Check entries */
306 assert_subscr(s1, imsi1);
307 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100308 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100309
310 /* Update entry 1 */
311 last_updated_subscr = NULL;
312 gprs_subscr_update(s1);
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100313 OSMO_ASSERT(last_updated_subscr == NULL);
314 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
315 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100316
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100317 /* There is no subscriber cache. Verify it */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100318 gprs_subscr_cleanup(s1);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100319 subscr_put(s1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100320 s1 = NULL;
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100321 sfound = gprs_subscr_get_by_imsi(imsi1);
322 OSMO_ASSERT(sfound == NULL);
323
Jacob Erlbecka695d242015-01-09 11:59:50 +0100324 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100325 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100326
Jacob Erlbecka695d242015-01-09 11:59:50 +0100327 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100328 gprs_subscr_cleanup(s2);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100329 subscr_put(s2);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100330 s2 = NULL;
331 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
332 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100333 assert_subscr(s3, imsi3);
334
335 /* Try to delete entry 3 */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100336 gprs_subscr_cleanup(s3);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100337 subscr_put(s3);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100338 s3 = NULL;
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100339 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100340
341 OSMO_ASSERT(llist_empty(&active_subscribers));
342
343 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200344
345 cleanup_test();
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100346}
347
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100348static void test_auth_triplets(void)
349{
350 struct gsm_subscriber *s1, *s1found;
351 const char *imsi1 = "1234567890";
352 struct gsm_auth_tuple *at;
353 struct sgsn_mm_ctx *ctx;
354 struct gprs_ra_id raid = { 0, };
355 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100356
357 printf("Testing authentication triplet handling\n");
358
359 /* Check for emptiness */
360 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
361
362 /* Allocate entry 1 */
363 s1 = gprs_subscr_get_or_create(imsi1);
364 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
365 s1found = gprs_subscr_get_by_imsi(imsi1);
366 OSMO_ASSERT(s1found == s1);
367 subscr_put(s1found);
368
369 /* Create a context */
370 OSMO_ASSERT(count(gprs_llme_list()) == 0);
371 ctx = alloc_mm_ctx(local_tlli, &raid);
372
373 /* Attach s1 to ctx */
374 ctx->subscr = subscr_get(s1);
375 ctx->subscr->sgsn_data->mm = ctx;
376
377 /* Try to get auth tuple */
378 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
379 OSMO_ASSERT(at == NULL);
380
381 /* Add triplets */
382 s1->sgsn_data->auth_triplets[0].key_seq = 0;
383 s1->sgsn_data->auth_triplets[1].key_seq = 1;
384 s1->sgsn_data->auth_triplets[2].key_seq = 2;
385
386 /* Try to get auth tuple */
387 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
388 OSMO_ASSERT(at != NULL);
389 OSMO_ASSERT(at->key_seq == 0);
390 OSMO_ASSERT(at->use_count == 1);
391 at = sgsn_auth_get_tuple(ctx, at->key_seq);
392 OSMO_ASSERT(at != NULL);
393 OSMO_ASSERT(at->key_seq == 1);
394 OSMO_ASSERT(at->use_count == 1);
395 at = sgsn_auth_get_tuple(ctx, at->key_seq);
396 OSMO_ASSERT(at != NULL);
397 OSMO_ASSERT(at->key_seq == 2);
398 OSMO_ASSERT(at->use_count == 1);
399 at = sgsn_auth_get_tuple(ctx, at->key_seq);
400 OSMO_ASSERT(at == NULL);
401
402 /* Free MM context and subscriber */
403 subscr_put(s1);
Jacob Erlbeck70c177a2015-01-26 14:43:07 +0100404 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100405 s1found = gprs_subscr_get_by_imsi(imsi1);
406 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200407
408 cleanup_test();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100409}
410
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100411#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
412
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100413static int rx_gsup_message(const uint8_t *data, size_t data_len)
414{
415 struct msgb *msg;
416 int rc;
417
418 msg = msgb_alloc(1024, __func__);
419 msg->l2h = msgb_put(msg, data_len);
420 OSMO_ASSERT(msg->l2h != NULL);
421 memcpy(msg->l2h, data, data_len);
422 rc = gprs_subscr_rx_gsup_message(msg);
423 msgb_free(msg);
424
425 return rc;
426}
427
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100428static void test_subscriber_gsup(void)
429{
430 struct gsm_subscriber *s1, *s1found;
431 const char *imsi1 = "1234567890";
432 struct sgsn_mm_ctx *ctx;
433 struct gprs_ra_id raid = { 0, };
434 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100435 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100436 int rc;
437
438 static const uint8_t send_auth_info_res[] = {
439 0x0a,
440 TEST_GSUP_IMSI1_IE,
441 0x03, 0x22, /* Auth tuple */
442 0x20, 0x10,
443 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
444 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
445 0x21, 0x04,
446 0x21, 0x22, 0x23, 0x24,
447 0x22, 0x08,
448 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
449 0x03, 0x22, /* Auth tuple */
450 0x20, 0x10,
451 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
452 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
453 0x21, 0x04,
454 0xa1, 0xa2, 0xa3, 0xa4,
455 0x22, 0x08,
456 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
457 };
458
459 static const uint8_t send_auth_info_err[] = {
460 0x09,
461 TEST_GSUP_IMSI1_IE,
462 0x02, 0x01, 0x07 /* GPRS not allowed */
463 };
464
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400465#define MSISDN 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09
466
467 static const uint8_t s1_msisdn[] = { MSISDN };
468
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100469 static const uint8_t update_location_res[] = {
470 0x06,
471 TEST_GSUP_IMSI1_IE,
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400472 0x08, 0x09, MSISDN,
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100473 0x04, 0x00, /* PDP info complete */
474 0x05, 0x12,
475 0x10, 0x01, 0x01,
476 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
477 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
478 0x05, 0x11,
479 0x10, 0x01, 0x02,
480 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
481 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
482 };
483
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400484#undef MSISDN
485
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100486 static const uint8_t update_location_err[] = {
487 0x05,
488 TEST_GSUP_IMSI1_IE,
489 0x02, 0x01, 0x07 /* GPRS not allowed */
490 };
491
492 static const uint8_t location_cancellation_req[] = {
493 0x1c,
494 TEST_GSUP_IMSI1_IE,
495 0x06, 0x01, 0x00,
496 };
497
Jacob Erlbecke7fea452015-04-07 17:49:48 +0200498 static const uint8_t location_cancellation_req_withdraw[] = {
499 0x1c,
500 TEST_GSUP_IMSI1_IE,
501 0x06, 0x01, 0x01,
502 };
503
Jacob Erlbeck00b8b912015-01-08 15:29:01 +0100504 static const uint8_t location_cancellation_req_other[] = {
505 0x1c,
506 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
507 0x06, 0x01, 0x00,
508 };
509
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100510 static const uint8_t purge_ms_err[] = {
511 0x0d,
512 TEST_GSUP_IMSI1_IE,
513 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
514 };
515
Jacob Erlbeck9ca3ace2015-01-29 14:17:51 +0100516 static const uint8_t purge_ms_err_no_cause[] = {
517 0x0d,
518 TEST_GSUP_IMSI1_IE,
519 };
520
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100521 static const uint8_t purge_ms_res[] = {
522 0x0e,
523 TEST_GSUP_IMSI1_IE,
524 0x07, 0x00,
525 };
526
527
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100528 static const uint8_t insert_data_req[] = {
529 0x10,
530 TEST_GSUP_IMSI1_IE,
531 0x05, 0x11,
532 0x10, 0x01, 0x03,
533 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
534 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
535 };
536
537 static const uint8_t delete_data_req[] = {
538 0x14,
539 TEST_GSUP_IMSI1_IE,
540 0x10, 0x01, 0x03,
541 };
542
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100543 printf("Testing subcriber GSUP handling\n");
544
545 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
546
547 /* Check for emptiness */
548 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
549
550 /* Allocate entry 1 */
551 s1 = gprs_subscr_get_or_create(imsi1);
552 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
553 s1found = gprs_subscr_get_by_imsi(imsi1);
554 OSMO_ASSERT(s1found == s1);
555 subscr_put(s1found);
556
557 /* Create a context */
558 OSMO_ASSERT(count(gprs_llme_list()) == 0);
559 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100560
561 /* Attach s1 to ctx */
562 ctx->subscr = subscr_get(s1);
563 ctx->subscr->sgsn_data->mm = ctx;
564
565 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100566 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100567 OSMO_ASSERT(rc >= 0);
568 OSMO_ASSERT(last_updated_subscr == s1);
569
570 /* Check triplets */
571 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
572 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
573 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
574
575 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100576 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100577 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100578 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100579 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100580
581 /* Check triplets */
582 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
583 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
584 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
585
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100586 /* Inject UpdateLocRes GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100587 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100588 OSMO_ASSERT(rc >= 0);
589 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100590 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100591 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Holger Hans Peter Freyther786cfee2015-04-23 09:53:53 -0400592 OSMO_ASSERT(s1->sgsn_data->msisdn_len == sizeof(s1_msisdn));
593 OSMO_ASSERT(memcmp(s1->sgsn_data->msisdn, s1_msisdn, sizeof(s1_msisdn)) == 0);
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100594 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
595 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
596 struct sgsn_subscriber_pdp_data, list);
597 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
598 pdpd = llist_entry(pdpd->list.next,
599 struct sgsn_subscriber_pdp_data, list);
600 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100601
602 /* Check authorization */
603 OSMO_ASSERT(s1->authorized == 1);
604
605 /* Inject UpdateLocErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100606 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100607 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100608 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100609 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100610
611 /* Check authorization */
612 OSMO_ASSERT(s1->authorized == 0);
613
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100614 /* Inject InsertSubscrData GSUP message */
615 last_updated_subscr = NULL;
616 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
617 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
618 OSMO_ASSERT(last_updated_subscr == NULL);
619
620 /* Inject DeleteSubscrData GSUP message */
621 last_updated_subscr = NULL;
622 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
623 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
624 OSMO_ASSERT(last_updated_subscr == NULL);
625
Jacob Erlbeck00b8b912015-01-08 15:29:01 +0100626 /* Inject wrong LocCancelReq GSUP message */
627 last_updated_subscr = NULL;
628 rc = rx_gsup_message(location_cancellation_req_other,
629 sizeof(location_cancellation_req_other));
630 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
631 OSMO_ASSERT(last_updated_subscr == NULL);
632
633 /* Check cancellation result */
634 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
635 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
636
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100637 /* Inject LocCancelReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100638 rc = rx_gsup_message(location_cancellation_req,
639 sizeof(location_cancellation_req));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100640 OSMO_ASSERT(rc >= 0);
641 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100642 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100643
644 /* Check cancellation result */
645 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
646 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
647
Jacob Erlbecke7fea452015-04-07 17:49:48 +0200648 /* Inject LocCancelReq(withdraw) GSUP message */
649 rc = rx_gsup_message(location_cancellation_req_withdraw,
650 sizeof(location_cancellation_req_withdraw));
651 OSMO_ASSERT(rc >= 0);
652 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_IMPL_DETACHED);
653
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100654 /* Inject PurgeMsRes GSUP message */
655 rc = rx_gsup_message(purge_ms_res,
656 sizeof(purge_ms_res));
657 OSMO_ASSERT(rc >= 0);
658 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
659
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100660 /* Free MM context and subscriber */
Jacob Erlbeck265e7352015-01-30 11:57:25 +0100661 OSMO_ASSERT(ctx->subscr == NULL);
662 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100663 subscr_put(s1);
664 s1found = gprs_subscr_get_by_imsi(imsi1);
665 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100666
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100667 /* Inject PurgeMsRes GSUP message */
668 rc = rx_gsup_message(purge_ms_res,
669 sizeof(purge_ms_res));
670 OSMO_ASSERT(rc >= 0);
671
672 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
673 rc = rx_gsup_message(purge_ms_err,
674 sizeof(purge_ms_err));
675 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
676
Jacob Erlbeck9ca3ace2015-01-29 14:17:51 +0100677 /* Inject PurgeMsErr() GSUP message */
678 rc = rx_gsup_message(purge_ms_err_no_cause,
679 sizeof(purge_ms_err_no_cause));
680 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
681
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100682 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
683 last_updated_subscr = NULL;
684 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck629dacc2015-01-15 17:50:16 +0100685 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100686 OSMO_ASSERT(last_updated_subscr == NULL);
687
688 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
689 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
690 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
691 OSMO_ASSERT(last_updated_subscr == NULL);
692
693 /* Inject LocCancelReq GSUP message (unknown IMSI) */
694 rc = rx_gsup_message(location_cancellation_req,
695 sizeof(location_cancellation_req));
696 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
697 OSMO_ASSERT(last_updated_subscr == NULL);
698
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100699 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200700
701 cleanup_test();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100702}
703
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +0100704int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
705{
706 msgb_free(msg);
707 return 0;
708};
709
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200710/*
711 * Test that a GMM Detach will remove the MMCTX and the
712 * associated LLME.
713 */
714static void test_gmm_detach(void)
715{
716 struct gprs_ra_id raid = { 0, };
717 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200718 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200719
720 printf("Testing GMM detach\n");
721
722 /* DTAP - Detach Request (MO) */
723 /* normal detach, power_off = 0 */
724 static const unsigned char detach_req[] = {
725 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
726 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
727 };
728
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200729 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200730
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100731 /* Create a context */
732 OSMO_ASSERT(count(gprs_llme_list()) == 0);
733 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200734
735 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100736 send_0408_message(ctx->llme, local_tlli,
737 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200738
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100739 /* verify that a single message (hopefully the Detach Accept) has been
740 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100741 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100742
743 /* verify that things are gone */
744 OSMO_ASSERT(count(gprs_llme_list()) == 0);
745 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
746 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200747
748 cleanup_test();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100749}
750
751/*
752 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
753 * will not sent a Detach Accept message (power_off = 1)
754 */
755static void test_gmm_detach_power_off(void)
756{
757 struct gprs_ra_id raid = { 0, };
758 struct sgsn_mm_ctx *ctx, *ictx;
759 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100760
761 printf("Testing GMM detach (power off)\n");
762
763 /* DTAP - Detach Request (MO) */
764 /* normal detach, power_off = 1 */
765 static const unsigned char detach_req[] = {
766 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
767 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
768 };
769
770 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
771
772 /* Create a context */
773 OSMO_ASSERT(count(gprs_llme_list()) == 0);
774 ctx = alloc_mm_ctx(local_tlli, &raid);
775
776 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100777 send_0408_message(ctx->llme, local_tlli,
778 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100779
780 /* verify that no message (and therefore no Detach Accept) has been
781 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100782 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100783
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200784 /* verify that things are gone */
785 OSMO_ASSERT(count(gprs_llme_list()) == 0);
786 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200787 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200788
789 cleanup_test();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200790}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200791
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200792/*
793 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
794 */
795static void test_gmm_detach_no_mmctx(void)
796{
797 struct gprs_llc_lle *lle;
798 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200799
800 printf("Testing GMM detach (no MMCTX)\n");
801
802 /* DTAP - Detach Request (MO) */
803 /* normal detach, power_off = 0 */
804 static const unsigned char detach_req[] = {
805 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
806 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
807 };
808
809 /* Create an LLME */
810 OSMO_ASSERT(count(gprs_llme_list()) == 0);
811 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
812 lle = gprs_lle_get_or_create(local_tlli, 3);
813
814 OSMO_ASSERT(count(gprs_llme_list()) == 1);
815
816 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100817 send_0408_message(lle->llme, local_tlli,
818 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200819
820 /* verify that the LLME is gone */
821 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200822
823 cleanup_test();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200824}
825
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100826/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100827 * Test that a single GMM Detach Accept message will not cause the SGSN to send
828 * any message or leave an MM context at the SGSN.
829 */
830static void test_gmm_detach_accept_unexpected(void)
831{
832 struct gprs_llc_lle *lle;
833 uint32_t local_tlli;
834
835 printf("Testing GMM detach accept (unexpected)\n");
836
837 /* DTAP - Detach Accept (MT) */
838 /* normal detach */
839 static const unsigned char detach_acc[] = {
840 0x08, 0x06
841 };
842
843 /* Create an LLME */
844 OSMO_ASSERT(count(gprs_llme_list()) == 0);
845 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
846 lle = gprs_lle_get_or_create(local_tlli, 3);
847
848 /* inject the detach */
849 send_0408_message(lle->llme, local_tlli,
850 detach_acc, ARRAY_SIZE(detach_acc));
851
852 /* verify that no message (and therefore no Status or XID reset) has been
853 * sent by the SGSN */
854 OSMO_ASSERT(sgsn_tx_counter == 0);
855
856 /* verify that things are gone */
857 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200858
859 cleanup_test();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100860}
861
862/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100863 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
864 */
865static void test_gmm_status_no_mmctx(void)
866{
867 struct gprs_llc_lle *lle;
868 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100869
870 printf("Testing GMM Status (no MMCTX)\n");
871
872 /* DTAP - GMM Status, protocol error */
873 static const unsigned char gmm_status[] = {
874 0x08, 0x20, 0x6f
875 };
876
877 /* Create an LLME */
878 OSMO_ASSERT(count(gprs_llme_list()) == 0);
879 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
880 lle = gprs_lle_get_or_create(local_tlli, 3);
881
882 OSMO_ASSERT(count(gprs_llme_list()) == 1);
883
884 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100885 send_0408_message(lle->llme, local_tlli,
886 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100887
888 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100889 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100890
891 /* verify that the LLME is gone */
892 OSMO_ASSERT(count(gprs_llme_list()) == 0);
Jacob Erlbeck515fc332015-10-12 19:36:31 +0200893
894 cleanup_test();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100895}
896
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100897/*
898 * Test the GMM Attach procedure
899 */
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100900static void test_gmm_attach(int retry)
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100901{
902 struct gprs_ra_id raid = { 0, };
903 struct sgsn_mm_ctx *ctx = NULL;
904 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100905 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100906 uint32_t foreign_tlli;
907 uint32_t local_tlli = 0;
908 struct gprs_llc_lle *lle;
909
910 /* DTAP - Attach Request */
911 /* The P-TMSI is not known by the SGSN */
912 static const unsigned char attach_req[] = {
913 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
914 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
915 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
916 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
917 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
918 };
919
920 /* DTAP - Identity Response IMEI */
921 static const unsigned char ident_resp_imei[] = {
922 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
923 0x56
924 };
925
926 /* DTAP - Identity Response IMSI */
927 static const unsigned char ident_resp_imsi[] = {
928 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
929 0x54
930 };
931
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100932 /* DTAP - Authentication and Ciphering Resp */
933 static const unsigned char auth_ciph_resp[] = {
934 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
935 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
936 };
937
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100938 /* DTAP - Attach Complete */
939 static const unsigned char attach_compl[] = {
940 0x08, 0x03
941 };
942
943 /* DTAP - Detach Request (MO) */
944 /* normal detach, power_off = 0 */
945 static const unsigned char detach_req[] = {
946 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
947 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
948 };
949
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100950 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100951
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100952 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
953
954 /* Create a LLE/LLME */
955 OSMO_ASSERT(count(gprs_llme_list()) == 0);
956 lle = gprs_lle_get_or_create(foreign_tlli, 3);
957 OSMO_ASSERT(count(gprs_llme_list()) == 1);
958
959 /* inject the attach request */
960 send_0408_message(lle->llme, foreign_tlli,
961 attach_req, ARRAY_SIZE(attach_req));
962
963 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
964 OSMO_ASSERT(ctx != NULL);
965 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
966
967 /* we expect an identity request (IMEI) */
968 OSMO_ASSERT(sgsn_tx_counter == 1);
969
970 /* inject the identity response (IMEI) */
971 send_0408_message(ctx->llme, foreign_tlli,
972 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
973
974 /* we expect an identity request (IMSI) */
975 OSMO_ASSERT(sgsn_tx_counter == 1);
976
977 /* inject the identity response (IMSI) */
978 send_0408_message(ctx->llme, foreign_tlli,
979 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
980
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100981 /* check that the MM context has not been removed due to a failed
982 * authorization */
983 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
984
Jacob Erlbeck67318ef2014-10-28 16:23:46 +0100985 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100986
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100987retry_attach_req:
988
989 if (retry && sgsn_tx_counter == 0) {
990 fprintf(stderr, "Retrying attach request\n");
991 /* re-inject the attach request */
992 send_0408_message(lle->llme, foreign_tlli,
993 attach_req, ARRAY_SIZE(attach_req));
994 }
995
996 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
997 /* we got an auth & ciph request */
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100998
999 /* inject the auth & ciph response */
1000 send_0408_message(ctx->llme, foreign_tlli,
1001 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1002
1003 /* check that the MM context has not been removed due to a
1004 * failed authorization */
1005 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
Holger Hans Peter Freythera9f671c2015-05-05 22:52:40 +02001006 if (ctx->subscr && ctx->subscr->sgsn_data->msisdn_len > 0)
1007 OSMO_ASSERT(strcmp(ctx->msisdn, "+49166213323") == 0);
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001008 }
1009
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001010 if (retry && sgsn_tx_counter == 0)
1011 goto retry_attach_req;
1012
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001013 /* we expect an attach accept/reject */
1014 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001015 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1016 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001017
1018 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +01001019 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001020
1021 /* inject the attach complete */
1022 send_0408_message(ctx->llme, local_tlli,
1023 attach_compl, ARRAY_SIZE(attach_compl));
1024
1025 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1026
1027 /* we don't expect a response */
1028 OSMO_ASSERT(sgsn_tx_counter == 0);
1029
1030 /* inject the detach */
1031 send_0408_message(ctx->llme, local_tlli,
1032 detach_req, ARRAY_SIZE(detach_req));
1033
1034 /* verify that things are gone */
1035 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1036 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1037 OSMO_ASSERT(!ictx);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001038
1039 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001040}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001041
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001042static void test_gmm_attach_acl(void)
1043{
1044 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1045
1046 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1047 sgsn_acl_add("123456789012345", &sgsn->cfg);
1048 printf("Auth policy 'closed': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001049 test_gmm_attach(0);
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001050 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001051
1052 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001053
1054 cleanup_test();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001055}
1056
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001057int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001058 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001059 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001060 if (rc == -ENOTSUP) {
1061 OSMO_ASSERT(mmctx->subscr);
1062 gprs_subscr_update(mmctx->subscr);
1063 }
1064 return rc;
1065};
1066
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001067int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1068 gprs_subscr_update(mmctx->subscr);
1069 return 0;
1070};
1071
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001072static void test_gmm_attach_subscr(void)
1073{
1074 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1075 struct gsm_subscriber *subscr;
1076
1077 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001078 subscr_request_update_location_cb = my_subscr_request_update_location;
1079 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001080
1081 subscr = gprs_subscr_get_or_create("123456789012345");
1082 subscr->authorized = 1;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001083
1084 printf("Auth policy 'remote': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001085 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001086 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001087 assert_no_subscrs();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001088
1089 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001090 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1091 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001092
1093 cleanup_test();
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001094}
1095
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001096int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1097{
1098 /* Fake an authentication */
1099 OSMO_ASSERT(mmctx->subscr);
1100 mmctx->is_authenticated = 1;
1101 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001102
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001103 return 0;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001104};
1105
1106static void test_gmm_attach_subscr_fake_auth(void)
1107{
1108 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1109 struct gsm_subscriber *subscr;
1110
1111 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001112 subscr_request_update_location_cb = my_subscr_request_update_location;
1113 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001114
1115 subscr = gprs_subscr_get_or_create("123456789012345");
1116 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001117 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001118 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001119
1120 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001121 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001122 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001123 assert_no_subscrs();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001124
1125 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001126 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1127 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001128
1129 cleanup_test();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001130}
1131
1132int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1133{
1134 struct gsm_auth_tuple at = {
1135 .sres = {0x51, 0xe5, 0x51, 0xe5},
1136 .key_seq = 0
1137 };
1138
1139 /* Fake an authentication */
1140 OSMO_ASSERT(mmctx->subscr);
1141 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1142
1143 gprs_subscr_update_auth_info(mmctx->subscr);
1144
1145 return 0;
1146};
1147
1148static void test_gmm_attach_subscr_real_auth(void)
1149{
1150 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1151 struct gsm_subscriber *subscr;
1152
1153 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1154 subscr_request_update_location_cb = my_subscr_request_update_location;
1155 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1156
1157 subscr = gprs_subscr_get_or_create("123456789012345");
1158 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001159 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001160 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001161
1162 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001163
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001164 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001165 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001166 assert_no_subscrs();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001167
1168 sgsn->cfg.auth_policy = saved_auth_policy;
1169 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1170 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001171
1172 cleanup_test();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001173}
1174
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001175#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1176 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1177
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001178static int auth_info_skip = 0;
1179static int upd_loc_skip = 0;
1180
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001181int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1182{
1183 static const uint8_t send_auth_info_res[] = {
1184 0x0a,
1185 TEST_GSUP_IMSI_LONG_IE,
1186 0x03, 0x22, /* Auth tuple */
1187 0x20, 0x10,
1188 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1189 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1190 0x21, 0x04,
1191 0x51, 0xe5, 0x51, 0xe5,
1192 0x22, 0x08,
1193 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1194 };
1195
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001196 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001197
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001198 if (auth_info_skip > 0) {
1199 auth_info_skip -= 1;
1200 return -EAGAIN;
1201 }
1202
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001203 /* Fake an SendAuthInfoRes */
1204 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1205
1206 return 0;
1207};
1208
1209int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1210 static const uint8_t update_location_res[] = {
1211 0x06,
1212 TEST_GSUP_IMSI_LONG_IE,
1213 0x04, 0x00, /* PDP info complete */
1214 0x05, 0x12,
1215 0x10, 0x01, 0x01,
1216 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1217 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
Holger Hans Peter Freythera9f671c2015-05-05 22:52:40 +02001218 0x08, 0x07, /* MSISDN 49166213323 encoded */
1219 0x91, 0x94, 0x61, 0x26, 0x31, 0x23, 0xF3,
Holger Hans Peter Freytherfe4a9f62015-05-17 20:58:40 +02001220 0x09, 0x07, /* MSISDN 38166213323 encoded */
1221 0x91, 0x83, 0x61, 0x26, 0x31, 0x23, 0xF3,
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001222 };
1223
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001224 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001225
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001226 if (upd_loc_skip > 0) {
1227 upd_loc_skip -= 1;
1228 return -EAGAIN;
1229 }
1230
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001231 /* Fake an UpdateLocRes */
1232 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1233};
1234
1235
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001236static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001237{
1238 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1239 struct gsm_subscriber *subscr;
1240
1241 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1242 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1243 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001244 if (retry) {
1245 upd_loc_skip = 3;
1246 auth_info_skip = 3;
1247 }
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001248
1249 subscr = gprs_subscr_get_or_create("123456789012345");
1250 subscr->authorized = 1;
1251 sgsn->cfg.require_authentication = 1;
1252 sgsn->cfg.require_update_location = 1;
1253 subscr_put(subscr);
1254
1255 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001256 test_gmm_attach(retry);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001257 assert_no_subscrs();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001258
1259 sgsn->cfg.auth_policy = saved_auth_policy;
1260 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1261 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001262 upd_loc_skip = 0;
1263 auth_info_skip = 0;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001264
1265 cleanup_test();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001266}
1267
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001268int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1269{
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001270 struct gprs_gsup_message to_peer = {0};
1271 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001272 struct msgb *reply_msg;
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001273 int rc;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001274
1275 /* Simulate the GSUP peer */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001276 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1277 OSMO_ASSERT(rc >= 0);
1278 OSMO_ASSERT(to_peer.imsi[0] != 0);
1279 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001280
1281 /* This invalidates the pointers in to_peer */
1282 msgb_free(msg);
1283
1284 switch (to_peer.message_type) {
1285 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1286 /* Send UPDATE_LOCATION_RESULT */
1287 return my_subscr_request_update_gsup_auth(NULL);
1288
1289 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1290 /* Send SEND_AUTH_INFO_RESULT */
1291 return my_subscr_request_auth_info_gsup_auth(NULL);
1292
1293 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001294 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1295 break;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001296
1297 default:
1298 if ((to_peer.message_type & 0b00000011) == 0) {
1299 /* Unhandled request */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001300 /* Send error(NOT_IMPL) */
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001301 from_peer.message_type = to_peer.message_type + 1;
1302 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1303 break;
1304 }
1305
1306 /* Ignore it */
1307 return 0;
1308 }
1309
1310 reply_msg = gprs_gsup_msgb_alloc();
1311 reply_msg->l2h = reply_msg->data;
1312 gprs_gsup_encode(reply_msg, &from_peer);
1313 gprs_subscr_rx_gsup_message(reply_msg);
1314 msgb_free(reply_msg);
1315
1316 return 0;
1317};
1318
1319static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1320{
1321 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1322 struct gsm_subscriber *subscr;
1323
1324 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001325 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1326
1327 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1328
1329 if (retry) {
1330 upd_loc_skip = 3;
1331 auth_info_skip = 3;
1332 }
1333
1334 printf("Auth policy 'remote', real GSUP based auth: ");
1335 test_gmm_attach(retry);
1336
1337 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001338 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001339 assert_no_subscrs();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001340
1341 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001342 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1343 upd_loc_skip = 0;
1344 auth_info_skip = 0;
1345 talloc_free(sgsn->gsup_client);
1346 sgsn->gsup_client = NULL;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001347
1348 cleanup_test();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001349}
1350
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001351/*
1352 * Test the GMM Rejects
1353 */
1354static void test_gmm_reject(void)
1355{
1356 struct gprs_ra_id raid = { 0, };
1357 struct sgsn_mm_ctx *ctx = NULL;
1358 uint32_t foreign_tlli;
1359 struct gprs_llc_lle *lle;
1360 int idx;
1361
1362 /* DTAP - Attach Request */
1363 /* Invalid MI length */
1364 static const unsigned char attach_req_inv_mi_len[] = {
1365 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1366 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1367 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1368 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1369 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1370 };
1371
1372 /* DTAP - Attach Request */
1373 /* Invalid MI type (IMEI) */
1374 static const unsigned char attach_req_inv_mi_type[] = {
1375 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1376 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1377 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1378 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1379 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1380 };
1381
1382 /* DTAP - Routing Area Update Request */
1383 static const unsigned char dtap_ra_upd_req[] = {
1384 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1385 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1386 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1387 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1388 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1389 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1390 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1391 };
1392
1393 /* DTAP - Routing Area Update Request */
1394 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1395 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1396 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1397 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1398 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1399 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1400 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1401 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1402 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1403 };
1404
1405 /* DTAP - Routing Area Update Request */
1406 /* Invalid cap length */
1407 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1408 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1409 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1410 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1411 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1412 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1413 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1414 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1415 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1416 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1417 };
1418
1419 struct test {
1420 const char *title;
1421 const unsigned char *msg;
1422 unsigned msg_len;
1423 unsigned num_resp;
1424
1425 };
1426 static struct test tests[] = {
1427 {
1428 .title = "Attach Request (invalid MI length)",
1429 .msg = attach_req_inv_mi_len,
1430 .msg_len = sizeof(attach_req_inv_mi_len),
1431 .num_resp = 1 /* Reject */
1432
1433 },
1434 {
1435 .title = "Attach Request (invalid MI type)",
1436 .msg = attach_req_inv_mi_type,
1437 .msg_len = sizeof(attach_req_inv_mi_type),
1438 .num_resp = 1 /* Reject */
1439 },
1440 {
1441 .title = "Routing Area Update Request (valid)",
1442 .msg = dtap_ra_upd_req,
1443 .msg_len = sizeof(dtap_ra_upd_req),
1444 .num_resp = 2 /* XID Reset + Reject */
1445 },
1446 {
1447 .title = "Routing Area Update Request (invalid type)",
1448 .msg = dtap_ra_upd_req_inv_type,
1449 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1450 .num_resp = 1 /* Reject */
1451 },
1452 {
1453 .title = "Routing Area Update Request (invalid CAP length)",
1454 .msg = dtap_ra_upd_req_inv_cap_len,
1455 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1456 .num_resp = 1 /* Reject */
1457 },
1458 };
1459
1460 printf("Testing GMM reject\n");
1461
1462 /* reset the PRNG used by sgsn_alloc_ptmsi */
1463 srand(1);
1464
1465 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1466
1467 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1468
1469 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1470 const struct test *test = &tests[idx];
1471 printf(" - %s\n", test->title);
1472
1473 /* Create a LLE/LLME */
1474 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1475 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1476
1477 /* Inject the Request message */
1478 send_0408_message(lle->llme, foreign_tlli,
1479 test->msg, test->msg_len);
1480
1481 /* We expect a Reject message */
1482 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1483 sgsn_tx_counter, test->num_resp);
1484 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1485
1486 /* verify that LLME/MM are removed */
1487 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1488 OSMO_ASSERT(ctx == NULL);
1489 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1490 }
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001491
1492 cleanup_test();
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001493}
1494
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001495/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001496 * Test cancellation of attached MM contexts
1497 */
1498static void test_gmm_cancel(void)
1499{
1500 struct gprs_ra_id raid = { 0, };
1501 struct sgsn_mm_ctx *ctx = NULL;
1502 struct sgsn_mm_ctx *ictx;
1503 uint32_t ptmsi1;
1504 uint32_t foreign_tlli;
1505 uint32_t local_tlli = 0;
1506 struct gprs_llc_lle *lle;
1507 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1508
1509 /* DTAP - Attach Request */
1510 /* The P-TMSI is not known by the SGSN */
1511 static const unsigned char attach_req[] = {
1512 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1513 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1514 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1515 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1516 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1517 };
1518
1519 /* DTAP - Identity Response IMEI */
1520 static const unsigned char ident_resp_imei[] = {
1521 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1522 0x56
1523 };
1524
1525 /* DTAP - Identity Response IMSI */
1526 static const unsigned char ident_resp_imsi[] = {
1527 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1528 0x54
1529 };
1530
1531 /* DTAP - Attach Complete */
1532 static const unsigned char attach_compl[] = {
1533 0x08, 0x03
1534 };
1535
1536 printf("Testing cancellation\n");
1537
1538 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1539
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001540 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1541
1542 /* Create a LLE/LLME */
1543 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1544 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1545 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1546
1547 /* inject the attach request */
1548 send_0408_message(lle->llme, foreign_tlli,
1549 attach_req, ARRAY_SIZE(attach_req));
1550
1551 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1552 OSMO_ASSERT(ctx != NULL);
1553 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1554
1555 /* we expect an identity request (IMEI) */
1556 OSMO_ASSERT(sgsn_tx_counter == 1);
1557
1558 /* inject the identity response (IMEI) */
1559 send_0408_message(ctx->llme, foreign_tlli,
1560 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1561
1562 /* we expect an identity request (IMSI) */
1563 OSMO_ASSERT(sgsn_tx_counter == 1);
1564
1565 /* inject the identity response (IMSI) */
1566 send_0408_message(ctx->llme, foreign_tlli,
1567 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1568
1569 /* check that the MM context has not been removed due to a failed
1570 * authorization */
1571 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1572
1573 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1574
1575 /* we expect an attach accept/reject */
1576 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001577 ptmsi1 = get_new_ptmsi(&last_dl_parse_ctx);
1578 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001579
1580 /* this has been randomly assigned by the SGSN */
1581 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1582
1583 /* inject the attach complete */
1584 send_0408_message(ctx->llme, local_tlli,
1585 attach_compl, ARRAY_SIZE(attach_compl));
1586
1587 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1588
1589 /* we don't expect a response */
1590 OSMO_ASSERT(sgsn_tx_counter == 0);
1591
1592 /* cancel */
Jacob Erlbeck41010082015-01-05 17:51:17 +01001593 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001594
1595 /* verify that things are gone */
1596 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1597 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1598 OSMO_ASSERT(!ictx);
1599
1600 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001601
1602 cleanup_test();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001603}
1604
1605/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001606 * Test the dynamic allocation of P-TMSIs
1607 */
1608static void test_gmm_ptmsi_allocation(void)
1609{
1610 struct gprs_ra_id raid = { 0, };
1611 struct sgsn_mm_ctx *ctx = NULL;
1612 struct sgsn_mm_ctx *ictx;
1613 uint32_t foreign_tlli;
1614 uint32_t ptmsi1;
1615 uint32_t ptmsi2;
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001616 uint32_t received_ptmsi;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001617 uint32_t old_ptmsi;
1618 uint32_t local_tlli = 0;
1619 struct gprs_llc_lle *lle;
1620 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1621
1622 /* DTAP - Attach Request (IMSI 12131415161718) */
1623 static const unsigned char attach_req[] = {
1624 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1625 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1626 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1627 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1628 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1629 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1630 0x00,
1631 };
1632
1633 /* DTAP - Identity Response IMEI */
1634 static const unsigned char ident_resp_imei[] = {
1635 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1636 0x56
1637 };
1638
1639 /* DTAP - Attach Complete */
1640 static const unsigned char attach_compl[] = {
1641 0x08, 0x03
1642 };
1643
1644 /* DTAP - Routing Area Update Request */
1645 static const unsigned char ra_upd_req[] = {
1646 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1647 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1648 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1649 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1650 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1651 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1652 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1653 };
1654
1655 /* DTAP - Routing Area Update Complete */
1656 static const unsigned char ra_upd_complete[] = {
1657 0x08, 0x0a
1658 };
1659
1660 /* DTAP - Detach Request (MO) */
1661 /* normal detach, power_off = 1 */
1662 static const unsigned char detach_req[] = {
1663 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1664 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1665 };
1666
1667 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1668
1669 printf("Testing P-TMSI allocation\n");
1670
1671 printf(" - sgsn_alloc_ptmsi\n");
1672
1673 /* reset the PRNG used by sgsn_alloc_ptmsi */
1674 srand(1);
1675
1676 ptmsi1 = sgsn_alloc_ptmsi();
1677 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1678
1679 ptmsi2 = sgsn_alloc_ptmsi();
1680 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1681
1682 OSMO_ASSERT(ptmsi1 != ptmsi2);
1683
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001684 ptmsi1 = ptmsi2 = GSM_RESERVED_TMSI;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001685
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001686 printf(" - Repeated Attach Request\n");
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001687
1688 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1689
1690 /* Create a LLE/LLME */
1691 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1692 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1693 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1694
1695 /* inject the attach request */
1696 send_0408_message(lle->llme, foreign_tlli,
1697 attach_req, ARRAY_SIZE(attach_req));
1698
1699 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1700 OSMO_ASSERT(ctx != NULL);
1701 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001702 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1703 ptmsi1 = ctx->p_tmsi;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001704
1705 old_ptmsi = ctx->p_tmsi_old;
1706
1707 /* we expect an identity request (IMEI) */
1708 OSMO_ASSERT(sgsn_tx_counter == 1);
1709
1710 /* inject the identity response (IMEI) */
1711 send_0408_message(ctx->llme, foreign_tlli,
1712 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1713
1714 /* check that the MM context has not been removed due to a failed
1715 * authorization */
1716 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1717
1718 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1719 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1720
1721 /* we expect an attach accept */
1722 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001723 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1724 OSMO_ASSERT(received_ptmsi == ptmsi1);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001725
1726 /* we ignore this and send the attach again */
1727 send_0408_message(lle->llme, foreign_tlli,
1728 attach_req, ARRAY_SIZE(attach_req));
1729
1730 /* the allocated P-TMSI should be the same */
1731 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1732 OSMO_ASSERT(ctx != NULL);
1733 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1734 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1735 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1736
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001737 /* we expect an attach accept */
1738 OSMO_ASSERT(sgsn_tx_counter == 1);
1739 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1740 OSMO_ASSERT(received_ptmsi == ptmsi1);
1741
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001742 /* inject the attach complete */
1743 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1744 send_0408_message(ctx->llme, local_tlli,
1745 attach_compl, ARRAY_SIZE(attach_compl));
1746
1747 /* we don't expect a response */
1748 OSMO_ASSERT(sgsn_tx_counter == 0);
1749
1750 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1751 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1752 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1753
1754 printf(" - Repeated RA Update Request\n");
1755
1756 /* inject the RA update request */
1757 send_0408_message(ctx->llme, local_tlli,
1758 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1759
1760 /* we expect an RA update accept */
1761 OSMO_ASSERT(sgsn_tx_counter == 1);
1762
1763 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1764 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001765 OSMO_ASSERT(ctx->p_tmsi != GSM_RESERVED_TMSI);
1766 OSMO_ASSERT(ctx->p_tmsi != ptmsi1);
1767 ptmsi2 = ctx->p_tmsi;
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001768
1769 /* repeat the RA update request */
1770 send_0408_message(ctx->llme, local_tlli,
1771 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1772
1773 /* we expect an RA update accept */
1774 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck28c28f92015-10-12 19:36:32 +02001775 received_ptmsi = get_new_ptmsi(&last_dl_parse_ctx);
1776 OSMO_ASSERT(received_ptmsi == ptmsi2);
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001777
1778 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1779 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1780 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1781
1782 /* inject the RA update complete */
1783 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1784 send_0408_message(ctx->llme, local_tlli,
1785 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1786
1787 /* we don't expect a response */
1788 OSMO_ASSERT(sgsn_tx_counter == 0);
1789
1790 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1791 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1792 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1793
1794 /* inject the detach */
1795 send_0408_message(ctx->llme, local_tlli,
1796 detach_req, ARRAY_SIZE(detach_req));
1797
1798 /* verify that things are gone */
1799 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1800 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1801 OSMO_ASSERT(!ictx);
1802
1803 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001804
1805 cleanup_test();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001806}
1807
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01001808static void test_apn_matching(void)
1809{
1810 struct apn_ctx *actx, *actxs[9];
1811
1812 printf("Testing APN matching\n");
1813
1814 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
1815 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
1816 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
1817 actxs[3] = NULL;
1818
1819 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
1820 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
1821 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
1822 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
1823
1824 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
1825
1826 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1827 OSMO_ASSERT(actx == actxs[2]);
1828 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
1829 OSMO_ASSERT(actx == actxs[2]);
1830 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
1831 OSMO_ASSERT(actx == actxs[1]);
1832 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
1833 OSMO_ASSERT(actx == actxs[1]);
1834 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
1835 OSMO_ASSERT(actx == actxs[0]);
1836 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1837 OSMO_ASSERT(actx == NULL);
1838
1839 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
1840 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1841 OSMO_ASSERT(actx == actxs[3]);
1842
1843 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
1844 OSMO_ASSERT(actx == actxs[4]);
1845
1846 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
1847 OSMO_ASSERT(actx == actxs[6]);
1848
1849 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1850 OSMO_ASSERT(actx == actxs[5]);
1851
1852 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
1853 OSMO_ASSERT(actx == actxs[7]);
1854
1855 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
1856 OSMO_ASSERT(actx == actxs[8]);
1857
1858 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1859 OSMO_ASSERT(actx == actxs[7]);
1860
1861 /* Free APN contexts and check how the matching changes */
1862
1863 sgsn_apn_ctx_free(actxs[7]);
1864 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1865 OSMO_ASSERT(actx == actxs[8]);
1866
1867 sgsn_apn_ctx_free(actxs[8]);
1868 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1869 OSMO_ASSERT(actx == actxs[6]);
1870
1871 sgsn_apn_ctx_free(actxs[6]);
1872 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1873 OSMO_ASSERT(actx == actxs[1]);
1874
1875 sgsn_apn_ctx_free(actxs[5]);
1876 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1877 OSMO_ASSERT(actx == actxs[4]);
1878
1879 sgsn_apn_ctx_free(actxs[4]);
1880 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1881 OSMO_ASSERT(actx == actxs[2]);
1882
1883 sgsn_apn_ctx_free(actxs[2]);
1884 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1885 OSMO_ASSERT(actx == actxs[1]);
1886
1887 sgsn_apn_ctx_free(actxs[1]);
1888 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1889 OSMO_ASSERT(actx == actxs[0]);
1890
1891 sgsn_apn_ctx_free(actxs[0]);
1892 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1893 OSMO_ASSERT(actx == actxs[3]);
1894
1895 sgsn_apn_ctx_free(actxs[3]);
1896 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1897 OSMO_ASSERT(actx == NULL);
Jacob Erlbeck515fc332015-10-12 19:36:31 +02001898
1899 cleanup_test();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01001900}
1901
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001902struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
1903 struct sgsn_subscriber_data *sdata);
1904
1905static void test_ggsn_selection(void)
1906{
1907 struct apn_ctx *actxs[4];
1908 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
1909 struct gsm_subscriber *s1;
1910 const char *imsi1 = "1234567890";
1911 struct sgsn_mm_ctx *ctx;
1912 struct gprs_ra_id raid = { 0, };
1913 uint32_t local_tlli = 0xffeeddcc;
1914 enum gsm48_gsm_cause gsm_cause;
1915 struct tlv_parsed tp;
1916 uint8_t apn_enc[GSM_APN_LENGTH + 10];
1917 struct sgsn_subscriber_pdp_data *pdp_data;
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001918 char apn_str[GSM_APN_LENGTH];
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001919
1920 printf("Testing GGSN selection\n");
1921
1922 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
1923
1924 /* Check for emptiness */
1925 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
1926
1927 /* Create a context */
1928 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1929 ctx = alloc_mm_ctx(local_tlli, &raid);
1930 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
1931
1932 /* Allocate and attach a subscriber */
1933 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
1934 assert_subscr(s1, imsi1);
1935
1936 tp.lv[GSM48_IE_GSM_APN].len = 0;
1937 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1938
1939 /* TODO: Add PDP info entries to s1 */
1940
1941 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
1942 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
1943 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
1944
1945 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
1946 actxs[0]->ggsn = ggcs[0];
1947 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
1948 actxs[1]->ggsn = ggcs[1];
1949 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
1950 actxs[2]->ggsn = ggcs[2];
1951
Holger Hans Peter Freytherab9422e2015-05-24 20:51:17 +08001952 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
1953 pdp_data->context_id = 1;
1954 pdp_data->pdp_type = 0x0121;
1955 strncpy(pdp_data->apn_str, "*", sizeof(pdp_data->apn_str)-1);
1956
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001957 /* Resolve GGSNs */
1958
1959 tp.lv[GSM48_IE_GSM_APN].len =
1960 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
1961
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001962 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001963 OSMO_ASSERT(ggc != NULL);
1964 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001965 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001966
1967 tp.lv[GSM48_IE_GSM_APN].len =
1968 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
1969
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001970 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001971 OSMO_ASSERT(ggc != NULL);
1972 OSMO_ASSERT(ggc->id == 1);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001973 OSMO_ASSERT(strcmp(apn_str, "Other.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001974
1975 tp.lv[GSM48_IE_GSM_APN].len = 0;
1976 tp.lv[GSM48_IE_GSM_APN].val = NULL;
1977
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001978 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001979 OSMO_ASSERT(ggc != NULL);
1980 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001981 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001982
1983 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
1984 actxs[3]->ggsn = ggcs[2];
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001985 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001986 OSMO_ASSERT(ggc != NULL);
1987 OSMO_ASSERT(ggc->id == 2);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001988 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001989
1990 sgsn_apn_ctx_free(actxs[3]);
1991 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1992
1993 tp.lv[GSM48_IE_GSM_APN].len =
1994 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
1995
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001996 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01001997 OSMO_ASSERT(ggc == NULL);
1998 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08001999 OSMO_ASSERT(strcmp(apn_str, "Foo.Bar") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002000
2001 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002002 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002003 OSMO_ASSERT(ggc == NULL);
2004 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
2005
2006 /* Add PDP data entry to subscriber */
2007
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002008 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
2009
2010 tp.lv[GSM48_IE_GSM_APN].len =
2011 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
2012
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002013 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002014 OSMO_ASSERT(ggc != NULL);
2015 OSMO_ASSERT(ggc->id == 0);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002016 OSMO_ASSERT(strcmp(apn_str, "Test.Apn") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002017
2018 tp.lv[GSM48_IE_GSM_APN].len =
2019 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
2020
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002021 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause, apn_str);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002022 OSMO_ASSERT(ggc == NULL);
2023 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
Holger Hans Peter Freyther2b1d49a2015-05-25 12:26:49 +08002024 OSMO_ASSERT(strcmp(apn_str, "") == 0);
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002025
2026 /* Cleanup */
2027
2028 subscr_put(s1);
2029 sgsn_mm_ctx_cleanup_free(ctx);
2030
2031 assert_no_subscrs();
2032
2033 sgsn_apn_ctx_free(actxs[0]);
2034 sgsn_apn_ctx_free(actxs[1]);
2035 sgsn_apn_ctx_free(actxs[2]);
2036
2037 sgsn_ggsn_ctx_free(ggcs[0]);
2038 sgsn_ggsn_ctx_free(ggcs[1]);
2039 sgsn_ggsn_ctx_free(ggcs[2]);
2040
2041 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
Jacob Erlbeck515fc332015-10-12 19:36:31 +02002042
2043 cleanup_test();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002044}
2045
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002046static struct log_info_cat gprs_categories[] = {
2047 [DMM] = {
2048 .name = "DMM",
2049 .description = "Layer3 Mobility Management (MM)",
2050 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002051 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002052 },
2053 [DPAG] = {
2054 .name = "DPAG",
2055 .description = "Paging Subsystem",
2056 .color = "\033[1;38m",
2057 .enabled = 1, .loglevel = LOGL_NOTICE,
2058 },
2059 [DMEAS] = {
2060 .name = "DMEAS",
2061 .description = "Radio Measurement Processing",
2062 .enabled = 0, .loglevel = LOGL_NOTICE,
2063 },
2064 [DREF] = {
2065 .name = "DREF",
2066 .description = "Reference Counting",
2067 .enabled = 0, .loglevel = LOGL_NOTICE,
2068 },
2069 [DGPRS] = {
2070 .name = "DGPRS",
2071 .description = "GPRS Packet Service",
2072 .enabled = 1, .loglevel = LOGL_DEBUG,
2073 },
2074 [DNS] = {
2075 .name = "DNS",
2076 .description = "GPRS Network Service (NS)",
2077 .enabled = 1, .loglevel = LOGL_INFO,
2078 },
2079 [DBSSGP] = {
2080 .name = "DBSSGP",
2081 .description = "GPRS BSS Gateway Protocol (BSSGP)",
2082 .enabled = 1, .loglevel = LOGL_DEBUG,
2083 },
2084 [DLLC] = {
2085 .name = "DLLC",
2086 .description = "GPRS Logical Link Control Protocol (LLC)",
2087 .enabled = 1, .loglevel = LOGL_DEBUG,
2088 },
2089 [DSNDCP] = {
2090 .name = "DSNDCP",
2091 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
2092 .enabled = 1, .loglevel = LOGL_DEBUG,
2093 },
2094};
2095
2096static struct log_info info = {
2097 .cat = gprs_categories,
2098 .num_cat = ARRAY_SIZE(gprs_categories),
2099};
2100
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002101int main(int argc, char **argv)
2102{
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002103 void *osmo_sgsn_ctx;
2104
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002105 osmo_init_logging(&info);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002106 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
2107 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
2108 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002109
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01002110 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002111 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01002112
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002113 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01002114 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01002115 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01002116 test_subscriber_gsup();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02002117 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01002118 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02002119 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01002120 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01002121 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01002122 test_gmm_attach_acl();
2123 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01002124 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01002125 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01002126 test_gmm_attach_subscr_gsup_auth(0);
2127 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01002128 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01002129 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01002130 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01002131 test_gmm_ptmsi_allocation();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01002132 test_apn_matching();
Jacob Erlbeck3400f112015-02-02 18:03:05 +01002133 test_ggsn_selection();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002134 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01002135
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002136 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01002137 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01002138 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02002139 return 0;
2140}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02002141
2142
2143/* stubs */
2144struct osmo_prim_hdr;
2145int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2146{
2147 abort();
2148}