blob: 1036e41fc3591ccd0c1beab2c364e23f2f1f9396 [file] [log] [blame]
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001/* Test the SGSN */
2/*
3 * (C) 2014 by Holger Hans Peter Freyther
4 * (C) 2014 by sysmocom s.f.m.c. GmbH
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020029
Jacob Erlbeck189999d2014-10-27 14:34:13 +010030#include <osmocom/gprs/gprs_bssgp.h>
31
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020032#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeckbce20612015-01-05 18:57:32 +010033#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020034
35#include <osmocom/core/application.h>
36#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010037#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020038
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020039#include <stdio.h>
40
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020041extern void *tall_msgb_ctx;
42
43void *tall_bsc_ctx;
44static struct sgsn_instance sgsn_inst = {
45 .config_file = "osmo_sgsn.cfg",
46 .cfg = {
47 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010048 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020049 },
50};
51struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010052unsigned sgsn_tx_counter = 0;
53
54/* override */
55int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
56 struct bssgp_dl_ud_par *dup)
57{
58 sgsn_tx_counter += 1;
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +010059 msgb_free(msg);
Jacob Erlbeck189999d2014-10-27 14:34:13 +010060 return 0;
61}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020062
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010063/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010064void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
65void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010066 &__real_sgsn_update_subscriber_data;
67
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010068void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010069{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010070 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010071}
72
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010073/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
74int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
75int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
76 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010077
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010078int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
79 return (*subscr_request_update_location_cb)(mmctx);
80};
81
82/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
83int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
84int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
85 &__real_gprs_subscr_request_auth_info;
86
87int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
88 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010089};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010090
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010091/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
92int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
93int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
94 &__real_gprs_gsup_client_send;
95
96int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
97{
98 return (*gprs_gsup_client_send_cb)(gsupc, msg);
99};
100
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200101static int count(struct llist_head *head)
102{
103 struct llist_head *cur;
104 int count = 0;
105
106 llist_for_each(cur, head)
107 count += 1;
108
109 return count;
110}
111
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200112static struct msgb *create_msg(const uint8_t *data, size_t len)
113{
114 struct msgb *msg = msgb_alloc(len + 8, "test message");
115 msg->l1h = msgb_put(msg, 8);
116 msg->l2h = msgb_put(msg, len);
117 memcpy(msg->l2h, data, len);
118
119 msgb_bcid(msg) = msg->l1h;
120 msgb_gmmh(msg) = msg->l2h;
121 return msg;
122}
123
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100124/*
125 * Create a context and search for it
126 */
127static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
128{
129 struct sgsn_mm_ctx *ctx, *ictx;
130 struct gprs_llc_lle *lle;
131 int old_count = count(gprs_llme_list());
132
133 lle = gprs_lle_get_or_create(tlli, 3);
134 ctx = sgsn_mm_ctx_alloc(tlli, raid);
135 ctx->mm_state = GMM_REGISTERED_NORMAL;
136 ctx->llme = lle->llme;
137
138 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
139 OSMO_ASSERT(ictx == ctx);
140
141 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
142
143 return ctx;
144}
145
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100146static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
147 const uint8_t *data, size_t data_len)
148{
149 struct msgb *msg;
150
151 sgsn_tx_counter = 0;
152
153 msg = create_msg(data, data_len);
154 msgb_tlli(msg) = tlli;
155 gsm0408_gprs_rcvmsg(msg, llme);
156 msgb_free(msg);
157}
158
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200159static void test_llme(void)
160{
161 struct gprs_llc_lle *lle, *lle_copy;
162 uint32_t local_tlli;
163 uint32_t foreign_tlli;
164
165 printf("Testing LLME allocations\n");
166 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
167 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
168
169 /* initial state */
170 OSMO_ASSERT(count(gprs_llme_list()) == 0);
171
172 /* Create a new entry */
173 lle = gprs_lle_get_or_create(local_tlli, 3);
174 OSMO_ASSERT(lle);
175 OSMO_ASSERT(count(gprs_llme_list()) == 1);
176
177 /* No new entry is created */
178 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
179 OSMO_ASSERT(lle == lle_copy);
180 OSMO_ASSERT(count(gprs_llme_list()) == 1);
181 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
182 OSMO_ASSERT(lle == lle_copy);
183 OSMO_ASSERT(count(gprs_llme_list()) == 1);
184
185 /* unassign which should delete it*/
186 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
187
188 /* Check that everything was cleaned up */
189 OSMO_ASSERT(count(gprs_llme_list()) == 0);
190}
191
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100192struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100193void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100194{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100195 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100196 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100197 __func__, mmctx, mmctx->subscr);
198 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100199}
200
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100201static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
202{
203 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100204 OSMO_ASSERT(subscr);
205 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100206
207 sfound = gprs_subscr_get_by_imsi(imsi);
208 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100209
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100210 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100211}
212
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100213static void show_subscrs(FILE *out)
214{
215 struct gsm_subscriber *subscr;
216
217 llist_for_each_entry(subscr, &active_subscribers, entry) {
218 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100219 "use count: %d\n",
220 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100221 }
222}
223
224static void assert_no_subscrs()
225{
226 show_subscrs(stdout);
227 fflush(stdout);
228 OSMO_ASSERT(llist_empty(&active_subscribers));
229}
230
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100231static void test_subscriber(void)
232{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100233 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100234 const char *imsi1 = "1234567890";
235 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100236 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100237
238 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
239
240 printf("Testing core subscriber data API\n");
241
242 /* Check for emptiness */
243 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
244 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100245 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100246
247 /* Allocate entry 1 */
248 s1 = gprs_subscr_get_or_create(imsi1);
249 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100250 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100251 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100252
253 /* Allocate entry 2 */
254 s2 = gprs_subscr_get_or_create(imsi2);
255 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100256
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100257 /* Allocate entry 3 */
258 s3 = gprs_subscr_get_or_create(imsi3);
259
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100260 /* Check entries */
261 assert_subscr(s1, imsi1);
262 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100263 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100264
265 /* Update entry 1 */
266 last_updated_subscr = NULL;
267 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100268 OSMO_ASSERT(last_updated_subscr == NULL);
269 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
270 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100271
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100272 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100273 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100274 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100275 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100276 sfound = gprs_subscr_get_by_imsi(imsi1);
277 OSMO_ASSERT(sfound == NULL);
278
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100279 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100280 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100281
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100282 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100283 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100284 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100285 s2 = NULL;
286 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
287 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100288 assert_subscr(s3, imsi3);
289
290 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100291 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100292 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100293 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100294 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100295
296 OSMO_ASSERT(llist_empty(&active_subscribers));
297
298 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
299}
300
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100301static void test_auth_triplets(void)
302{
303 struct gsm_subscriber *s1, *s1found;
304 const char *imsi1 = "1234567890";
305 struct gsm_auth_tuple *at;
306 struct sgsn_mm_ctx *ctx;
307 struct gprs_ra_id raid = { 0, };
308 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100309
310 printf("Testing authentication triplet handling\n");
311
312 /* Check for emptiness */
313 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
314
315 /* Allocate entry 1 */
316 s1 = gprs_subscr_get_or_create(imsi1);
317 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
318 s1found = gprs_subscr_get_by_imsi(imsi1);
319 OSMO_ASSERT(s1found == s1);
320 subscr_put(s1found);
321
322 /* Create a context */
323 OSMO_ASSERT(count(gprs_llme_list()) == 0);
324 ctx = alloc_mm_ctx(local_tlli, &raid);
325
326 /* Attach s1 to ctx */
327 ctx->subscr = subscr_get(s1);
328 ctx->subscr->sgsn_data->mm = ctx;
329
330 /* Try to get auth tuple */
331 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
332 OSMO_ASSERT(at == NULL);
333
334 /* Add triplets */
335 s1->sgsn_data->auth_triplets[0].key_seq = 0;
336 s1->sgsn_data->auth_triplets[1].key_seq = 1;
337 s1->sgsn_data->auth_triplets[2].key_seq = 2;
338
339 /* Try to get auth tuple */
340 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
341 OSMO_ASSERT(at != NULL);
342 OSMO_ASSERT(at->key_seq == 0);
343 OSMO_ASSERT(at->use_count == 1);
344 at = sgsn_auth_get_tuple(ctx, at->key_seq);
345 OSMO_ASSERT(at != NULL);
346 OSMO_ASSERT(at->key_seq == 1);
347 OSMO_ASSERT(at->use_count == 1);
348 at = sgsn_auth_get_tuple(ctx, at->key_seq);
349 OSMO_ASSERT(at != NULL);
350 OSMO_ASSERT(at->key_seq == 2);
351 OSMO_ASSERT(at->use_count == 1);
352 at = sgsn_auth_get_tuple(ctx, at->key_seq);
353 OSMO_ASSERT(at == NULL);
354
355 /* Free MM context and subscriber */
356 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100357 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100358 s1found = gprs_subscr_get_by_imsi(imsi1);
359 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100360}
361
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100362#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
363
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100364static int rx_gsup_message(const uint8_t *data, size_t data_len)
365{
366 struct msgb *msg;
367 int rc;
368
369 msg = msgb_alloc(1024, __func__);
370 msg->l2h = msgb_put(msg, data_len);
371 OSMO_ASSERT(msg->l2h != NULL);
372 memcpy(msg->l2h, data, data_len);
373 rc = gprs_subscr_rx_gsup_message(msg);
374 msgb_free(msg);
375
376 return rc;
377}
378
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100379static void test_subscriber_gsup(void)
380{
381 struct gsm_subscriber *s1, *s1found;
382 const char *imsi1 = "1234567890";
383 struct sgsn_mm_ctx *ctx;
384 struct gprs_ra_id raid = { 0, };
385 uint32_t local_tlli = 0xffeeddcc;
386 struct gprs_llc_llme *llme;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100387 int rc;
388
389 static const uint8_t send_auth_info_res[] = {
390 0x0a,
391 TEST_GSUP_IMSI1_IE,
392 0x03, 0x22, /* Auth tuple */
393 0x20, 0x10,
394 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
395 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
396 0x21, 0x04,
397 0x21, 0x22, 0x23, 0x24,
398 0x22, 0x08,
399 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
400 0x03, 0x22, /* Auth tuple */
401 0x20, 0x10,
402 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
403 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
404 0x21, 0x04,
405 0xa1, 0xa2, 0xa3, 0xa4,
406 0x22, 0x08,
407 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
408 };
409
410 static const uint8_t send_auth_info_err[] = {
411 0x09,
412 TEST_GSUP_IMSI1_IE,
413 0x02, 0x01, 0x07 /* GPRS not allowed */
414 };
415
416 static const uint8_t update_location_res[] = {
417 0x06,
418 TEST_GSUP_IMSI1_IE,
419 0x04, 0x00, /* PDP info complete */
420 0x05, 0x12,
421 0x10, 0x01, 0x01,
422 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
423 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
424 0x05, 0x11,
425 0x10, 0x01, 0x02,
426 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
427 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
428 };
429
430 static const uint8_t update_location_err[] = {
431 0x05,
432 TEST_GSUP_IMSI1_IE,
433 0x02, 0x01, 0x07 /* GPRS not allowed */
434 };
435
436 static const uint8_t location_cancellation_req[] = {
437 0x1c,
438 TEST_GSUP_IMSI1_IE,
439 0x06, 0x01, 0x00,
440 };
441
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100442 static const uint8_t location_cancellation_req_other[] = {
443 0x1c,
444 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
445 0x06, 0x01, 0x00,
446 };
447
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100448 static const uint8_t purge_ms_err[] = {
449 0x0d,
450 TEST_GSUP_IMSI1_IE,
451 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
452 };
453
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100454 static const uint8_t purge_ms_err_no_cause[] = {
455 0x0d,
456 TEST_GSUP_IMSI1_IE,
457 };
458
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100459 static const uint8_t purge_ms_res[] = {
460 0x0e,
461 TEST_GSUP_IMSI1_IE,
462 0x07, 0x00,
463 };
464
465
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100466 static const uint8_t insert_data_req[] = {
467 0x10,
468 TEST_GSUP_IMSI1_IE,
469 0x05, 0x11,
470 0x10, 0x01, 0x03,
471 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
472 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
473 };
474
475 static const uint8_t delete_data_req[] = {
476 0x14,
477 TEST_GSUP_IMSI1_IE,
478 0x10, 0x01, 0x03,
479 };
480
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100481 printf("Testing subcriber GSUP handling\n");
482
483 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
484
485 /* Check for emptiness */
486 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
487
488 /* Allocate entry 1 */
489 s1 = gprs_subscr_get_or_create(imsi1);
490 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
491 s1found = gprs_subscr_get_by_imsi(imsi1);
492 OSMO_ASSERT(s1found == s1);
493 subscr_put(s1found);
494
495 /* Create a context */
496 OSMO_ASSERT(count(gprs_llme_list()) == 0);
497 ctx = alloc_mm_ctx(local_tlli, &raid);
498 llme = ctx->llme;
499
500 /* Attach s1 to ctx */
501 ctx->subscr = subscr_get(s1);
502 ctx->subscr->sgsn_data->mm = ctx;
503
504 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100505 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100506 OSMO_ASSERT(rc >= 0);
507 OSMO_ASSERT(last_updated_subscr == s1);
508
509 /* Check triplets */
510 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
511 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
512 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
513
514 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100515 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_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 triplets */
520 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
521 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
522 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
523
524 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100525 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100526 OSMO_ASSERT(rc >= 0);
527 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100528 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100529
530 /* Check authorization */
531 OSMO_ASSERT(s1->authorized == 1);
532
533 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100534 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100535 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100536 OSMO_ASSERT(last_updated_subscr == s1);
537
538 /* Check authorization */
539 OSMO_ASSERT(s1->authorized == 0);
540
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100541 /* Inject InsertSubscrData GSUP message */
542 last_updated_subscr = NULL;
543 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
544 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
545 OSMO_ASSERT(last_updated_subscr == NULL);
546
547 /* Inject DeleteSubscrData GSUP message */
548 last_updated_subscr = NULL;
549 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
550 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
551 OSMO_ASSERT(last_updated_subscr == NULL);
552
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100553 /* Inject wrong LocCancelReq GSUP message */
554 last_updated_subscr = NULL;
555 rc = rx_gsup_message(location_cancellation_req_other,
556 sizeof(location_cancellation_req_other));
557 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
558 OSMO_ASSERT(last_updated_subscr == NULL);
559
560 /* Check cancellation result */
561 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
562 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
563
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100564 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100565 rc = rx_gsup_message(location_cancellation_req,
566 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100567 OSMO_ASSERT(rc >= 0);
568 OSMO_ASSERT(last_updated_subscr == s1);
569
570 /* Check cancellation result */
571 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
572 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
573
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100574 /* Inject PurgeMsRes GSUP message */
575 rc = rx_gsup_message(purge_ms_res,
576 sizeof(purge_ms_res));
577 OSMO_ASSERT(rc >= 0);
578 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
579
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100580 /* Free MM context and subscriber */
581 subscr_put(s1);
582 s1found = gprs_subscr_get_by_imsi(imsi1);
583 OSMO_ASSERT(s1found == NULL);
584 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
585
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100586 /* Inject PurgeMsRes GSUP message */
587 rc = rx_gsup_message(purge_ms_res,
588 sizeof(purge_ms_res));
589 OSMO_ASSERT(rc >= 0);
590
591 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
592 rc = rx_gsup_message(purge_ms_err,
593 sizeof(purge_ms_err));
594 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
595
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100596 /* Inject PurgeMsErr() GSUP message */
597 rc = rx_gsup_message(purge_ms_err_no_cause,
598 sizeof(purge_ms_err_no_cause));
599 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
600
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100601 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
602 last_updated_subscr = NULL;
603 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100604 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100605 OSMO_ASSERT(last_updated_subscr == NULL);
606
607 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
608 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
609 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
610 OSMO_ASSERT(last_updated_subscr == NULL);
611
612 /* Inject LocCancelReq GSUP message (unknown IMSI) */
613 rc = rx_gsup_message(location_cancellation_req,
614 sizeof(location_cancellation_req));
615 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
616 OSMO_ASSERT(last_updated_subscr == NULL);
617
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100618 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
619}
620
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100621int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
622{
623 msgb_free(msg);
624 return 0;
625};
626
627
628static void test_subscriber_blocking(void)
629{
630 struct gsm_subscriber *s1;
631 const char *imsi1 = "1234567890";
632 struct sgsn_mm_ctx *ctx;
633 struct gprs_ra_id raid = { 0, };
634 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100635 int rc;
636
637 printf("Testing subcriber procedure blocking\n");
638
639 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
640 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
641
642 /* Check for emptiness */
643 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
644
645 /* Create a context */
646 OSMO_ASSERT(count(gprs_llme_list()) == 0);
647 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100648 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
649
650 /* Allocate and attach a subscriber */
651 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
652 assert_subscr(s1, imsi1);
653
654 /* Start SendAuthInfoRequest procedure */
655 rc = gprs_subscr_query_auth_info(s1);
656 /* Not blocking */
657 OSMO_ASSERT(rc == 0);
658
659 /* Start UpdateLocation procedure */
660 rc = gprs_subscr_location_update(s1);
661 /* Blocking */
662 OSMO_ASSERT(rc == 0);
663
664 /* Start PurgeMS procedure */
665 rc = gprs_subscr_purge(s1);
666 /* Not blocking */
667 OSMO_ASSERT(rc == 0);
668 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
669
670 /* Start PurgeMS procedure (retry) */
671 rc = gprs_subscr_purge(s1);
672 /* Not blocking */
673 OSMO_ASSERT(rc == 0);
674
675 /* Start SendAuthInfoRequest procedure */
676 rc = gprs_subscr_query_auth_info(s1);
677 /* Blocking */
678 OSMO_ASSERT(rc == -EAGAIN);
679
680 /* Start UpdateLocation procedure */
681 rc = gprs_subscr_location_update(s1);
682 /* Blocking */
683 OSMO_ASSERT(rc == -EAGAIN);
684
685 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
686 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
687
688 /* Start SendAuthInfoRequest procedure */
689 rc = gprs_subscr_query_auth_info(s1);
690 /* Not blocking */
691 OSMO_ASSERT(rc == 0);
692
693 /* Start UpdateLocation procedure */
694 rc = gprs_subscr_location_update(s1);
695 /* Blocking */
696 OSMO_ASSERT(rc == 0);
697
698 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100699 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100700
701 assert_no_subscrs();
702
703 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
704 talloc_free(sgsn->gsup_client);
705 sgsn->gsup_client = NULL;
706}
707
708
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200709/*
710 * Test that a GMM Detach will remove the MMCTX and the
711 * associated LLME.
712 */
713static void test_gmm_detach(void)
714{
715 struct gprs_ra_id raid = { 0, };
716 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200717 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200718
719 printf("Testing GMM detach\n");
720
721 /* DTAP - Detach Request (MO) */
722 /* normal detach, power_off = 0 */
723 static const unsigned char detach_req[] = {
724 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
725 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
726 };
727
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200728 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200729
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100730 /* Create a context */
731 OSMO_ASSERT(count(gprs_llme_list()) == 0);
732 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200733
734 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100735 send_0408_message(ctx->llme, local_tlli,
736 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200737
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100738 /* verify that a single message (hopefully the Detach Accept) has been
739 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100740 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100741
742 /* verify that things are gone */
743 OSMO_ASSERT(count(gprs_llme_list()) == 0);
744 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
745 OSMO_ASSERT(!ictx);
746}
747
748/*
749 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
750 * will not sent a Detach Accept message (power_off = 1)
751 */
752static void test_gmm_detach_power_off(void)
753{
754 struct gprs_ra_id raid = { 0, };
755 struct sgsn_mm_ctx *ctx, *ictx;
756 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100757
758 printf("Testing GMM detach (power off)\n");
759
760 /* DTAP - Detach Request (MO) */
761 /* normal detach, power_off = 1 */
762 static const unsigned char detach_req[] = {
763 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
764 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
765 };
766
767 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
768
769 /* Create a context */
770 OSMO_ASSERT(count(gprs_llme_list()) == 0);
771 ctx = alloc_mm_ctx(local_tlli, &raid);
772
773 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100774 send_0408_message(ctx->llme, local_tlli,
775 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100776
777 /* verify that no message (and therefore no Detach Accept) has been
778 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100779 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100780
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200781 /* verify that things are gone */
782 OSMO_ASSERT(count(gprs_llme_list()) == 0);
783 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200784 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200785}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200786
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200787/*
788 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
789 */
790static void test_gmm_detach_no_mmctx(void)
791{
792 struct gprs_llc_lle *lle;
793 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200794
795 printf("Testing GMM detach (no MMCTX)\n");
796
797 /* DTAP - Detach Request (MO) */
798 /* normal detach, power_off = 0 */
799 static const unsigned char detach_req[] = {
800 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
801 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
802 };
803
804 /* Create an LLME */
805 OSMO_ASSERT(count(gprs_llme_list()) == 0);
806 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
807 lle = gprs_lle_get_or_create(local_tlli, 3);
808
809 OSMO_ASSERT(count(gprs_llme_list()) == 1);
810
811 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100812 send_0408_message(lle->llme, local_tlli,
813 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200814
815 /* verify that the LLME is gone */
816 OSMO_ASSERT(count(gprs_llme_list()) == 0);
817}
818
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100819/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100820 * Test that a single GMM Detach Accept message will not cause the SGSN to send
821 * any message or leave an MM context at the SGSN.
822 */
823static void test_gmm_detach_accept_unexpected(void)
824{
825 struct gprs_llc_lle *lle;
826 uint32_t local_tlli;
827
828 printf("Testing GMM detach accept (unexpected)\n");
829
830 /* DTAP - Detach Accept (MT) */
831 /* normal detach */
832 static const unsigned char detach_acc[] = {
833 0x08, 0x06
834 };
835
836 /* Create an LLME */
837 OSMO_ASSERT(count(gprs_llme_list()) == 0);
838 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
839 lle = gprs_lle_get_or_create(local_tlli, 3);
840
841 /* inject the detach */
842 send_0408_message(lle->llme, local_tlli,
843 detach_acc, ARRAY_SIZE(detach_acc));
844
845 /* verify that no message (and therefore no Status or XID reset) has been
846 * sent by the SGSN */
847 OSMO_ASSERT(sgsn_tx_counter == 0);
848
849 /* verify that things are gone */
850 OSMO_ASSERT(count(gprs_llme_list()) == 0);
851}
852
853/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100854 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
855 */
856static void test_gmm_status_no_mmctx(void)
857{
858 struct gprs_llc_lle *lle;
859 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100860
861 printf("Testing GMM Status (no MMCTX)\n");
862
863 /* DTAP - GMM Status, protocol error */
864 static const unsigned char gmm_status[] = {
865 0x08, 0x20, 0x6f
866 };
867
868 /* Create an LLME */
869 OSMO_ASSERT(count(gprs_llme_list()) == 0);
870 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
871 lle = gprs_lle_get_or_create(local_tlli, 3);
872
873 OSMO_ASSERT(count(gprs_llme_list()) == 1);
874
875 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100876 send_0408_message(lle->llme, local_tlli,
877 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100878
879 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100880 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100881
882 /* verify that the LLME is gone */
883 OSMO_ASSERT(count(gprs_llme_list()) == 0);
884}
885
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100886/*
887 * Test the GMM Attach procedure
888 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100889static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100890{
891 struct gprs_ra_id raid = { 0, };
892 struct sgsn_mm_ctx *ctx = NULL;
893 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100894 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100895 uint32_t foreign_tlli;
896 uint32_t local_tlli = 0;
897 struct gprs_llc_lle *lle;
898
899 /* DTAP - Attach Request */
900 /* The P-TMSI is not known by the SGSN */
901 static const unsigned char attach_req[] = {
902 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
903 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
904 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
905 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
906 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
907 };
908
909 /* DTAP - Identity Response IMEI */
910 static const unsigned char ident_resp_imei[] = {
911 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
912 0x56
913 };
914
915 /* DTAP - Identity Response IMSI */
916 static const unsigned char ident_resp_imsi[] = {
917 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
918 0x54
919 };
920
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100921 /* DTAP - Authentication and Ciphering Resp */
922 static const unsigned char auth_ciph_resp[] = {
923 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
924 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
925 };
926
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100927 /* DTAP - Attach Complete */
928 static const unsigned char attach_compl[] = {
929 0x08, 0x03
930 };
931
932 /* DTAP - Detach Request (MO) */
933 /* normal detach, power_off = 0 */
934 static const unsigned char detach_req[] = {
935 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
936 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
937 };
938
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100939 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100940
941 /* reset the PRNG used by sgsn_alloc_ptmsi */
942 srand(1);
943
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100944 ptmsi1 = sgsn_alloc_ptmsi();
945 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
946
947 /* reset the PRNG, so that the same P-TMSI sequence will be generated
948 * again */
949 srand(1);
950
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100951 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
952
953 /* Create a LLE/LLME */
954 OSMO_ASSERT(count(gprs_llme_list()) == 0);
955 lle = gprs_lle_get_or_create(foreign_tlli, 3);
956 OSMO_ASSERT(count(gprs_llme_list()) == 1);
957
958 /* inject the attach request */
959 send_0408_message(lle->llme, foreign_tlli,
960 attach_req, ARRAY_SIZE(attach_req));
961
962 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
963 OSMO_ASSERT(ctx != NULL);
964 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
965
966 /* we expect an identity request (IMEI) */
967 OSMO_ASSERT(sgsn_tx_counter == 1);
968
969 /* inject the identity response (IMEI) */
970 send_0408_message(ctx->llme, foreign_tlli,
971 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
972
973 /* we expect an identity request (IMSI) */
974 OSMO_ASSERT(sgsn_tx_counter == 1);
975
976 /* inject the identity response (IMSI) */
977 send_0408_message(ctx->llme, foreign_tlli,
978 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
979
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100980 /* check that the MM context has not been removed due to a failed
981 * authorization */
982 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
983
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100984 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100985
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100986retry_attach_req:
987
988 if (retry && sgsn_tx_counter == 0) {
989 fprintf(stderr, "Retrying attach request\n");
990 /* re-inject the attach request */
991 send_0408_message(lle->llme, foreign_tlli,
992 attach_req, ARRAY_SIZE(attach_req));
993 }
994
995 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
996 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100997
998 /* inject the auth & ciph response */
999 send_0408_message(ctx->llme, foreign_tlli,
1000 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1001
1002 /* check that the MM context has not been removed due to a
1003 * failed authorization */
1004 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1005 }
1006
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001007 if (retry && sgsn_tx_counter == 0)
1008 goto retry_attach_req;
1009
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001010 /* we expect an attach accept/reject */
1011 OSMO_ASSERT(sgsn_tx_counter == 1);
1012
1013 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001014 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001015
1016 /* inject the attach complete */
1017 send_0408_message(ctx->llme, local_tlli,
1018 attach_compl, ARRAY_SIZE(attach_compl));
1019
1020 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1021
1022 /* we don't expect a response */
1023 OSMO_ASSERT(sgsn_tx_counter == 0);
1024
1025 /* inject the detach */
1026 send_0408_message(ctx->llme, local_tlli,
1027 detach_req, ARRAY_SIZE(detach_req));
1028
1029 /* verify that things are gone */
1030 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1031 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1032 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001033}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001034
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001035static void test_gmm_attach_acl(void)
1036{
1037 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1038
1039 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1040 sgsn_acl_add("123456789012345", &sgsn->cfg);
1041 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001042 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001043 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001044
1045 sgsn->cfg.auth_policy = saved_auth_policy;
1046}
1047
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001048int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001049 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001050 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001051 if (rc == -ENOTSUP) {
1052 OSMO_ASSERT(mmctx->subscr);
1053 gprs_subscr_update(mmctx->subscr);
1054 }
1055 return rc;
1056};
1057
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001058int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1059 gprs_subscr_update(mmctx->subscr);
1060 return 0;
1061};
1062
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001063static void test_gmm_attach_subscr(void)
1064{
1065 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1066 struct gsm_subscriber *subscr;
1067
1068 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001069 subscr_request_update_location_cb = my_subscr_request_update_location;
1070 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001071
1072 subscr = gprs_subscr_get_or_create("123456789012345");
1073 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001074
1075 printf("Auth policy 'remote': ");
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 Erlbeckbe2c8d92014-11-12 10:18:09 +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;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001083}
1084
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001085int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1086{
1087 /* Fake an authentication */
1088 OSMO_ASSERT(mmctx->subscr);
1089 mmctx->is_authenticated = 1;
1090 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001091
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001092 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001093};
1094
1095static void test_gmm_attach_subscr_fake_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;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001101 subscr_request_update_location_cb = my_subscr_request_update_location;
1102 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001103
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 Erlbeck2e5e94c2014-12-08 15:26:47 +01001108
1109 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001110 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001111 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001112 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001113
1114 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001115 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1116 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1117}
1118
1119int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1120{
1121 struct gsm_auth_tuple at = {
1122 .sres = {0x51, 0xe5, 0x51, 0xe5},
1123 .key_seq = 0
1124 };
1125
1126 /* Fake an authentication */
1127 OSMO_ASSERT(mmctx->subscr);
1128 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1129
1130 gprs_subscr_update_auth_info(mmctx->subscr);
1131
1132 return 0;
1133};
1134
1135static void test_gmm_attach_subscr_real_auth(void)
1136{
1137 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1138 struct gsm_subscriber *subscr;
1139
1140 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1141 subscr_request_update_location_cb = my_subscr_request_update_location;
1142 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1143
1144 subscr = gprs_subscr_get_or_create("123456789012345");
1145 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001146 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001147 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001148
1149 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001150
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001151 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001152 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001153 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001154
1155 sgsn->cfg.auth_policy = saved_auth_policy;
1156 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1157 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001158}
1159
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001160#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1161 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1162
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001163static int auth_info_skip = 0;
1164static int upd_loc_skip = 0;
1165
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001166int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1167{
1168 static const uint8_t send_auth_info_res[] = {
1169 0x0a,
1170 TEST_GSUP_IMSI_LONG_IE,
1171 0x03, 0x22, /* Auth tuple */
1172 0x20, 0x10,
1173 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1174 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1175 0x21, 0x04,
1176 0x51, 0xe5, 0x51, 0xe5,
1177 0x22, 0x08,
1178 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1179 };
1180
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001181 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001182
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001183 if (auth_info_skip > 0) {
1184 auth_info_skip -= 1;
1185 return -EAGAIN;
1186 }
1187
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001188 /* Fake an SendAuthInfoRes */
1189 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1190
1191 return 0;
1192};
1193
1194int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1195 static const uint8_t update_location_res[] = {
1196 0x06,
1197 TEST_GSUP_IMSI_LONG_IE,
1198 0x04, 0x00, /* PDP info complete */
1199 0x05, 0x12,
1200 0x10, 0x01, 0x01,
1201 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1202 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1203 };
1204
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001205 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001206
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001207 if (upd_loc_skip > 0) {
1208 upd_loc_skip -= 1;
1209 return -EAGAIN;
1210 }
1211
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001212 /* Fake an UpdateLocRes */
1213 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1214};
1215
1216
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001217static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001218{
1219 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1220 struct gsm_subscriber *subscr;
1221
1222 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1223 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1224 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001225 if (retry) {
1226 upd_loc_skip = 3;
1227 auth_info_skip = 3;
1228 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001229
1230 subscr = gprs_subscr_get_or_create("123456789012345");
1231 subscr->authorized = 1;
1232 sgsn->cfg.require_authentication = 1;
1233 sgsn->cfg.require_update_location = 1;
1234 subscr_put(subscr);
1235
1236 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001237 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001238 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001239
1240 sgsn->cfg.auth_policy = saved_auth_policy;
1241 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1242 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001243 upd_loc_skip = 0;
1244 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001245}
1246
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001247int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1248{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001249 struct gprs_gsup_message to_peer = {0};
1250 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001251 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001252 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001253
1254 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001255 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1256 OSMO_ASSERT(rc >= 0);
1257 OSMO_ASSERT(to_peer.imsi[0] != 0);
1258 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001259
1260 /* This invalidates the pointers in to_peer */
1261 msgb_free(msg);
1262
1263 switch (to_peer.message_type) {
1264 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1265 /* Send UPDATE_LOCATION_RESULT */
1266 return my_subscr_request_update_gsup_auth(NULL);
1267
1268 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1269 /* Send SEND_AUTH_INFO_RESULT */
1270 return my_subscr_request_auth_info_gsup_auth(NULL);
1271
1272 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001273 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1274 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001275
1276 default:
1277 if ((to_peer.message_type & 0b00000011) == 0) {
1278 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001279 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001280 from_peer.message_type = to_peer.message_type + 1;
1281 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1282 break;
1283 }
1284
1285 /* Ignore it */
1286 return 0;
1287 }
1288
1289 reply_msg = gprs_gsup_msgb_alloc();
1290 reply_msg->l2h = reply_msg->data;
1291 gprs_gsup_encode(reply_msg, &from_peer);
1292 gprs_subscr_rx_gsup_message(reply_msg);
1293 msgb_free(reply_msg);
1294
1295 return 0;
1296};
1297
1298static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1299{
1300 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1301 struct gsm_subscriber *subscr;
1302
1303 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001304 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1305
1306 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1307
1308 if (retry) {
1309 upd_loc_skip = 3;
1310 auth_info_skip = 3;
1311 }
1312
1313 printf("Auth policy 'remote', real GSUP based auth: ");
1314 test_gmm_attach(retry);
1315
1316 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001317 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001318 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001319
1320 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001321 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1322 upd_loc_skip = 0;
1323 auth_info_skip = 0;
1324 talloc_free(sgsn->gsup_client);
1325 sgsn->gsup_client = NULL;
1326}
1327
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001328/*
1329 * Test the GMM Rejects
1330 */
1331static void test_gmm_reject(void)
1332{
1333 struct gprs_ra_id raid = { 0, };
1334 struct sgsn_mm_ctx *ctx = NULL;
1335 uint32_t foreign_tlli;
1336 struct gprs_llc_lle *lle;
1337 int idx;
1338
1339 /* DTAP - Attach Request */
1340 /* Invalid MI length */
1341 static const unsigned char attach_req_inv_mi_len[] = {
1342 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1343 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1344 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1345 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1346 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1347 };
1348
1349 /* DTAP - Attach Request */
1350 /* Invalid MI type (IMEI) */
1351 static const unsigned char attach_req_inv_mi_type[] = {
1352 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1353 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1354 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1355 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1356 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1357 };
1358
1359 /* DTAP - Routing Area Update Request */
1360 static const unsigned char dtap_ra_upd_req[] = {
1361 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1362 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1363 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1364 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1365 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1366 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1367 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1368 };
1369
1370 /* DTAP - Routing Area Update Request */
1371 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1372 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1373 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1374 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1375 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1376 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1377 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1378 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1379 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1380 };
1381
1382 /* DTAP - Routing Area Update Request */
1383 /* Invalid cap length */
1384 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1385 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1386 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1387 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1388 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1389 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1390 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1391 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1392 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1393 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1394 };
1395
1396 struct test {
1397 const char *title;
1398 const unsigned char *msg;
1399 unsigned msg_len;
1400 unsigned num_resp;
1401
1402 };
1403 static struct test tests[] = {
1404 {
1405 .title = "Attach Request (invalid MI length)",
1406 .msg = attach_req_inv_mi_len,
1407 .msg_len = sizeof(attach_req_inv_mi_len),
1408 .num_resp = 1 /* Reject */
1409
1410 },
1411 {
1412 .title = "Attach Request (invalid MI type)",
1413 .msg = attach_req_inv_mi_type,
1414 .msg_len = sizeof(attach_req_inv_mi_type),
1415 .num_resp = 1 /* Reject */
1416 },
1417 {
1418 .title = "Routing Area Update Request (valid)",
1419 .msg = dtap_ra_upd_req,
1420 .msg_len = sizeof(dtap_ra_upd_req),
1421 .num_resp = 2 /* XID Reset + Reject */
1422 },
1423 {
1424 .title = "Routing Area Update Request (invalid type)",
1425 .msg = dtap_ra_upd_req_inv_type,
1426 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1427 .num_resp = 1 /* Reject */
1428 },
1429 {
1430 .title = "Routing Area Update Request (invalid CAP length)",
1431 .msg = dtap_ra_upd_req_inv_cap_len,
1432 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1433 .num_resp = 1 /* Reject */
1434 },
1435 };
1436
1437 printf("Testing GMM reject\n");
1438
1439 /* reset the PRNG used by sgsn_alloc_ptmsi */
1440 srand(1);
1441
1442 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1443
1444 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1445
1446 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1447 const struct test *test = &tests[idx];
1448 printf(" - %s\n", test->title);
1449
1450 /* Create a LLE/LLME */
1451 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1452 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1453
1454 /* Inject the Request message */
1455 send_0408_message(lle->llme, foreign_tlli,
1456 test->msg, test->msg_len);
1457
1458 /* We expect a Reject message */
1459 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1460 sgsn_tx_counter, test->num_resp);
1461 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1462
1463 /* verify that LLME/MM are removed */
1464 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1465 OSMO_ASSERT(ctx == NULL);
1466 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1467 }
1468}
1469
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001470/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001471 * Test cancellation of attached MM contexts
1472 */
1473static void test_gmm_cancel(void)
1474{
1475 struct gprs_ra_id raid = { 0, };
1476 struct sgsn_mm_ctx *ctx = NULL;
1477 struct sgsn_mm_ctx *ictx;
1478 uint32_t ptmsi1;
1479 uint32_t foreign_tlli;
1480 uint32_t local_tlli = 0;
1481 struct gprs_llc_lle *lle;
1482 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1483
1484 /* DTAP - Attach Request */
1485 /* The P-TMSI is not known by the SGSN */
1486 static const unsigned char attach_req[] = {
1487 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1488 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1489 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1490 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1491 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1492 };
1493
1494 /* DTAP - Identity Response IMEI */
1495 static const unsigned char ident_resp_imei[] = {
1496 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1497 0x56
1498 };
1499
1500 /* DTAP - Identity Response IMSI */
1501 static const unsigned char ident_resp_imsi[] = {
1502 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1503 0x54
1504 };
1505
1506 /* DTAP - Attach Complete */
1507 static const unsigned char attach_compl[] = {
1508 0x08, 0x03
1509 };
1510
1511 printf("Testing cancellation\n");
1512
1513 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1514
1515 /* reset the PRNG used by sgsn_alloc_ptmsi */
1516 srand(1);
1517
1518 ptmsi1 = sgsn_alloc_ptmsi();
1519 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1520
1521 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1522 * again */
1523 srand(1);
1524
1525 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1526
1527 /* Create a LLE/LLME */
1528 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1529 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1530 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1531
1532 /* inject the attach request */
1533 send_0408_message(lle->llme, foreign_tlli,
1534 attach_req, ARRAY_SIZE(attach_req));
1535
1536 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1537 OSMO_ASSERT(ctx != NULL);
1538 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1539
1540 /* we expect an identity request (IMEI) */
1541 OSMO_ASSERT(sgsn_tx_counter == 1);
1542
1543 /* inject the identity response (IMEI) */
1544 send_0408_message(ctx->llme, foreign_tlli,
1545 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1546
1547 /* we expect an identity request (IMSI) */
1548 OSMO_ASSERT(sgsn_tx_counter == 1);
1549
1550 /* inject the identity response (IMSI) */
1551 send_0408_message(ctx->llme, foreign_tlli,
1552 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1553
1554 /* check that the MM context has not been removed due to a failed
1555 * authorization */
1556 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1557
1558 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1559
1560 /* we expect an attach accept/reject */
1561 OSMO_ASSERT(sgsn_tx_counter == 1);
1562
1563 /* this has been randomly assigned by the SGSN */
1564 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1565
1566 /* inject the attach complete */
1567 send_0408_message(ctx->llme, local_tlli,
1568 attach_compl, ARRAY_SIZE(attach_compl));
1569
1570 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1571
1572 /* we don't expect a response */
1573 OSMO_ASSERT(sgsn_tx_counter == 0);
1574
1575 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001576 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001577
1578 /* verify that things are gone */
1579 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1580 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1581 OSMO_ASSERT(!ictx);
1582
1583 sgsn->cfg.auth_policy = saved_auth_policy;
1584}
1585
1586/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001587 * Test the dynamic allocation of P-TMSIs
1588 */
1589static void test_gmm_ptmsi_allocation(void)
1590{
1591 struct gprs_ra_id raid = { 0, };
1592 struct sgsn_mm_ctx *ctx = NULL;
1593 struct sgsn_mm_ctx *ictx;
1594 uint32_t foreign_tlli;
1595 uint32_t ptmsi1;
1596 uint32_t ptmsi2;
1597 uint32_t old_ptmsi;
1598 uint32_t local_tlli = 0;
1599 struct gprs_llc_lle *lle;
1600 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1601
1602 /* DTAP - Attach Request (IMSI 12131415161718) */
1603 static const unsigned char attach_req[] = {
1604 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1605 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1606 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1607 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1608 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1609 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1610 0x00,
1611 };
1612
1613 /* DTAP - Identity Response IMEI */
1614 static const unsigned char ident_resp_imei[] = {
1615 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1616 0x56
1617 };
1618
1619 /* DTAP - Attach Complete */
1620 static const unsigned char attach_compl[] = {
1621 0x08, 0x03
1622 };
1623
1624 /* DTAP - Routing Area Update Request */
1625 static const unsigned char ra_upd_req[] = {
1626 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1627 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1628 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1629 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1630 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1631 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1632 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1633 };
1634
1635 /* DTAP - Routing Area Update Complete */
1636 static const unsigned char ra_upd_complete[] = {
1637 0x08, 0x0a
1638 };
1639
1640 /* DTAP - Detach Request (MO) */
1641 /* normal detach, power_off = 1 */
1642 static const unsigned char detach_req[] = {
1643 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1644 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1645 };
1646
1647 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1648
1649 printf("Testing P-TMSI allocation\n");
1650
1651 printf(" - sgsn_alloc_ptmsi\n");
1652
1653 /* reset the PRNG used by sgsn_alloc_ptmsi */
1654 srand(1);
1655
1656 ptmsi1 = sgsn_alloc_ptmsi();
1657 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1658
1659 ptmsi2 = sgsn_alloc_ptmsi();
1660 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1661
1662 OSMO_ASSERT(ptmsi1 != ptmsi2);
1663
1664 printf(" - Repeated Attach Request\n");
1665
1666 /* reset the PRNG, so that the same P-TMSI will be generated
1667 * again */
1668 srand(1);
1669
1670 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1671
1672 /* Create a LLE/LLME */
1673 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1674 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1675 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1676
1677 /* inject the attach request */
1678 send_0408_message(lle->llme, foreign_tlli,
1679 attach_req, ARRAY_SIZE(attach_req));
1680
1681 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1682 OSMO_ASSERT(ctx != NULL);
1683 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1684 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1685
1686 old_ptmsi = ctx->p_tmsi_old;
1687
1688 /* we expect an identity request (IMEI) */
1689 OSMO_ASSERT(sgsn_tx_counter == 1);
1690
1691 /* inject the identity response (IMEI) */
1692 send_0408_message(ctx->llme, foreign_tlli,
1693 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1694
1695 /* check that the MM context has not been removed due to a failed
1696 * authorization */
1697 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1698
1699 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1700 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1701
1702 /* we expect an attach accept */
1703 OSMO_ASSERT(sgsn_tx_counter == 1);
1704
1705 /* we ignore this and send the attach again */
1706 send_0408_message(lle->llme, foreign_tlli,
1707 attach_req, ARRAY_SIZE(attach_req));
1708
1709 /* the allocated P-TMSI should be the same */
1710 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1711 OSMO_ASSERT(ctx != NULL);
1712 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1713 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1714 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1715
1716 /* inject the attach complete */
1717 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1718 send_0408_message(ctx->llme, local_tlli,
1719 attach_compl, ARRAY_SIZE(attach_compl));
1720
1721 /* we don't expect a response */
1722 OSMO_ASSERT(sgsn_tx_counter == 0);
1723
1724 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1725 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1726 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1727
1728 printf(" - Repeated RA Update Request\n");
1729
1730 /* inject the RA update request */
1731 send_0408_message(ctx->llme, local_tlli,
1732 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1733
1734 /* we expect an RA update accept */
1735 OSMO_ASSERT(sgsn_tx_counter == 1);
1736
1737 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1738 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1739 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1740
1741 /* repeat the RA update request */
1742 send_0408_message(ctx->llme, local_tlli,
1743 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1744
1745 /* we expect an RA update accept */
1746 OSMO_ASSERT(sgsn_tx_counter == 1);
1747
1748 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1749 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1750 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1751
1752 /* inject the RA update complete */
1753 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1754 send_0408_message(ctx->llme, local_tlli,
1755 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1756
1757 /* we don't expect a response */
1758 OSMO_ASSERT(sgsn_tx_counter == 0);
1759
1760 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1761 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1762 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1763
1764 /* inject the detach */
1765 send_0408_message(ctx->llme, local_tlli,
1766 detach_req, ARRAY_SIZE(detach_req));
1767
1768 /* verify that things are gone */
1769 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1770 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1771 OSMO_ASSERT(!ictx);
1772
1773 sgsn->cfg.auth_policy = saved_auth_policy;
1774}
1775
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001776static struct log_info_cat gprs_categories[] = {
1777 [DMM] = {
1778 .name = "DMM",
1779 .description = "Layer3 Mobility Management (MM)",
1780 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001781 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001782 },
1783 [DPAG] = {
1784 .name = "DPAG",
1785 .description = "Paging Subsystem",
1786 .color = "\033[1;38m",
1787 .enabled = 1, .loglevel = LOGL_NOTICE,
1788 },
1789 [DMEAS] = {
1790 .name = "DMEAS",
1791 .description = "Radio Measurement Processing",
1792 .enabled = 0, .loglevel = LOGL_NOTICE,
1793 },
1794 [DREF] = {
1795 .name = "DREF",
1796 .description = "Reference Counting",
1797 .enabled = 0, .loglevel = LOGL_NOTICE,
1798 },
1799 [DGPRS] = {
1800 .name = "DGPRS",
1801 .description = "GPRS Packet Service",
1802 .enabled = 1, .loglevel = LOGL_DEBUG,
1803 },
1804 [DNS] = {
1805 .name = "DNS",
1806 .description = "GPRS Network Service (NS)",
1807 .enabled = 1, .loglevel = LOGL_INFO,
1808 },
1809 [DBSSGP] = {
1810 .name = "DBSSGP",
1811 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1812 .enabled = 1, .loglevel = LOGL_DEBUG,
1813 },
1814 [DLLC] = {
1815 .name = "DLLC",
1816 .description = "GPRS Logical Link Control Protocol (LLC)",
1817 .enabled = 1, .loglevel = LOGL_DEBUG,
1818 },
1819 [DSNDCP] = {
1820 .name = "DSNDCP",
1821 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1822 .enabled = 1, .loglevel = LOGL_DEBUG,
1823 },
1824};
1825
1826static struct log_info info = {
1827 .cat = gprs_categories,
1828 .num_cat = ARRAY_SIZE(gprs_categories),
1829};
1830
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001831int main(int argc, char **argv)
1832{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001833 osmo_init_logging(&info);
1834 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1835 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1836
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001837 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001838 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001839
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001840 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001841 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001842 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001843 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001844 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001845 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001846 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001847 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001848 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001849 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001850 test_gmm_attach_acl();
1851 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001852 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001853 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001854 test_gmm_attach_subscr_gsup_auth(0);
1855 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001856 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001857 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001858 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001859 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001860 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001861
1862 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001863 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001864 return 0;
1865}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001866
1867
1868/* stubs */
1869struct osmo_prim_hdr;
1870int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1871{
1872 abort();
1873}