blob: 425cf63ff8de25da6fa9704e42decc64970dcb97 [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;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100386 int rc;
387
388 static const uint8_t send_auth_info_res[] = {
389 0x0a,
390 TEST_GSUP_IMSI1_IE,
391 0x03, 0x22, /* Auth tuple */
392 0x20, 0x10,
393 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
394 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
395 0x21, 0x04,
396 0x21, 0x22, 0x23, 0x24,
397 0x22, 0x08,
398 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
399 0x03, 0x22, /* Auth tuple */
400 0x20, 0x10,
401 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
402 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
403 0x21, 0x04,
404 0xa1, 0xa2, 0xa3, 0xa4,
405 0x22, 0x08,
406 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
407 };
408
409 static const uint8_t send_auth_info_err[] = {
410 0x09,
411 TEST_GSUP_IMSI1_IE,
412 0x02, 0x01, 0x07 /* GPRS not allowed */
413 };
414
415 static const uint8_t update_location_res[] = {
416 0x06,
417 TEST_GSUP_IMSI1_IE,
418 0x04, 0x00, /* PDP info complete */
419 0x05, 0x12,
420 0x10, 0x01, 0x01,
421 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
422 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
423 0x05, 0x11,
424 0x10, 0x01, 0x02,
425 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
426 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
427 };
428
429 static const uint8_t update_location_err[] = {
430 0x05,
431 TEST_GSUP_IMSI1_IE,
432 0x02, 0x01, 0x07 /* GPRS not allowed */
433 };
434
435 static const uint8_t location_cancellation_req[] = {
436 0x1c,
437 TEST_GSUP_IMSI1_IE,
438 0x06, 0x01, 0x00,
439 };
440
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100441 static const uint8_t location_cancellation_req_other[] = {
442 0x1c,
443 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
444 0x06, 0x01, 0x00,
445 };
446
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100447 static const uint8_t purge_ms_err[] = {
448 0x0d,
449 TEST_GSUP_IMSI1_IE,
450 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
451 };
452
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100453 static const uint8_t purge_ms_err_no_cause[] = {
454 0x0d,
455 TEST_GSUP_IMSI1_IE,
456 };
457
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100458 static const uint8_t purge_ms_res[] = {
459 0x0e,
460 TEST_GSUP_IMSI1_IE,
461 0x07, 0x00,
462 };
463
464
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100465 static const uint8_t insert_data_req[] = {
466 0x10,
467 TEST_GSUP_IMSI1_IE,
468 0x05, 0x11,
469 0x10, 0x01, 0x03,
470 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
471 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
472 };
473
474 static const uint8_t delete_data_req[] = {
475 0x14,
476 TEST_GSUP_IMSI1_IE,
477 0x10, 0x01, 0x03,
478 };
479
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100480 printf("Testing subcriber GSUP handling\n");
481
482 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
483
484 /* Check for emptiness */
485 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
486
487 /* Allocate entry 1 */
488 s1 = gprs_subscr_get_or_create(imsi1);
489 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
490 s1found = gprs_subscr_get_by_imsi(imsi1);
491 OSMO_ASSERT(s1found == s1);
492 subscr_put(s1found);
493
494 /* Create a context */
495 OSMO_ASSERT(count(gprs_llme_list()) == 0);
496 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100497
498 /* Attach s1 to ctx */
499 ctx->subscr = subscr_get(s1);
500 ctx->subscr->sgsn_data->mm = ctx;
501
502 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100503 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100504 OSMO_ASSERT(rc >= 0);
505 OSMO_ASSERT(last_updated_subscr == s1);
506
507 /* Check triplets */
508 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
509 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
510 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
511
512 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100513 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100514 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100515 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100516 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100517
518 /* Check triplets */
519 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
520 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
521 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
522
523 /* Inject UpdateLocReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100524 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100525 OSMO_ASSERT(rc >= 0);
526 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100527 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100528 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
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);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100537 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100538
539 /* Check authorization */
540 OSMO_ASSERT(s1->authorized == 0);
541
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100542 /* Inject InsertSubscrData GSUP message */
543 last_updated_subscr = NULL;
544 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
545 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
546 OSMO_ASSERT(last_updated_subscr == NULL);
547
548 /* Inject DeleteSubscrData GSUP message */
549 last_updated_subscr = NULL;
550 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
551 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
552 OSMO_ASSERT(last_updated_subscr == NULL);
553
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100554 /* Inject wrong LocCancelReq GSUP message */
555 last_updated_subscr = NULL;
556 rc = rx_gsup_message(location_cancellation_req_other,
557 sizeof(location_cancellation_req_other));
558 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
559 OSMO_ASSERT(last_updated_subscr == NULL);
560
561 /* Check cancellation result */
562 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
563 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
564
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100565 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100566 rc = rx_gsup_message(location_cancellation_req,
567 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100568 OSMO_ASSERT(rc >= 0);
569 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100570 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100571
572 /* Check cancellation result */
573 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
574 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
575
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100576 /* Inject PurgeMsRes GSUP message */
577 rc = rx_gsup_message(purge_ms_res,
578 sizeof(purge_ms_res));
579 OSMO_ASSERT(rc >= 0);
580 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
581
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100582 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100583 OSMO_ASSERT(ctx->subscr == NULL);
584 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100585 subscr_put(s1);
586 s1found = gprs_subscr_get_by_imsi(imsi1);
587 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100588
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100589 /* Inject PurgeMsRes GSUP message */
590 rc = rx_gsup_message(purge_ms_res,
591 sizeof(purge_ms_res));
592 OSMO_ASSERT(rc >= 0);
593
594 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
595 rc = rx_gsup_message(purge_ms_err,
596 sizeof(purge_ms_err));
597 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
598
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100599 /* Inject PurgeMsErr() GSUP message */
600 rc = rx_gsup_message(purge_ms_err_no_cause,
601 sizeof(purge_ms_err_no_cause));
602 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
603
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100604 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
605 last_updated_subscr = NULL;
606 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100607 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100608 OSMO_ASSERT(last_updated_subscr == NULL);
609
610 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
611 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
612 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
613 OSMO_ASSERT(last_updated_subscr == NULL);
614
615 /* Inject LocCancelReq GSUP message (unknown IMSI) */
616 rc = rx_gsup_message(location_cancellation_req,
617 sizeof(location_cancellation_req));
618 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
619 OSMO_ASSERT(last_updated_subscr == NULL);
620
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100621 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
622}
623
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100624int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
625{
626 msgb_free(msg);
627 return 0;
628};
629
630
631static void test_subscriber_blocking(void)
632{
633 struct gsm_subscriber *s1;
634 const char *imsi1 = "1234567890";
635 struct sgsn_mm_ctx *ctx;
636 struct gprs_ra_id raid = { 0, };
637 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100638 int rc;
639
640 printf("Testing subcriber procedure blocking\n");
641
642 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
643 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
644
645 /* Check for emptiness */
646 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
647
648 /* Create a context */
649 OSMO_ASSERT(count(gprs_llme_list()) == 0);
650 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100651 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
652
653 /* Allocate and attach a subscriber */
654 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
655 assert_subscr(s1, imsi1);
656
657 /* Start SendAuthInfoRequest procedure */
658 rc = gprs_subscr_query_auth_info(s1);
659 /* Not blocking */
660 OSMO_ASSERT(rc == 0);
661
662 /* Start UpdateLocation procedure */
663 rc = gprs_subscr_location_update(s1);
664 /* Blocking */
665 OSMO_ASSERT(rc == 0);
666
667 /* Start PurgeMS procedure */
668 rc = gprs_subscr_purge(s1);
669 /* Not blocking */
670 OSMO_ASSERT(rc == 0);
671 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
672
673 /* Start PurgeMS procedure (retry) */
674 rc = gprs_subscr_purge(s1);
675 /* Not blocking */
676 OSMO_ASSERT(rc == 0);
677
678 /* Start SendAuthInfoRequest procedure */
679 rc = gprs_subscr_query_auth_info(s1);
680 /* Blocking */
681 OSMO_ASSERT(rc == -EAGAIN);
682
683 /* Start UpdateLocation procedure */
684 rc = gprs_subscr_location_update(s1);
685 /* Blocking */
686 OSMO_ASSERT(rc == -EAGAIN);
687
688 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
689 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
690
691 /* Start SendAuthInfoRequest procedure */
692 rc = gprs_subscr_query_auth_info(s1);
693 /* Not blocking */
694 OSMO_ASSERT(rc == 0);
695
696 /* Start UpdateLocation procedure */
697 rc = gprs_subscr_location_update(s1);
698 /* Blocking */
699 OSMO_ASSERT(rc == 0);
700
701 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100702 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100703
704 assert_no_subscrs();
705
706 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
707 talloc_free(sgsn->gsup_client);
708 sgsn->gsup_client = NULL;
709}
710
711
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200712/*
713 * Test that a GMM Detach will remove the MMCTX and the
714 * associated LLME.
715 */
716static void test_gmm_detach(void)
717{
718 struct gprs_ra_id raid = { 0, };
719 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200720 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200721
722 printf("Testing GMM detach\n");
723
724 /* DTAP - Detach Request (MO) */
725 /* normal detach, power_off = 0 */
726 static const unsigned char detach_req[] = {
727 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
728 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
729 };
730
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200731 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200732
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100733 /* Create a context */
734 OSMO_ASSERT(count(gprs_llme_list()) == 0);
735 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200736
737 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100738 send_0408_message(ctx->llme, local_tlli,
739 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200740
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100741 /* verify that a single message (hopefully the Detach Accept) has been
742 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100743 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100744
745 /* verify that things are gone */
746 OSMO_ASSERT(count(gprs_llme_list()) == 0);
747 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
748 OSMO_ASSERT(!ictx);
749}
750
751/*
752 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
753 * will not sent a Detach Accept message (power_off = 1)
754 */
755static void test_gmm_detach_power_off(void)
756{
757 struct gprs_ra_id raid = { 0, };
758 struct sgsn_mm_ctx *ctx, *ictx;
759 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100760
761 printf("Testing GMM detach (power off)\n");
762
763 /* DTAP - Detach Request (MO) */
764 /* normal detach, power_off = 1 */
765 static const unsigned char detach_req[] = {
766 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
767 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
768 };
769
770 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
771
772 /* Create a context */
773 OSMO_ASSERT(count(gprs_llme_list()) == 0);
774 ctx = alloc_mm_ctx(local_tlli, &raid);
775
776 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100777 send_0408_message(ctx->llme, local_tlli,
778 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100779
780 /* verify that no message (and therefore no Detach Accept) has been
781 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100782 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100783
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200784 /* verify that things are gone */
785 OSMO_ASSERT(count(gprs_llme_list()) == 0);
786 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200787 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200788}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200789
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200790/*
791 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
792 */
793static void test_gmm_detach_no_mmctx(void)
794{
795 struct gprs_llc_lle *lle;
796 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200797
798 printf("Testing GMM detach (no MMCTX)\n");
799
800 /* DTAP - Detach Request (MO) */
801 /* normal detach, power_off = 0 */
802 static const unsigned char detach_req[] = {
803 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
804 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
805 };
806
807 /* Create an LLME */
808 OSMO_ASSERT(count(gprs_llme_list()) == 0);
809 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
810 lle = gprs_lle_get_or_create(local_tlli, 3);
811
812 OSMO_ASSERT(count(gprs_llme_list()) == 1);
813
814 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100815 send_0408_message(lle->llme, local_tlli,
816 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200817
818 /* verify that the LLME is gone */
819 OSMO_ASSERT(count(gprs_llme_list()) == 0);
820}
821
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100822/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100823 * Test that a single GMM Detach Accept message will not cause the SGSN to send
824 * any message or leave an MM context at the SGSN.
825 */
826static void test_gmm_detach_accept_unexpected(void)
827{
828 struct gprs_llc_lle *lle;
829 uint32_t local_tlli;
830
831 printf("Testing GMM detach accept (unexpected)\n");
832
833 /* DTAP - Detach Accept (MT) */
834 /* normal detach */
835 static const unsigned char detach_acc[] = {
836 0x08, 0x06
837 };
838
839 /* Create an LLME */
840 OSMO_ASSERT(count(gprs_llme_list()) == 0);
841 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
842 lle = gprs_lle_get_or_create(local_tlli, 3);
843
844 /* inject the detach */
845 send_0408_message(lle->llme, local_tlli,
846 detach_acc, ARRAY_SIZE(detach_acc));
847
848 /* verify that no message (and therefore no Status or XID reset) has been
849 * sent by the SGSN */
850 OSMO_ASSERT(sgsn_tx_counter == 0);
851
852 /* verify that things are gone */
853 OSMO_ASSERT(count(gprs_llme_list()) == 0);
854}
855
856/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100857 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
858 */
859static void test_gmm_status_no_mmctx(void)
860{
861 struct gprs_llc_lle *lle;
862 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100863
864 printf("Testing GMM Status (no MMCTX)\n");
865
866 /* DTAP - GMM Status, protocol error */
867 static const unsigned char gmm_status[] = {
868 0x08, 0x20, 0x6f
869 };
870
871 /* Create an LLME */
872 OSMO_ASSERT(count(gprs_llme_list()) == 0);
873 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
874 lle = gprs_lle_get_or_create(local_tlli, 3);
875
876 OSMO_ASSERT(count(gprs_llme_list()) == 1);
877
878 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100879 send_0408_message(lle->llme, local_tlli,
880 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100881
882 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100883 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100884
885 /* verify that the LLME is gone */
886 OSMO_ASSERT(count(gprs_llme_list()) == 0);
887}
888
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100889/*
890 * Test the GMM Attach procedure
891 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100892static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100893{
894 struct gprs_ra_id raid = { 0, };
895 struct sgsn_mm_ctx *ctx = NULL;
896 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100897 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100898 uint32_t foreign_tlli;
899 uint32_t local_tlli = 0;
900 struct gprs_llc_lle *lle;
901
902 /* DTAP - Attach Request */
903 /* The P-TMSI is not known by the SGSN */
904 static const unsigned char attach_req[] = {
905 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
906 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
907 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
908 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
909 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
910 };
911
912 /* DTAP - Identity Response IMEI */
913 static const unsigned char ident_resp_imei[] = {
914 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
915 0x56
916 };
917
918 /* DTAP - Identity Response IMSI */
919 static const unsigned char ident_resp_imsi[] = {
920 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
921 0x54
922 };
923
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100924 /* DTAP - Authentication and Ciphering Resp */
925 static const unsigned char auth_ciph_resp[] = {
926 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
927 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
928 };
929
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100930 /* DTAP - Attach Complete */
931 static const unsigned char attach_compl[] = {
932 0x08, 0x03
933 };
934
935 /* DTAP - Detach Request (MO) */
936 /* normal detach, power_off = 0 */
937 static const unsigned char detach_req[] = {
938 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
939 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
940 };
941
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100942 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100943
944 /* reset the PRNG used by sgsn_alloc_ptmsi */
945 srand(1);
946
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100947 ptmsi1 = sgsn_alloc_ptmsi();
948 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
949
950 /* reset the PRNG, so that the same P-TMSI sequence will be generated
951 * again */
952 srand(1);
953
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100954 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
955
956 /* Create a LLE/LLME */
957 OSMO_ASSERT(count(gprs_llme_list()) == 0);
958 lle = gprs_lle_get_or_create(foreign_tlli, 3);
959 OSMO_ASSERT(count(gprs_llme_list()) == 1);
960
961 /* inject the attach request */
962 send_0408_message(lle->llme, foreign_tlli,
963 attach_req, ARRAY_SIZE(attach_req));
964
965 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
966 OSMO_ASSERT(ctx != NULL);
967 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
968
969 /* we expect an identity request (IMEI) */
970 OSMO_ASSERT(sgsn_tx_counter == 1);
971
972 /* inject the identity response (IMEI) */
973 send_0408_message(ctx->llme, foreign_tlli,
974 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
975
976 /* we expect an identity request (IMSI) */
977 OSMO_ASSERT(sgsn_tx_counter == 1);
978
979 /* inject the identity response (IMSI) */
980 send_0408_message(ctx->llme, foreign_tlli,
981 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
982
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100983 /* check that the MM context has not been removed due to a failed
984 * authorization */
985 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
986
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100987 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100988
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100989retry_attach_req:
990
991 if (retry && sgsn_tx_counter == 0) {
992 fprintf(stderr, "Retrying attach request\n");
993 /* re-inject the attach request */
994 send_0408_message(lle->llme, foreign_tlli,
995 attach_req, ARRAY_SIZE(attach_req));
996 }
997
998 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
999 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001000
1001 /* inject the auth & ciph response */
1002 send_0408_message(ctx->llme, foreign_tlli,
1003 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1004
1005 /* check that the MM context has not been removed due to a
1006 * failed authorization */
1007 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1008 }
1009
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001010 if (retry && sgsn_tx_counter == 0)
1011 goto retry_attach_req;
1012
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001013 /* we expect an attach accept/reject */
1014 OSMO_ASSERT(sgsn_tx_counter == 1);
1015
1016 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +01001017 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001018
1019 /* inject the attach complete */
1020 send_0408_message(ctx->llme, local_tlli,
1021 attach_compl, ARRAY_SIZE(attach_compl));
1022
1023 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1024
1025 /* we don't expect a response */
1026 OSMO_ASSERT(sgsn_tx_counter == 0);
1027
1028 /* inject the detach */
1029 send_0408_message(ctx->llme, local_tlli,
1030 detach_req, ARRAY_SIZE(detach_req));
1031
1032 /* verify that things are gone */
1033 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1034 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1035 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001036}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001037
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001038static void test_gmm_attach_acl(void)
1039{
1040 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1041
1042 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1043 sgsn_acl_add("123456789012345", &sgsn->cfg);
1044 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001045 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +01001046 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001047
1048 sgsn->cfg.auth_policy = saved_auth_policy;
1049}
1050
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001051int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001052 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001053 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001054 if (rc == -ENOTSUP) {
1055 OSMO_ASSERT(mmctx->subscr);
1056 gprs_subscr_update(mmctx->subscr);
1057 }
1058 return rc;
1059};
1060
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001061int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1062 gprs_subscr_update(mmctx->subscr);
1063 return 0;
1064};
1065
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001066static void test_gmm_attach_subscr(void)
1067{
1068 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1069 struct gsm_subscriber *subscr;
1070
1071 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001072 subscr_request_update_location_cb = my_subscr_request_update_location;
1073 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001074
1075 subscr = gprs_subscr_get_or_create("123456789012345");
1076 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001077
1078 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001079 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001080 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001081 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001082
1083 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001084 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1085 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001086}
1087
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001088int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1089{
1090 /* Fake an authentication */
1091 OSMO_ASSERT(mmctx->subscr);
1092 mmctx->is_authenticated = 1;
1093 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001094
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001095 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001096};
1097
1098static void test_gmm_attach_subscr_fake_auth(void)
1099{
1100 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1101 struct gsm_subscriber *subscr;
1102
1103 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001104 subscr_request_update_location_cb = my_subscr_request_update_location;
1105 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001106
1107 subscr = gprs_subscr_get_or_create("123456789012345");
1108 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001109 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001110 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001111
1112 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001113 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001114 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001115 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001116
1117 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001118 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1119 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1120}
1121
1122int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1123{
1124 struct gsm_auth_tuple at = {
1125 .sres = {0x51, 0xe5, 0x51, 0xe5},
1126 .key_seq = 0
1127 };
1128
1129 /* Fake an authentication */
1130 OSMO_ASSERT(mmctx->subscr);
1131 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1132
1133 gprs_subscr_update_auth_info(mmctx->subscr);
1134
1135 return 0;
1136};
1137
1138static void test_gmm_attach_subscr_real_auth(void)
1139{
1140 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1141 struct gsm_subscriber *subscr;
1142
1143 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1144 subscr_request_update_location_cb = my_subscr_request_update_location;
1145 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1146
1147 subscr = gprs_subscr_get_or_create("123456789012345");
1148 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001149 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001150 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001151
1152 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001153
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001154 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001155 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001156 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001157
1158 sgsn->cfg.auth_policy = saved_auth_policy;
1159 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1160 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001161}
1162
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001163#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1164 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1165
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001166static int auth_info_skip = 0;
1167static int upd_loc_skip = 0;
1168
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001169int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1170{
1171 static const uint8_t send_auth_info_res[] = {
1172 0x0a,
1173 TEST_GSUP_IMSI_LONG_IE,
1174 0x03, 0x22, /* Auth tuple */
1175 0x20, 0x10,
1176 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1177 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1178 0x21, 0x04,
1179 0x51, 0xe5, 0x51, 0xe5,
1180 0x22, 0x08,
1181 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1182 };
1183
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001184 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001185
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001186 if (auth_info_skip > 0) {
1187 auth_info_skip -= 1;
1188 return -EAGAIN;
1189 }
1190
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001191 /* Fake an SendAuthInfoRes */
1192 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1193
1194 return 0;
1195};
1196
1197int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1198 static const uint8_t update_location_res[] = {
1199 0x06,
1200 TEST_GSUP_IMSI_LONG_IE,
1201 0x04, 0x00, /* PDP info complete */
1202 0x05, 0x12,
1203 0x10, 0x01, 0x01,
1204 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1205 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1206 };
1207
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001208 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001209
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001210 if (upd_loc_skip > 0) {
1211 upd_loc_skip -= 1;
1212 return -EAGAIN;
1213 }
1214
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001215 /* Fake an UpdateLocRes */
1216 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1217};
1218
1219
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001220static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001221{
1222 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1223 struct gsm_subscriber *subscr;
1224
1225 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1226 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1227 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001228 if (retry) {
1229 upd_loc_skip = 3;
1230 auth_info_skip = 3;
1231 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001232
1233 subscr = gprs_subscr_get_or_create("123456789012345");
1234 subscr->authorized = 1;
1235 sgsn->cfg.require_authentication = 1;
1236 sgsn->cfg.require_update_location = 1;
1237 subscr_put(subscr);
1238
1239 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001240 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001241 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001242
1243 sgsn->cfg.auth_policy = saved_auth_policy;
1244 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1245 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001246 upd_loc_skip = 0;
1247 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001248}
1249
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001250int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1251{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001252 struct gprs_gsup_message to_peer = {0};
1253 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001254 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001255 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001256
1257 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001258 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1259 OSMO_ASSERT(rc >= 0);
1260 OSMO_ASSERT(to_peer.imsi[0] != 0);
1261 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001262
1263 /* This invalidates the pointers in to_peer */
1264 msgb_free(msg);
1265
1266 switch (to_peer.message_type) {
1267 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1268 /* Send UPDATE_LOCATION_RESULT */
1269 return my_subscr_request_update_gsup_auth(NULL);
1270
1271 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1272 /* Send SEND_AUTH_INFO_RESULT */
1273 return my_subscr_request_auth_info_gsup_auth(NULL);
1274
1275 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001276 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1277 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001278
1279 default:
1280 if ((to_peer.message_type & 0b00000011) == 0) {
1281 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001282 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001283 from_peer.message_type = to_peer.message_type + 1;
1284 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1285 break;
1286 }
1287
1288 /* Ignore it */
1289 return 0;
1290 }
1291
1292 reply_msg = gprs_gsup_msgb_alloc();
1293 reply_msg->l2h = reply_msg->data;
1294 gprs_gsup_encode(reply_msg, &from_peer);
1295 gprs_subscr_rx_gsup_message(reply_msg);
1296 msgb_free(reply_msg);
1297
1298 return 0;
1299};
1300
1301static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1302{
1303 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1304 struct gsm_subscriber *subscr;
1305
1306 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001307 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1308
1309 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1310
1311 if (retry) {
1312 upd_loc_skip = 3;
1313 auth_info_skip = 3;
1314 }
1315
1316 printf("Auth policy 'remote', real GSUP based auth: ");
1317 test_gmm_attach(retry);
1318
1319 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001320 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001321 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001322
1323 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001324 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1325 upd_loc_skip = 0;
1326 auth_info_skip = 0;
1327 talloc_free(sgsn->gsup_client);
1328 sgsn->gsup_client = NULL;
1329}
1330
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001331/*
1332 * Test the GMM Rejects
1333 */
1334static void test_gmm_reject(void)
1335{
1336 struct gprs_ra_id raid = { 0, };
1337 struct sgsn_mm_ctx *ctx = NULL;
1338 uint32_t foreign_tlli;
1339 struct gprs_llc_lle *lle;
1340 int idx;
1341
1342 /* DTAP - Attach Request */
1343 /* Invalid MI length */
1344 static const unsigned char attach_req_inv_mi_len[] = {
1345 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1346 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1347 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1348 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1349 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1350 };
1351
1352 /* DTAP - Attach Request */
1353 /* Invalid MI type (IMEI) */
1354 static const unsigned char attach_req_inv_mi_type[] = {
1355 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1356 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1357 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1358 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1359 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1360 };
1361
1362 /* DTAP - Routing Area Update Request */
1363 static const unsigned char dtap_ra_upd_req[] = {
1364 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1365 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1366 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1367 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1368 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1369 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1370 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1371 };
1372
1373 /* DTAP - Routing Area Update Request */
1374 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1375 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1376 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1377 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1378 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1379 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1380 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1381 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1382 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1383 };
1384
1385 /* DTAP - Routing Area Update Request */
1386 /* Invalid cap length */
1387 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1388 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1389 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1390 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1391 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1392 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1393 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1394 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1395 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1396 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1397 };
1398
1399 struct test {
1400 const char *title;
1401 const unsigned char *msg;
1402 unsigned msg_len;
1403 unsigned num_resp;
1404
1405 };
1406 static struct test tests[] = {
1407 {
1408 .title = "Attach Request (invalid MI length)",
1409 .msg = attach_req_inv_mi_len,
1410 .msg_len = sizeof(attach_req_inv_mi_len),
1411 .num_resp = 1 /* Reject */
1412
1413 },
1414 {
1415 .title = "Attach Request (invalid MI type)",
1416 .msg = attach_req_inv_mi_type,
1417 .msg_len = sizeof(attach_req_inv_mi_type),
1418 .num_resp = 1 /* Reject */
1419 },
1420 {
1421 .title = "Routing Area Update Request (valid)",
1422 .msg = dtap_ra_upd_req,
1423 .msg_len = sizeof(dtap_ra_upd_req),
1424 .num_resp = 2 /* XID Reset + Reject */
1425 },
1426 {
1427 .title = "Routing Area Update Request (invalid type)",
1428 .msg = dtap_ra_upd_req_inv_type,
1429 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1430 .num_resp = 1 /* Reject */
1431 },
1432 {
1433 .title = "Routing Area Update Request (invalid CAP length)",
1434 .msg = dtap_ra_upd_req_inv_cap_len,
1435 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1436 .num_resp = 1 /* Reject */
1437 },
1438 };
1439
1440 printf("Testing GMM reject\n");
1441
1442 /* reset the PRNG used by sgsn_alloc_ptmsi */
1443 srand(1);
1444
1445 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1446
1447 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1448
1449 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1450 const struct test *test = &tests[idx];
1451 printf(" - %s\n", test->title);
1452
1453 /* Create a LLE/LLME */
1454 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1455 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1456
1457 /* Inject the Request message */
1458 send_0408_message(lle->llme, foreign_tlli,
1459 test->msg, test->msg_len);
1460
1461 /* We expect a Reject message */
1462 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1463 sgsn_tx_counter, test->num_resp);
1464 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1465
1466 /* verify that LLME/MM are removed */
1467 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1468 OSMO_ASSERT(ctx == NULL);
1469 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1470 }
1471}
1472
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001473/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001474 * Test cancellation of attached MM contexts
1475 */
1476static void test_gmm_cancel(void)
1477{
1478 struct gprs_ra_id raid = { 0, };
1479 struct sgsn_mm_ctx *ctx = NULL;
1480 struct sgsn_mm_ctx *ictx;
1481 uint32_t ptmsi1;
1482 uint32_t foreign_tlli;
1483 uint32_t local_tlli = 0;
1484 struct gprs_llc_lle *lle;
1485 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1486
1487 /* DTAP - Attach Request */
1488 /* The P-TMSI is not known by the SGSN */
1489 static const unsigned char attach_req[] = {
1490 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1491 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1492 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1493 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1494 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1495 };
1496
1497 /* DTAP - Identity Response IMEI */
1498 static const unsigned char ident_resp_imei[] = {
1499 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1500 0x56
1501 };
1502
1503 /* DTAP - Identity Response IMSI */
1504 static const unsigned char ident_resp_imsi[] = {
1505 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1506 0x54
1507 };
1508
1509 /* DTAP - Attach Complete */
1510 static const unsigned char attach_compl[] = {
1511 0x08, 0x03
1512 };
1513
1514 printf("Testing cancellation\n");
1515
1516 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1517
1518 /* reset the PRNG used by sgsn_alloc_ptmsi */
1519 srand(1);
1520
1521 ptmsi1 = sgsn_alloc_ptmsi();
1522 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1523
1524 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1525 * again */
1526 srand(1);
1527
1528 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1529
1530 /* Create a LLE/LLME */
1531 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1532 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1533 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1534
1535 /* inject the attach request */
1536 send_0408_message(lle->llme, foreign_tlli,
1537 attach_req, ARRAY_SIZE(attach_req));
1538
1539 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1540 OSMO_ASSERT(ctx != NULL);
1541 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1542
1543 /* we expect an identity request (IMEI) */
1544 OSMO_ASSERT(sgsn_tx_counter == 1);
1545
1546 /* inject the identity response (IMEI) */
1547 send_0408_message(ctx->llme, foreign_tlli,
1548 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1549
1550 /* we expect an identity request (IMSI) */
1551 OSMO_ASSERT(sgsn_tx_counter == 1);
1552
1553 /* inject the identity response (IMSI) */
1554 send_0408_message(ctx->llme, foreign_tlli,
1555 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1556
1557 /* check that the MM context has not been removed due to a failed
1558 * authorization */
1559 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1560
1561 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1562
1563 /* we expect an attach accept/reject */
1564 OSMO_ASSERT(sgsn_tx_counter == 1);
1565
1566 /* this has been randomly assigned by the SGSN */
1567 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1568
1569 /* inject the attach complete */
1570 send_0408_message(ctx->llme, local_tlli,
1571 attach_compl, ARRAY_SIZE(attach_compl));
1572
1573 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1574
1575 /* we don't expect a response */
1576 OSMO_ASSERT(sgsn_tx_counter == 0);
1577
1578 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001579 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001580
1581 /* verify that things are gone */
1582 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1583 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1584 OSMO_ASSERT(!ictx);
1585
1586 sgsn->cfg.auth_policy = saved_auth_policy;
1587}
1588
1589/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001590 * Test the dynamic allocation of P-TMSIs
1591 */
1592static void test_gmm_ptmsi_allocation(void)
1593{
1594 struct gprs_ra_id raid = { 0, };
1595 struct sgsn_mm_ctx *ctx = NULL;
1596 struct sgsn_mm_ctx *ictx;
1597 uint32_t foreign_tlli;
1598 uint32_t ptmsi1;
1599 uint32_t ptmsi2;
1600 uint32_t old_ptmsi;
1601 uint32_t local_tlli = 0;
1602 struct gprs_llc_lle *lle;
1603 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1604
1605 /* DTAP - Attach Request (IMSI 12131415161718) */
1606 static const unsigned char attach_req[] = {
1607 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1608 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1609 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1610 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1611 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1612 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1613 0x00,
1614 };
1615
1616 /* DTAP - Identity Response IMEI */
1617 static const unsigned char ident_resp_imei[] = {
1618 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1619 0x56
1620 };
1621
1622 /* DTAP - Attach Complete */
1623 static const unsigned char attach_compl[] = {
1624 0x08, 0x03
1625 };
1626
1627 /* DTAP - Routing Area Update Request */
1628 static const unsigned char ra_upd_req[] = {
1629 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1630 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1631 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1632 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1633 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1634 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1635 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1636 };
1637
1638 /* DTAP - Routing Area Update Complete */
1639 static const unsigned char ra_upd_complete[] = {
1640 0x08, 0x0a
1641 };
1642
1643 /* DTAP - Detach Request (MO) */
1644 /* normal detach, power_off = 1 */
1645 static const unsigned char detach_req[] = {
1646 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1647 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1648 };
1649
1650 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1651
1652 printf("Testing P-TMSI allocation\n");
1653
1654 printf(" - sgsn_alloc_ptmsi\n");
1655
1656 /* reset the PRNG used by sgsn_alloc_ptmsi */
1657 srand(1);
1658
1659 ptmsi1 = sgsn_alloc_ptmsi();
1660 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1661
1662 ptmsi2 = sgsn_alloc_ptmsi();
1663 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1664
1665 OSMO_ASSERT(ptmsi1 != ptmsi2);
1666
1667 printf(" - Repeated Attach Request\n");
1668
1669 /* reset the PRNG, so that the same P-TMSI will be generated
1670 * again */
1671 srand(1);
1672
1673 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1674
1675 /* Create a LLE/LLME */
1676 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1677 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1678 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1679
1680 /* inject the attach request */
1681 send_0408_message(lle->llme, foreign_tlli,
1682 attach_req, ARRAY_SIZE(attach_req));
1683
1684 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1685 OSMO_ASSERT(ctx != NULL);
1686 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1687 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1688
1689 old_ptmsi = ctx->p_tmsi_old;
1690
1691 /* we expect an identity request (IMEI) */
1692 OSMO_ASSERT(sgsn_tx_counter == 1);
1693
1694 /* inject the identity response (IMEI) */
1695 send_0408_message(ctx->llme, foreign_tlli,
1696 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1697
1698 /* check that the MM context has not been removed due to a failed
1699 * authorization */
1700 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1701
1702 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1703 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1704
1705 /* we expect an attach accept */
1706 OSMO_ASSERT(sgsn_tx_counter == 1);
1707
1708 /* we ignore this and send the attach again */
1709 send_0408_message(lle->llme, foreign_tlli,
1710 attach_req, ARRAY_SIZE(attach_req));
1711
1712 /* the allocated P-TMSI should be the same */
1713 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1714 OSMO_ASSERT(ctx != NULL);
1715 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1716 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1717 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1718
1719 /* inject the attach complete */
1720 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1721 send_0408_message(ctx->llme, local_tlli,
1722 attach_compl, ARRAY_SIZE(attach_compl));
1723
1724 /* we don't expect a response */
1725 OSMO_ASSERT(sgsn_tx_counter == 0);
1726
1727 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1728 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1729 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1730
1731 printf(" - Repeated RA Update Request\n");
1732
1733 /* inject the RA update request */
1734 send_0408_message(ctx->llme, local_tlli,
1735 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1736
1737 /* we expect an RA update accept */
1738 OSMO_ASSERT(sgsn_tx_counter == 1);
1739
1740 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1741 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1742 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1743
1744 /* repeat the RA update request */
1745 send_0408_message(ctx->llme, local_tlli,
1746 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1747
1748 /* we expect an RA update accept */
1749 OSMO_ASSERT(sgsn_tx_counter == 1);
1750
1751 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1752 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1753 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1754
1755 /* inject the RA update complete */
1756 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1757 send_0408_message(ctx->llme, local_tlli,
1758 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1759
1760 /* we don't expect a response */
1761 OSMO_ASSERT(sgsn_tx_counter == 0);
1762
1763 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1764 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1765 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1766
1767 /* inject the detach */
1768 send_0408_message(ctx->llme, local_tlli,
1769 detach_req, ARRAY_SIZE(detach_req));
1770
1771 /* verify that things are gone */
1772 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1773 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1774 OSMO_ASSERT(!ictx);
1775
1776 sgsn->cfg.auth_policy = saved_auth_policy;
1777}
1778
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001779static struct log_info_cat gprs_categories[] = {
1780 [DMM] = {
1781 .name = "DMM",
1782 .description = "Layer3 Mobility Management (MM)",
1783 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001784 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001785 },
1786 [DPAG] = {
1787 .name = "DPAG",
1788 .description = "Paging Subsystem",
1789 .color = "\033[1;38m",
1790 .enabled = 1, .loglevel = LOGL_NOTICE,
1791 },
1792 [DMEAS] = {
1793 .name = "DMEAS",
1794 .description = "Radio Measurement Processing",
1795 .enabled = 0, .loglevel = LOGL_NOTICE,
1796 },
1797 [DREF] = {
1798 .name = "DREF",
1799 .description = "Reference Counting",
1800 .enabled = 0, .loglevel = LOGL_NOTICE,
1801 },
1802 [DGPRS] = {
1803 .name = "DGPRS",
1804 .description = "GPRS Packet Service",
1805 .enabled = 1, .loglevel = LOGL_DEBUG,
1806 },
1807 [DNS] = {
1808 .name = "DNS",
1809 .description = "GPRS Network Service (NS)",
1810 .enabled = 1, .loglevel = LOGL_INFO,
1811 },
1812 [DBSSGP] = {
1813 .name = "DBSSGP",
1814 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1815 .enabled = 1, .loglevel = LOGL_DEBUG,
1816 },
1817 [DLLC] = {
1818 .name = "DLLC",
1819 .description = "GPRS Logical Link Control Protocol (LLC)",
1820 .enabled = 1, .loglevel = LOGL_DEBUG,
1821 },
1822 [DSNDCP] = {
1823 .name = "DSNDCP",
1824 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1825 .enabled = 1, .loglevel = LOGL_DEBUG,
1826 },
1827};
1828
1829static struct log_info info = {
1830 .cat = gprs_categories,
1831 .num_cat = ARRAY_SIZE(gprs_categories),
1832};
1833
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001834int main(int argc, char **argv)
1835{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01001836 void *osmo_sgsn_ctx;
1837
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001838 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01001839 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1840 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
1841 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001842
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001843 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001844 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001845
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001846 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001847 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01001848 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01001849 test_subscriber_gsup();
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +01001850 test_subscriber_blocking();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02001851 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01001852 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02001853 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01001854 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01001855 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001856 test_gmm_attach_acl();
1857 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001858 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001859 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001860 test_gmm_attach_subscr_gsup_auth(0);
1861 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001862 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001863 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001864 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001865 test_gmm_ptmsi_allocation();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001866 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01001867
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01001868 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01001869 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01001870 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001871 return 0;
1872}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001873
1874
1875/* stubs */
1876struct osmo_prim_hdr;
1877int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1878{
1879 abort();
1880}