blob: 25e031014aae3018bf6e0db757365c10b10d4a9e [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>
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020029
Jacob Erlbeck189999d2014-10-27 14:34:13 +010030#include <osmocom/gprs/gprs_bssgp.h>
31
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020032#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeckbce20612015-01-05 18:57:32 +010033#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020034
35#include <osmocom/core/application.h>
36#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010037#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020038
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020039#include <stdio.h>
40
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020041extern void *tall_msgb_ctx;
42
43void *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;
53
54/* override */
55int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
56 struct bssgp_dl_ud_par *dup)
57{
58 sgsn_tx_counter += 1;
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +010059 msgb_free(msg);
Jacob Erlbeck189999d2014-10-27 14:34:13 +010060 return 0;
61}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020062
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010063/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010064void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
65void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010066 &__real_sgsn_update_subscriber_data;
67
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010068void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010069{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010070 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010071}
72
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010073/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
74int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
75int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
76 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010077
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010078int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
79 return (*subscr_request_update_location_cb)(mmctx);
80};
81
82/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
83int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
84int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
85 &__real_gprs_subscr_request_auth_info;
86
87int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
88 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010089};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010090
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010091/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
92int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
93int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
94 &__real_gprs_gsup_client_send;
95
96int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
97{
98 return (*gprs_gsup_client_send_cb)(gsupc, msg);
99};
100
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200101static int count(struct llist_head *head)
102{
103 struct llist_head *cur;
104 int count = 0;
105
106 llist_for_each(cur, head)
107 count += 1;
108
109 return count;
110}
111
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200112static struct msgb *create_msg(const uint8_t *data, size_t len)
113{
114 struct msgb *msg = msgb_alloc(len + 8, "test message");
115 msg->l1h = msgb_put(msg, 8);
116 msg->l2h = msgb_put(msg, len);
117 memcpy(msg->l2h, data, len);
118
119 msgb_bcid(msg) = msg->l1h;
120 msgb_gmmh(msg) = msg->l2h;
121 return msg;
122}
123
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100124/*
125 * Create a context and search for it
126 */
127static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
128{
129 struct sgsn_mm_ctx *ctx, *ictx;
130 struct gprs_llc_lle *lle;
131 int old_count = count(gprs_llme_list());
132
133 lle = gprs_lle_get_or_create(tlli, 3);
134 ctx = sgsn_mm_ctx_alloc(tlli, raid);
135 ctx->mm_state = GMM_REGISTERED_NORMAL;
136 ctx->llme = lle->llme;
137
138 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
139 OSMO_ASSERT(ictx == ctx);
140
141 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
142
143 return ctx;
144}
145
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100146static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
147 const uint8_t *data, size_t data_len)
148{
149 struct msgb *msg;
150
151 sgsn_tx_counter = 0;
152
153 msg = create_msg(data, data_len);
154 msgb_tlli(msg) = tlli;
155 gsm0408_gprs_rcvmsg(msg, llme);
156 msgb_free(msg);
157}
158
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200159static void test_llme(void)
160{
161 struct gprs_llc_lle *lle, *lle_copy;
162 uint32_t local_tlli;
163 uint32_t foreign_tlli;
164
165 printf("Testing LLME allocations\n");
166 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
167 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
168
169 /* initial state */
170 OSMO_ASSERT(count(gprs_llme_list()) == 0);
171
172 /* Create a new entry */
173 lle = gprs_lle_get_or_create(local_tlli, 3);
174 OSMO_ASSERT(lle);
175 OSMO_ASSERT(count(gprs_llme_list()) == 1);
176
177 /* No new entry is created */
178 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
179 OSMO_ASSERT(lle == lle_copy);
180 OSMO_ASSERT(count(gprs_llme_list()) == 1);
181 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
182 OSMO_ASSERT(lle == lle_copy);
183 OSMO_ASSERT(count(gprs_llme_list()) == 1);
184
185 /* unassign which should delete it*/
186 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
187
188 /* Check that everything was cleaned up */
189 OSMO_ASSERT(count(gprs_llme_list()) == 0);
190}
191
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100192struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100193void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100194{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100195 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100196 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100197 __func__, mmctx, mmctx->subscr);
198 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100199}
200
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100201static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
202{
203 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100204 OSMO_ASSERT(subscr);
205 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100206
207 sfound = gprs_subscr_get_by_imsi(imsi);
208 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100209
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100210 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100211}
212
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100213static void show_subscrs(FILE *out)
214{
215 struct gsm_subscriber *subscr;
216
217 llist_for_each_entry(subscr, &active_subscribers, entry) {
218 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100219 "use count: %d\n",
220 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100221 }
222}
223
224static void assert_no_subscrs()
225{
226 show_subscrs(stdout);
227 fflush(stdout);
228 OSMO_ASSERT(llist_empty(&active_subscribers));
229}
230
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100231static void test_subscriber(void)
232{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100233 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100234 const char *imsi1 = "1234567890";
235 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100236 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100237
238 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
239
240 printf("Testing core subscriber data API\n");
241
242 /* Check for emptiness */
243 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
244 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100245 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100246
247 /* Allocate entry 1 */
248 s1 = gprs_subscr_get_or_create(imsi1);
249 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100250 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100251 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100252
253 /* Allocate entry 2 */
254 s2 = gprs_subscr_get_or_create(imsi2);
255 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100256
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100257 /* Allocate entry 3 */
258 s3 = gprs_subscr_get_or_create(imsi3);
259
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100260 /* Check entries */
261 assert_subscr(s1, imsi1);
262 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100263 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100264
265 /* Update entry 1 */
266 last_updated_subscr = NULL;
267 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100268 OSMO_ASSERT(last_updated_subscr == NULL);
269 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
270 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100271
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100272 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100273 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100274 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100275 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100276 sfound = gprs_subscr_get_by_imsi(imsi1);
277 OSMO_ASSERT(sfound == NULL);
278
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100279 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100280 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100281
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100282 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100283 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100284 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100285 s2 = NULL;
286 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
287 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100288 assert_subscr(s3, imsi3);
289
290 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100291 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100292 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100293 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100294 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100295
296 OSMO_ASSERT(llist_empty(&active_subscribers));
297
298 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
299}
300
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100301static void test_auth_triplets(void)
302{
303 struct gsm_subscriber *s1, *s1found;
304 const char *imsi1 = "1234567890";
305 struct gsm_auth_tuple *at;
306 struct sgsn_mm_ctx *ctx;
307 struct gprs_ra_id raid = { 0, };
308 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100309
310 printf("Testing authentication triplet handling\n");
311
312 /* Check for emptiness */
313 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
314
315 /* Allocate entry 1 */
316 s1 = gprs_subscr_get_or_create(imsi1);
317 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
318 s1found = gprs_subscr_get_by_imsi(imsi1);
319 OSMO_ASSERT(s1found == s1);
320 subscr_put(s1found);
321
322 /* Create a context */
323 OSMO_ASSERT(count(gprs_llme_list()) == 0);
324 ctx = alloc_mm_ctx(local_tlli, &raid);
325
326 /* Attach s1 to ctx */
327 ctx->subscr = subscr_get(s1);
328 ctx->subscr->sgsn_data->mm = ctx;
329
330 /* Try to get auth tuple */
331 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
332 OSMO_ASSERT(at == NULL);
333
334 /* Add triplets */
335 s1->sgsn_data->auth_triplets[0].key_seq = 0;
336 s1->sgsn_data->auth_triplets[1].key_seq = 1;
337 s1->sgsn_data->auth_triplets[2].key_seq = 2;
338
339 /* Try to get auth tuple */
340 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
341 OSMO_ASSERT(at != NULL);
342 OSMO_ASSERT(at->key_seq == 0);
343 OSMO_ASSERT(at->use_count == 1);
344 at = sgsn_auth_get_tuple(ctx, at->key_seq);
345 OSMO_ASSERT(at != NULL);
346 OSMO_ASSERT(at->key_seq == 1);
347 OSMO_ASSERT(at->use_count == 1);
348 at = sgsn_auth_get_tuple(ctx, at->key_seq);
349 OSMO_ASSERT(at != NULL);
350 OSMO_ASSERT(at->key_seq == 2);
351 OSMO_ASSERT(at->use_count == 1);
352 at = sgsn_auth_get_tuple(ctx, at->key_seq);
353 OSMO_ASSERT(at == NULL);
354
355 /* Free MM context and subscriber */
356 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100357 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100358 s1found = gprs_subscr_get_by_imsi(imsi1);
359 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100360}
361
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100362#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
363
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100364static int rx_gsup_message(const uint8_t *data, size_t data_len)
365{
366 struct msgb *msg;
367 int rc;
368
369 msg = msgb_alloc(1024, __func__);
370 msg->l2h = msgb_put(msg, data_len);
371 OSMO_ASSERT(msg->l2h != NULL);
372 memcpy(msg->l2h, data, data_len);
373 rc = gprs_subscr_rx_gsup_message(msg);
374 msgb_free(msg);
375
376 return rc;
377}
378
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100379static void test_subscriber_gsup(void)
380{
381 struct gsm_subscriber *s1, *s1found;
382 const char *imsi1 = "1234567890";
383 struct sgsn_mm_ctx *ctx;
384 struct gprs_ra_id raid = { 0, };
385 uint32_t local_tlli = 0xffeeddcc;
386 struct gprs_llc_llme *llme;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100387 int rc;
388
389 static const uint8_t send_auth_info_res[] = {
390 0x0a,
391 TEST_GSUP_IMSI1_IE,
392 0x03, 0x22, /* Auth tuple */
393 0x20, 0x10,
394 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
395 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
396 0x21, 0x04,
397 0x21, 0x22, 0x23, 0x24,
398 0x22, 0x08,
399 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
400 0x03, 0x22, /* Auth tuple */
401 0x20, 0x10,
402 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
403 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
404 0x21, 0x04,
405 0xa1, 0xa2, 0xa3, 0xa4,
406 0x22, 0x08,
407 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
408 };
409
410 static const uint8_t send_auth_info_err[] = {
411 0x09,
412 TEST_GSUP_IMSI1_IE,
413 0x02, 0x01, 0x07 /* GPRS not allowed */
414 };
415
416 static const uint8_t update_location_res[] = {
417 0x06,
418 TEST_GSUP_IMSI1_IE,
419 0x04, 0x00, /* PDP info complete */
420 0x05, 0x12,
421 0x10, 0x01, 0x01,
422 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
423 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
424 0x05, 0x11,
425 0x10, 0x01, 0x02,
426 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
427 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
428 };
429
430 static const uint8_t update_location_err[] = {
431 0x05,
432 TEST_GSUP_IMSI1_IE,
433 0x02, 0x01, 0x07 /* GPRS not allowed */
434 };
435
436 static const uint8_t location_cancellation_req[] = {
437 0x1c,
438 TEST_GSUP_IMSI1_IE,
439 0x06, 0x01, 0x00,
440 };
441
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100442 static const uint8_t location_cancellation_req_other[] = {
443 0x1c,
444 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
445 0x06, 0x01, 0x00,
446 };
447
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100448 static const uint8_t purge_ms_err[] = {
449 0x0d,
450 TEST_GSUP_IMSI1_IE,
451 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
452 };
453
454 static const uint8_t purge_ms_res[] = {
455 0x0e,
456 TEST_GSUP_IMSI1_IE,
457 0x07, 0x00,
458 };
459
460
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100461 static const uint8_t insert_data_req[] = {
462 0x10,
463 TEST_GSUP_IMSI1_IE,
464 0x05, 0x11,
465 0x10, 0x01, 0x03,
466 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
467 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
468 };
469
470 static const uint8_t delete_data_req[] = {
471 0x14,
472 TEST_GSUP_IMSI1_IE,
473 0x10, 0x01, 0x03,
474 };
475
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100476 printf("Testing subcriber GSUP handling\n");
477
478 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
479
480 /* Check for emptiness */
481 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
482
483 /* Allocate entry 1 */
484 s1 = gprs_subscr_get_or_create(imsi1);
485 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
486 s1found = gprs_subscr_get_by_imsi(imsi1);
487 OSMO_ASSERT(s1found == s1);
488 subscr_put(s1found);
489
490 /* Create a context */
491 OSMO_ASSERT(count(gprs_llme_list()) == 0);
492 ctx = alloc_mm_ctx(local_tlli, &raid);
493 llme = ctx->llme;
494
495 /* Attach s1 to ctx */
496 ctx->subscr = subscr_get(s1);
497 ctx->subscr->sgsn_data->mm = ctx;
498
499 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100500 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100501 OSMO_ASSERT(rc >= 0);
502 OSMO_ASSERT(last_updated_subscr == s1);
503
504 /* Check triplets */
505 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
506 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
507 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
508
509 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100510 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100511 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100512 OSMO_ASSERT(last_updated_subscr == s1);
513
514 /* Check triplets */
515 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
516 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
517 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
518
519 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100520 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100521 OSMO_ASSERT(rc >= 0);
522 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100523 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100524
525 /* Check authorization */
526 OSMO_ASSERT(s1->authorized == 1);
527
528 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100529 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100530 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100531 OSMO_ASSERT(last_updated_subscr == s1);
532
533 /* Check authorization */
534 OSMO_ASSERT(s1->authorized == 0);
535
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100536 /* Inject InsertSubscrData GSUP message */
537 last_updated_subscr = NULL;
538 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
539 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
540 OSMO_ASSERT(last_updated_subscr == NULL);
541
542 /* Inject DeleteSubscrData GSUP message */
543 last_updated_subscr = NULL;
544 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
545 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
546 OSMO_ASSERT(last_updated_subscr == NULL);
547
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100548 /* Inject wrong LocCancelReq GSUP message */
549 last_updated_subscr = NULL;
550 rc = rx_gsup_message(location_cancellation_req_other,
551 sizeof(location_cancellation_req_other));
552 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
553 OSMO_ASSERT(last_updated_subscr == NULL);
554
555 /* Check cancellation result */
556 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
557 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
558
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100559 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100560 rc = rx_gsup_message(location_cancellation_req,
561 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100562 OSMO_ASSERT(rc >= 0);
563 OSMO_ASSERT(last_updated_subscr == s1);
564
565 /* Check cancellation result */
566 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
567 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
568
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100569 /* Inject PurgeMsRes GSUP message */
570 rc = rx_gsup_message(purge_ms_res,
571 sizeof(purge_ms_res));
572 OSMO_ASSERT(rc >= 0);
573 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
574
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100575 /* Free MM context and subscriber */
576 subscr_put(s1);
577 s1found = gprs_subscr_get_by_imsi(imsi1);
578 OSMO_ASSERT(s1found == NULL);
579 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
580
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100581 /* Inject PurgeMsRes GSUP message */
582 rc = rx_gsup_message(purge_ms_res,
583 sizeof(purge_ms_res));
584 OSMO_ASSERT(rc >= 0);
585
586 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
587 rc = rx_gsup_message(purge_ms_err,
588 sizeof(purge_ms_err));
589 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
590
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100591 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
592 last_updated_subscr = NULL;
593 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100594 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100595 OSMO_ASSERT(last_updated_subscr == NULL);
596
597 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
598 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
599 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
600 OSMO_ASSERT(last_updated_subscr == NULL);
601
602 /* Inject LocCancelReq GSUP message (unknown IMSI) */
603 rc = rx_gsup_message(location_cancellation_req,
604 sizeof(location_cancellation_req));
605 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
606 OSMO_ASSERT(last_updated_subscr == NULL);
607
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100608 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
609}
610
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100611int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
612{
613 msgb_free(msg);
614 return 0;
615};
616
617
618static void test_subscriber_blocking(void)
619{
620 struct gsm_subscriber *s1;
621 const char *imsi1 = "1234567890";
622 struct sgsn_mm_ctx *ctx;
623 struct gprs_ra_id raid = { 0, };
624 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100625 int rc;
626
627 printf("Testing subcriber procedure blocking\n");
628
629 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
630 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
631
632 /* Check for emptiness */
633 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
634
635 /* Create a context */
636 OSMO_ASSERT(count(gprs_llme_list()) == 0);
637 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100638 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
639
640 /* Allocate and attach a subscriber */
641 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
642 assert_subscr(s1, imsi1);
643
644 /* Start SendAuthInfoRequest procedure */
645 rc = gprs_subscr_query_auth_info(s1);
646 /* Not blocking */
647 OSMO_ASSERT(rc == 0);
648
649 /* Start UpdateLocation procedure */
650 rc = gprs_subscr_location_update(s1);
651 /* Blocking */
652 OSMO_ASSERT(rc == 0);
653
654 /* Start PurgeMS procedure */
655 rc = gprs_subscr_purge(s1);
656 /* Not blocking */
657 OSMO_ASSERT(rc == 0);
658 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
659
660 /* Start PurgeMS procedure (retry) */
661 rc = gprs_subscr_purge(s1);
662 /* Not blocking */
663 OSMO_ASSERT(rc == 0);
664
665 /* Start SendAuthInfoRequest procedure */
666 rc = gprs_subscr_query_auth_info(s1);
667 /* Blocking */
668 OSMO_ASSERT(rc == -EAGAIN);
669
670 /* Start UpdateLocation procedure */
671 rc = gprs_subscr_location_update(s1);
672 /* Blocking */
673 OSMO_ASSERT(rc == -EAGAIN);
674
675 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
676 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
677
678 /* Start SendAuthInfoRequest procedure */
679 rc = gprs_subscr_query_auth_info(s1);
680 /* Not blocking */
681 OSMO_ASSERT(rc == 0);
682
683 /* Start UpdateLocation procedure */
684 rc = gprs_subscr_location_update(s1);
685 /* Blocking */
686 OSMO_ASSERT(rc == 0);
687
688 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100689 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100690
691 assert_no_subscrs();
692
693 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
694 talloc_free(sgsn->gsup_client);
695 sgsn->gsup_client = NULL;
696}
697
698
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200699/*
700 * Test that a GMM Detach will remove the MMCTX and the
701 * associated LLME.
702 */
703static void test_gmm_detach(void)
704{
705 struct gprs_ra_id raid = { 0, };
706 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200707 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200708
709 printf("Testing GMM detach\n");
710
711 /* DTAP - Detach Request (MO) */
712 /* normal detach, power_off = 0 */
713 static const unsigned char detach_req[] = {
714 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
715 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
716 };
717
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200718 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200719
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100720 /* Create a context */
721 OSMO_ASSERT(count(gprs_llme_list()) == 0);
722 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200723
724 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100725 send_0408_message(ctx->llme, local_tlli,
726 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200727
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100728 /* verify that a single message (hopefully the Detach Accept) has been
729 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100730 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100731
732 /* verify that things are gone */
733 OSMO_ASSERT(count(gprs_llme_list()) == 0);
734 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
735 OSMO_ASSERT(!ictx);
736}
737
738/*
739 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
740 * will not sent a Detach Accept message (power_off = 1)
741 */
742static void test_gmm_detach_power_off(void)
743{
744 struct gprs_ra_id raid = { 0, };
745 struct sgsn_mm_ctx *ctx, *ictx;
746 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100747
748 printf("Testing GMM detach (power off)\n");
749
750 /* DTAP - Detach Request (MO) */
751 /* normal detach, power_off = 1 */
752 static const unsigned char detach_req[] = {
753 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
754 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
755 };
756
757 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
758
759 /* Create a context */
760 OSMO_ASSERT(count(gprs_llme_list()) == 0);
761 ctx = alloc_mm_ctx(local_tlli, &raid);
762
763 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100764 send_0408_message(ctx->llme, local_tlli,
765 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100766
767 /* verify that no message (and therefore no Detach Accept) has been
768 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100769 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100770
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200771 /* verify that things are gone */
772 OSMO_ASSERT(count(gprs_llme_list()) == 0);
773 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200774 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200775}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200776
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200777/*
778 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
779 */
780static void test_gmm_detach_no_mmctx(void)
781{
782 struct gprs_llc_lle *lle;
783 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200784
785 printf("Testing GMM detach (no MMCTX)\n");
786
787 /* DTAP - Detach Request (MO) */
788 /* normal detach, power_off = 0 */
789 static const unsigned char detach_req[] = {
790 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
791 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
792 };
793
794 /* Create an LLME */
795 OSMO_ASSERT(count(gprs_llme_list()) == 0);
796 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
797 lle = gprs_lle_get_or_create(local_tlli, 3);
798
799 OSMO_ASSERT(count(gprs_llme_list()) == 1);
800
801 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100802 send_0408_message(lle->llme, local_tlli,
803 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200804
805 /* verify that the LLME is gone */
806 OSMO_ASSERT(count(gprs_llme_list()) == 0);
807}
808
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100809/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100810 * Test that a single GMM Detach Accept message will not cause the SGSN to send
811 * any message or leave an MM context at the SGSN.
812 */
813static void test_gmm_detach_accept_unexpected(void)
814{
815 struct gprs_llc_lle *lle;
816 uint32_t local_tlli;
817
818 printf("Testing GMM detach accept (unexpected)\n");
819
820 /* DTAP - Detach Accept (MT) */
821 /* normal detach */
822 static const unsigned char detach_acc[] = {
823 0x08, 0x06
824 };
825
826 /* Create an LLME */
827 OSMO_ASSERT(count(gprs_llme_list()) == 0);
828 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
829 lle = gprs_lle_get_or_create(local_tlli, 3);
830
831 /* inject the detach */
832 send_0408_message(lle->llme, local_tlli,
833 detach_acc, ARRAY_SIZE(detach_acc));
834
835 /* verify that no message (and therefore no Status or XID reset) has been
836 * sent by the SGSN */
837 OSMO_ASSERT(sgsn_tx_counter == 0);
838
839 /* verify that things are gone */
840 OSMO_ASSERT(count(gprs_llme_list()) == 0);
841}
842
843/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100844 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
845 */
846static void test_gmm_status_no_mmctx(void)
847{
848 struct gprs_llc_lle *lle;
849 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100850
851 printf("Testing GMM Status (no MMCTX)\n");
852
853 /* DTAP - GMM Status, protocol error */
854 static const unsigned char gmm_status[] = {
855 0x08, 0x20, 0x6f
856 };
857
858 /* Create an LLME */
859 OSMO_ASSERT(count(gprs_llme_list()) == 0);
860 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
861 lle = gprs_lle_get_or_create(local_tlli, 3);
862
863 OSMO_ASSERT(count(gprs_llme_list()) == 1);
864
865 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100866 send_0408_message(lle->llme, local_tlli,
867 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100868
869 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100870 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100871
872 /* verify that the LLME is gone */
873 OSMO_ASSERT(count(gprs_llme_list()) == 0);
874}
875
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100876/*
877 * Test the GMM Attach procedure
878 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100879static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100880{
881 struct gprs_ra_id raid = { 0, };
882 struct sgsn_mm_ctx *ctx = NULL;
883 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100884 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100885 uint32_t foreign_tlli;
886 uint32_t local_tlli = 0;
887 struct gprs_llc_lle *lle;
888
889 /* DTAP - Attach Request */
890 /* The P-TMSI is not known by the SGSN */
891 static const unsigned char attach_req[] = {
892 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
893 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
894 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
895 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
896 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
897 };
898
899 /* DTAP - Identity Response IMEI */
900 static const unsigned char ident_resp_imei[] = {
901 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
902 0x56
903 };
904
905 /* DTAP - Identity Response IMSI */
906 static const unsigned char ident_resp_imsi[] = {
907 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
908 0x54
909 };
910
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100911 /* DTAP - Authentication and Ciphering Resp */
912 static const unsigned char auth_ciph_resp[] = {
913 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
914 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
915 };
916
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100917 /* DTAP - Attach Complete */
918 static const unsigned char attach_compl[] = {
919 0x08, 0x03
920 };
921
922 /* DTAP - Detach Request (MO) */
923 /* normal detach, power_off = 0 */
924 static const unsigned char detach_req[] = {
925 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
926 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
927 };
928
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100929 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100930
931 /* reset the PRNG used by sgsn_alloc_ptmsi */
932 srand(1);
933
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100934 ptmsi1 = sgsn_alloc_ptmsi();
935 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
936
937 /* reset the PRNG, so that the same P-TMSI sequence will be generated
938 * again */
939 srand(1);
940
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100941 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
942
943 /* Create a LLE/LLME */
944 OSMO_ASSERT(count(gprs_llme_list()) == 0);
945 lle = gprs_lle_get_or_create(foreign_tlli, 3);
946 OSMO_ASSERT(count(gprs_llme_list()) == 1);
947
948 /* inject the attach request */
949 send_0408_message(lle->llme, foreign_tlli,
950 attach_req, ARRAY_SIZE(attach_req));
951
952 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
953 OSMO_ASSERT(ctx != NULL);
954 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
955
956 /* we expect an identity request (IMEI) */
957 OSMO_ASSERT(sgsn_tx_counter == 1);
958
959 /* inject the identity response (IMEI) */
960 send_0408_message(ctx->llme, foreign_tlli,
961 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
962
963 /* we expect an identity request (IMSI) */
964 OSMO_ASSERT(sgsn_tx_counter == 1);
965
966 /* inject the identity response (IMSI) */
967 send_0408_message(ctx->llme, foreign_tlli,
968 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
969
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100970 /* check that the MM context has not been removed due to a failed
971 * authorization */
972 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
973
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100974 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100975
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100976retry_attach_req:
977
978 if (retry && sgsn_tx_counter == 0) {
979 fprintf(stderr, "Retrying attach request\n");
980 /* re-inject the attach request */
981 send_0408_message(lle->llme, foreign_tlli,
982 attach_req, ARRAY_SIZE(attach_req));
983 }
984
985 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
986 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100987
988 /* inject the auth & ciph response */
989 send_0408_message(ctx->llme, foreign_tlli,
990 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
991
992 /* check that the MM context has not been removed due to a
993 * failed authorization */
994 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
995 }
996
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100997 if (retry && sgsn_tx_counter == 0)
998 goto retry_attach_req;
999
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001000 /* we expect an attach accept/reject */
1001 OSMO_ASSERT(sgsn_tx_counter == 1);
1002
1003 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001004 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001005
1006 /* inject the attach complete */
1007 send_0408_message(ctx->llme, local_tlli,
1008 attach_compl, ARRAY_SIZE(attach_compl));
1009
1010 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1011
1012 /* we don't expect a response */
1013 OSMO_ASSERT(sgsn_tx_counter == 0);
1014
1015 /* inject the detach */
1016 send_0408_message(ctx->llme, local_tlli,
1017 detach_req, ARRAY_SIZE(detach_req));
1018
1019 /* verify that things are gone */
1020 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1021 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1022 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001023}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001024
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001025static void test_gmm_attach_acl(void)
1026{
1027 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1028
1029 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1030 sgsn_acl_add("123456789012345", &sgsn->cfg);
1031 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001032 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001033 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001034
1035 sgsn->cfg.auth_policy = saved_auth_policy;
1036}
1037
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001038int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001039 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001040 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001041 if (rc == -ENOTSUP) {
1042 OSMO_ASSERT(mmctx->subscr);
1043 gprs_subscr_update(mmctx->subscr);
1044 }
1045 return rc;
1046};
1047
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001048int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1049 gprs_subscr_update(mmctx->subscr);
1050 return 0;
1051};
1052
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001053static void test_gmm_attach_subscr(void)
1054{
1055 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1056 struct gsm_subscriber *subscr;
1057
1058 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001059 subscr_request_update_location_cb = my_subscr_request_update_location;
1060 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001061
1062 subscr = gprs_subscr_get_or_create("123456789012345");
1063 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001064
1065 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001066 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001067 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001068 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001069
1070 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001071 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1072 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001073}
1074
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001075int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1076{
1077 /* Fake an authentication */
1078 OSMO_ASSERT(mmctx->subscr);
1079 mmctx->is_authenticated = 1;
1080 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001081
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001082 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001083};
1084
1085static void test_gmm_attach_subscr_fake_auth(void)
1086{
1087 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1088 struct gsm_subscriber *subscr;
1089
1090 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001091 subscr_request_update_location_cb = my_subscr_request_update_location;
1092 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001093
1094 subscr = gprs_subscr_get_or_create("123456789012345");
1095 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001096 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001097 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001098
1099 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001100 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001101 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001102 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001103
1104 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001105 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1106 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1107}
1108
1109int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1110{
1111 struct gsm_auth_tuple at = {
1112 .sres = {0x51, 0xe5, 0x51, 0xe5},
1113 .key_seq = 0
1114 };
1115
1116 /* Fake an authentication */
1117 OSMO_ASSERT(mmctx->subscr);
1118 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1119
1120 gprs_subscr_update_auth_info(mmctx->subscr);
1121
1122 return 0;
1123};
1124
1125static void test_gmm_attach_subscr_real_auth(void)
1126{
1127 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1128 struct gsm_subscriber *subscr;
1129
1130 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1131 subscr_request_update_location_cb = my_subscr_request_update_location;
1132 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1133
1134 subscr = gprs_subscr_get_or_create("123456789012345");
1135 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001136 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001137 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001138
1139 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001140
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001141 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001142 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001143 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001144
1145 sgsn->cfg.auth_policy = saved_auth_policy;
1146 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1147 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001148}
1149
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001150#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1151 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1152
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001153static int auth_info_skip = 0;
1154static int upd_loc_skip = 0;
1155
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001156int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1157{
1158 static const uint8_t send_auth_info_res[] = {
1159 0x0a,
1160 TEST_GSUP_IMSI_LONG_IE,
1161 0x03, 0x22, /* Auth tuple */
1162 0x20, 0x10,
1163 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1164 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1165 0x21, 0x04,
1166 0x51, 0xe5, 0x51, 0xe5,
1167 0x22, 0x08,
1168 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1169 };
1170
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001171 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001172
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001173 if (auth_info_skip > 0) {
1174 auth_info_skip -= 1;
1175 return -EAGAIN;
1176 }
1177
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001178 /* Fake an SendAuthInfoRes */
1179 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1180
1181 return 0;
1182};
1183
1184int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1185 static const uint8_t update_location_res[] = {
1186 0x06,
1187 TEST_GSUP_IMSI_LONG_IE,
1188 0x04, 0x00, /* PDP info complete */
1189 0x05, 0x12,
1190 0x10, 0x01, 0x01,
1191 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1192 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1193 };
1194
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001195 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001196
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001197 if (upd_loc_skip > 0) {
1198 upd_loc_skip -= 1;
1199 return -EAGAIN;
1200 }
1201
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001202 /* Fake an UpdateLocRes */
1203 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1204};
1205
1206
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001207static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001208{
1209 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1210 struct gsm_subscriber *subscr;
1211
1212 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1213 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1214 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001215 if (retry) {
1216 upd_loc_skip = 3;
1217 auth_info_skip = 3;
1218 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001219
1220 subscr = gprs_subscr_get_or_create("123456789012345");
1221 subscr->authorized = 1;
1222 sgsn->cfg.require_authentication = 1;
1223 sgsn->cfg.require_update_location = 1;
1224 subscr_put(subscr);
1225
1226 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001227 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001228 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001229
1230 sgsn->cfg.auth_policy = saved_auth_policy;
1231 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1232 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001233 upd_loc_skip = 0;
1234 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001235}
1236
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001237int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1238{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001239 struct gprs_gsup_message to_peer = {0};
1240 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001241 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001242 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001243
1244 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001245 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1246 OSMO_ASSERT(rc >= 0);
1247 OSMO_ASSERT(to_peer.imsi[0] != 0);
1248 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001249
1250 /* This invalidates the pointers in to_peer */
1251 msgb_free(msg);
1252
1253 switch (to_peer.message_type) {
1254 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1255 /* Send UPDATE_LOCATION_RESULT */
1256 return my_subscr_request_update_gsup_auth(NULL);
1257
1258 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1259 /* Send SEND_AUTH_INFO_RESULT */
1260 return my_subscr_request_auth_info_gsup_auth(NULL);
1261
1262 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001263 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1264 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001265
1266 default:
1267 if ((to_peer.message_type & 0b00000011) == 0) {
1268 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001269 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001270 from_peer.message_type = to_peer.message_type + 1;
1271 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1272 break;
1273 }
1274
1275 /* Ignore it */
1276 return 0;
1277 }
1278
1279 reply_msg = gprs_gsup_msgb_alloc();
1280 reply_msg->l2h = reply_msg->data;
1281 gprs_gsup_encode(reply_msg, &from_peer);
1282 gprs_subscr_rx_gsup_message(reply_msg);
1283 msgb_free(reply_msg);
1284
1285 return 0;
1286};
1287
1288static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1289{
1290 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1291 struct gsm_subscriber *subscr;
1292
1293 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001294 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1295
1296 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1297
1298 if (retry) {
1299 upd_loc_skip = 3;
1300 auth_info_skip = 3;
1301 }
1302
1303 printf("Auth policy 'remote', real GSUP based auth: ");
1304 test_gmm_attach(retry);
1305
1306 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001307 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001308 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001309
1310 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001311 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1312 upd_loc_skip = 0;
1313 auth_info_skip = 0;
1314 talloc_free(sgsn->gsup_client);
1315 sgsn->gsup_client = NULL;
1316}
1317
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001318/*
1319 * Test the GMM Rejects
1320 */
1321static void test_gmm_reject(void)
1322{
1323 struct gprs_ra_id raid = { 0, };
1324 struct sgsn_mm_ctx *ctx = NULL;
1325 uint32_t foreign_tlli;
1326 struct gprs_llc_lle *lle;
1327 int idx;
1328
1329 /* DTAP - Attach Request */
1330 /* Invalid MI length */
1331 static const unsigned char attach_req_inv_mi_len[] = {
1332 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1333 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1334 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1335 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1336 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1337 };
1338
1339 /* DTAP - Attach Request */
1340 /* Invalid MI type (IMEI) */
1341 static const unsigned char attach_req_inv_mi_type[] = {
1342 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1343 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1344 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1345 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1346 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1347 };
1348
1349 /* DTAP - Routing Area Update Request */
1350 static const unsigned char dtap_ra_upd_req[] = {
1351 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1352 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1353 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1354 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1355 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1356 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1357 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1358 };
1359
1360 /* DTAP - Routing Area Update Request */
1361 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1362 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1363 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1364 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1365 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1366 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1367 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1368 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1369 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1370 };
1371
1372 /* DTAP - Routing Area Update Request */
1373 /* Invalid cap length */
1374 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1375 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1376 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1377 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1378 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1379 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1380 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1381 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1382 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1383 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1384 };
1385
1386 struct test {
1387 const char *title;
1388 const unsigned char *msg;
1389 unsigned msg_len;
1390 unsigned num_resp;
1391
1392 };
1393 static struct test tests[] = {
1394 {
1395 .title = "Attach Request (invalid MI length)",
1396 .msg = attach_req_inv_mi_len,
1397 .msg_len = sizeof(attach_req_inv_mi_len),
1398 .num_resp = 1 /* Reject */
1399
1400 },
1401 {
1402 .title = "Attach Request (invalid MI type)",
1403 .msg = attach_req_inv_mi_type,
1404 .msg_len = sizeof(attach_req_inv_mi_type),
1405 .num_resp = 1 /* Reject */
1406 },
1407 {
1408 .title = "Routing Area Update Request (valid)",
1409 .msg = dtap_ra_upd_req,
1410 .msg_len = sizeof(dtap_ra_upd_req),
1411 .num_resp = 2 /* XID Reset + Reject */
1412 },
1413 {
1414 .title = "Routing Area Update Request (invalid type)",
1415 .msg = dtap_ra_upd_req_inv_type,
1416 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1417 .num_resp = 1 /* Reject */
1418 },
1419 {
1420 .title = "Routing Area Update Request (invalid CAP length)",
1421 .msg = dtap_ra_upd_req_inv_cap_len,
1422 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1423 .num_resp = 1 /* Reject */
1424 },
1425 };
1426
1427 printf("Testing GMM reject\n");
1428
1429 /* reset the PRNG used by sgsn_alloc_ptmsi */
1430 srand(1);
1431
1432 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1433
1434 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1435
1436 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1437 const struct test *test = &tests[idx];
1438 printf(" - %s\n", test->title);
1439
1440 /* Create a LLE/LLME */
1441 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1442 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1443
1444 /* Inject the Request message */
1445 send_0408_message(lle->llme, foreign_tlli,
1446 test->msg, test->msg_len);
1447
1448 /* We expect a Reject message */
1449 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1450 sgsn_tx_counter, test->num_resp);
1451 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1452
1453 /* verify that LLME/MM are removed */
1454 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1455 OSMO_ASSERT(ctx == NULL);
1456 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1457 }
1458}
1459
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001460/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001461 * Test cancellation of attached MM contexts
1462 */
1463static void test_gmm_cancel(void)
1464{
1465 struct gprs_ra_id raid = { 0, };
1466 struct sgsn_mm_ctx *ctx = NULL;
1467 struct sgsn_mm_ctx *ictx;
1468 uint32_t ptmsi1;
1469 uint32_t foreign_tlli;
1470 uint32_t local_tlli = 0;
1471 struct gprs_llc_lle *lle;
1472 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1473
1474 /* DTAP - Attach Request */
1475 /* The P-TMSI is not known by the SGSN */
1476 static const unsigned char attach_req[] = {
1477 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1478 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1479 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1480 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1481 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1482 };
1483
1484 /* DTAP - Identity Response IMEI */
1485 static const unsigned char ident_resp_imei[] = {
1486 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1487 0x56
1488 };
1489
1490 /* DTAP - Identity Response IMSI */
1491 static const unsigned char ident_resp_imsi[] = {
1492 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1493 0x54
1494 };
1495
1496 /* DTAP - Attach Complete */
1497 static const unsigned char attach_compl[] = {
1498 0x08, 0x03
1499 };
1500
1501 printf("Testing cancellation\n");
1502
1503 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1504
1505 /* reset the PRNG used by sgsn_alloc_ptmsi */
1506 srand(1);
1507
1508 ptmsi1 = sgsn_alloc_ptmsi();
1509 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1510
1511 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1512 * again */
1513 srand(1);
1514
1515 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1516
1517 /* Create a LLE/LLME */
1518 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1519 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1520 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1521
1522 /* inject the attach request */
1523 send_0408_message(lle->llme, foreign_tlli,
1524 attach_req, ARRAY_SIZE(attach_req));
1525
1526 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1527 OSMO_ASSERT(ctx != NULL);
1528 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1529
1530 /* we expect an identity request (IMEI) */
1531 OSMO_ASSERT(sgsn_tx_counter == 1);
1532
1533 /* inject the identity response (IMEI) */
1534 send_0408_message(ctx->llme, foreign_tlli,
1535 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1536
1537 /* we expect an identity request (IMSI) */
1538 OSMO_ASSERT(sgsn_tx_counter == 1);
1539
1540 /* inject the identity response (IMSI) */
1541 send_0408_message(ctx->llme, foreign_tlli,
1542 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1543
1544 /* check that the MM context has not been removed due to a failed
1545 * authorization */
1546 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1547
1548 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1549
1550 /* we expect an attach accept/reject */
1551 OSMO_ASSERT(sgsn_tx_counter == 1);
1552
1553 /* this has been randomly assigned by the SGSN */
1554 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1555
1556 /* inject the attach complete */
1557 send_0408_message(ctx->llme, local_tlli,
1558 attach_compl, ARRAY_SIZE(attach_compl));
1559
1560 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1561
1562 /* we don't expect a response */
1563 OSMO_ASSERT(sgsn_tx_counter == 0);
1564
1565 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001566 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001567
1568 /* verify that things are gone */
1569 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1570 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1571 OSMO_ASSERT(!ictx);
1572
1573 sgsn->cfg.auth_policy = saved_auth_policy;
1574}
1575
1576/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001577 * Test the dynamic allocation of P-TMSIs
1578 */
1579static void test_gmm_ptmsi_allocation(void)
1580{
1581 struct gprs_ra_id raid = { 0, };
1582 struct sgsn_mm_ctx *ctx = NULL;
1583 struct sgsn_mm_ctx *ictx;
1584 uint32_t foreign_tlli;
1585 uint32_t ptmsi1;
1586 uint32_t ptmsi2;
1587 uint32_t old_ptmsi;
1588 uint32_t local_tlli = 0;
1589 struct gprs_llc_lle *lle;
1590 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1591
1592 /* DTAP - Attach Request (IMSI 12131415161718) */
1593 static const unsigned char attach_req[] = {
1594 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1595 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1596 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1597 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1598 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1599 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1600 0x00,
1601 };
1602
1603 /* DTAP - Identity Response IMEI */
1604 static const unsigned char ident_resp_imei[] = {
1605 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1606 0x56
1607 };
1608
1609 /* DTAP - Attach Complete */
1610 static const unsigned char attach_compl[] = {
1611 0x08, 0x03
1612 };
1613
1614 /* DTAP - Routing Area Update Request */
1615 static const unsigned char ra_upd_req[] = {
1616 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1617 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1618 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1619 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1620 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1621 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1622 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1623 };
1624
1625 /* DTAP - Routing Area Update Complete */
1626 static const unsigned char ra_upd_complete[] = {
1627 0x08, 0x0a
1628 };
1629
1630 /* DTAP - Detach Request (MO) */
1631 /* normal detach, power_off = 1 */
1632 static const unsigned char detach_req[] = {
1633 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1634 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1635 };
1636
1637 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1638
1639 printf("Testing P-TMSI allocation\n");
1640
1641 printf(" - sgsn_alloc_ptmsi\n");
1642
1643 /* reset the PRNG used by sgsn_alloc_ptmsi */
1644 srand(1);
1645
1646 ptmsi1 = sgsn_alloc_ptmsi();
1647 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1648
1649 ptmsi2 = sgsn_alloc_ptmsi();
1650 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1651
1652 OSMO_ASSERT(ptmsi1 != ptmsi2);
1653
1654 printf(" - Repeated Attach Request\n");
1655
1656 /* reset the PRNG, so that the same P-TMSI will be generated
1657 * again */
1658 srand(1);
1659
1660 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1661
1662 /* Create a LLE/LLME */
1663 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1664 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1665 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1666
1667 /* inject the attach request */
1668 send_0408_message(lle->llme, foreign_tlli,
1669 attach_req, ARRAY_SIZE(attach_req));
1670
1671 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1672 OSMO_ASSERT(ctx != NULL);
1673 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1674 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1675
1676 old_ptmsi = ctx->p_tmsi_old;
1677
1678 /* we expect an identity request (IMEI) */
1679 OSMO_ASSERT(sgsn_tx_counter == 1);
1680
1681 /* inject the identity response (IMEI) */
1682 send_0408_message(ctx->llme, foreign_tlli,
1683 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1684
1685 /* check that the MM context has not been removed due to a failed
1686 * authorization */
1687 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1688
1689 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1690 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1691
1692 /* we expect an attach accept */
1693 OSMO_ASSERT(sgsn_tx_counter == 1);
1694
1695 /* we ignore this and send the attach again */
1696 send_0408_message(lle->llme, foreign_tlli,
1697 attach_req, ARRAY_SIZE(attach_req));
1698
1699 /* the allocated P-TMSI should be the same */
1700 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1701 OSMO_ASSERT(ctx != NULL);
1702 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1703 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1704 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1705
1706 /* inject the attach complete */
1707 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1708 send_0408_message(ctx->llme, local_tlli,
1709 attach_compl, ARRAY_SIZE(attach_compl));
1710
1711 /* we don't expect a response */
1712 OSMO_ASSERT(sgsn_tx_counter == 0);
1713
1714 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1715 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1716 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1717
1718 printf(" - Repeated RA Update Request\n");
1719
1720 /* inject the RA update request */
1721 send_0408_message(ctx->llme, local_tlli,
1722 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1723
1724 /* we expect an RA update accept */
1725 OSMO_ASSERT(sgsn_tx_counter == 1);
1726
1727 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1728 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1729 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1730
1731 /* repeat the RA update request */
1732 send_0408_message(ctx->llme, local_tlli,
1733 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1734
1735 /* we expect an RA update accept */
1736 OSMO_ASSERT(sgsn_tx_counter == 1);
1737
1738 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1739 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1740 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1741
1742 /* inject the RA update complete */
1743 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1744 send_0408_message(ctx->llme, local_tlli,
1745 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
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 == ptmsi2);
1753
1754 /* inject the detach */
1755 send_0408_message(ctx->llme, local_tlli,
1756 detach_req, ARRAY_SIZE(detach_req));
1757
1758 /* verify that things are gone */
1759 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1760 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1761 OSMO_ASSERT(!ictx);
1762
1763 sgsn->cfg.auth_policy = saved_auth_policy;
1764}
1765
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001766static struct log_info_cat gprs_categories[] = {
1767 [DMM] = {
1768 .name = "DMM",
1769 .description = "Layer3 Mobility Management (MM)",
1770 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001771 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001772 },
1773 [DPAG] = {
1774 .name = "DPAG",
1775 .description = "Paging Subsystem",
1776 .color = "\033[1;38m",
1777 .enabled = 1, .loglevel = LOGL_NOTICE,
1778 },
1779 [DMEAS] = {
1780 .name = "DMEAS",
1781 .description = "Radio Measurement Processing",
1782 .enabled = 0, .loglevel = LOGL_NOTICE,
1783 },
1784 [DREF] = {
1785 .name = "DREF",
1786 .description = "Reference Counting",
1787 .enabled = 0, .loglevel = LOGL_NOTICE,
1788 },
1789 [DGPRS] = {
1790 .name = "DGPRS",
1791 .description = "GPRS Packet Service",
1792 .enabled = 1, .loglevel = LOGL_DEBUG,
1793 },
1794 [DNS] = {
1795 .name = "DNS",
1796 .description = "GPRS Network Service (NS)",
1797 .enabled = 1, .loglevel = LOGL_INFO,
1798 },
1799 [DBSSGP] = {
1800 .name = "DBSSGP",
1801 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1802 .enabled = 1, .loglevel = LOGL_DEBUG,
1803 },
1804 [DLLC] = {
1805 .name = "DLLC",
1806 .description = "GPRS Logical Link Control Protocol (LLC)",
1807 .enabled = 1, .loglevel = LOGL_DEBUG,
1808 },
1809 [DSNDCP] = {
1810 .name = "DSNDCP",
1811 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1812 .enabled = 1, .loglevel = LOGL_DEBUG,
1813 },
1814};
1815
1816static struct log_info info = {
1817 .cat = gprs_categories,
1818 .num_cat = ARRAY_SIZE(gprs_categories),
1819};
1820
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001821int main(int argc, char **argv)
1822{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001823 osmo_init_logging(&info);
1824 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1825 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1826
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001827 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001828 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001829
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001830 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001831 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001832 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001833 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001834 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001835 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001836 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001837 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001838 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001839 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001840 test_gmm_attach_acl();
1841 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001842 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001843 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001844 test_gmm_attach_subscr_gsup_auth(0);
1845 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001846 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001847 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001848 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001849 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001850 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001851
1852 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001853 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001854 return 0;
1855}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001856
1857
1858/* stubs */
1859struct osmo_prim_hdr;
1860int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1861{
1862 abort();
1863}