blob: 5fa33a2663c04115b42dff86140a98565bbf9ad8 [file] [log] [blame]
Holger Hans Peter Freyther232f6212014-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 Freyther49dbcd92014-10-02 21:27:24 +020022#include <openbsc/gprs_llc.h>
23#include <openbsc/sgsn.h>
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +020024#include <openbsc/gprs_gmm.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020025#include <openbsc/debug.h>
Jacob Erlbecke8b69682014-11-12 10:12:11 +010026#include <openbsc/gsm_subscriber.h>
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +010027#include <openbsc/gprs_gsup_messages.h>
28#include <openbsc/gprs_gsup_client.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020029
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010030#include <osmocom/gprs/gprs_bssgp.h>
31
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020032#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck092bbc82015-01-05 18:57:32 +010033#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020034
35#include <osmocom/core/application.h>
36#include <osmocom/core/msgb.h>
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010037#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020038
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +020039#include <stdio.h>
40
Holger Hans Peter Freyther49dbcd92014-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 Erlbeckd7b77732014-11-04 10:08:37 +010048 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020049 },
50};
51struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck0b2da872014-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 Erlbeck6e6b3302015-01-13 11:56:28 +010059 msgb_free(msg);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +010060 return 0;
61}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +020062
Jacob Erlbecke8b69682014-11-12 10:12:11 +010063/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck428f1ec2015-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 Erlbecke8b69682014-11-12 10:12:11 +010066 &__real_sgsn_update_subscriber_data;
67
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +010068void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +010069{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +010070 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +010071}
72
Jacob Erlbeck828059f2014-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 Erlbeckd04f7cc2014-11-12 10:18:09 +010077
Jacob Erlbeck828059f2014-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 Erlbeckd04f7cc2014-11-12 10:18:09 +010089};
Jacob Erlbecke8b69682014-11-12 10:12:11 +010090
Jacob Erlbeck0d2cf602015-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 Freyther49dbcd92014-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 Freyther94246842014-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 Erlbeckf43a2992014-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 Erlbeck75488292014-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 Freyther49dbcd92014-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 Erlbecke8b69682014-11-12 10:12:11 +0100192struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100193void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100194{
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100195 OSMO_ASSERT(mmctx);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100196 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck428f1ec2015-01-26 13:52:42 +0100197 __func__, mmctx, mmctx->subscr);
198 last_updated_subscr = mmctx->subscr;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100199}
200
Jacob Erlbecka695d242015-01-09 11:59:50 +0100201static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
202{
203 struct gsm_subscriber *sfound;
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100204 OSMO_ASSERT(subscr);
205 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100206
207 sfound = gprs_subscr_get_by_imsi(imsi);
208 OSMO_ASSERT(sfound == subscr);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100209
Jacob Erlbeckf3df29d2015-01-19 08:57:07 +0100210 subscr_put(sfound);
Jacob Erlbecka695d242015-01-09 11:59:50 +0100211}
212
Jacob Erlbeck8768f2b2015-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 Freytherd95cb732015-01-20 21:14:03 +0100219 "use count: %d\n",
220 subscr->imsi, subscr->use_count);
Jacob Erlbeck8768f2b2015-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 Erlbecke8b69682014-11-12 10:12:11 +0100231static void test_subscriber(void)
232{
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100233 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100234 const char *imsi1 = "1234567890";
235 const char *imsi2 = "9876543210";
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100236 const char *imsi3 = "5656565656";
Jacob Erlbecke8b69682014-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 Erlbeck9bf4be92015-01-06 16:32:41 +0100245 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-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 Erlbecka695d242015-01-09 11:59:50 +0100250 assert_subscr(s1, imsi1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100251 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbecke8b69682014-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 Erlbecka695d242015-01-09 11:59:50 +0100256
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100257 /* Allocate entry 3 */
258 s3 = gprs_subscr_get_or_create(imsi3);
259
Jacob Erlbecka695d242015-01-09 11:59:50 +0100260 /* Check entries */
261 assert_subscr(s1, imsi1);
262 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100263 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100264
265 /* Update entry 1 */
266 last_updated_subscr = NULL;
267 gprs_subscr_update(s1);
Jacob Erlbeck428f1ec2015-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 Erlbecke8b69682014-11-12 10:12:11 +0100271
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100272 /* There is no subscriber cache. Verify it */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100273 gprs_subscr_cleanup(s1);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100274 subscr_put(s1);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100275 s1 = NULL;
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100276 sfound = gprs_subscr_get_by_imsi(imsi1);
277 OSMO_ASSERT(sfound == NULL);
278
Jacob Erlbecka695d242015-01-09 11:59:50 +0100279 assert_subscr(s2, imsi2);
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100280 assert_subscr(s3, imsi3);
Jacob Erlbecke8b69682014-11-12 10:12:11 +0100281
Jacob Erlbecka695d242015-01-09 11:59:50 +0100282 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100283 gprs_subscr_cleanup(s2);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100284 subscr_put(s2);
Jacob Erlbecke8b69682014-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 Erlbeck9bf4be92015-01-06 16:32:41 +0100288 assert_subscr(s3, imsi3);
289
290 /* Try to delete entry 3 */
Jacob Erlbecke71ab2f2015-01-26 11:07:24 +0100291 gprs_subscr_cleanup(s3);
Jacob Erlbeck7a7d8812015-01-23 13:52:55 +0100292 subscr_put(s3);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +0100293 s3 = NULL;
Jacob Erlbeck9bf4be92015-01-06 16:32:41 +0100294 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbecke8b69682014-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 Erlbeckb1332b62014-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 Erlbeckb1332b62014-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 Erlbeck70c177a2015-01-26 14:43:07 +0100357 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100358 s1found = gprs_subscr_get_by_imsi(imsi1);
359 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeckb1332b62014-12-08 15:52:00 +0100360}
361
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100362#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
363
Jacob Erlbeckb5c51432014-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 Erlbeck5641cfc2014-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 Erlbeck94a346a2014-12-17 14:03:35 +0100386 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbeck5641cfc2014-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 Erlbeck00b8b912015-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 Erlbeck86bc8702015-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 Erlbeck9ca3ace2015-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 Erlbeck86bc8702015-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 Erlbeck4f414862015-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 Erlbeck5641cfc2014-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);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100498
499 /* Attach s1 to ctx */
500 ctx->subscr = subscr_get(s1);
501 ctx->subscr->sgsn_data->mm = ctx;
502
503 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100504 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100505 OSMO_ASSERT(rc >= 0);
506 OSMO_ASSERT(last_updated_subscr == s1);
507
508 /* Check triplets */
509 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
510 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
511 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
512
513 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100514 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100515 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100516 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100517 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100518
519 /* Check triplets */
520 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
521 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
522 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
523
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100524 /* Inject UpdateLocRes GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100525 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100526 OSMO_ASSERT(rc >= 0);
527 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100528 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100529 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbeck94a346a2014-12-17 14:03:35 +0100530 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
531 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
532 struct sgsn_subscriber_pdp_data, list);
533 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
534 pdpd = llist_entry(pdpd->list.next,
535 struct sgsn_subscriber_pdp_data, list);
536 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100537
538 /* Check authorization */
539 OSMO_ASSERT(s1->authorized == 1);
540
541 /* Inject UpdateLocErr GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100542 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeck092bbc82015-01-05 18:57:32 +0100543 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100544 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100545 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100546
547 /* Check authorization */
548 OSMO_ASSERT(s1->authorized == 0);
549
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100550 /* Inject InsertSubscrData GSUP message */
551 last_updated_subscr = NULL;
552 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
553 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
554 OSMO_ASSERT(last_updated_subscr == NULL);
555
556 /* Inject DeleteSubscrData GSUP message */
557 last_updated_subscr = NULL;
558 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
559 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
560 OSMO_ASSERT(last_updated_subscr == NULL);
561
Jacob Erlbeck00b8b912015-01-08 15:29:01 +0100562 /* Inject wrong LocCancelReq GSUP message */
563 last_updated_subscr = NULL;
564 rc = rx_gsup_message(location_cancellation_req_other,
565 sizeof(location_cancellation_req_other));
566 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
567 OSMO_ASSERT(last_updated_subscr == NULL);
568
569 /* Check cancellation result */
570 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
571 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
572
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100573 /* Inject LocCancelReq GSUP message */
Jacob Erlbeckb5c51432014-12-19 18:19:50 +0100574 rc = rx_gsup_message(location_cancellation_req,
575 sizeof(location_cancellation_req));
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100576 OSMO_ASSERT(rc >= 0);
577 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck736da132015-01-29 14:55:34 +0100578 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100579
580 /* Check cancellation result */
581 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
582 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
583
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100584 /* Inject PurgeMsRes GSUP message */
585 rc = rx_gsup_message(purge_ms_res,
586 sizeof(purge_ms_res));
587 OSMO_ASSERT(rc >= 0);
588 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
589
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100590 /* Free MM context and subscriber */
Jacob Erlbeck265e7352015-01-30 11:57:25 +0100591 OSMO_ASSERT(ctx->subscr == NULL);
592 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100593 subscr_put(s1);
594 s1found = gprs_subscr_get_by_imsi(imsi1);
595 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100596
Jacob Erlbeck86bc8702015-01-29 14:12:29 +0100597 /* Inject PurgeMsRes GSUP message */
598 rc = rx_gsup_message(purge_ms_res,
599 sizeof(purge_ms_res));
600 OSMO_ASSERT(rc >= 0);
601
602 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
603 rc = rx_gsup_message(purge_ms_err,
604 sizeof(purge_ms_err));
605 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
606
Jacob Erlbeck9ca3ace2015-01-29 14:17:51 +0100607 /* Inject PurgeMsErr() GSUP message */
608 rc = rx_gsup_message(purge_ms_err_no_cause,
609 sizeof(purge_ms_err_no_cause));
610 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
611
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100612 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
613 last_updated_subscr = NULL;
614 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck629dacc2015-01-15 17:50:16 +0100615 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck4f414862015-01-15 17:08:30 +0100616 OSMO_ASSERT(last_updated_subscr == NULL);
617
618 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
619 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
620 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
621 OSMO_ASSERT(last_updated_subscr == NULL);
622
623 /* Inject LocCancelReq GSUP message (unknown IMSI) */
624 rc = rx_gsup_message(location_cancellation_req,
625 sizeof(location_cancellation_req));
626 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
627 OSMO_ASSERT(last_updated_subscr == NULL);
628
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +0100629 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
630}
631
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +0100632int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
633{
634 msgb_free(msg);
635 return 0;
636};
637
638
639static void test_subscriber_blocking(void)
640{
641 struct gsm_subscriber *s1;
642 const char *imsi1 = "1234567890";
643 struct sgsn_mm_ctx *ctx;
644 struct gprs_ra_id raid = { 0, };
645 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +0100646 int rc;
647
648 printf("Testing subcriber procedure blocking\n");
649
650 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
651 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
652
653 /* Check for emptiness */
654 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
655
656 /* Create a context */
657 OSMO_ASSERT(count(gprs_llme_list()) == 0);
658 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +0100659 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
660
661 /* Allocate and attach a subscriber */
662 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
663 assert_subscr(s1, imsi1);
664
665 /* Start SendAuthInfoRequest procedure */
666 rc = gprs_subscr_query_auth_info(s1);
667 /* Not blocking */
668 OSMO_ASSERT(rc == 0);
669
670 /* Start UpdateLocation procedure */
671 rc = gprs_subscr_location_update(s1);
672 /* Blocking */
673 OSMO_ASSERT(rc == 0);
674
675 /* Start PurgeMS procedure */
676 rc = gprs_subscr_purge(s1);
677 /* Not blocking */
678 OSMO_ASSERT(rc == 0);
679 OSMO_ASSERT(s1->sgsn_data->blocked_by == SGSN_SUBSCR_PROC_PURGE);
680
681 /* Start PurgeMS procedure (retry) */
682 rc = gprs_subscr_purge(s1);
683 /* Not blocking */
684 OSMO_ASSERT(rc == 0);
685
686 /* Start SendAuthInfoRequest procedure */
687 rc = gprs_subscr_query_auth_info(s1);
688 /* Blocking */
689 OSMO_ASSERT(rc == -EAGAIN);
690
691 /* Start UpdateLocation procedure */
692 rc = gprs_subscr_location_update(s1);
693 /* Blocking */
694 OSMO_ASSERT(rc == -EAGAIN);
695
696 /* Unblock manually (normally done by the caller of gprs_subscr_purge) */
697 s1->sgsn_data->blocked_by = SGSN_SUBSCR_PROC_NONE;
698
699 /* Start SendAuthInfoRequest procedure */
700 rc = gprs_subscr_query_auth_info(s1);
701 /* Not blocking */
702 OSMO_ASSERT(rc == 0);
703
704 /* Start UpdateLocation procedure */
705 rc = gprs_subscr_location_update(s1);
706 /* Blocking */
707 OSMO_ASSERT(rc == 0);
708
709 subscr_put(s1);
Jacob Erlbeck70c177a2015-01-26 14:43:07 +0100710 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +0100711
712 assert_no_subscrs();
713
714 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
715 talloc_free(sgsn->gsup_client);
716 sgsn->gsup_client = NULL;
717}
718
719
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200720/*
721 * Test that a GMM Detach will remove the MMCTX and the
722 * associated LLME.
723 */
724static void test_gmm_detach(void)
725{
726 struct gprs_ra_id raid = { 0, };
727 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200728 uint32_t local_tlli;
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200729
730 printf("Testing GMM detach\n");
731
732 /* DTAP - Detach Request (MO) */
733 /* normal detach, power_off = 0 */
734 static const unsigned char detach_req[] = {
735 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
736 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
737 };
738
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200739 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200740
Jacob Erlbeckf43a2992014-10-27 13:23:49 +0100741 /* Create a context */
742 OSMO_ASSERT(count(gprs_llme_list()) == 0);
743 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200744
745 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100746 send_0408_message(ctx->llme, local_tlli,
747 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200748
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100749 /* verify that a single message (hopefully the Detach Accept) has been
750 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100751 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100752
753 /* verify that things are gone */
754 OSMO_ASSERT(count(gprs_llme_list()) == 0);
755 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
756 OSMO_ASSERT(!ictx);
757}
758
759/*
760 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
761 * will not sent a Detach Accept message (power_off = 1)
762 */
763static void test_gmm_detach_power_off(void)
764{
765 struct gprs_ra_id raid = { 0, };
766 struct sgsn_mm_ctx *ctx, *ictx;
767 uint32_t local_tlli;
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100768
769 printf("Testing GMM detach (power off)\n");
770
771 /* DTAP - Detach Request (MO) */
772 /* normal detach, power_off = 1 */
773 static const unsigned char detach_req[] = {
774 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
775 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
776 };
777
778 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
779
780 /* Create a context */
781 OSMO_ASSERT(count(gprs_llme_list()) == 0);
782 ctx = alloc_mm_ctx(local_tlli, &raid);
783
784 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100785 send_0408_message(ctx->llme, local_tlli,
786 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100787
788 /* verify that no message (and therefore no Detach Accept) has been
789 * sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100790 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck0b2da872014-10-27 14:34:13 +0100791
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200792 /* verify that things are gone */
793 OSMO_ASSERT(count(gprs_llme_list()) == 0);
794 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck12396bd2014-09-30 13:51:45 +0200795 OSMO_ASSERT(!ictx);
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +0200796}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +0200797
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200798/*
799 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
800 */
801static void test_gmm_detach_no_mmctx(void)
802{
803 struct gprs_llc_lle *lle;
804 uint32_t local_tlli;
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200805
806 printf("Testing GMM detach (no MMCTX)\n");
807
808 /* DTAP - Detach Request (MO) */
809 /* normal detach, power_off = 0 */
810 static const unsigned char detach_req[] = {
811 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
812 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
813 };
814
815 /* Create an LLME */
816 OSMO_ASSERT(count(gprs_llme_list()) == 0);
817 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
818 lle = gprs_lle_get_or_create(local_tlli, 3);
819
820 OSMO_ASSERT(count(gprs_llme_list()) == 1);
821
822 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100823 send_0408_message(lle->llme, local_tlli,
824 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck42d284f2014-10-21 13:09:55 +0200825
826 /* verify that the LLME is gone */
827 OSMO_ASSERT(count(gprs_llme_list()) == 0);
828}
829
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100830/*
Jacob Erlbeck021a0d12014-11-24 15:04:15 +0100831 * Test that a single GMM Detach Accept message will not cause the SGSN to send
832 * any message or leave an MM context at the SGSN.
833 */
834static void test_gmm_detach_accept_unexpected(void)
835{
836 struct gprs_llc_lle *lle;
837 uint32_t local_tlli;
838
839 printf("Testing GMM detach accept (unexpected)\n");
840
841 /* DTAP - Detach Accept (MT) */
842 /* normal detach */
843 static const unsigned char detach_acc[] = {
844 0x08, 0x06
845 };
846
847 /* Create an LLME */
848 OSMO_ASSERT(count(gprs_llme_list()) == 0);
849 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
850 lle = gprs_lle_get_or_create(local_tlli, 3);
851
852 /* inject the detach */
853 send_0408_message(lle->llme, local_tlli,
854 detach_acc, ARRAY_SIZE(detach_acc));
855
856 /* verify that no message (and therefore no Status or XID reset) has been
857 * sent by the SGSN */
858 OSMO_ASSERT(sgsn_tx_counter == 0);
859
860 /* verify that things are gone */
861 OSMO_ASSERT(count(gprs_llme_list()) == 0);
862}
863
864/*
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100865 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
866 */
867static void test_gmm_status_no_mmctx(void)
868{
869 struct gprs_llc_lle *lle;
870 uint32_t local_tlli;
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100871
872 printf("Testing GMM Status (no MMCTX)\n");
873
874 /* DTAP - GMM Status, protocol error */
875 static const unsigned char gmm_status[] = {
876 0x08, 0x20, 0x6f
877 };
878
879 /* Create an LLME */
880 OSMO_ASSERT(count(gprs_llme_list()) == 0);
881 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
882 lle = gprs_lle_get_or_create(local_tlli, 3);
883
884 OSMO_ASSERT(count(gprs_llme_list()) == 1);
885
886 /* inject the detach */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100887 send_0408_message(lle->llme, local_tlli,
888 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100889
890 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck75488292014-10-29 10:31:18 +0100891 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +0100892
893 /* verify that the LLME is gone */
894 OSMO_ASSERT(count(gprs_llme_list()) == 0);
895}
896
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100897/*
898 * Test the GMM Attach procedure
899 */
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100900static void test_gmm_attach(int retry)
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100901{
902 struct gprs_ra_id raid = { 0, };
903 struct sgsn_mm_ctx *ctx = NULL;
904 struct sgsn_mm_ctx *ictx;
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100905 uint32_t ptmsi1;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100906 uint32_t foreign_tlli;
907 uint32_t local_tlli = 0;
908 struct gprs_llc_lle *lle;
909
910 /* DTAP - Attach Request */
911 /* The P-TMSI is not known by the SGSN */
912 static const unsigned char attach_req[] = {
913 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
914 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
915 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
916 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
917 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
918 };
919
920 /* DTAP - Identity Response IMEI */
921 static const unsigned char ident_resp_imei[] = {
922 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
923 0x56
924 };
925
926 /* DTAP - Identity Response IMSI */
927 static const unsigned char ident_resp_imsi[] = {
928 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
929 0x54
930 };
931
Jacob Erlbeck828059f2014-11-28 14:55:25 +0100932 /* DTAP - Authentication and Ciphering Resp */
933 static const unsigned char auth_ciph_resp[] = {
934 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
935 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
936 };
937
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100938 /* DTAP - Attach Complete */
939 static const unsigned char attach_compl[] = {
940 0x08, 0x03
941 };
942
943 /* DTAP - Detach Request (MO) */
944 /* normal detach, power_off = 0 */
945 static const unsigned char detach_req[] = {
946 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
947 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
948 };
949
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100950 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100951
952 /* reset the PRNG used by sgsn_alloc_ptmsi */
953 srand(1);
954
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +0100955 ptmsi1 = sgsn_alloc_ptmsi();
956 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
957
958 /* reset the PRNG, so that the same P-TMSI sequence will be generated
959 * again */
960 srand(1);
961
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100962 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
963
964 /* Create a LLE/LLME */
965 OSMO_ASSERT(count(gprs_llme_list()) == 0);
966 lle = gprs_lle_get_or_create(foreign_tlli, 3);
967 OSMO_ASSERT(count(gprs_llme_list()) == 1);
968
969 /* inject the attach request */
970 send_0408_message(lle->llme, foreign_tlli,
971 attach_req, ARRAY_SIZE(attach_req));
972
973 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
974 OSMO_ASSERT(ctx != NULL);
975 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
976
977 /* we expect an identity request (IMEI) */
978 OSMO_ASSERT(sgsn_tx_counter == 1);
979
980 /* inject the identity response (IMEI) */
981 send_0408_message(ctx->llme, foreign_tlli,
982 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
983
984 /* we expect an identity request (IMSI) */
985 OSMO_ASSERT(sgsn_tx_counter == 1);
986
987 /* inject the identity response (IMSI) */
988 send_0408_message(ctx->llme, foreign_tlli,
989 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
990
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100991 /* check that the MM context has not been removed due to a failed
992 * authorization */
993 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
994
Jacob Erlbeck67318ef2014-10-28 16:23:46 +0100995 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +0100996
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +0100997retry_attach_req:
998
999 if (retry && sgsn_tx_counter == 0) {
1000 fprintf(stderr, "Retrying attach request\n");
1001 /* re-inject the attach request */
1002 send_0408_message(lle->llme, foreign_tlli,
1003 attach_req, ARRAY_SIZE(attach_req));
1004 }
1005
1006 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
1007 /* we got an auth & ciph request */
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001008
1009 /* inject the auth & ciph response */
1010 send_0408_message(ctx->llme, foreign_tlli,
1011 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
1012
1013 /* check that the MM context has not been removed due to a
1014 * failed authorization */
1015 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1016 }
1017
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001018 if (retry && sgsn_tx_counter == 0)
1019 goto retry_attach_req;
1020
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001021 /* we expect an attach accept/reject */
1022 OSMO_ASSERT(sgsn_tx_counter == 1);
1023
1024 /* this has been randomly assigned by the SGSN */
Jacob Erlbeck0a2c7912014-11-24 14:40:28 +01001025 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001026
1027 /* inject the attach complete */
1028 send_0408_message(ctx->llme, local_tlli,
1029 attach_compl, ARRAY_SIZE(attach_compl));
1030
1031 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1032
1033 /* we don't expect a response */
1034 OSMO_ASSERT(sgsn_tx_counter == 0);
1035
1036 /* inject the detach */
1037 send_0408_message(ctx->llme, local_tlli,
1038 detach_req, ARRAY_SIZE(detach_req));
1039
1040 /* verify that things are gone */
1041 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1042 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1043 OSMO_ASSERT(!ictx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001044}
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001045
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001046static void test_gmm_attach_acl(void)
1047{
1048 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1049
1050 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
1051 sgsn_acl_add("123456789012345", &sgsn->cfg);
1052 printf("Auth policy 'closed': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001053 test_gmm_attach(0);
Jacob Erlbeck79d438a2014-10-29 22:12:20 +01001054 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001055
1056 sgsn->cfg.auth_policy = saved_auth_policy;
1057}
1058
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001059int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001060 int rc;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001061 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001062 if (rc == -ENOTSUP) {
1063 OSMO_ASSERT(mmctx->subscr);
1064 gprs_subscr_update(mmctx->subscr);
1065 }
1066 return rc;
1067};
1068
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001069int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
1070 gprs_subscr_update(mmctx->subscr);
1071 return 0;
1072};
1073
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001074static void test_gmm_attach_subscr(void)
1075{
1076 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1077 struct gsm_subscriber *subscr;
1078
1079 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001080 subscr_request_update_location_cb = my_subscr_request_update_location;
1081 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001082
1083 subscr = gprs_subscr_get_or_create("123456789012345");
1084 subscr->authorized = 1;
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001085
1086 printf("Auth policy 'remote': ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001087 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001088 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001089 assert_no_subscrs();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001090
1091 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001092 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1093 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001094}
1095
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001096int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1097{
1098 /* Fake an authentication */
1099 OSMO_ASSERT(mmctx->subscr);
1100 mmctx->is_authenticated = 1;
1101 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001102
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001103 return 0;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001104};
1105
1106static void test_gmm_attach_subscr_fake_auth(void)
1107{
1108 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1109 struct gsm_subscriber *subscr;
1110
1111 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001112 subscr_request_update_location_cb = my_subscr_request_update_location;
1113 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001114
1115 subscr = gprs_subscr_get_or_create("123456789012345");
1116 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001117 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001118 sgsn->cfg.require_update_location = 1;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001119
1120 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001121 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001122 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001123 assert_no_subscrs();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001124
1125 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001126 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1127 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1128}
1129
1130int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1131{
1132 struct gsm_auth_tuple at = {
1133 .sres = {0x51, 0xe5, 0x51, 0xe5},
1134 .key_seq = 0
1135 };
1136
1137 /* Fake an authentication */
1138 OSMO_ASSERT(mmctx->subscr);
1139 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1140
1141 gprs_subscr_update_auth_info(mmctx->subscr);
1142
1143 return 0;
1144};
1145
1146static void test_gmm_attach_subscr_real_auth(void)
1147{
1148 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1149 struct gsm_subscriber *subscr;
1150
1151 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1152 subscr_request_update_location_cb = my_subscr_request_update_location;
1153 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1154
1155 subscr = gprs_subscr_get_or_create("123456789012345");
1156 subscr->authorized = 1;
Jacob Erlbeck16b17ed2014-12-17 13:20:08 +01001157 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck6ff7f642014-12-19 18:08:48 +01001158 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001159
1160 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001161
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001162 test_gmm_attach(0);
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001163 subscr_put(subscr);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001164 assert_no_subscrs();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001165
1166 sgsn->cfg.auth_policy = saved_auth_policy;
1167 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1168 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001169}
1170
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001171#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1172 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1173
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001174static int auth_info_skip = 0;
1175static int upd_loc_skip = 0;
1176
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001177int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1178{
1179 static const uint8_t send_auth_info_res[] = {
1180 0x0a,
1181 TEST_GSUP_IMSI_LONG_IE,
1182 0x03, 0x22, /* Auth tuple */
1183 0x20, 0x10,
1184 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1185 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1186 0x21, 0x04,
1187 0x51, 0xe5, 0x51, 0xe5,
1188 0x22, 0x08,
1189 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1190 };
1191
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001192 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001193
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001194 if (auth_info_skip > 0) {
1195 auth_info_skip -= 1;
1196 return -EAGAIN;
1197 }
1198
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001199 /* Fake an SendAuthInfoRes */
1200 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1201
1202 return 0;
1203};
1204
1205int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1206 static const uint8_t update_location_res[] = {
1207 0x06,
1208 TEST_GSUP_IMSI_LONG_IE,
1209 0x04, 0x00, /* PDP info complete */
1210 0x05, 0x12,
1211 0x10, 0x01, 0x01,
1212 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1213 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1214 };
1215
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001216 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001217
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001218 if (upd_loc_skip > 0) {
1219 upd_loc_skip -= 1;
1220 return -EAGAIN;
1221 }
1222
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001223 /* Fake an UpdateLocRes */
1224 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1225};
1226
1227
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001228static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001229{
1230 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1231 struct gsm_subscriber *subscr;
1232
1233 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1234 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1235 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001236 if (retry) {
1237 upd_loc_skip = 3;
1238 auth_info_skip = 3;
1239 }
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001240
1241 subscr = gprs_subscr_get_or_create("123456789012345");
1242 subscr->authorized = 1;
1243 sgsn->cfg.require_authentication = 1;
1244 sgsn->cfg.require_update_location = 1;
1245 subscr_put(subscr);
1246
1247 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001248 test_gmm_attach(retry);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001249 assert_no_subscrs();
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001250
1251 sgsn->cfg.auth_policy = saved_auth_policy;
1252 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1253 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001254 upd_loc_skip = 0;
1255 auth_info_skip = 0;
Jacob Erlbeckdebbdd72014-12-19 18:26:09 +01001256}
1257
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001258int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1259{
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001260 struct gprs_gsup_message to_peer = {0};
1261 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001262 struct msgb *reply_msg;
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001263 int rc;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001264
1265 /* Simulate the GSUP peer */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001266 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1267 OSMO_ASSERT(rc >= 0);
1268 OSMO_ASSERT(to_peer.imsi[0] != 0);
1269 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001270
1271 /* This invalidates the pointers in to_peer */
1272 msgb_free(msg);
1273
1274 switch (to_peer.message_type) {
1275 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1276 /* Send UPDATE_LOCATION_RESULT */
1277 return my_subscr_request_update_gsup_auth(NULL);
1278
1279 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1280 /* Send SEND_AUTH_INFO_RESULT */
1281 return my_subscr_request_auth_info_gsup_auth(NULL);
1282
1283 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001284 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1285 break;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001286
1287 default:
1288 if ((to_peer.message_type & 0b00000011) == 0) {
1289 /* Unhandled request */
Jacob Erlbeckb3982c12015-01-06 16:32:41 +01001290 /* Send error(NOT_IMPL) */
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001291 from_peer.message_type = to_peer.message_type + 1;
1292 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1293 break;
1294 }
1295
1296 /* Ignore it */
1297 return 0;
1298 }
1299
1300 reply_msg = gprs_gsup_msgb_alloc();
1301 reply_msg->l2h = reply_msg->data;
1302 gprs_gsup_encode(reply_msg, &from_peer);
1303 gprs_subscr_rx_gsup_message(reply_msg);
1304 msgb_free(reply_msg);
1305
1306 return 0;
1307};
1308
1309static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1310{
1311 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1312 struct gsm_subscriber *subscr;
1313
1314 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001315 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1316
1317 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1318
1319 if (retry) {
1320 upd_loc_skip = 3;
1321 auth_info_skip = 3;
1322 }
1323
1324 printf("Auth policy 'remote', real GSUP based auth: ");
1325 test_gmm_attach(retry);
1326
1327 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freytherd95cb732015-01-20 21:14:03 +01001328 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck8768f2b2015-01-13 11:46:32 +01001329 assert_no_subscrs();
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001330
1331 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001332 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1333 upd_loc_skip = 0;
1334 auth_info_skip = 0;
1335 talloc_free(sgsn->gsup_client);
1336 sgsn->gsup_client = NULL;
1337}
1338
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001339/*
1340 * Test the GMM Rejects
1341 */
1342static void test_gmm_reject(void)
1343{
1344 struct gprs_ra_id raid = { 0, };
1345 struct sgsn_mm_ctx *ctx = NULL;
1346 uint32_t foreign_tlli;
1347 struct gprs_llc_lle *lle;
1348 int idx;
1349
1350 /* DTAP - Attach Request */
1351 /* Invalid MI length */
1352 static const unsigned char attach_req_inv_mi_len[] = {
1353 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1354 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1355 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1356 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1357 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1358 };
1359
1360 /* DTAP - Attach Request */
1361 /* Invalid MI type (IMEI) */
1362 static const unsigned char attach_req_inv_mi_type[] = {
1363 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1364 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1365 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1366 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1367 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1368 };
1369
1370 /* DTAP - Routing Area Update Request */
1371 static const unsigned char dtap_ra_upd_req[] = {
1372 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1373 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1374 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1375 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1376 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1377 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1378 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1379 };
1380
1381 /* DTAP - Routing Area Update Request */
1382 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1383 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1384 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1385 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1386 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1387 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1388 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1389 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1390 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1391 };
1392
1393 /* DTAP - Routing Area Update Request */
1394 /* Invalid cap length */
1395 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1396 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1397 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1398 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1399 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1400 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1401 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1402 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1403 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1404 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1405 };
1406
1407 struct test {
1408 const char *title;
1409 const unsigned char *msg;
1410 unsigned msg_len;
1411 unsigned num_resp;
1412
1413 };
1414 static struct test tests[] = {
1415 {
1416 .title = "Attach Request (invalid MI length)",
1417 .msg = attach_req_inv_mi_len,
1418 .msg_len = sizeof(attach_req_inv_mi_len),
1419 .num_resp = 1 /* Reject */
1420
1421 },
1422 {
1423 .title = "Attach Request (invalid MI type)",
1424 .msg = attach_req_inv_mi_type,
1425 .msg_len = sizeof(attach_req_inv_mi_type),
1426 .num_resp = 1 /* Reject */
1427 },
1428 {
1429 .title = "Routing Area Update Request (valid)",
1430 .msg = dtap_ra_upd_req,
1431 .msg_len = sizeof(dtap_ra_upd_req),
1432 .num_resp = 2 /* XID Reset + Reject */
1433 },
1434 {
1435 .title = "Routing Area Update Request (invalid type)",
1436 .msg = dtap_ra_upd_req_inv_type,
1437 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1438 .num_resp = 1 /* Reject */
1439 },
1440 {
1441 .title = "Routing Area Update Request (invalid CAP length)",
1442 .msg = dtap_ra_upd_req_inv_cap_len,
1443 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1444 .num_resp = 1 /* Reject */
1445 },
1446 };
1447
1448 printf("Testing GMM reject\n");
1449
1450 /* reset the PRNG used by sgsn_alloc_ptmsi */
1451 srand(1);
1452
1453 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1454
1455 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1456
1457 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1458 const struct test *test = &tests[idx];
1459 printf(" - %s\n", test->title);
1460
1461 /* Create a LLE/LLME */
1462 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1463 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1464
1465 /* Inject the Request message */
1466 send_0408_message(lle->llme, foreign_tlli,
1467 test->msg, test->msg_len);
1468
1469 /* We expect a Reject message */
1470 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1471 sgsn_tx_counter, test->num_resp);
1472 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1473
1474 /* verify that LLME/MM are removed */
1475 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1476 OSMO_ASSERT(ctx == NULL);
1477 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1478 }
1479}
1480
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001481/*
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001482 * Test cancellation of attached MM contexts
1483 */
1484static void test_gmm_cancel(void)
1485{
1486 struct gprs_ra_id raid = { 0, };
1487 struct sgsn_mm_ctx *ctx = NULL;
1488 struct sgsn_mm_ctx *ictx;
1489 uint32_t ptmsi1;
1490 uint32_t foreign_tlli;
1491 uint32_t local_tlli = 0;
1492 struct gprs_llc_lle *lle;
1493 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1494
1495 /* DTAP - Attach Request */
1496 /* The P-TMSI is not known by the SGSN */
1497 static const unsigned char attach_req[] = {
1498 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1499 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1500 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1501 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1502 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1503 };
1504
1505 /* DTAP - Identity Response IMEI */
1506 static const unsigned char ident_resp_imei[] = {
1507 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1508 0x56
1509 };
1510
1511 /* DTAP - Identity Response IMSI */
1512 static const unsigned char ident_resp_imsi[] = {
1513 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1514 0x54
1515 };
1516
1517 /* DTAP - Attach Complete */
1518 static const unsigned char attach_compl[] = {
1519 0x08, 0x03
1520 };
1521
1522 printf("Testing cancellation\n");
1523
1524 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1525
1526 /* reset the PRNG used by sgsn_alloc_ptmsi */
1527 srand(1);
1528
1529 ptmsi1 = sgsn_alloc_ptmsi();
1530 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1531
1532 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1533 * again */
1534 srand(1);
1535
1536 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1537
1538 /* Create a LLE/LLME */
1539 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1540 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1541 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1542
1543 /* inject the attach request */
1544 send_0408_message(lle->llme, foreign_tlli,
1545 attach_req, ARRAY_SIZE(attach_req));
1546
1547 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1548 OSMO_ASSERT(ctx != NULL);
1549 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1550
1551 /* we expect an identity request (IMEI) */
1552 OSMO_ASSERT(sgsn_tx_counter == 1);
1553
1554 /* inject the identity response (IMEI) */
1555 send_0408_message(ctx->llme, foreign_tlli,
1556 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1557
1558 /* we expect an identity request (IMSI) */
1559 OSMO_ASSERT(sgsn_tx_counter == 1);
1560
1561 /* inject the identity response (IMSI) */
1562 send_0408_message(ctx->llme, foreign_tlli,
1563 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1564
1565 /* check that the MM context has not been removed due to a failed
1566 * authorization */
1567 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1568
1569 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1570
1571 /* we expect an attach accept/reject */
1572 OSMO_ASSERT(sgsn_tx_counter == 1);
1573
1574 /* this has been randomly assigned by the SGSN */
1575 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1576
1577 /* inject the attach complete */
1578 send_0408_message(ctx->llme, local_tlli,
1579 attach_compl, ARRAY_SIZE(attach_compl));
1580
1581 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1582
1583 /* we don't expect a response */
1584 OSMO_ASSERT(sgsn_tx_counter == 0);
1585
1586 /* cancel */
Jacob Erlbeck41010082015-01-05 17:51:17 +01001587 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001588
1589 /* verify that things are gone */
1590 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1591 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1592 OSMO_ASSERT(!ictx);
1593
1594 sgsn->cfg.auth_policy = saved_auth_policy;
1595}
1596
1597/*
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001598 * Test the dynamic allocation of P-TMSIs
1599 */
1600static void test_gmm_ptmsi_allocation(void)
1601{
1602 struct gprs_ra_id raid = { 0, };
1603 struct sgsn_mm_ctx *ctx = NULL;
1604 struct sgsn_mm_ctx *ictx;
1605 uint32_t foreign_tlli;
1606 uint32_t ptmsi1;
1607 uint32_t ptmsi2;
1608 uint32_t old_ptmsi;
1609 uint32_t local_tlli = 0;
1610 struct gprs_llc_lle *lle;
1611 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1612
1613 /* DTAP - Attach Request (IMSI 12131415161718) */
1614 static const unsigned char attach_req[] = {
1615 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1616 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1617 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1618 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1619 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1620 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1621 0x00,
1622 };
1623
1624 /* DTAP - Identity Response IMEI */
1625 static const unsigned char ident_resp_imei[] = {
1626 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1627 0x56
1628 };
1629
1630 /* DTAP - Attach Complete */
1631 static const unsigned char attach_compl[] = {
1632 0x08, 0x03
1633 };
1634
1635 /* DTAP - Routing Area Update Request */
1636 static const unsigned char ra_upd_req[] = {
1637 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1638 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1639 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1640 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1641 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1642 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1643 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1644 };
1645
1646 /* DTAP - Routing Area Update Complete */
1647 static const unsigned char ra_upd_complete[] = {
1648 0x08, 0x0a
1649 };
1650
1651 /* DTAP - Detach Request (MO) */
1652 /* normal detach, power_off = 1 */
1653 static const unsigned char detach_req[] = {
1654 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1655 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1656 };
1657
1658 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1659
1660 printf("Testing P-TMSI allocation\n");
1661
1662 printf(" - sgsn_alloc_ptmsi\n");
1663
1664 /* reset the PRNG used by sgsn_alloc_ptmsi */
1665 srand(1);
1666
1667 ptmsi1 = sgsn_alloc_ptmsi();
1668 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1669
1670 ptmsi2 = sgsn_alloc_ptmsi();
1671 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1672
1673 OSMO_ASSERT(ptmsi1 != ptmsi2);
1674
1675 printf(" - Repeated Attach Request\n");
1676
1677 /* reset the PRNG, so that the same P-TMSI will be generated
1678 * again */
1679 srand(1);
1680
1681 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1682
1683 /* Create a LLE/LLME */
1684 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1685 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1686 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1687
1688 /* inject the attach request */
1689 send_0408_message(lle->llme, foreign_tlli,
1690 attach_req, ARRAY_SIZE(attach_req));
1691
1692 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1693 OSMO_ASSERT(ctx != NULL);
1694 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1695 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1696
1697 old_ptmsi = ctx->p_tmsi_old;
1698
1699 /* we expect an identity request (IMEI) */
1700 OSMO_ASSERT(sgsn_tx_counter == 1);
1701
1702 /* inject the identity response (IMEI) */
1703 send_0408_message(ctx->llme, foreign_tlli,
1704 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1705
1706 /* check that the MM context has not been removed due to a failed
1707 * authorization */
1708 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1709
1710 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1711 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1712
1713 /* we expect an attach accept */
1714 OSMO_ASSERT(sgsn_tx_counter == 1);
1715
1716 /* we ignore this and send the attach again */
1717 send_0408_message(lle->llme, foreign_tlli,
1718 attach_req, ARRAY_SIZE(attach_req));
1719
1720 /* the allocated P-TMSI should be the same */
1721 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1722 OSMO_ASSERT(ctx != NULL);
1723 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1724 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1725 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1726
1727 /* inject the attach complete */
1728 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1729 send_0408_message(ctx->llme, local_tlli,
1730 attach_compl, ARRAY_SIZE(attach_compl));
1731
1732 /* we don't expect a response */
1733 OSMO_ASSERT(sgsn_tx_counter == 0);
1734
1735 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1736 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1737 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1738
1739 printf(" - Repeated RA Update Request\n");
1740
1741 /* inject the RA update request */
1742 send_0408_message(ctx->llme, local_tlli,
1743 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1744
1745 /* we expect an RA update accept */
1746 OSMO_ASSERT(sgsn_tx_counter == 1);
1747
1748 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1749 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1750 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1751
1752 /* repeat the RA update request */
1753 send_0408_message(ctx->llme, local_tlli,
1754 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1755
1756 /* we expect an RA update accept */
1757 OSMO_ASSERT(sgsn_tx_counter == 1);
1758
1759 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1760 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1761 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1762
1763 /* inject the RA update complete */
1764 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1765 send_0408_message(ctx->llme, local_tlli,
1766 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1767
1768 /* we don't expect a response */
1769 OSMO_ASSERT(sgsn_tx_counter == 0);
1770
1771 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1772 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1773 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1774
1775 /* inject the detach */
1776 send_0408_message(ctx->llme, local_tlli,
1777 detach_req, ARRAY_SIZE(detach_req));
1778
1779 /* verify that things are gone */
1780 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1781 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1782 OSMO_ASSERT(!ictx);
1783
1784 sgsn->cfg.auth_policy = saved_auth_policy;
1785}
1786
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01001787static void test_apn_matching(void)
1788{
1789 struct apn_ctx *actx, *actxs[9];
1790
1791 printf("Testing APN matching\n");
1792
1793 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
1794 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
1795 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
1796 actxs[3] = NULL;
1797
1798 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
1799 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
1800 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
1801 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
1802
1803 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
1804
1805 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1806 OSMO_ASSERT(actx == actxs[2]);
1807 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
1808 OSMO_ASSERT(actx == actxs[2]);
1809 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
1810 OSMO_ASSERT(actx == actxs[1]);
1811 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
1812 OSMO_ASSERT(actx == actxs[1]);
1813 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
1814 OSMO_ASSERT(actx == actxs[0]);
1815 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1816 OSMO_ASSERT(actx == NULL);
1817
1818 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
1819 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1820 OSMO_ASSERT(actx == actxs[3]);
1821
1822 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
1823 OSMO_ASSERT(actx == actxs[4]);
1824
1825 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
1826 OSMO_ASSERT(actx == actxs[6]);
1827
1828 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1829 OSMO_ASSERT(actx == actxs[5]);
1830
1831 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
1832 OSMO_ASSERT(actx == actxs[7]);
1833
1834 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
1835 OSMO_ASSERT(actx == actxs[8]);
1836
1837 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1838 OSMO_ASSERT(actx == actxs[7]);
1839
1840 /* Free APN contexts and check how the matching changes */
1841
1842 sgsn_apn_ctx_free(actxs[7]);
1843 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1844 OSMO_ASSERT(actx == actxs[8]);
1845
1846 sgsn_apn_ctx_free(actxs[8]);
1847 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1848 OSMO_ASSERT(actx == actxs[6]);
1849
1850 sgsn_apn_ctx_free(actxs[6]);
1851 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1852 OSMO_ASSERT(actx == actxs[1]);
1853
1854 sgsn_apn_ctx_free(actxs[5]);
1855 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1856 OSMO_ASSERT(actx == actxs[4]);
1857
1858 sgsn_apn_ctx_free(actxs[4]);
1859 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1860 OSMO_ASSERT(actx == actxs[2]);
1861
1862 sgsn_apn_ctx_free(actxs[2]);
1863 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1864 OSMO_ASSERT(actx == actxs[1]);
1865
1866 sgsn_apn_ctx_free(actxs[1]);
1867 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1868 OSMO_ASSERT(actx == actxs[0]);
1869
1870 sgsn_apn_ctx_free(actxs[0]);
1871 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1872 OSMO_ASSERT(actx == actxs[3]);
1873
1874 sgsn_apn_ctx_free(actxs[3]);
1875 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1876 OSMO_ASSERT(actx == NULL);
1877}
1878
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001879static struct log_info_cat gprs_categories[] = {
1880 [DMM] = {
1881 .name = "DMM",
1882 .description = "Layer3 Mobility Management (MM)",
1883 .color = "\033[1;33m",
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001884 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001885 },
1886 [DPAG] = {
1887 .name = "DPAG",
1888 .description = "Paging Subsystem",
1889 .color = "\033[1;38m",
1890 .enabled = 1, .loglevel = LOGL_NOTICE,
1891 },
1892 [DMEAS] = {
1893 .name = "DMEAS",
1894 .description = "Radio Measurement Processing",
1895 .enabled = 0, .loglevel = LOGL_NOTICE,
1896 },
1897 [DREF] = {
1898 .name = "DREF",
1899 .description = "Reference Counting",
1900 .enabled = 0, .loglevel = LOGL_NOTICE,
1901 },
1902 [DGPRS] = {
1903 .name = "DGPRS",
1904 .description = "GPRS Packet Service",
1905 .enabled = 1, .loglevel = LOGL_DEBUG,
1906 },
1907 [DNS] = {
1908 .name = "DNS",
1909 .description = "GPRS Network Service (NS)",
1910 .enabled = 1, .loglevel = LOGL_INFO,
1911 },
1912 [DBSSGP] = {
1913 .name = "DBSSGP",
1914 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1915 .enabled = 1, .loglevel = LOGL_DEBUG,
1916 },
1917 [DLLC] = {
1918 .name = "DLLC",
1919 .description = "GPRS Logical Link Control Protocol (LLC)",
1920 .enabled = 1, .loglevel = LOGL_DEBUG,
1921 },
1922 [DSNDCP] = {
1923 .name = "DSNDCP",
1924 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1925 .enabled = 1, .loglevel = LOGL_DEBUG,
1926 },
1927};
1928
1929static struct log_info info = {
1930 .cat = gprs_categories,
1931 .num_cat = ARRAY_SIZE(gprs_categories),
1932};
1933
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001934int main(int argc, char **argv)
1935{
Jacob Erlbeck265e7352015-01-30 11:57:25 +01001936 void *osmo_sgsn_ctx;
1937
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001938 osmo_init_logging(&info);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01001939 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1940 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
1941 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001942
Jacob Erlbeckb2acd742014-11-13 10:48:39 +01001943 sgsn_auth_init();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001944 gprs_subscr_init(sgsn);
Jacob Erlbeck7c24b3e2014-10-29 12:11:58 +01001945
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001946 test_llme();
Jacob Erlbecke8b69682014-11-12 10:12:11 +01001947 test_subscriber();
Jacob Erlbeckb1332b62014-12-08 15:52:00 +01001948 test_auth_triplets();
Jacob Erlbeck5641cfc2014-12-12 15:01:37 +01001949 test_subscriber_gsup();
Jacob Erlbeckfdf8ce52015-01-08 16:23:25 +01001950 test_subscriber_blocking();
Holger Hans Peter Freyther94246842014-10-02 22:24:47 +02001951 test_gmm_detach();
Jacob Erlbeck0b2da872014-10-27 14:34:13 +01001952 test_gmm_detach_power_off();
Jacob Erlbeck42d284f2014-10-21 13:09:55 +02001953 test_gmm_detach_no_mmctx();
Jacob Erlbeck021a0d12014-11-24 15:04:15 +01001954 test_gmm_detach_accept_unexpected();
Jacob Erlbeckb35ee6b2014-10-28 09:47:03 +01001955 test_gmm_status_no_mmctx();
Jacob Erlbeckd04f7cc2014-11-12 10:18:09 +01001956 test_gmm_attach_acl();
1957 test_gmm_attach_subscr();
Jacob Erlbeckd8126992014-12-08 15:26:47 +01001958 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck828059f2014-11-28 14:55:25 +01001959 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck803ebfa2014-12-19 18:30:41 +01001960 test_gmm_attach_subscr_gsup_auth(0);
1961 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeck0d2cf602015-01-09 15:07:16 +01001962 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck6f4bbd42014-11-06 13:43:41 +01001963 test_gmm_reject();
Jacob Erlbeckbf0b8742014-11-11 14:47:38 +01001964 test_gmm_cancel();
Jacob Erlbecke06476a2014-11-06 15:43:10 +01001965 test_gmm_ptmsi_allocation();
Jacob Erlbeck9b3ca642015-02-03 13:47:53 +01001966 test_apn_matching();
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001967 printf("Done\n");
Jacob Erlbeck80dbcf12015-01-13 11:46:32 +01001968
Jacob Erlbeck265e7352015-01-30 11:57:25 +01001969 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeck6e6b3302015-01-13 11:56:28 +01001970 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck265e7352015-01-30 11:57:25 +01001971 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther232f6212014-09-30 09:10:25 +02001972 return 0;
1973}
Holger Hans Peter Freyther49dbcd92014-10-02 21:27:24 +02001974
1975
1976/* stubs */
1977struct osmo_prim_hdr;
1978int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
1979{
1980 abort();
1981}