blob: 733380a59d63f8f43f7cc860cdbe8dd3cfbd194b [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 Erlbeck9999fd92015-01-15 17:08:30 +0100448 static const uint8_t insert_data_req[] = {
449 0x10,
450 TEST_GSUP_IMSI1_IE,
451 0x05, 0x11,
452 0x10, 0x01, 0x03,
453 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
454 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
455 };
456
457 static const uint8_t delete_data_req[] = {
458 0x14,
459 TEST_GSUP_IMSI1_IE,
460 0x10, 0x01, 0x03,
461 };
462
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100463 printf("Testing subcriber GSUP handling\n");
464
465 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
466
467 /* Check for emptiness */
468 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
469
470 /* Allocate entry 1 */
471 s1 = gprs_subscr_get_or_create(imsi1);
472 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
473 s1found = gprs_subscr_get_by_imsi(imsi1);
474 OSMO_ASSERT(s1found == s1);
475 subscr_put(s1found);
476
477 /* Create a context */
478 OSMO_ASSERT(count(gprs_llme_list()) == 0);
479 ctx = alloc_mm_ctx(local_tlli, &raid);
480 llme = ctx->llme;
481
482 /* Attach s1 to ctx */
483 ctx->subscr = subscr_get(s1);
484 ctx->subscr->sgsn_data->mm = ctx;
485
486 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100487 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100488 OSMO_ASSERT(rc >= 0);
489 OSMO_ASSERT(last_updated_subscr == s1);
490
491 /* Check triplets */
492 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
493 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
494 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
495
496 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100497 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100498 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100499 OSMO_ASSERT(last_updated_subscr == s1);
500
501 /* Check triplets */
502 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
503 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
504 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
505
506 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100507 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100508 OSMO_ASSERT(rc >= 0);
509 OSMO_ASSERT(last_updated_subscr == s1);
510
511 /* Check authorization */
512 OSMO_ASSERT(s1->authorized == 1);
513
514 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100515 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100516 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100517 OSMO_ASSERT(last_updated_subscr == s1);
518
519 /* Check authorization */
520 OSMO_ASSERT(s1->authorized == 0);
521
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100522 /* Inject InsertSubscrData GSUP message */
523 last_updated_subscr = NULL;
524 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
525 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
526 OSMO_ASSERT(last_updated_subscr == NULL);
527
528 /* Inject DeleteSubscrData GSUP message */
529 last_updated_subscr = NULL;
530 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
531 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
532 OSMO_ASSERT(last_updated_subscr == NULL);
533
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100534 /* Inject wrong LocCancelReq GSUP message */
535 last_updated_subscr = NULL;
536 rc = rx_gsup_message(location_cancellation_req_other,
537 sizeof(location_cancellation_req_other));
538 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
539 OSMO_ASSERT(last_updated_subscr == NULL);
540
541 /* Check cancellation result */
542 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
543 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
544
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100545 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100546 rc = rx_gsup_message(location_cancellation_req,
547 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100548 OSMO_ASSERT(rc >= 0);
549 OSMO_ASSERT(last_updated_subscr == s1);
550
551 /* Check cancellation result */
552 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
553 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
554
555 /* Free MM context and subscriber */
556 subscr_put(s1);
557 s1found = gprs_subscr_get_by_imsi(imsi1);
558 OSMO_ASSERT(s1found == NULL);
559 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
560
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100561 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
562 last_updated_subscr = NULL;
563 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100564 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100565 OSMO_ASSERT(last_updated_subscr == NULL);
566
567 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
568 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
569 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
570 OSMO_ASSERT(last_updated_subscr == NULL);
571
572 /* Inject LocCancelReq GSUP message (unknown IMSI) */
573 rc = rx_gsup_message(location_cancellation_req,
574 sizeof(location_cancellation_req));
575 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
576 OSMO_ASSERT(last_updated_subscr == NULL);
577
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100578 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
579}
580
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100581int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
582{
583 msgb_free(msg);
584 return 0;
585};
586
587
588static void test_subscriber_blocking(void)
589{
590 struct gsm_subscriber *s1;
591 const char *imsi1 = "1234567890";
592 struct sgsn_mm_ctx *ctx;
593 struct gprs_ra_id raid = { 0, };
594 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100595 int rc;
596
597 printf("Testing subcriber procedure blocking\n");
598
599 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
600 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
601
602 /* Check for emptiness */
603 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
604
605 /* Create a context */
606 OSMO_ASSERT(count(gprs_llme_list()) == 0);
607 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100608 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
609
610 /* Allocate and attach a subscriber */
611 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
612 assert_subscr(s1, imsi1);
613
614 /* Start SendAuthInfoRequest procedure */
615 rc = gprs_subscr_query_auth_info(s1);
616 /* Not blocking */
617 OSMO_ASSERT(rc == 0);
618
619 /* Start UpdateLocation procedure */
620 rc = gprs_subscr_location_update(s1);
621 /* Blocking */
622 OSMO_ASSERT(rc == 0);
623
624 /* Start PurgeMS procedure */
625 rc = gprs_subscr_purge(s1);
626 /* Not blocking */
627 OSMO_ASSERT(rc == 0);
628 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
629
630 /* Start PurgeMS procedure (retry) */
631 rc = gprs_subscr_purge(s1);
632 /* Not blocking */
633 OSMO_ASSERT(rc == 0);
634
635 /* Start SendAuthInfoRequest procedure */
636 rc = gprs_subscr_query_auth_info(s1);
637 /* Blocking */
638 OSMO_ASSERT(rc == -EAGAIN);
639
640 /* Start UpdateLocation procedure */
641 rc = gprs_subscr_location_update(s1);
642 /* Blocking */
643 OSMO_ASSERT(rc == -EAGAIN);
644
645 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
646 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
647
648 /* Start SendAuthInfoRequest procedure */
649 rc = gprs_subscr_query_auth_info(s1);
650 /* Not blocking */
651 OSMO_ASSERT(rc == 0);
652
653 /* Start UpdateLocation procedure */
654 rc = gprs_subscr_location_update(s1);
655 /* Blocking */
656 OSMO_ASSERT(rc == 0);
657
658 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100659 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100660
661 assert_no_subscrs();
662
663 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
664 talloc_free(sgsn->gsup_client);
665 sgsn->gsup_client = NULL;
666}
667
668
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200669/*
670 * Test that a GMM Detach will remove the MMCTX and the
671 * associated LLME.
672 */
673static void test_gmm_detach(void)
674{
675 struct gprs_ra_id raid = { 0, };
676 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200677 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200678
679 printf("Testing GMM detach\n");
680
681 /* DTAP - Detach Request (MO) */
682 /* normal detach, power_off = 0 */
683 static const unsigned char detach_req[] = {
684 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
685 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
686 };
687
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200688 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200689
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100690 /* Create a context */
691 OSMO_ASSERT(count(gprs_llme_list()) == 0);
692 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200693
694 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100695 send_0408_message(ctx->llme, local_tlli,
696 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200697
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100698 /* verify that a single message (hopefully the Detach Accept) has been
699 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100700 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100701
702 /* verify that things are gone */
703 OSMO_ASSERT(count(gprs_llme_list()) == 0);
704 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
705 OSMO_ASSERT(!ictx);
706}
707
708/*
709 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
710 * will not sent a Detach Accept message (power_off = 1)
711 */
712static void test_gmm_detach_power_off(void)
713{
714 struct gprs_ra_id raid = { 0, };
715 struct sgsn_mm_ctx *ctx, *ictx;
716 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100717
718 printf("Testing GMM detach (power off)\n");
719
720 /* DTAP - Detach Request (MO) */
721 /* normal detach, power_off = 1 */
722 static const unsigned char detach_req[] = {
723 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
724 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
725 };
726
727 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
728
729 /* Create a context */
730 OSMO_ASSERT(count(gprs_llme_list()) == 0);
731 ctx = alloc_mm_ctx(local_tlli, &raid);
732
733 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100734 send_0408_message(ctx->llme, local_tlli,
735 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100736
737 /* verify that no message (and therefore no Detach Accept) has been
738 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100739 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100740
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200741 /* verify that things are gone */
742 OSMO_ASSERT(count(gprs_llme_list()) == 0);
743 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200744 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200745}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200746
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200747/*
748 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
749 */
750static void test_gmm_detach_no_mmctx(void)
751{
752 struct gprs_llc_lle *lle;
753 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200754
755 printf("Testing GMM detach (no MMCTX)\n");
756
757 /* DTAP - Detach Request (MO) */
758 /* normal detach, power_off = 0 */
759 static const unsigned char detach_req[] = {
760 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
761 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
762 };
763
764 /* Create an LLME */
765 OSMO_ASSERT(count(gprs_llme_list()) == 0);
766 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
767 lle = gprs_lle_get_or_create(local_tlli, 3);
768
769 OSMO_ASSERT(count(gprs_llme_list()) == 1);
770
771 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100772 send_0408_message(lle->llme, local_tlli,
773 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200774
775 /* verify that the LLME is gone */
776 OSMO_ASSERT(count(gprs_llme_list()) == 0);
777}
778
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100779/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100780 * Test that a single GMM Detach Accept message will not cause the SGSN to send
781 * any message or leave an MM context at the SGSN.
782 */
783static void test_gmm_detach_accept_unexpected(void)
784{
785 struct gprs_llc_lle *lle;
786 uint32_t local_tlli;
787
788 printf("Testing GMM detach accept (unexpected)\n");
789
790 /* DTAP - Detach Accept (MT) */
791 /* normal detach */
792 static const unsigned char detach_acc[] = {
793 0x08, 0x06
794 };
795
796 /* Create an LLME */
797 OSMO_ASSERT(count(gprs_llme_list()) == 0);
798 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
799 lle = gprs_lle_get_or_create(local_tlli, 3);
800
801 /* inject the detach */
802 send_0408_message(lle->llme, local_tlli,
803 detach_acc, ARRAY_SIZE(detach_acc));
804
805 /* verify that no message (and therefore no Status or XID reset) has been
806 * sent by the SGSN */
807 OSMO_ASSERT(sgsn_tx_counter == 0);
808
809 /* verify that things are gone */
810 OSMO_ASSERT(count(gprs_llme_list()) == 0);
811}
812
813/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100814 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
815 */
816static void test_gmm_status_no_mmctx(void)
817{
818 struct gprs_llc_lle *lle;
819 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100820
821 printf("Testing GMM Status (no MMCTX)\n");
822
823 /* DTAP - GMM Status, protocol error */
824 static const unsigned char gmm_status[] = {
825 0x08, 0x20, 0x6f
826 };
827
828 /* Create an LLME */
829 OSMO_ASSERT(count(gprs_llme_list()) == 0);
830 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
831 lle = gprs_lle_get_or_create(local_tlli, 3);
832
833 OSMO_ASSERT(count(gprs_llme_list()) == 1);
834
835 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100836 send_0408_message(lle->llme, local_tlli,
837 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100838
839 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100840 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100841
842 /* verify that the LLME is gone */
843 OSMO_ASSERT(count(gprs_llme_list()) == 0);
844}
845
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100846/*
847 * Test the GMM Attach procedure
848 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100849static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100850{
851 struct gprs_ra_id raid = { 0, };
852 struct sgsn_mm_ctx *ctx = NULL;
853 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100854 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100855 uint32_t foreign_tlli;
856 uint32_t local_tlli = 0;
857 struct gprs_llc_lle *lle;
858
859 /* DTAP - Attach Request */
860 /* The P-TMSI is not known by the SGSN */
861 static const unsigned char attach_req[] = {
862 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
863 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
864 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
865 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
866 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
867 };
868
869 /* DTAP - Identity Response IMEI */
870 static const unsigned char ident_resp_imei[] = {
871 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
872 0x56
873 };
874
875 /* DTAP - Identity Response IMSI */
876 static const unsigned char ident_resp_imsi[] = {
877 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
878 0x54
879 };
880
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100881 /* DTAP - Authentication and Ciphering Resp */
882 static const unsigned char auth_ciph_resp[] = {
883 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
884 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
885 };
886
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100887 /* DTAP - Attach Complete */
888 static const unsigned char attach_compl[] = {
889 0x08, 0x03
890 };
891
892 /* DTAP - Detach Request (MO) */
893 /* normal detach, power_off = 0 */
894 static const unsigned char detach_req[] = {
895 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
896 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
897 };
898
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100899 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100900
901 /* reset the PRNG used by sgsn_alloc_ptmsi */
902 srand(1);
903
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100904 ptmsi1 = sgsn_alloc_ptmsi();
905 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
906
907 /* reset the PRNG, so that the same P-TMSI sequence will be generated
908 * again */
909 srand(1);
910
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100911 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
912
913 /* Create a LLE/LLME */
914 OSMO_ASSERT(count(gprs_llme_list()) == 0);
915 lle = gprs_lle_get_or_create(foreign_tlli, 3);
916 OSMO_ASSERT(count(gprs_llme_list()) == 1);
917
918 /* inject the attach request */
919 send_0408_message(lle->llme, foreign_tlli,
920 attach_req, ARRAY_SIZE(attach_req));
921
922 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
923 OSMO_ASSERT(ctx != NULL);
924 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
925
926 /* we expect an identity request (IMEI) */
927 OSMO_ASSERT(sgsn_tx_counter == 1);
928
929 /* inject the identity response (IMEI) */
930 send_0408_message(ctx->llme, foreign_tlli,
931 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
932
933 /* we expect an identity request (IMSI) */
934 OSMO_ASSERT(sgsn_tx_counter == 1);
935
936 /* inject the identity response (IMSI) */
937 send_0408_message(ctx->llme, foreign_tlli,
938 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
939
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100940 /* check that the MM context has not been removed due to a failed
941 * authorization */
942 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
943
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100944 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100945
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100946retry_attach_req:
947
948 if (retry && sgsn_tx_counter == 0) {
949 fprintf(stderr, "Retrying attach request\n");
950 /* re-inject the attach request */
951 send_0408_message(lle->llme, foreign_tlli,
952 attach_req, ARRAY_SIZE(attach_req));
953 }
954
955 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
956 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100957
958 /* inject the auth & ciph response */
959 send_0408_message(ctx->llme, foreign_tlli,
960 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
961
962 /* check that the MM context has not been removed due to a
963 * failed authorization */
964 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
965 }
966
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100967 if (retry && sgsn_tx_counter == 0)
968 goto retry_attach_req;
969
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100970 /* we expect an attach accept/reject */
971 OSMO_ASSERT(sgsn_tx_counter == 1);
972
973 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100974 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100975
976 /* inject the attach complete */
977 send_0408_message(ctx->llme, local_tlli,
978 attach_compl, ARRAY_SIZE(attach_compl));
979
980 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
981
982 /* we don't expect a response */
983 OSMO_ASSERT(sgsn_tx_counter == 0);
984
985 /* inject the detach */
986 send_0408_message(ctx->llme, local_tlli,
987 detach_req, ARRAY_SIZE(detach_req));
988
989 /* verify that things are gone */
990 OSMO_ASSERT(count(gprs_llme_list()) == 0);
991 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
992 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100993}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100994
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100995static void test_gmm_attach_acl(void)
996{
997 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
998
999 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1000 sgsn_acl_add("123456789012345", &sgsn->cfg);
1001 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001002 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001003 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001004
1005 sgsn->cfg.auth_policy = saved_auth_policy;
1006}
1007
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001008int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001009 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001010 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001011 if (rc == -ENOTSUP) {
1012 OSMO_ASSERT(mmctx->subscr);
1013 gprs_subscr_update(mmctx->subscr);
1014 }
1015 return rc;
1016};
1017
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001018int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1019 gprs_subscr_update(mmctx->subscr);
1020 return 0;
1021};
1022
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001023static void test_gmm_attach_subscr(void)
1024{
1025 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1026 struct gsm_subscriber *subscr;
1027
1028 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001029 subscr_request_update_location_cb = my_subscr_request_update_location;
1030 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001031
1032 subscr = gprs_subscr_get_or_create("123456789012345");
1033 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001034
1035 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001036 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001037 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001038 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001039
1040 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001041 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1042 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001043}
1044
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001045int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1046{
1047 /* Fake an authentication */
1048 OSMO_ASSERT(mmctx->subscr);
1049 mmctx->is_authenticated = 1;
1050 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001051
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001052 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001053};
1054
1055static void test_gmm_attach_subscr_fake_auth(void)
1056{
1057 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1058 struct gsm_subscriber *subscr;
1059
1060 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001061 subscr_request_update_location_cb = my_subscr_request_update_location;
1062 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001063
1064 subscr = gprs_subscr_get_or_create("123456789012345");
1065 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001066 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001067 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001068
1069 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001070 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001071 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001072 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001073
1074 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001075 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1076 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1077}
1078
1079int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1080{
1081 struct gsm_auth_tuple at = {
1082 .sres = {0x51, 0xe5, 0x51, 0xe5},
1083 .key_seq = 0
1084 };
1085
1086 /* Fake an authentication */
1087 OSMO_ASSERT(mmctx->subscr);
1088 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1089
1090 gprs_subscr_update_auth_info(mmctx->subscr);
1091
1092 return 0;
1093};
1094
1095static void test_gmm_attach_subscr_real_auth(void)
1096{
1097 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1098 struct gsm_subscriber *subscr;
1099
1100 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1101 subscr_request_update_location_cb = my_subscr_request_update_location;
1102 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1103
1104 subscr = gprs_subscr_get_or_create("123456789012345");
1105 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001106 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001107 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001108
1109 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001110
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001111 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001112 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001113 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001114
1115 sgsn->cfg.auth_policy = saved_auth_policy;
1116 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1117 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001118}
1119
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001120#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1121 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1122
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001123static int auth_info_skip = 0;
1124static int upd_loc_skip = 0;
1125
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001126int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1127{
1128 static const uint8_t send_auth_info_res[] = {
1129 0x0a,
1130 TEST_GSUP_IMSI_LONG_IE,
1131 0x03, 0x22, /* Auth tuple */
1132 0x20, 0x10,
1133 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1134 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1135 0x21, 0x04,
1136 0x51, 0xe5, 0x51, 0xe5,
1137 0x22, 0x08,
1138 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1139 };
1140
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001141 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001142
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001143 if (auth_info_skip > 0) {
1144 auth_info_skip -= 1;
1145 return -EAGAIN;
1146 }
1147
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001148 /* Fake an SendAuthInfoRes */
1149 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1150
1151 return 0;
1152};
1153
1154int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1155 static const uint8_t update_location_res[] = {
1156 0x06,
1157 TEST_GSUP_IMSI_LONG_IE,
1158 0x04, 0x00, /* PDP info complete */
1159 0x05, 0x12,
1160 0x10, 0x01, 0x01,
1161 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1162 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1163 };
1164
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001165 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001166
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001167 if (upd_loc_skip > 0) {
1168 upd_loc_skip -= 1;
1169 return -EAGAIN;
1170 }
1171
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001172 /* Fake an UpdateLocRes */
1173 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1174};
1175
1176
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001177static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001178{
1179 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1180 struct gsm_subscriber *subscr;
1181
1182 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1183 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1184 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001185 if (retry) {
1186 upd_loc_skip = 3;
1187 auth_info_skip = 3;
1188 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001189
1190 subscr = gprs_subscr_get_or_create("123456789012345");
1191 subscr->authorized = 1;
1192 sgsn->cfg.require_authentication = 1;
1193 sgsn->cfg.require_update_location = 1;
1194 subscr_put(subscr);
1195
1196 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001197 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001198 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001199
1200 sgsn->cfg.auth_policy = saved_auth_policy;
1201 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1202 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001203 upd_loc_skip = 0;
1204 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001205}
1206
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001207int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1208{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001209 struct gprs_gsup_message to_peer = {0};
1210 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001211 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001212 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001213
1214 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001215 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1216 OSMO_ASSERT(rc >= 0);
1217 OSMO_ASSERT(to_peer.imsi[0] != 0);
1218 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001219
1220 /* This invalidates the pointers in to_peer */
1221 msgb_free(msg);
1222
1223 switch (to_peer.message_type) {
1224 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1225 /* Send UPDATE_LOCATION_RESULT */
1226 return my_subscr_request_update_gsup_auth(NULL);
1227
1228 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1229 /* Send SEND_AUTH_INFO_RESULT */
1230 return my_subscr_request_auth_info_gsup_auth(NULL);
1231
1232 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001233 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1234 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001235
1236 default:
1237 if ((to_peer.message_type & 0b00000011) == 0) {
1238 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001239 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001240 from_peer.message_type = to_peer.message_type + 1;
1241 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1242 break;
1243 }
1244
1245 /* Ignore it */
1246 return 0;
1247 }
1248
1249 reply_msg = gprs_gsup_msgb_alloc();
1250 reply_msg->l2h = reply_msg->data;
1251 gprs_gsup_encode(reply_msg, &from_peer);
1252 gprs_subscr_rx_gsup_message(reply_msg);
1253 msgb_free(reply_msg);
1254
1255 return 0;
1256};
1257
1258static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1259{
1260 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1261 struct gsm_subscriber *subscr;
1262
1263 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001264 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1265
1266 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1267
1268 if (retry) {
1269 upd_loc_skip = 3;
1270 auth_info_skip = 3;
1271 }
1272
1273 printf("Auth policy 'remote', real GSUP based auth: ");
1274 test_gmm_attach(retry);
1275
1276 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001277 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001278 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001279
1280 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001281 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1282 upd_loc_skip = 0;
1283 auth_info_skip = 0;
1284 talloc_free(sgsn->gsup_client);
1285 sgsn->gsup_client = NULL;
1286}
1287
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001288/*
1289 * Test the GMM Rejects
1290 */
1291static void test_gmm_reject(void)
1292{
1293 struct gprs_ra_id raid = { 0, };
1294 struct sgsn_mm_ctx *ctx = NULL;
1295 uint32_t foreign_tlli;
1296 struct gprs_llc_lle *lle;
1297 int idx;
1298
1299 /* DTAP - Attach Request */
1300 /* Invalid MI length */
1301 static const unsigned char attach_req_inv_mi_len[] = {
1302 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1303 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1304 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1305 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1306 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1307 };
1308
1309 /* DTAP - Attach Request */
1310 /* Invalid MI type (IMEI) */
1311 static const unsigned char attach_req_inv_mi_type[] = {
1312 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1313 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1314 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1315 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1316 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1317 };
1318
1319 /* DTAP - Routing Area Update Request */
1320 static const unsigned char dtap_ra_upd_req[] = {
1321 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1322 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1323 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1324 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1325 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1326 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1327 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1328 };
1329
1330 /* DTAP - Routing Area Update Request */
1331 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1332 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1333 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1334 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1335 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1336 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1337 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1338 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1339 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1340 };
1341
1342 /* DTAP - Routing Area Update Request */
1343 /* Invalid cap length */
1344 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1345 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1346 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1347 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1348 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1349 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1350 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1351 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1352 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1353 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1354 };
1355
1356 struct test {
1357 const char *title;
1358 const unsigned char *msg;
1359 unsigned msg_len;
1360 unsigned num_resp;
1361
1362 };
1363 static struct test tests[] = {
1364 {
1365 .title = "Attach Request (invalid MI length)",
1366 .msg = attach_req_inv_mi_len,
1367 .msg_len = sizeof(attach_req_inv_mi_len),
1368 .num_resp = 1 /* Reject */
1369
1370 },
1371 {
1372 .title = "Attach Request (invalid MI type)",
1373 .msg = attach_req_inv_mi_type,
1374 .msg_len = sizeof(attach_req_inv_mi_type),
1375 .num_resp = 1 /* Reject */
1376 },
1377 {
1378 .title = "Routing Area Update Request (valid)",
1379 .msg = dtap_ra_upd_req,
1380 .msg_len = sizeof(dtap_ra_upd_req),
1381 .num_resp = 2 /* XID Reset + Reject */
1382 },
1383 {
1384 .title = "Routing Area Update Request (invalid type)",
1385 .msg = dtap_ra_upd_req_inv_type,
1386 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1387 .num_resp = 1 /* Reject */
1388 },
1389 {
1390 .title = "Routing Area Update Request (invalid CAP length)",
1391 .msg = dtap_ra_upd_req_inv_cap_len,
1392 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1393 .num_resp = 1 /* Reject */
1394 },
1395 };
1396
1397 printf("Testing GMM reject\n");
1398
1399 /* reset the PRNG used by sgsn_alloc_ptmsi */
1400 srand(1);
1401
1402 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1403
1404 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1405
1406 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1407 const struct test *test = &tests[idx];
1408 printf(" - %s\n", test->title);
1409
1410 /* Create a LLE/LLME */
1411 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1412 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1413
1414 /* Inject the Request message */
1415 send_0408_message(lle->llme, foreign_tlli,
1416 test->msg, test->msg_len);
1417
1418 /* We expect a Reject message */
1419 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1420 sgsn_tx_counter, test->num_resp);
1421 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1422
1423 /* verify that LLME/MM are removed */
1424 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1425 OSMO_ASSERT(ctx == NULL);
1426 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1427 }
1428}
1429
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001430/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001431 * Test cancellation of attached MM contexts
1432 */
1433static void test_gmm_cancel(void)
1434{
1435 struct gprs_ra_id raid = { 0, };
1436 struct sgsn_mm_ctx *ctx = NULL;
1437 struct sgsn_mm_ctx *ictx;
1438 uint32_t ptmsi1;
1439 uint32_t foreign_tlli;
1440 uint32_t local_tlli = 0;
1441 struct gprs_llc_lle *lle;
1442 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1443
1444 /* DTAP - Attach Request */
1445 /* The P-TMSI is not known by the SGSN */
1446 static const unsigned char attach_req[] = {
1447 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1448 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1449 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1450 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1451 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1452 };
1453
1454 /* DTAP - Identity Response IMEI */
1455 static const unsigned char ident_resp_imei[] = {
1456 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1457 0x56
1458 };
1459
1460 /* DTAP - Identity Response IMSI */
1461 static const unsigned char ident_resp_imsi[] = {
1462 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1463 0x54
1464 };
1465
1466 /* DTAP - Attach Complete */
1467 static const unsigned char attach_compl[] = {
1468 0x08, 0x03
1469 };
1470
1471 printf("Testing cancellation\n");
1472
1473 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1474
1475 /* reset the PRNG used by sgsn_alloc_ptmsi */
1476 srand(1);
1477
1478 ptmsi1 = sgsn_alloc_ptmsi();
1479 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1480
1481 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1482 * again */
1483 srand(1);
1484
1485 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1486
1487 /* Create a LLE/LLME */
1488 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1489 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1490 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1491
1492 /* inject the attach request */
1493 send_0408_message(lle->llme, foreign_tlli,
1494 attach_req, ARRAY_SIZE(attach_req));
1495
1496 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1497 OSMO_ASSERT(ctx != NULL);
1498 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1499
1500 /* we expect an identity request (IMEI) */
1501 OSMO_ASSERT(sgsn_tx_counter == 1);
1502
1503 /* inject the identity response (IMEI) */
1504 send_0408_message(ctx->llme, foreign_tlli,
1505 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1506
1507 /* we expect an identity request (IMSI) */
1508 OSMO_ASSERT(sgsn_tx_counter == 1);
1509
1510 /* inject the identity response (IMSI) */
1511 send_0408_message(ctx->llme, foreign_tlli,
1512 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1513
1514 /* check that the MM context has not been removed due to a failed
1515 * authorization */
1516 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1517
1518 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1519
1520 /* we expect an attach accept/reject */
1521 OSMO_ASSERT(sgsn_tx_counter == 1);
1522
1523 /* this has been randomly assigned by the SGSN */
1524 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1525
1526 /* inject the attach complete */
1527 send_0408_message(ctx->llme, local_tlli,
1528 attach_compl, ARRAY_SIZE(attach_compl));
1529
1530 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1531
1532 /* we don't expect a response */
1533 OSMO_ASSERT(sgsn_tx_counter == 0);
1534
1535 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001536 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001537
1538 /* verify that things are gone */
1539 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1540 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1541 OSMO_ASSERT(!ictx);
1542
1543 sgsn->cfg.auth_policy = saved_auth_policy;
1544}
1545
1546/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001547 * Test the dynamic allocation of P-TMSIs
1548 */
1549static void test_gmm_ptmsi_allocation(void)
1550{
1551 struct gprs_ra_id raid = { 0, };
1552 struct sgsn_mm_ctx *ctx = NULL;
1553 struct sgsn_mm_ctx *ictx;
1554 uint32_t foreign_tlli;
1555 uint32_t ptmsi1;
1556 uint32_t ptmsi2;
1557 uint32_t old_ptmsi;
1558 uint32_t local_tlli = 0;
1559 struct gprs_llc_lle *lle;
1560 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1561
1562 /* DTAP - Attach Request (IMSI 12131415161718) */
1563 static const unsigned char attach_req[] = {
1564 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1565 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1566 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1567 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1568 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1569 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1570 0x00,
1571 };
1572
1573 /* DTAP - Identity Response IMEI */
1574 static const unsigned char ident_resp_imei[] = {
1575 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1576 0x56
1577 };
1578
1579 /* DTAP - Attach Complete */
1580 static const unsigned char attach_compl[] = {
1581 0x08, 0x03
1582 };
1583
1584 /* DTAP - Routing Area Update Request */
1585 static const unsigned char ra_upd_req[] = {
1586 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1587 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1588 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1589 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1590 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1591 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1592 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1593 };
1594
1595 /* DTAP - Routing Area Update Complete */
1596 static const unsigned char ra_upd_complete[] = {
1597 0x08, 0x0a
1598 };
1599
1600 /* DTAP - Detach Request (MO) */
1601 /* normal detach, power_off = 1 */
1602 static const unsigned char detach_req[] = {
1603 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1604 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1605 };
1606
1607 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1608
1609 printf("Testing P-TMSI allocation\n");
1610
1611 printf(" - sgsn_alloc_ptmsi\n");
1612
1613 /* reset the PRNG used by sgsn_alloc_ptmsi */
1614 srand(1);
1615
1616 ptmsi1 = sgsn_alloc_ptmsi();
1617 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1618
1619 ptmsi2 = sgsn_alloc_ptmsi();
1620 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1621
1622 OSMO_ASSERT(ptmsi1 != ptmsi2);
1623
1624 printf(" - Repeated Attach Request\n");
1625
1626 /* reset the PRNG, so that the same P-TMSI will be generated
1627 * again */
1628 srand(1);
1629
1630 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1631
1632 /* Create a LLE/LLME */
1633 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1634 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1635 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1636
1637 /* inject the attach request */
1638 send_0408_message(lle->llme, foreign_tlli,
1639 attach_req, ARRAY_SIZE(attach_req));
1640
1641 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1642 OSMO_ASSERT(ctx != NULL);
1643 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1644 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1645
1646 old_ptmsi = ctx->p_tmsi_old;
1647
1648 /* we expect an identity request (IMEI) */
1649 OSMO_ASSERT(sgsn_tx_counter == 1);
1650
1651 /* inject the identity response (IMEI) */
1652 send_0408_message(ctx->llme, foreign_tlli,
1653 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1654
1655 /* check that the MM context has not been removed due to a failed
1656 * authorization */
1657 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1658
1659 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1660 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1661
1662 /* we expect an attach accept */
1663 OSMO_ASSERT(sgsn_tx_counter == 1);
1664
1665 /* we ignore this and send the attach again */
1666 send_0408_message(lle->llme, foreign_tlli,
1667 attach_req, ARRAY_SIZE(attach_req));
1668
1669 /* the allocated P-TMSI should be the same */
1670 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1671 OSMO_ASSERT(ctx != NULL);
1672 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1673 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1674 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1675
1676 /* inject the attach complete */
1677 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1678 send_0408_message(ctx->llme, local_tlli,
1679 attach_compl, ARRAY_SIZE(attach_compl));
1680
1681 /* we don't expect a response */
1682 OSMO_ASSERT(sgsn_tx_counter == 0);
1683
1684 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1685 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1686 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1687
1688 printf(" - Repeated RA Update Request\n");
1689
1690 /* inject the RA update request */
1691 send_0408_message(ctx->llme, local_tlli,
1692 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1693
1694 /* we expect an RA update accept */
1695 OSMO_ASSERT(sgsn_tx_counter == 1);
1696
1697 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1698 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1699 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1700
1701 /* repeat the RA update request */
1702 send_0408_message(ctx->llme, local_tlli,
1703 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1704
1705 /* we expect an RA update accept */
1706 OSMO_ASSERT(sgsn_tx_counter == 1);
1707
1708 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1709 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1710 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1711
1712 /* inject the RA update complete */
1713 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1714 send_0408_message(ctx->llme, local_tlli,
1715 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1716
1717 /* we don't expect a response */
1718 OSMO_ASSERT(sgsn_tx_counter == 0);
1719
1720 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1721 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1722 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1723
1724 /* inject the detach */
1725 send_0408_message(ctx->llme, local_tlli,
1726 detach_req, ARRAY_SIZE(detach_req));
1727
1728 /* verify that things are gone */
1729 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1730 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1731 OSMO_ASSERT(!ictx);
1732
1733 sgsn->cfg.auth_policy = saved_auth_policy;
1734}
1735
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001736static struct log_info_cat gprs_categories[] = {
1737 [DMM] = {
1738 .name = "DMM",
1739 .description = "Layer3 Mobility Management (MM)",
1740 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001741 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001742 },
1743 [DPAG] = {
1744 .name = "DPAG",
1745 .description = "Paging Subsystem",
1746 .color = "\033[1;38m",
1747 .enabled = 1, .loglevel = LOGL_NOTICE,
1748 },
1749 [DMEAS] = {
1750 .name = "DMEAS",
1751 .description = "Radio Measurement Processing",
1752 .enabled = 0, .loglevel = LOGL_NOTICE,
1753 },
1754 [DREF] = {
1755 .name = "DREF",
1756 .description = "Reference Counting",
1757 .enabled = 0, .loglevel = LOGL_NOTICE,
1758 },
1759 [DGPRS] = {
1760 .name = "DGPRS",
1761 .description = "GPRS Packet Service",
1762 .enabled = 1, .loglevel = LOGL_DEBUG,
1763 },
1764 [DNS] = {
1765 .name = "DNS",
1766 .description = "GPRS Network Service (NS)",
1767 .enabled = 1, .loglevel = LOGL_INFO,
1768 },
1769 [DBSSGP] = {
1770 .name = "DBSSGP",
1771 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1772 .enabled = 1, .loglevel = LOGL_DEBUG,
1773 },
1774 [DLLC] = {
1775 .name = "DLLC",
1776 .description = "GPRS Logical Link Control Protocol (LLC)",
1777 .enabled = 1, .loglevel = LOGL_DEBUG,
1778 },
1779 [DSNDCP] = {
1780 .name = "DSNDCP",
1781 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1782 .enabled = 1, .loglevel = LOGL_DEBUG,
1783 },
1784};
1785
1786static struct log_info info = {
1787 .cat = gprs_categories,
1788 .num_cat = ARRAY_SIZE(gprs_categories),
1789};
1790
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001791int main(int argc, char **argv)
1792{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001793 osmo_init_logging(&info);
1794 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1795 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1796
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001797 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001798 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001799
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001800 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001801 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001802 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001803 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001804 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001805 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001806 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001807 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001808 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001809 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001810 test_gmm_attach_acl();
1811 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001812 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001813 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001814 test_gmm_attach_subscr_gsup_auth(0);
1815 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001816 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001817 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001818 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001819 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001820 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001821
1822 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001823 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001824 return 0;
1825}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001826
1827
1828/* stubs */
1829struct osmo_prim_hdr;
1830int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1831{
1832 abort();
1833}