blob: 5e74b0ece5e1c0b0543dcad985db604ed2460de2 [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);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100518 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100519
520 /* Check triplets */
521 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
522 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
523 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
524
525 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100526 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100527 OSMO_ASSERT(rc >= 0);
528 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100529 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100530 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100531
532 /* Check authorization */
533 OSMO_ASSERT(s1->authorized == 1);
534
535 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100536 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100537 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100538 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100539 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100540
541 /* Check authorization */
542 OSMO_ASSERT(s1->authorized == 0);
543
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100544 /* Inject InsertSubscrData GSUP message */
545 last_updated_subscr = NULL;
546 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
547 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
548 OSMO_ASSERT(last_updated_subscr == NULL);
549
550 /* Inject DeleteSubscrData GSUP message */
551 last_updated_subscr = NULL;
552 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
553 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
554 OSMO_ASSERT(last_updated_subscr == NULL);
555
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100556 /* Inject wrong LocCancelReq GSUP message */
557 last_updated_subscr = NULL;
558 rc = rx_gsup_message(location_cancellation_req_other,
559 sizeof(location_cancellation_req_other));
560 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
561 OSMO_ASSERT(last_updated_subscr == NULL);
562
563 /* Check cancellation result */
564 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
565 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
566
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100567 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100568 rc = rx_gsup_message(location_cancellation_req,
569 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100570 OSMO_ASSERT(rc >= 0);
571 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100572 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100573
574 /* Check cancellation result */
575 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
576 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
577
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100578 /* Inject PurgeMsRes GSUP message */
579 rc = rx_gsup_message(purge_ms_res,
580 sizeof(purge_ms_res));
581 OSMO_ASSERT(rc >= 0);
582 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
583
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100584 /* Free MM context and subscriber */
585 subscr_put(s1);
586 s1found = gprs_subscr_get_by_imsi(imsi1);
587 OSMO_ASSERT(s1found == NULL);
588 gprs_llgmm_assign(llme, local_tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
589
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100590 /* Inject PurgeMsRes GSUP message */
591 rc = rx_gsup_message(purge_ms_res,
592 sizeof(purge_ms_res));
593 OSMO_ASSERT(rc >= 0);
594
595 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
596 rc = rx_gsup_message(purge_ms_err,
597 sizeof(purge_ms_err));
598 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
599
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100600 /* Inject PurgeMsErr() GSUP message */
601 rc = rx_gsup_message(purge_ms_err_no_cause,
602 sizeof(purge_ms_err_no_cause));
603 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
604
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100605 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
606 last_updated_subscr = NULL;
607 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100608 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100609 OSMO_ASSERT(last_updated_subscr == NULL);
610
611 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
612 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
613 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
614 OSMO_ASSERT(last_updated_subscr == NULL);
615
616 /* Inject LocCancelReq GSUP message (unknown IMSI) */
617 rc = rx_gsup_message(location_cancellation_req,
618 sizeof(location_cancellation_req));
619 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
620 OSMO_ASSERT(last_updated_subscr == NULL);
621
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100622 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
623}
624
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100625int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
626{
627 msgb_free(msg);
628 return 0;
629};
630
631
632static void test_subscriber_blocking(void)
633{
634 struct gsm_subscriber *s1;
635 const char *imsi1 = "1234567890";
636 struct sgsn_mm_ctx *ctx;
637 struct gprs_ra_id raid = { 0, };
638 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100639 int rc;
640
641 printf("Testing subcriber procedure blocking\n");
642
643 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
644 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
645
646 /* Check for emptiness */
647 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
648
649 /* Create a context */
650 OSMO_ASSERT(count(gprs_llme_list()) == 0);
651 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100652 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
653
654 /* Allocate and attach a subscriber */
655 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
656 assert_subscr(s1, imsi1);
657
658 /* Start SendAuthInfoRequest procedure */
659 rc = gprs_subscr_query_auth_info(s1);
660 /* Not blocking */
661 OSMO_ASSERT(rc == 0);
662
663 /* Start UpdateLocation procedure */
664 rc = gprs_subscr_location_update(s1);
665 /* Blocking */
666 OSMO_ASSERT(rc == 0);
667
668 /* Start PurgeMS procedure */
669 rc = gprs_subscr_purge(s1);
670 /* Not blocking */
671 OSMO_ASSERT(rc == 0);
672 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
673
674 /* Start PurgeMS procedure (retry) */
675 rc = gprs_subscr_purge(s1);
676 /* Not blocking */
677 OSMO_ASSERT(rc == 0);
678
679 /* Start SendAuthInfoRequest procedure */
680 rc = gprs_subscr_query_auth_info(s1);
681 /* Blocking */
682 OSMO_ASSERT(rc == -EAGAIN);
683
684 /* Start UpdateLocation procedure */
685 rc = gprs_subscr_location_update(s1);
686 /* Blocking */
687 OSMO_ASSERT(rc == -EAGAIN);
688
689 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
690 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
691
692 /* Start SendAuthInfoRequest procedure */
693 rc = gprs_subscr_query_auth_info(s1);
694 /* Not blocking */
695 OSMO_ASSERT(rc == 0);
696
697 /* Start UpdateLocation procedure */
698 rc = gprs_subscr_location_update(s1);
699 /* Blocking */
700 OSMO_ASSERT(rc == 0);
701
702 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100703 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100704
705 assert_no_subscrs();
706
707 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
708 talloc_free(sgsn->gsup_client);
709 sgsn->gsup_client = NULL;
710}
711
712
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200713/*
714 * Test that a GMM Detach will remove the MMCTX and the
715 * associated LLME.
716 */
717static void test_gmm_detach(void)
718{
719 struct gprs_ra_id raid = { 0, };
720 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200721 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200722
723 printf("Testing GMM detach\n");
724
725 /* DTAP - Detach Request (MO) */
726 /* normal detach, power_off = 0 */
727 static const unsigned char detach_req[] = {
728 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
729 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
730 };
731
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200732 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200733
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100734 /* Create a context */
735 OSMO_ASSERT(count(gprs_llme_list()) == 0);
736 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200737
738 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100739 send_0408_message(ctx->llme, local_tlli,
740 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200741
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100742 /* verify that a single message (hopefully the Detach Accept) has been
743 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100744 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100745
746 /* verify that things are gone */
747 OSMO_ASSERT(count(gprs_llme_list()) == 0);
748 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
749 OSMO_ASSERT(!ictx);
750}
751
752/*
753 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
754 * will not sent a Detach Accept message (power_off = 1)
755 */
756static void test_gmm_detach_power_off(void)
757{
758 struct gprs_ra_id raid = { 0, };
759 struct sgsn_mm_ctx *ctx, *ictx;
760 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100761
762 printf("Testing GMM detach (power off)\n");
763
764 /* DTAP - Detach Request (MO) */
765 /* normal detach, power_off = 1 */
766 static const unsigned char detach_req[] = {
767 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
768 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
769 };
770
771 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
772
773 /* Create a context */
774 OSMO_ASSERT(count(gprs_llme_list()) == 0);
775 ctx = alloc_mm_ctx(local_tlli, &raid);
776
777 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100778 send_0408_message(ctx->llme, local_tlli,
779 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100780
781 /* verify that no message (and therefore no Detach Accept) has been
782 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100783 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100784
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200785 /* verify that things are gone */
786 OSMO_ASSERT(count(gprs_llme_list()) == 0);
787 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200788 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200789}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200790
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200791/*
792 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
793 */
794static void test_gmm_detach_no_mmctx(void)
795{
796 struct gprs_llc_lle *lle;
797 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200798
799 printf("Testing GMM detach (no MMCTX)\n");
800
801 /* DTAP - Detach Request (MO) */
802 /* normal detach, power_off = 0 */
803 static const unsigned char detach_req[] = {
804 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
805 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
806 };
807
808 /* Create an LLME */
809 OSMO_ASSERT(count(gprs_llme_list()) == 0);
810 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
811 lle = gprs_lle_get_or_create(local_tlli, 3);
812
813 OSMO_ASSERT(count(gprs_llme_list()) == 1);
814
815 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100816 send_0408_message(lle->llme, local_tlli,
817 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200818
819 /* verify that the LLME is gone */
820 OSMO_ASSERT(count(gprs_llme_list()) == 0);
821}
822
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100823/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100824 * Test that a single GMM Detach Accept message will not cause the SGSN to send
825 * any message or leave an MM context at the SGSN.
826 */
827static void test_gmm_detach_accept_unexpected(void)
828{
829 struct gprs_llc_lle *lle;
830 uint32_t local_tlli;
831
832 printf("Testing GMM detach accept (unexpected)\n");
833
834 /* DTAP - Detach Accept (MT) */
835 /* normal detach */
836 static const unsigned char detach_acc[] = {
837 0x08, 0x06
838 };
839
840 /* Create an LLME */
841 OSMO_ASSERT(count(gprs_llme_list()) == 0);
842 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
843 lle = gprs_lle_get_or_create(local_tlli, 3);
844
845 /* inject the detach */
846 send_0408_message(lle->llme, local_tlli,
847 detach_acc, ARRAY_SIZE(detach_acc));
848
849 /* verify that no message (and therefore no Status or XID reset) has been
850 * sent by the SGSN */
851 OSMO_ASSERT(sgsn_tx_counter == 0);
852
853 /* verify that things are gone */
854 OSMO_ASSERT(count(gprs_llme_list()) == 0);
855}
856
857/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100858 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
859 */
860static void test_gmm_status_no_mmctx(void)
861{
862 struct gprs_llc_lle *lle;
863 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100864
865 printf("Testing GMM Status (no MMCTX)\n");
866
867 /* DTAP - GMM Status, protocol error */
868 static const unsigned char gmm_status[] = {
869 0x08, 0x20, 0x6f
870 };
871
872 /* Create an LLME */
873 OSMO_ASSERT(count(gprs_llme_list()) == 0);
874 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
875 lle = gprs_lle_get_or_create(local_tlli, 3);
876
877 OSMO_ASSERT(count(gprs_llme_list()) == 1);
878
879 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100880 send_0408_message(lle->llme, local_tlli,
881 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100882
883 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100884 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100885
886 /* verify that the LLME is gone */
887 OSMO_ASSERT(count(gprs_llme_list()) == 0);
888}
889
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100890/*
891 * Test the GMM Attach procedure
892 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100893static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100894{
895 struct gprs_ra_id raid = { 0, };
896 struct sgsn_mm_ctx *ctx = NULL;
897 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100898 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100899 uint32_t foreign_tlli;
900 uint32_t local_tlli = 0;
901 struct gprs_llc_lle *lle;
902
903 /* DTAP - Attach Request */
904 /* The P-TMSI is not known by the SGSN */
905 static const unsigned char attach_req[] = {
906 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
907 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
908 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
909 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
910 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
911 };
912
913 /* DTAP - Identity Response IMEI */
914 static const unsigned char ident_resp_imei[] = {
915 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
916 0x56
917 };
918
919 /* DTAP - Identity Response IMSI */
920 static const unsigned char ident_resp_imsi[] = {
921 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
922 0x54
923 };
924
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100925 /* DTAP - Authentication and Ciphering Resp */
926 static const unsigned char auth_ciph_resp[] = {
927 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
928 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
929 };
930
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100931 /* DTAP - Attach Complete */
932 static const unsigned char attach_compl[] = {
933 0x08, 0x03
934 };
935
936 /* DTAP - Detach Request (MO) */
937 /* normal detach, power_off = 0 */
938 static const unsigned char detach_req[] = {
939 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
940 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
941 };
942
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100943 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100944
945 /* reset the PRNG used by sgsn_alloc_ptmsi */
946 srand(1);
947
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100948 ptmsi1 = sgsn_alloc_ptmsi();
949 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
950
951 /* reset the PRNG, so that the same P-TMSI sequence will be generated
952 * again */
953 srand(1);
954
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100955 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
956
957 /* Create a LLE/LLME */
958 OSMO_ASSERT(count(gprs_llme_list()) == 0);
959 lle = gprs_lle_get_or_create(foreign_tlli, 3);
960 OSMO_ASSERT(count(gprs_llme_list()) == 1);
961
962 /* inject the attach request */
963 send_0408_message(lle->llme, foreign_tlli,
964 attach_req, ARRAY_SIZE(attach_req));
965
966 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
967 OSMO_ASSERT(ctx != NULL);
968 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
969
970 /* we expect an identity request (IMEI) */
971 OSMO_ASSERT(sgsn_tx_counter == 1);
972
973 /* inject the identity response (IMEI) */
974 send_0408_message(ctx->llme, foreign_tlli,
975 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
976
977 /* we expect an identity request (IMSI) */
978 OSMO_ASSERT(sgsn_tx_counter == 1);
979
980 /* inject the identity response (IMSI) */
981 send_0408_message(ctx->llme, foreign_tlli,
982 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
983
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100984 /* check that the MM context has not been removed due to a failed
985 * authorization */
986 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
987
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100988 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100989
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100990retry_attach_req:
991
992 if (retry && sgsn_tx_counter == 0) {
993 fprintf(stderr, "Retrying attach request\n");
994 /* re-inject the attach request */
995 send_0408_message(lle->llme, foreign_tlli,
996 attach_req, ARRAY_SIZE(attach_req));
997 }
998
999 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
1000 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001001
1002 /* inject the auth & ciph response */
1003 send_0408_message(ctx->llme, foreign_tlli,
1004 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1005
1006 /* check that the MM context has not been removed due to a
1007 * failed authorization */
1008 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1009 }
1010
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001011 if (retry && sgsn_tx_counter == 0)
1012 goto retry_attach_req;
1013
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001014 /* we expect an attach accept/reject */
1015 OSMO_ASSERT(sgsn_tx_counter == 1);
1016
1017 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001018 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001019
1020 /* inject the attach complete */
1021 send_0408_message(ctx->llme, local_tlli,
1022 attach_compl, ARRAY_SIZE(attach_compl));
1023
1024 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1025
1026 /* we don't expect a response */
1027 OSMO_ASSERT(sgsn_tx_counter == 0);
1028
1029 /* inject the detach */
1030 send_0408_message(ctx->llme, local_tlli,
1031 detach_req, ARRAY_SIZE(detach_req));
1032
1033 /* verify that things are gone */
1034 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1035 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1036 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001037}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001038
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001039static void test_gmm_attach_acl(void)
1040{
1041 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1042
1043 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1044 sgsn_acl_add("123456789012345", &sgsn->cfg);
1045 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001046 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001047 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001048
1049 sgsn->cfg.auth_policy = saved_auth_policy;
1050}
1051
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001052int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001053 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001054 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001055 if (rc == -ENOTSUP) {
1056 OSMO_ASSERT(mmctx->subscr);
1057 gprs_subscr_update(mmctx->subscr);
1058 }
1059 return rc;
1060};
1061
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001062int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1063 gprs_subscr_update(mmctx->subscr);
1064 return 0;
1065};
1066
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001067static void test_gmm_attach_subscr(void)
1068{
1069 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1070 struct gsm_subscriber *subscr;
1071
1072 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001073 subscr_request_update_location_cb = my_subscr_request_update_location;
1074 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001075
1076 subscr = gprs_subscr_get_or_create("123456789012345");
1077 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001078
1079 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001080 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001081 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001082 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001083
1084 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001085 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1086 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001087}
1088
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001089int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1090{
1091 /* Fake an authentication */
1092 OSMO_ASSERT(mmctx->subscr);
1093 mmctx->is_authenticated = 1;
1094 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001095
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001096 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001097};
1098
1099static void test_gmm_attach_subscr_fake_auth(void)
1100{
1101 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1102 struct gsm_subscriber *subscr;
1103
1104 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001105 subscr_request_update_location_cb = my_subscr_request_update_location;
1106 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001107
1108 subscr = gprs_subscr_get_or_create("123456789012345");
1109 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001110 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001111 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001112
1113 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001114 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001115 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001116 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001117
1118 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001119 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1120 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1121}
1122
1123int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1124{
1125 struct gsm_auth_tuple at = {
1126 .sres = {0x51, 0xe5, 0x51, 0xe5},
1127 .key_seq = 0
1128 };
1129
1130 /* Fake an authentication */
1131 OSMO_ASSERT(mmctx->subscr);
1132 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1133
1134 gprs_subscr_update_auth_info(mmctx->subscr);
1135
1136 return 0;
1137};
1138
1139static void test_gmm_attach_subscr_real_auth(void)
1140{
1141 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1142 struct gsm_subscriber *subscr;
1143
1144 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1145 subscr_request_update_location_cb = my_subscr_request_update_location;
1146 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1147
1148 subscr = gprs_subscr_get_or_create("123456789012345");
1149 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001150 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001151 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001152
1153 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001154
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001155 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001156 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001157 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001158
1159 sgsn->cfg.auth_policy = saved_auth_policy;
1160 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1161 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001162}
1163
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001164#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1165 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1166
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001167static int auth_info_skip = 0;
1168static int upd_loc_skip = 0;
1169
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001170int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1171{
1172 static const uint8_t send_auth_info_res[] = {
1173 0x0a,
1174 TEST_GSUP_IMSI_LONG_IE,
1175 0x03, 0x22, /* Auth tuple */
1176 0x20, 0x10,
1177 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1178 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1179 0x21, 0x04,
1180 0x51, 0xe5, 0x51, 0xe5,
1181 0x22, 0x08,
1182 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1183 };
1184
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001185 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001186
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001187 if (auth_info_skip > 0) {
1188 auth_info_skip -= 1;
1189 return -EAGAIN;
1190 }
1191
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001192 /* Fake an SendAuthInfoRes */
1193 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1194
1195 return 0;
1196};
1197
1198int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1199 static const uint8_t update_location_res[] = {
1200 0x06,
1201 TEST_GSUP_IMSI_LONG_IE,
1202 0x04, 0x00, /* PDP info complete */
1203 0x05, 0x12,
1204 0x10, 0x01, 0x01,
1205 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1206 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1207 };
1208
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001209 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001210
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001211 if (upd_loc_skip > 0) {
1212 upd_loc_skip -= 1;
1213 return -EAGAIN;
1214 }
1215
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001216 /* Fake an UpdateLocRes */
1217 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1218};
1219
1220
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001221static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001222{
1223 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1224 struct gsm_subscriber *subscr;
1225
1226 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1227 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1228 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001229 if (retry) {
1230 upd_loc_skip = 3;
1231 auth_info_skip = 3;
1232 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001233
1234 subscr = gprs_subscr_get_or_create("123456789012345");
1235 subscr->authorized = 1;
1236 sgsn->cfg.require_authentication = 1;
1237 sgsn->cfg.require_update_location = 1;
1238 subscr_put(subscr);
1239
1240 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001241 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001242 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001243
1244 sgsn->cfg.auth_policy = saved_auth_policy;
1245 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1246 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001247 upd_loc_skip = 0;
1248 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001249}
1250
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001251int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1252{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001253 struct gprs_gsup_message to_peer = {0};
1254 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001255 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001256 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001257
1258 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001259 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1260 OSMO_ASSERT(rc >= 0);
1261 OSMO_ASSERT(to_peer.imsi[0] != 0);
1262 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001263
1264 /* This invalidates the pointers in to_peer */
1265 msgb_free(msg);
1266
1267 switch (to_peer.message_type) {
1268 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1269 /* Send UPDATE_LOCATION_RESULT */
1270 return my_subscr_request_update_gsup_auth(NULL);
1271
1272 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1273 /* Send SEND_AUTH_INFO_RESULT */
1274 return my_subscr_request_auth_info_gsup_auth(NULL);
1275
1276 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001277 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1278 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001279
1280 default:
1281 if ((to_peer.message_type & 0b00000011) == 0) {
1282 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001283 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001284 from_peer.message_type = to_peer.message_type + 1;
1285 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1286 break;
1287 }
1288
1289 /* Ignore it */
1290 return 0;
1291 }
1292
1293 reply_msg = gprs_gsup_msgb_alloc();
1294 reply_msg->l2h = reply_msg->data;
1295 gprs_gsup_encode(reply_msg, &from_peer);
1296 gprs_subscr_rx_gsup_message(reply_msg);
1297 msgb_free(reply_msg);
1298
1299 return 0;
1300};
1301
1302static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1303{
1304 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1305 struct gsm_subscriber *subscr;
1306
1307 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001308 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1309
1310 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1311
1312 if (retry) {
1313 upd_loc_skip = 3;
1314 auth_info_skip = 3;
1315 }
1316
1317 printf("Auth policy 'remote', real GSUP based auth: ");
1318 test_gmm_attach(retry);
1319
1320 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001321 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001322 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001323
1324 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001325 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1326 upd_loc_skip = 0;
1327 auth_info_skip = 0;
1328 talloc_free(sgsn->gsup_client);
1329 sgsn->gsup_client = NULL;
1330}
1331
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001332/*
1333 * Test the GMM Rejects
1334 */
1335static void test_gmm_reject(void)
1336{
1337 struct gprs_ra_id raid = { 0, };
1338 struct sgsn_mm_ctx *ctx = NULL;
1339 uint32_t foreign_tlli;
1340 struct gprs_llc_lle *lle;
1341 int idx;
1342
1343 /* DTAP - Attach Request */
1344 /* Invalid MI length */
1345 static const unsigned char attach_req_inv_mi_len[] = {
1346 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1347 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1348 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1349 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1350 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1351 };
1352
1353 /* DTAP - Attach Request */
1354 /* Invalid MI type (IMEI) */
1355 static const unsigned char attach_req_inv_mi_type[] = {
1356 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1357 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1358 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1359 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1360 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1361 };
1362
1363 /* DTAP - Routing Area Update Request */
1364 static const unsigned char dtap_ra_upd_req[] = {
1365 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1366 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1367 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1368 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1369 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1370 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1371 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1372 };
1373
1374 /* DTAP - Routing Area Update Request */
1375 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1376 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1377 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1378 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1379 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1380 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1381 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1382 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1383 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1384 };
1385
1386 /* DTAP - Routing Area Update Request */
1387 /* Invalid cap length */
1388 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1389 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1390 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1391 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1392 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1393 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1394 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1395 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1396 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1397 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1398 };
1399
1400 struct test {
1401 const char *title;
1402 const unsigned char *msg;
1403 unsigned msg_len;
1404 unsigned num_resp;
1405
1406 };
1407 static struct test tests[] = {
1408 {
1409 .title = "Attach Request (invalid MI length)",
1410 .msg = attach_req_inv_mi_len,
1411 .msg_len = sizeof(attach_req_inv_mi_len),
1412 .num_resp = 1 /* Reject */
1413
1414 },
1415 {
1416 .title = "Attach Request (invalid MI type)",
1417 .msg = attach_req_inv_mi_type,
1418 .msg_len = sizeof(attach_req_inv_mi_type),
1419 .num_resp = 1 /* Reject */
1420 },
1421 {
1422 .title = "Routing Area Update Request (valid)",
1423 .msg = dtap_ra_upd_req,
1424 .msg_len = sizeof(dtap_ra_upd_req),
1425 .num_resp = 2 /* XID Reset + Reject */
1426 },
1427 {
1428 .title = "Routing Area Update Request (invalid type)",
1429 .msg = dtap_ra_upd_req_inv_type,
1430 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1431 .num_resp = 1 /* Reject */
1432 },
1433 {
1434 .title = "Routing Area Update Request (invalid CAP length)",
1435 .msg = dtap_ra_upd_req_inv_cap_len,
1436 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1437 .num_resp = 1 /* Reject */
1438 },
1439 };
1440
1441 printf("Testing GMM reject\n");
1442
1443 /* reset the PRNG used by sgsn_alloc_ptmsi */
1444 srand(1);
1445
1446 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1447
1448 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1449
1450 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1451 const struct test *test = &tests[idx];
1452 printf(" - %s\n", test->title);
1453
1454 /* Create a LLE/LLME */
1455 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1456 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1457
1458 /* Inject the Request message */
1459 send_0408_message(lle->llme, foreign_tlli,
1460 test->msg, test->msg_len);
1461
1462 /* We expect a Reject message */
1463 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1464 sgsn_tx_counter, test->num_resp);
1465 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1466
1467 /* verify that LLME/MM are removed */
1468 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1469 OSMO_ASSERT(ctx == NULL);
1470 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1471 }
1472}
1473
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001474/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001475 * Test cancellation of attached MM contexts
1476 */
1477static void test_gmm_cancel(void)
1478{
1479 struct gprs_ra_id raid = { 0, };
1480 struct sgsn_mm_ctx *ctx = NULL;
1481 struct sgsn_mm_ctx *ictx;
1482 uint32_t ptmsi1;
1483 uint32_t foreign_tlli;
1484 uint32_t local_tlli = 0;
1485 struct gprs_llc_lle *lle;
1486 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1487
1488 /* DTAP - Attach Request */
1489 /* The P-TMSI is not known by the SGSN */
1490 static const unsigned char attach_req[] = {
1491 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1492 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1493 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1494 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1495 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1496 };
1497
1498 /* DTAP - Identity Response IMEI */
1499 static const unsigned char ident_resp_imei[] = {
1500 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1501 0x56
1502 };
1503
1504 /* DTAP - Identity Response IMSI */
1505 static const unsigned char ident_resp_imsi[] = {
1506 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1507 0x54
1508 };
1509
1510 /* DTAP - Attach Complete */
1511 static const unsigned char attach_compl[] = {
1512 0x08, 0x03
1513 };
1514
1515 printf("Testing cancellation\n");
1516
1517 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1518
1519 /* reset the PRNG used by sgsn_alloc_ptmsi */
1520 srand(1);
1521
1522 ptmsi1 = sgsn_alloc_ptmsi();
1523 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1524
1525 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1526 * again */
1527 srand(1);
1528
1529 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1530
1531 /* Create a LLE/LLME */
1532 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1533 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1534 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1535
1536 /* inject the attach request */
1537 send_0408_message(lle->llme, foreign_tlli,
1538 attach_req, ARRAY_SIZE(attach_req));
1539
1540 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1541 OSMO_ASSERT(ctx != NULL);
1542 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1543
1544 /* we expect an identity request (IMEI) */
1545 OSMO_ASSERT(sgsn_tx_counter == 1);
1546
1547 /* inject the identity response (IMEI) */
1548 send_0408_message(ctx->llme, foreign_tlli,
1549 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1550
1551 /* we expect an identity request (IMSI) */
1552 OSMO_ASSERT(sgsn_tx_counter == 1);
1553
1554 /* inject the identity response (IMSI) */
1555 send_0408_message(ctx->llme, foreign_tlli,
1556 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1557
1558 /* check that the MM context has not been removed due to a failed
1559 * authorization */
1560 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1561
1562 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1563
1564 /* we expect an attach accept/reject */
1565 OSMO_ASSERT(sgsn_tx_counter == 1);
1566
1567 /* this has been randomly assigned by the SGSN */
1568 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1569
1570 /* inject the attach complete */
1571 send_0408_message(ctx->llme, local_tlli,
1572 attach_compl, ARRAY_SIZE(attach_compl));
1573
1574 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1575
1576 /* we don't expect a response */
1577 OSMO_ASSERT(sgsn_tx_counter == 0);
1578
1579 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001580 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001581
1582 /* verify that things are gone */
1583 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1584 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1585 OSMO_ASSERT(!ictx);
1586
1587 sgsn->cfg.auth_policy = saved_auth_policy;
1588}
1589
1590/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001591 * Test the dynamic allocation of P-TMSIs
1592 */
1593static void test_gmm_ptmsi_allocation(void)
1594{
1595 struct gprs_ra_id raid = { 0, };
1596 struct sgsn_mm_ctx *ctx = NULL;
1597 struct sgsn_mm_ctx *ictx;
1598 uint32_t foreign_tlli;
1599 uint32_t ptmsi1;
1600 uint32_t ptmsi2;
1601 uint32_t old_ptmsi;
1602 uint32_t local_tlli = 0;
1603 struct gprs_llc_lle *lle;
1604 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1605
1606 /* DTAP - Attach Request (IMSI 12131415161718) */
1607 static const unsigned char attach_req[] = {
1608 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1609 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1610 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1611 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1612 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1613 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1614 0x00,
1615 };
1616
1617 /* DTAP - Identity Response IMEI */
1618 static const unsigned char ident_resp_imei[] = {
1619 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1620 0x56
1621 };
1622
1623 /* DTAP - Attach Complete */
1624 static const unsigned char attach_compl[] = {
1625 0x08, 0x03
1626 };
1627
1628 /* DTAP - Routing Area Update Request */
1629 static const unsigned char ra_upd_req[] = {
1630 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1631 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1632 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1633 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1634 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1635 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1636 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1637 };
1638
1639 /* DTAP - Routing Area Update Complete */
1640 static const unsigned char ra_upd_complete[] = {
1641 0x08, 0x0a
1642 };
1643
1644 /* DTAP - Detach Request (MO) */
1645 /* normal detach, power_off = 1 */
1646 static const unsigned char detach_req[] = {
1647 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1648 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1649 };
1650
1651 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1652
1653 printf("Testing P-TMSI allocation\n");
1654
1655 printf(" - sgsn_alloc_ptmsi\n");
1656
1657 /* reset the PRNG used by sgsn_alloc_ptmsi */
1658 srand(1);
1659
1660 ptmsi1 = sgsn_alloc_ptmsi();
1661 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1662
1663 ptmsi2 = sgsn_alloc_ptmsi();
1664 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1665
1666 OSMO_ASSERT(ptmsi1 != ptmsi2);
1667
1668 printf(" - Repeated Attach Request\n");
1669
1670 /* reset the PRNG, so that the same P-TMSI will be generated
1671 * again */
1672 srand(1);
1673
1674 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1675
1676 /* Create a LLE/LLME */
1677 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1678 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1679 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1680
1681 /* inject the attach request */
1682 send_0408_message(lle->llme, foreign_tlli,
1683 attach_req, ARRAY_SIZE(attach_req));
1684
1685 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1686 OSMO_ASSERT(ctx != NULL);
1687 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1688 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1689
1690 old_ptmsi = ctx->p_tmsi_old;
1691
1692 /* we expect an identity request (IMEI) */
1693 OSMO_ASSERT(sgsn_tx_counter == 1);
1694
1695 /* inject the identity response (IMEI) */
1696 send_0408_message(ctx->llme, foreign_tlli,
1697 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1698
1699 /* check that the MM context has not been removed due to a failed
1700 * authorization */
1701 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1702
1703 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1704 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1705
1706 /* we expect an attach accept */
1707 OSMO_ASSERT(sgsn_tx_counter == 1);
1708
1709 /* we ignore this and send the attach again */
1710 send_0408_message(lle->llme, foreign_tlli,
1711 attach_req, ARRAY_SIZE(attach_req));
1712
1713 /* the allocated P-TMSI should be the same */
1714 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1715 OSMO_ASSERT(ctx != NULL);
1716 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1717 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1718 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1719
1720 /* inject the attach complete */
1721 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1722 send_0408_message(ctx->llme, local_tlli,
1723 attach_compl, ARRAY_SIZE(attach_compl));
1724
1725 /* we don't expect a response */
1726 OSMO_ASSERT(sgsn_tx_counter == 0);
1727
1728 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1729 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1730 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1731
1732 printf(" - Repeated RA Update Request\n");
1733
1734 /* inject the RA update request */
1735 send_0408_message(ctx->llme, local_tlli,
1736 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1737
1738 /* we expect an RA update accept */
1739 OSMO_ASSERT(sgsn_tx_counter == 1);
1740
1741 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1742 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1743 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1744
1745 /* repeat the RA update request */
1746 send_0408_message(ctx->llme, local_tlli,
1747 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1748
1749 /* we expect an RA update accept */
1750 OSMO_ASSERT(sgsn_tx_counter == 1);
1751
1752 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1753 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1754 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1755
1756 /* inject the RA update complete */
1757 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1758 send_0408_message(ctx->llme, local_tlli,
1759 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1760
1761 /* we don't expect a response */
1762 OSMO_ASSERT(sgsn_tx_counter == 0);
1763
1764 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1765 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1766 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1767
1768 /* inject the detach */
1769 send_0408_message(ctx->llme, local_tlli,
1770 detach_req, ARRAY_SIZE(detach_req));
1771
1772 /* verify that things are gone */
1773 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1774 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1775 OSMO_ASSERT(!ictx);
1776
1777 sgsn->cfg.auth_policy = saved_auth_policy;
1778}
1779
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001780static struct log_info_cat gprs_categories[] = {
1781 [DMM] = {
1782 .name = "DMM",
1783 .description = "Layer3 Mobility Management (MM)",
1784 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001785 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001786 },
1787 [DPAG] = {
1788 .name = "DPAG",
1789 .description = "Paging Subsystem",
1790 .color = "\033[1;38m",
1791 .enabled = 1, .loglevel = LOGL_NOTICE,
1792 },
1793 [DMEAS] = {
1794 .name = "DMEAS",
1795 .description = "Radio Measurement Processing",
1796 .enabled = 0, .loglevel = LOGL_NOTICE,
1797 },
1798 [DREF] = {
1799 .name = "DREF",
1800 .description = "Reference Counting",
1801 .enabled = 0, .loglevel = LOGL_NOTICE,
1802 },
1803 [DGPRS] = {
1804 .name = "DGPRS",
1805 .description = "GPRS Packet Service",
1806 .enabled = 1, .loglevel = LOGL_DEBUG,
1807 },
1808 [DNS] = {
1809 .name = "DNS",
1810 .description = "GPRS Network Service (NS)",
1811 .enabled = 1, .loglevel = LOGL_INFO,
1812 },
1813 [DBSSGP] = {
1814 .name = "DBSSGP",
1815 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1816 .enabled = 1, .loglevel = LOGL_DEBUG,
1817 },
1818 [DLLC] = {
1819 .name = "DLLC",
1820 .description = "GPRS Logical Link Control Protocol (LLC)",
1821 .enabled = 1, .loglevel = LOGL_DEBUG,
1822 },
1823 [DSNDCP] = {
1824 .name = "DSNDCP",
1825 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1826 .enabled = 1, .loglevel = LOGL_DEBUG,
1827 },
1828};
1829
1830static struct log_info info = {
1831 .cat = gprs_categories,
1832 .num_cat = ARRAY_SIZE(gprs_categories),
1833};
1834
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001835int main(int argc, char **argv)
1836{
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001837 osmo_init_logging(&info);
1838 tall_bsc_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1839 tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
1840
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001841 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001842 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001843
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001844 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001845 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001846 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001847 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001848 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001849 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001850 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001851 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001852 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001853 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001854 test_gmm_attach_acl();
1855 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001856 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001857 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001858 test_gmm_attach_subscr_gsup_auth(0);
1859 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001860 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001861 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001862 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001863 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001864 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001865
1866 talloc_report_full(tall_bsc_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001867 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001868 return 0;
1869}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001870
1871
1872/* stubs */
1873struct osmo_prim_hdr;
1874int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1875{
1876 abort();
1877}