blob: da7da855f532c76989a7fb8626a4d80b1aa27d00 [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;
309 struct gprs_llc_llme *llme;
310
311 printf("Testing authentication triplet handling\n");
312
313 /* Check for emptiness */
314 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
315
316 /* Allocate entry 1 */
317 s1 = gprs_subscr_get_or_create(imsi1);
318 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
319 s1found = gprs_subscr_get_by_imsi(imsi1);
320 OSMO_ASSERT(s1found == s1);
321 subscr_put(s1found);
322
323 /* Create a context */
324 OSMO_ASSERT(count(gprs_llme_list()) == 0);
325 ctx = alloc_mm_ctx(local_tlli, &raid);
326
327 /* Attach s1 to ctx */
328 ctx->subscr = subscr_get(s1);
329 ctx->subscr->sgsn_data->mm = ctx;
330
331 /* Try to get auth tuple */
332 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
333 OSMO_ASSERT(at == NULL);
334
335 /* Add triplets */
336 s1->sgsn_data->auth_triplets[0].key_seq = 0;
337 s1->sgsn_data->auth_triplets[1].key_seq = 1;
338 s1->sgsn_data->auth_triplets[2].key_seq = 2;
339
340 /* Try to get auth tuple */
341 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
342 OSMO_ASSERT(at != NULL);
343 OSMO_ASSERT(at->key_seq == 0);
344 OSMO_ASSERT(at->use_count == 1);
345 at = sgsn_auth_get_tuple(ctx, at->key_seq);
346 OSMO_ASSERT(at != NULL);
347 OSMO_ASSERT(at->key_seq == 1);
348 OSMO_ASSERT(at->use_count == 1);
349 at = sgsn_auth_get_tuple(ctx, at->key_seq);
350 OSMO_ASSERT(at != NULL);
351 OSMO_ASSERT(at->key_seq == 2);
352 OSMO_ASSERT(at->use_count == 1);
353 at = sgsn_auth_get_tuple(ctx, at->key_seq);
354 OSMO_ASSERT(at == NULL);
355
356 /* Free MM context and subscriber */
357 subscr_put(s1);
358 llme = ctx->llme;
359 sgsn_mm_ctx_free(ctx);
360 s1found = gprs_subscr_get_by_imsi(imsi1);
361 OSMO_ASSERT(s1found == NULL);
362 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
363}
364
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100365#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
366
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100367static int rx_gsup_message(const uint8_t *data, size_t data_len)
368{
369 struct msgb *msg;
370 int rc;
371
372 msg = msgb_alloc(1024, __func__);
373 msg->l2h = msgb_put(msg, data_len);
374 OSMO_ASSERT(msg->l2h != NULL);
375 memcpy(msg->l2h, data, data_len);
376 rc = gprs_subscr_rx_gsup_message(msg);
377 msgb_free(msg);
378
379 return rc;
380}
381
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100382static void test_subscriber_gsup(void)
383{
384 struct gsm_subscriber *s1, *s1found;
385 const char *imsi1 = "1234567890";
386 struct sgsn_mm_ctx *ctx;
387 struct gprs_ra_id raid = { 0, };
388 uint32_t local_tlli = 0xffeeddcc;
389 struct gprs_llc_llme *llme;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100390 int rc;
391
392 static const uint8_t send_auth_info_res[] = {
393 0x0a,
394 TEST_GSUP_IMSI1_IE,
395 0x03, 0x22, /* Auth tuple */
396 0x20, 0x10,
397 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
398 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
399 0x21, 0x04,
400 0x21, 0x22, 0x23, 0x24,
401 0x22, 0x08,
402 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
403 0x03, 0x22, /* Auth tuple */
404 0x20, 0x10,
405 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
406 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
407 0x21, 0x04,
408 0xa1, 0xa2, 0xa3, 0xa4,
409 0x22, 0x08,
410 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
411 };
412
413 static const uint8_t send_auth_info_err[] = {
414 0x09,
415 TEST_GSUP_IMSI1_IE,
416 0x02, 0x01, 0x07 /* GPRS not allowed */
417 };
418
419 static const uint8_t update_location_res[] = {
420 0x06,
421 TEST_GSUP_IMSI1_IE,
422 0x04, 0x00, /* PDP info complete */
423 0x05, 0x12,
424 0x10, 0x01, 0x01,
425 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
426 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
427 0x05, 0x11,
428 0x10, 0x01, 0x02,
429 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
430 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
431 };
432
433 static const uint8_t update_location_err[] = {
434 0x05,
435 TEST_GSUP_IMSI1_IE,
436 0x02, 0x01, 0x07 /* GPRS not allowed */
437 };
438
439 static const uint8_t location_cancellation_req[] = {
440 0x1c,
441 TEST_GSUP_IMSI1_IE,
442 0x06, 0x01, 0x00,
443 };
444
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100445 static const uint8_t location_cancellation_req_other[] = {
446 0x1c,
447 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
448 0x06, 0x01, 0x00,
449 };
450
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100451 static const uint8_t insert_data_req[] = {
452 0x10,
453 TEST_GSUP_IMSI1_IE,
454 0x05, 0x11,
455 0x10, 0x01, 0x03,
456 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
457 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
458 };
459
460 static const uint8_t delete_data_req[] = {
461 0x14,
462 TEST_GSUP_IMSI1_IE,
463 0x10, 0x01, 0x03,
464 };
465
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100466 printf("Testing subcriber GSUP handling\n");
467
468 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
469
470 /* Check for emptiness */
471 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
472
473 /* Allocate entry 1 */
474 s1 = gprs_subscr_get_or_create(imsi1);
475 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
476 s1found = gprs_subscr_get_by_imsi(imsi1);
477 OSMO_ASSERT(s1found == s1);
478 subscr_put(s1found);
479
480 /* Create a context */
481 OSMO_ASSERT(count(gprs_llme_list()) == 0);
482 ctx = alloc_mm_ctx(local_tlli, &raid);
483 llme = ctx->llme;
484
485 /* Attach s1 to ctx */
486 ctx->subscr = subscr_get(s1);
487 ctx->subscr->sgsn_data->mm = ctx;
488
489 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100490 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100491 OSMO_ASSERT(rc >= 0);
492 OSMO_ASSERT(last_updated_subscr == s1);
493
494 /* Check triplets */
495 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
496 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
497 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
498
499 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100500 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100501 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100502 OSMO_ASSERT(last_updated_subscr == s1);
503
504 /* Check triplets */
505 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
506 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
507 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
508
509 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100510 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100511 OSMO_ASSERT(rc >= 0);
512 OSMO_ASSERT(last_updated_subscr == s1);
513
514 /* Check authorization */
515 OSMO_ASSERT(s1->authorized == 1);
516
517 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100518 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100519 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100520 OSMO_ASSERT(last_updated_subscr == s1);
521
522 /* Check authorization */
523 OSMO_ASSERT(s1->authorized == 0);
524
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100525 /* Inject InsertSubscrData GSUP message */
526 last_updated_subscr = NULL;
527 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
528 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
529 OSMO_ASSERT(last_updated_subscr == NULL);
530
531 /* Inject DeleteSubscrData GSUP message */
532 last_updated_subscr = NULL;
533 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
534 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
535 OSMO_ASSERT(last_updated_subscr == NULL);
536
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100537 /* Inject wrong LocCancelReq GSUP message */
538 last_updated_subscr = NULL;
539 rc = rx_gsup_message(location_cancellation_req_other,
540 sizeof(location_cancellation_req_other));
541 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
542 OSMO_ASSERT(last_updated_subscr == NULL);
543
544 /* Check cancellation result */
545 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
546 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
547
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100548 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100549 rc = rx_gsup_message(location_cancellation_req,
550 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100551 OSMO_ASSERT(rc >= 0);
552 OSMO_ASSERT(last_updated_subscr == s1);
553
554 /* Check cancellation result */
555 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
556 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
557
558 /* Free MM context and subscriber */
559 subscr_put(s1);
560 s1found = gprs_subscr_get_by_imsi(imsi1);
561 OSMO_ASSERT(s1found == NULL);
562 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
563
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100564 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
565 last_updated_subscr = NULL;
566 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100567 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100568 OSMO_ASSERT(last_updated_subscr == NULL);
569
570 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
571 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
572 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
573 OSMO_ASSERT(last_updated_subscr == NULL);
574
575 /* Inject LocCancelReq GSUP message (unknown IMSI) */
576 rc = rx_gsup_message(location_cancellation_req,
577 sizeof(location_cancellation_req));
578 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
579 OSMO_ASSERT(last_updated_subscr == NULL);
580
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100581 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
582}
583
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100584int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
585{
586 msgb_free(msg);
587 return 0;
588};
589
590
591static void test_subscriber_blocking(void)
592{
593 struct gsm_subscriber *s1;
594 const char *imsi1 = "1234567890";
595 struct sgsn_mm_ctx *ctx;
596 struct gprs_ra_id raid = { 0, };
597 uint32_t local_tlli = 0xffeeddcc;
598 struct gprs_llc_llme *llme;
599 int rc;
600
601 printf("Testing subcriber procedure blocking\n");
602
603 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
604 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
605
606 /* Check for emptiness */
607 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
608
609 /* Create a context */
610 OSMO_ASSERT(count(gprs_llme_list()) == 0);
611 ctx = alloc_mm_ctx(local_tlli, &raid);
612 llme = ctx->llme;
613 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
614
615 /* Allocate and attach a subscriber */
616 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
617 assert_subscr(s1, imsi1);
618
619 /* Start SendAuthInfoRequest procedure */
620 rc = gprs_subscr_query_auth_info(s1);
621 /* Not blocking */
622 OSMO_ASSERT(rc == 0);
623
624 /* Start UpdateLocation procedure */
625 rc = gprs_subscr_location_update(s1);
626 /* Blocking */
627 OSMO_ASSERT(rc == 0);
628
629 /* Start PurgeMS procedure */
630 rc = gprs_subscr_purge(s1);
631 /* Not blocking */
632 OSMO_ASSERT(rc == 0);
633 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
634
635 /* Start PurgeMS procedure (retry) */
636 rc = gprs_subscr_purge(s1);
637 /* Not blocking */
638 OSMO_ASSERT(rc == 0);
639
640 /* Start SendAuthInfoRequest procedure */
641 rc = gprs_subscr_query_auth_info(s1);
642 /* Blocking */
643 OSMO_ASSERT(rc == -EAGAIN);
644
645 /* Start UpdateLocation procedure */
646 rc = gprs_subscr_location_update(s1);
647 /* Blocking */
648 OSMO_ASSERT(rc == -EAGAIN);
649
650 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
651 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
652
653 /* Start SendAuthInfoRequest procedure */
654 rc = gprs_subscr_query_auth_info(s1);
655 /* Not blocking */
656 OSMO_ASSERT(rc == 0);
657
658 /* Start UpdateLocation procedure */
659 rc = gprs_subscr_location_update(s1);
660 /* Blocking */
661 OSMO_ASSERT(rc == 0);
662
663 subscr_put(s1);
664 sgsn_mm_ctx_free(ctx);
665 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
666
667 assert_no_subscrs();
668
669 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
670 talloc_free(sgsn->gsup_client);
671 sgsn->gsup_client = NULL;
672}
673
674
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200675/*
676 * Test that a GMM Detach will remove the MMCTX and the
677 * associated LLME.
678 */
679static void test_gmm_detach(void)
680{
681 struct gprs_ra_id raid = { 0, };
682 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200683 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200684
685 printf("Testing GMM detach\n");
686
687 /* DTAP - Detach Request (MO) */
688 /* normal detach, power_off = 0 */
689 static const unsigned char detach_req[] = {
690 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
691 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
692 };
693
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200694 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200695
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100696 /* Create a context */
697 OSMO_ASSERT(count(gprs_llme_list()) == 0);
698 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200699
700 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100701 send_0408_message(ctx->llme, local_tlli,
702 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200703
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100704 /* verify that a single message (hopefully the Detach Accept) has been
705 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100706 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100707
708 /* verify that things are gone */
709 OSMO_ASSERT(count(gprs_llme_list()) == 0);
710 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
711 OSMO_ASSERT(!ictx);
712}
713
714/*
715 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
716 * will not sent a Detach Accept message (power_off = 1)
717 */
718static void test_gmm_detach_power_off(void)
719{
720 struct gprs_ra_id raid = { 0, };
721 struct sgsn_mm_ctx *ctx, *ictx;
722 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100723
724 printf("Testing GMM detach (power off)\n");
725
726 /* DTAP - Detach Request (MO) */
727 /* normal detach, power_off = 1 */
728 static const unsigned char detach_req[] = {
729 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
730 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
731 };
732
733 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
734
735 /* Create a context */
736 OSMO_ASSERT(count(gprs_llme_list()) == 0);
737 ctx = alloc_mm_ctx(local_tlli, &raid);
738
739 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100740 send_0408_message(ctx->llme, local_tlli,
741 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100742
743 /* verify that no message (and therefore no Detach Accept) has been
744 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100745 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100746
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200747 /* verify that things are gone */
748 OSMO_ASSERT(count(gprs_llme_list()) == 0);
749 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200750 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200751}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200752
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200753/*
754 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
755 */
756static void test_gmm_detach_no_mmctx(void)
757{
758 struct gprs_llc_lle *lle;
759 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200760
761 printf("Testing GMM detach (no MMCTX)\n");
762
763 /* DTAP - Detach Request (MO) */
764 /* normal detach, power_off = 0 */
765 static const unsigned char detach_req[] = {
766 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
767 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
768 };
769
770 /* Create an LLME */
771 OSMO_ASSERT(count(gprs_llme_list()) == 0);
772 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
773 lle = gprs_lle_get_or_create(local_tlli, 3);
774
775 OSMO_ASSERT(count(gprs_llme_list()) == 1);
776
777 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100778 send_0408_message(lle->llme, local_tlli,
779 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200780
781 /* verify that the LLME is gone */
782 OSMO_ASSERT(count(gprs_llme_list()) == 0);
783}
784
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100785/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100786 * Test that a single GMM Detach Accept message will not cause the SGSN to send
787 * any message or leave an MM context at the SGSN.
788 */
789static void test_gmm_detach_accept_unexpected(void)
790{
791 struct gprs_llc_lle *lle;
792 uint32_t local_tlli;
793
794 printf("Testing GMM detach accept (unexpected)\n");
795
796 /* DTAP - Detach Accept (MT) */
797 /* normal detach */
798 static const unsigned char detach_acc[] = {
799 0x08, 0x06
800 };
801
802 /* Create an LLME */
803 OSMO_ASSERT(count(gprs_llme_list()) == 0);
804 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
805 lle = gprs_lle_get_or_create(local_tlli, 3);
806
807 /* inject the detach */
808 send_0408_message(lle->llme, local_tlli,
809 detach_acc, ARRAY_SIZE(detach_acc));
810
811 /* verify that no message (and therefore no Status or XID reset) has been
812 * sent by the SGSN */
813 OSMO_ASSERT(sgsn_tx_counter == 0);
814
815 /* verify that things are gone */
816 OSMO_ASSERT(count(gprs_llme_list()) == 0);
817}
818
819/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100820 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
821 */
822static void test_gmm_status_no_mmctx(void)
823{
824 struct gprs_llc_lle *lle;
825 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100826
827 printf("Testing GMM Status (no MMCTX)\n");
828
829 /* DTAP - GMM Status, protocol error */
830 static const unsigned char gmm_status[] = {
831 0x08, 0x20, 0x6f
832 };
833
834 /* Create an LLME */
835 OSMO_ASSERT(count(gprs_llme_list()) == 0);
836 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
837 lle = gprs_lle_get_or_create(local_tlli, 3);
838
839 OSMO_ASSERT(count(gprs_llme_list()) == 1);
840
841 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100842 send_0408_message(lle->llme, local_tlli,
843 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100844
845 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100846 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100847
848 /* verify that the LLME is gone */
849 OSMO_ASSERT(count(gprs_llme_list()) == 0);
850}
851
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100852/*
853 * Test the GMM Attach procedure
854 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100855static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100856{
857 struct gprs_ra_id raid = { 0, };
858 struct sgsn_mm_ctx *ctx = NULL;
859 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100860 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100861 uint32_t foreign_tlli;
862 uint32_t local_tlli = 0;
863 struct gprs_llc_lle *lle;
864
865 /* DTAP - Attach Request */
866 /* The P-TMSI is not known by the SGSN */
867 static const unsigned char attach_req[] = {
868 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
869 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
870 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
871 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
872 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
873 };
874
875 /* DTAP - Identity Response IMEI */
876 static const unsigned char ident_resp_imei[] = {
877 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
878 0x56
879 };
880
881 /* DTAP - Identity Response IMSI */
882 static const unsigned char ident_resp_imsi[] = {
883 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
884 0x54
885 };
886
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100887 /* DTAP - Authentication and Ciphering Resp */
888 static const unsigned char auth_ciph_resp[] = {
889 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
890 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
891 };
892
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100893 /* DTAP - Attach Complete */
894 static const unsigned char attach_compl[] = {
895 0x08, 0x03
896 };
897
898 /* DTAP - Detach Request (MO) */
899 /* normal detach, power_off = 0 */
900 static const unsigned char detach_req[] = {
901 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
902 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
903 };
904
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100905 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100906
907 /* reset the PRNG used by sgsn_alloc_ptmsi */
908 srand(1);
909
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100910 ptmsi1 = sgsn_alloc_ptmsi();
911 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
912
913 /* reset the PRNG, so that the same P-TMSI sequence will be generated
914 * again */
915 srand(1);
916
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100917 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
918
919 /* Create a LLE/LLME */
920 OSMO_ASSERT(count(gprs_llme_list()) == 0);
921 lle = gprs_lle_get_or_create(foreign_tlli, 3);
922 OSMO_ASSERT(count(gprs_llme_list()) == 1);
923
924 /* inject the attach request */
925 send_0408_message(lle->llme, foreign_tlli,
926 attach_req, ARRAY_SIZE(attach_req));
927
928 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
929 OSMO_ASSERT(ctx != NULL);
930 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
931
932 /* we expect an identity request (IMEI) */
933 OSMO_ASSERT(sgsn_tx_counter == 1);
934
935 /* inject the identity response (IMEI) */
936 send_0408_message(ctx->llme, foreign_tlli,
937 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
938
939 /* we expect an identity request (IMSI) */
940 OSMO_ASSERT(sgsn_tx_counter == 1);
941
942 /* inject the identity response (IMSI) */
943 send_0408_message(ctx->llme, foreign_tlli,
944 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
945
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100946 /* check that the MM context has not been removed due to a failed
947 * authorization */
948 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
949
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100950 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100951
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100952retry_attach_req:
953
954 if (retry && sgsn_tx_counter == 0) {
955 fprintf(stderr, "Retrying attach request\n");
956 /* re-inject the attach request */
957 send_0408_message(lle->llme, foreign_tlli,
958 attach_req, ARRAY_SIZE(attach_req));
959 }
960
961 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
962 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100963
964 /* inject the auth & ciph response */
965 send_0408_message(ctx->llme, foreign_tlli,
966 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
967
968 /* check that the MM context has not been removed due to a
969 * failed authorization */
970 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
971 }
972
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100973 if (retry && sgsn_tx_counter == 0)
974 goto retry_attach_req;
975
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100976 /* we expect an attach accept/reject */
977 OSMO_ASSERT(sgsn_tx_counter == 1);
978
979 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100980 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100981
982 /* inject the attach complete */
983 send_0408_message(ctx->llme, local_tlli,
984 attach_compl, ARRAY_SIZE(attach_compl));
985
986 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
987
988 /* we don't expect a response */
989 OSMO_ASSERT(sgsn_tx_counter == 0);
990
991 /* inject the detach */
992 send_0408_message(ctx->llme, local_tlli,
993 detach_req, ARRAY_SIZE(detach_req));
994
995 /* verify that things are gone */
996 OSMO_ASSERT(count(gprs_llme_list()) == 0);
997 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
998 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100999}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001000
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001001static void test_gmm_attach_acl(void)
1002{
1003 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1004
1005 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1006 sgsn_acl_add("123456789012345", &sgsn->cfg);
1007 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001008 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001009 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001010
1011 sgsn->cfg.auth_policy = saved_auth_policy;
1012}
1013
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001014int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001015 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001016 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001017 if (rc == -ENOTSUP) {
1018 OSMO_ASSERT(mmctx->subscr);
1019 gprs_subscr_update(mmctx->subscr);
1020 }
1021 return rc;
1022};
1023
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001024int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1025 gprs_subscr_update(mmctx->subscr);
1026 return 0;
1027};
1028
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001029static void test_gmm_attach_subscr(void)
1030{
1031 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1032 struct gsm_subscriber *subscr;
1033
1034 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001035 subscr_request_update_location_cb = my_subscr_request_update_location;
1036 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001037
1038 subscr = gprs_subscr_get_or_create("123456789012345");
1039 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001040
1041 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001042 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001043 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001044 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001045
1046 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001047 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1048 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001049}
1050
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001051int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1052{
1053 /* Fake an authentication */
1054 OSMO_ASSERT(mmctx->subscr);
1055 mmctx->is_authenticated = 1;
1056 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001057
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001058 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001059};
1060
1061static void test_gmm_attach_subscr_fake_auth(void)
1062{
1063 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1064 struct gsm_subscriber *subscr;
1065
1066 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001067 subscr_request_update_location_cb = my_subscr_request_update_location;
1068 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001069
1070 subscr = gprs_subscr_get_or_create("123456789012345");
1071 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001072 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001073 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001074
1075 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001076 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001077 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001078 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001079
1080 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001081 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1082 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1083}
1084
1085int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1086{
1087 struct gsm_auth_tuple at = {
1088 .sres = {0x51, 0xe5, 0x51, 0xe5},
1089 .key_seq = 0
1090 };
1091
1092 /* Fake an authentication */
1093 OSMO_ASSERT(mmctx->subscr);
1094 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1095
1096 gprs_subscr_update_auth_info(mmctx->subscr);
1097
1098 return 0;
1099};
1100
1101static void test_gmm_attach_subscr_real_auth(void)
1102{
1103 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1104 struct gsm_subscriber *subscr;
1105
1106 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1107 subscr_request_update_location_cb = my_subscr_request_update_location;
1108 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1109
1110 subscr = gprs_subscr_get_or_create("123456789012345");
1111 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001112 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001113 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001114
1115 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001116
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001117 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001118 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001119 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001120
1121 sgsn->cfg.auth_policy = saved_auth_policy;
1122 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1123 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001124}
1125
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001126#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1127 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1128
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001129static int auth_info_skip = 0;
1130static int upd_loc_skip = 0;
1131
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001132int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1133{
1134 static const uint8_t send_auth_info_res[] = {
1135 0x0a,
1136 TEST_GSUP_IMSI_LONG_IE,
1137 0x03, 0x22, /* Auth tuple */
1138 0x20, 0x10,
1139 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1140 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1141 0x21, 0x04,
1142 0x51, 0xe5, 0x51, 0xe5,
1143 0x22, 0x08,
1144 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1145 };
1146
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001147 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001148
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001149 if (auth_info_skip > 0) {
1150 auth_info_skip -= 1;
1151 return -EAGAIN;
1152 }
1153
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001154 /* Fake an SendAuthInfoRes */
1155 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1156
1157 return 0;
1158};
1159
1160int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1161 static const uint8_t update_location_res[] = {
1162 0x06,
1163 TEST_GSUP_IMSI_LONG_IE,
1164 0x04, 0x00, /* PDP info complete */
1165 0x05, 0x12,
1166 0x10, 0x01, 0x01,
1167 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1168 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
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 (upd_loc_skip > 0) {
1174 upd_loc_skip -= 1;
1175 return -EAGAIN;
1176 }
1177
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001178 /* Fake an UpdateLocRes */
1179 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1180};
1181
1182
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001183static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001184{
1185 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1186 struct gsm_subscriber *subscr;
1187
1188 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1189 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1190 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001191 if (retry) {
1192 upd_loc_skip = 3;
1193 auth_info_skip = 3;
1194 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001195
1196 subscr = gprs_subscr_get_or_create("123456789012345");
1197 subscr->authorized = 1;
1198 sgsn->cfg.require_authentication = 1;
1199 sgsn->cfg.require_update_location = 1;
1200 subscr_put(subscr);
1201
1202 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001203 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001204 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001205
1206 sgsn->cfg.auth_policy = saved_auth_policy;
1207 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1208 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001209 upd_loc_skip = 0;
1210 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001211}
1212
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001213int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1214{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001215 struct gprs_gsup_message to_peer = {0};
1216 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001217 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001218 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001219
1220 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001221 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1222 OSMO_ASSERT(rc >= 0);
1223 OSMO_ASSERT(to_peer.imsi[0] != 0);
1224 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001225
1226 /* This invalidates the pointers in to_peer */
1227 msgb_free(msg);
1228
1229 switch (to_peer.message_type) {
1230 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1231 /* Send UPDATE_LOCATION_RESULT */
1232 return my_subscr_request_update_gsup_auth(NULL);
1233
1234 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1235 /* Send SEND_AUTH_INFO_RESULT */
1236 return my_subscr_request_auth_info_gsup_auth(NULL);
1237
1238 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001239 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1240 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001241
1242 default:
1243 if ((to_peer.message_type & 0b00000011) == 0) {
1244 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001245 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001246 from_peer.message_type = to_peer.message_type + 1;
1247 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1248 break;
1249 }
1250
1251 /* Ignore it */
1252 return 0;
1253 }
1254
1255 reply_msg = gprs_gsup_msgb_alloc();
1256 reply_msg->l2h = reply_msg->data;
1257 gprs_gsup_encode(reply_msg, &from_peer);
1258 gprs_subscr_rx_gsup_message(reply_msg);
1259 msgb_free(reply_msg);
1260
1261 return 0;
1262};
1263
1264static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1265{
1266 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1267 struct gsm_subscriber *subscr;
1268
1269 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001270 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1271
1272 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1273
1274 if (retry) {
1275 upd_loc_skip = 3;
1276 auth_info_skip = 3;
1277 }
1278
1279 printf("Auth policy 'remote', real GSUP based auth: ");
1280 test_gmm_attach(retry);
1281
1282 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001283 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001284 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001285
1286 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001287 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1288 upd_loc_skip = 0;
1289 auth_info_skip = 0;
1290 talloc_free(sgsn->gsup_client);
1291 sgsn->gsup_client = NULL;
1292}
1293
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001294/*
1295 * Test the GMM Rejects
1296 */
1297static void test_gmm_reject(void)
1298{
1299 struct gprs_ra_id raid = { 0, };
1300 struct sgsn_mm_ctx *ctx = NULL;
1301 uint32_t foreign_tlli;
1302 struct gprs_llc_lle *lle;
1303 int idx;
1304
1305 /* DTAP - Attach Request */
1306 /* Invalid MI length */
1307 static const unsigned char attach_req_inv_mi_len[] = {
1308 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1309 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1310 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1311 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1312 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1313 };
1314
1315 /* DTAP - Attach Request */
1316 /* Invalid MI type (IMEI) */
1317 static const unsigned char attach_req_inv_mi_type[] = {
1318 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1319 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1320 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1321 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1322 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1323 };
1324
1325 /* DTAP - Routing Area Update Request */
1326 static const unsigned char dtap_ra_upd_req[] = {
1327 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1328 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1329 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1330 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1331 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1332 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1333 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1334 };
1335
1336 /* DTAP - Routing Area Update Request */
1337 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1338 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1339 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1340 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1341 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1342 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1343 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1344 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1345 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1346 };
1347
1348 /* DTAP - Routing Area Update Request */
1349 /* Invalid cap length */
1350 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1351 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1352 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1353 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1354 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1355 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1356 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1357 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1358 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1359 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1360 };
1361
1362 struct test {
1363 const char *title;
1364 const unsigned char *msg;
1365 unsigned msg_len;
1366 unsigned num_resp;
1367
1368 };
1369 static struct test tests[] = {
1370 {
1371 .title = "Attach Request (invalid MI length)",
1372 .msg = attach_req_inv_mi_len,
1373 .msg_len = sizeof(attach_req_inv_mi_len),
1374 .num_resp = 1 /* Reject */
1375
1376 },
1377 {
1378 .title = "Attach Request (invalid MI type)",
1379 .msg = attach_req_inv_mi_type,
1380 .msg_len = sizeof(attach_req_inv_mi_type),
1381 .num_resp = 1 /* Reject */
1382 },
1383 {
1384 .title = "Routing Area Update Request (valid)",
1385 .msg = dtap_ra_upd_req,
1386 .msg_len = sizeof(dtap_ra_upd_req),
1387 .num_resp = 2 /* XID Reset + Reject */
1388 },
1389 {
1390 .title = "Routing Area Update Request (invalid type)",
1391 .msg = dtap_ra_upd_req_inv_type,
1392 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1393 .num_resp = 1 /* Reject */
1394 },
1395 {
1396 .title = "Routing Area Update Request (invalid CAP length)",
1397 .msg = dtap_ra_upd_req_inv_cap_len,
1398 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1399 .num_resp = 1 /* Reject */
1400 },
1401 };
1402
1403 printf("Testing GMM reject\n");
1404
1405 /* reset the PRNG used by sgsn_alloc_ptmsi */
1406 srand(1);
1407
1408 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1409
1410 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1411
1412 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1413 const struct test *test = &tests[idx];
1414 printf(" - %s\n", test->title);
1415
1416 /* Create a LLE/LLME */
1417 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1418 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1419
1420 /* Inject the Request message */
1421 send_0408_message(lle->llme, foreign_tlli,
1422 test->msg, test->msg_len);
1423
1424 /* We expect a Reject message */
1425 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1426 sgsn_tx_counter, test->num_resp);
1427 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1428
1429 /* verify that LLME/MM are removed */
1430 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1431 OSMO_ASSERT(ctx == NULL);
1432 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1433 }
1434}
1435
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001436/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001437 * Test cancellation of attached MM contexts
1438 */
1439static void test_gmm_cancel(void)
1440{
1441 struct gprs_ra_id raid = { 0, };
1442 struct sgsn_mm_ctx *ctx = NULL;
1443 struct sgsn_mm_ctx *ictx;
1444 uint32_t ptmsi1;
1445 uint32_t foreign_tlli;
1446 uint32_t local_tlli = 0;
1447 struct gprs_llc_lle *lle;
1448 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1449
1450 /* DTAP - Attach Request */
1451 /* The P-TMSI is not known by the SGSN */
1452 static const unsigned char attach_req[] = {
1453 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1454 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1455 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1456 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1457 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1458 };
1459
1460 /* DTAP - Identity Response IMEI */
1461 static const unsigned char ident_resp_imei[] = {
1462 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1463 0x56
1464 };
1465
1466 /* DTAP - Identity Response IMSI */
1467 static const unsigned char ident_resp_imsi[] = {
1468 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1469 0x54
1470 };
1471
1472 /* DTAP - Attach Complete */
1473 static const unsigned char attach_compl[] = {
1474 0x08, 0x03
1475 };
1476
1477 printf("Testing cancellation\n");
1478
1479 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1480
1481 /* reset the PRNG used by sgsn_alloc_ptmsi */
1482 srand(1);
1483
1484 ptmsi1 = sgsn_alloc_ptmsi();
1485 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1486
1487 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1488 * again */
1489 srand(1);
1490
1491 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1492
1493 /* Create a LLE/LLME */
1494 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1495 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1496 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1497
1498 /* inject the attach request */
1499 send_0408_message(lle->llme, foreign_tlli,
1500 attach_req, ARRAY_SIZE(attach_req));
1501
1502 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1503 OSMO_ASSERT(ctx != NULL);
1504 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1505
1506 /* we expect an identity request (IMEI) */
1507 OSMO_ASSERT(sgsn_tx_counter == 1);
1508
1509 /* inject the identity response (IMEI) */
1510 send_0408_message(ctx->llme, foreign_tlli,
1511 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1512
1513 /* we expect an identity request (IMSI) */
1514 OSMO_ASSERT(sgsn_tx_counter == 1);
1515
1516 /* inject the identity response (IMSI) */
1517 send_0408_message(ctx->llme, foreign_tlli,
1518 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1519
1520 /* check that the MM context has not been removed due to a failed
1521 * authorization */
1522 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1523
1524 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1525
1526 /* we expect an attach accept/reject */
1527 OSMO_ASSERT(sgsn_tx_counter == 1);
1528
1529 /* this has been randomly assigned by the SGSN */
1530 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1531
1532 /* inject the attach complete */
1533 send_0408_message(ctx->llme, local_tlli,
1534 attach_compl, ARRAY_SIZE(attach_compl));
1535
1536 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1537
1538 /* we don't expect a response */
1539 OSMO_ASSERT(sgsn_tx_counter == 0);
1540
1541 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001542 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001543
1544 /* verify that things are gone */
1545 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1546 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1547 OSMO_ASSERT(!ictx);
1548
1549 sgsn->cfg.auth_policy = saved_auth_policy;
1550}
1551
1552/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001553 * Test the dynamic allocation of P-TMSIs
1554 */
1555static void test_gmm_ptmsi_allocation(void)
1556{
1557 struct gprs_ra_id raid = { 0, };
1558 struct sgsn_mm_ctx *ctx = NULL;
1559 struct sgsn_mm_ctx *ictx;
1560 uint32_t foreign_tlli;
1561 uint32_t ptmsi1;
1562 uint32_t ptmsi2;
1563 uint32_t old_ptmsi;
1564 uint32_t local_tlli = 0;
1565 struct gprs_llc_lle *lle;
1566 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1567
1568 /* DTAP - Attach Request (IMSI 12131415161718) */
1569 static const unsigned char attach_req[] = {
1570 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1571 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1572 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1573 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1574 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1575 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1576 0x00,
1577 };
1578
1579 /* DTAP - Identity Response IMEI */
1580 static const unsigned char ident_resp_imei[] = {
1581 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1582 0x56
1583 };
1584
1585 /* DTAP - Attach Complete */
1586 static const unsigned char attach_compl[] = {
1587 0x08, 0x03
1588 };
1589
1590 /* DTAP - Routing Area Update Request */
1591 static const unsigned char ra_upd_req[] = {
1592 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1593 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1594 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1595 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1596 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1597 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1598 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1599 };
1600
1601 /* DTAP - Routing Area Update Complete */
1602 static const unsigned char ra_upd_complete[] = {
1603 0x08, 0x0a
1604 };
1605
1606 /* DTAP - Detach Request (MO) */
1607 /* normal detach, power_off = 1 */
1608 static const unsigned char detach_req[] = {
1609 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1610 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1611 };
1612
1613 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1614
1615 printf("Testing P-TMSI allocation\n");
1616
1617 printf(" - sgsn_alloc_ptmsi\n");
1618
1619 /* reset the PRNG used by sgsn_alloc_ptmsi */
1620 srand(1);
1621
1622 ptmsi1 = sgsn_alloc_ptmsi();
1623 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1624
1625 ptmsi2 = sgsn_alloc_ptmsi();
1626 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1627
1628 OSMO_ASSERT(ptmsi1 != ptmsi2);
1629
1630 printf(" - Repeated Attach Request\n");
1631
1632 /* reset the PRNG, so that the same P-TMSI will be generated
1633 * again */
1634 srand(1);
1635
1636 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1637
1638 /* Create a LLE/LLME */
1639 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1640 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1641 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1642
1643 /* inject the attach request */
1644 send_0408_message(lle->llme, foreign_tlli,
1645 attach_req, ARRAY_SIZE(attach_req));
1646
1647 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1648 OSMO_ASSERT(ctx != NULL);
1649 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1650 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1651
1652 old_ptmsi = ctx->p_tmsi_old;
1653
1654 /* we expect an identity request (IMEI) */
1655 OSMO_ASSERT(sgsn_tx_counter == 1);
1656
1657 /* inject the identity response (IMEI) */
1658 send_0408_message(ctx->llme, foreign_tlli,
1659 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1660
1661 /* check that the MM context has not been removed due to a failed
1662 * authorization */
1663 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1664
1665 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1666 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1667
1668 /* we expect an attach accept */
1669 OSMO_ASSERT(sgsn_tx_counter == 1);
1670
1671 /* we ignore this and send the attach again */
1672 send_0408_message(lle->llme, foreign_tlli,
1673 attach_req, ARRAY_SIZE(attach_req));
1674
1675 /* the allocated P-TMSI should be the same */
1676 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1677 OSMO_ASSERT(ctx != NULL);
1678 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1679 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1680 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1681
1682 /* inject the attach complete */
1683 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1684 send_0408_message(ctx->llme, local_tlli,
1685 attach_compl, ARRAY_SIZE(attach_compl));
1686
1687 /* we don't expect a response */
1688 OSMO_ASSERT(sgsn_tx_counter == 0);
1689
1690 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1691 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1692 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1693
1694 printf(" - Repeated RA Update Request\n");
1695
1696 /* inject the RA update request */
1697 send_0408_message(ctx->llme, local_tlli,
1698 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1699
1700 /* we expect an RA update accept */
1701 OSMO_ASSERT(sgsn_tx_counter == 1);
1702
1703 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1704 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1705 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1706
1707 /* repeat the RA update request */
1708 send_0408_message(ctx->llme, local_tlli,
1709 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1710
1711 /* we expect an RA update accept */
1712 OSMO_ASSERT(sgsn_tx_counter == 1);
1713
1714 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1715 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1716 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1717
1718 /* inject the RA update complete */
1719 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1720 send_0408_message(ctx->llme, local_tlli,
1721 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1722
1723 /* we don't expect a response */
1724 OSMO_ASSERT(sgsn_tx_counter == 0);
1725
1726 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1727 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1728 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1729
1730 /* inject the detach */
1731 send_0408_message(ctx->llme, local_tlli,
1732 detach_req, ARRAY_SIZE(detach_req));
1733
1734 /* verify that things are gone */
1735 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1736 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1737 OSMO_ASSERT(!ictx);
1738
1739 sgsn->cfg.auth_policy = saved_auth_policy;
1740}
1741
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001742static struct log_info_cat gprs_categories[] = {
1743 [DMM] = {
1744 .name = "DMM",
1745 .description = "Layer3 Mobility Management (MM)",
1746 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001747 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001748 },
1749 [DPAG] = {
1750 .name = "DPAG",
1751 .description = "Paging Subsystem",
1752 .color = "\033[1;38m",
1753 .enabled = 1, .loglevel = LOGL_NOTICE,
1754 },
1755 [DMEAS] = {
1756 .name = "DMEAS",
1757 .description = "Radio Measurement Processing",
1758 .enabled = 0, .loglevel = LOGL_NOTICE,
1759 },
1760 [DREF] = {
1761 .name = "DREF",
1762 .description = "Reference Counting",
1763 .enabled = 0, .loglevel = LOGL_NOTICE,
1764 },
1765 [DGPRS] = {
1766 .name = "DGPRS",
1767 .description = "GPRS Packet Service",
1768 .enabled = 1, .loglevel = LOGL_DEBUG,
1769 },
1770 [DNS] = {
1771 .name = "DNS",
1772 .description = "GPRS Network Service (NS)",
1773 .enabled = 1, .loglevel = LOGL_INFO,
1774 },
1775 [DBSSGP] = {
1776 .name = "DBSSGP",
1777 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1778 .enabled = 1, .loglevel = LOGL_DEBUG,
1779 },
1780 [DLLC] = {
1781 .name = "DLLC",
1782 .description = "GPRS Logical Link Control Protocol (LLC)",
1783 .enabled = 1, .loglevel = LOGL_DEBUG,
1784 },
1785 [DSNDCP] = {
1786 .name = "DSNDCP",
1787 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1788 .enabled = 1, .loglevel = LOGL_DEBUG,
1789 },
1790};
1791
1792static struct log_info info = {
1793 .cat = gprs_categories,
1794 .num_cat = ARRAY_SIZE(gprs_categories),
1795};
1796
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001797int main(int argc, char **argv)
1798{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001799 osmo_init_logging(&info);
1800 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1801 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1802
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001803 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001804 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001805
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001806 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001807 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001808 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001809 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001810 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001811 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001812 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001813 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001814 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001815 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001816 test_gmm_attach_acl();
1817 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001818 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001819 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001820 test_gmm_attach_subscr_gsup_auth(0);
1821 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001822 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001823 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001824 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001825 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001826 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001827
1828 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001829 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001830 return 0;
1831}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001832
1833
1834/* stubs */
1835struct osmo_prim_hdr;
1836int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1837{
1838 abort();
1839}