blob: 6fc4f9906309ce6f873f4fa2606e33e2301bbd05 [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>
Jacob Erlbeck277b71e2015-02-02 18:03:05 +010029#include <openbsc/gprs_utils.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020030
Jacob Erlbeck189999d2014-10-27 14:34:13 +010031#include <osmocom/gprs/gprs_bssgp.h>
32
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020033#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeckbce20612015-01-05 18:57:32 +010034#include <openbsc/gsm_04_08_gprs.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020035
36#include <osmocom/core/application.h>
37#include <osmocom/core/msgb.h>
Jacob Erlbeck189999d2014-10-27 14:34:13 +010038#include <osmocom/core/rate_ctr.h>
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020039
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +020040#include <stdio.h>
41
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020042extern void *tall_msgb_ctx;
43
44void *tall_bsc_ctx;
45static struct sgsn_instance sgsn_inst = {
46 .config_file = "osmo_sgsn.cfg",
47 .cfg = {
48 .gtp_statedir = "./",
Jacob Erlbeck106f5472014-11-04 10:08:37 +010049 .auth_policy = SGSN_AUTH_POLICY_CLOSED,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020050 },
51};
52struct sgsn_instance *sgsn = &sgsn_inst;
Jacob Erlbeck189999d2014-10-27 14:34:13 +010053unsigned sgsn_tx_counter = 0;
54
55/* override */
56int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
57 struct bssgp_dl_ud_par *dup)
58{
59 sgsn_tx_counter += 1;
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +010060 msgb_free(msg);
Jacob Erlbeck189999d2014-10-27 14:34:13 +010061 return 0;
62}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +020063
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010064/* override, requires '-Wl,--wrap=sgsn_update_subscriber_data' */
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010065void __real_sgsn_update_subscriber_data(struct sgsn_mm_ctx *);
66void (*update_subscriber_data_cb)(struct sgsn_mm_ctx *) =
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010067 &__real_sgsn_update_subscriber_data;
68
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010069void __wrap_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010070{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +010071 (*update_subscriber_data_cb)(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010072}
73
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010074/* override, requires '-Wl,--wrap=gprs_subscr_request_update_location' */
75int __real_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx);
76int (*subscr_request_update_location_cb)(struct sgsn_mm_ctx *mmctx) =
77 &__real_gprs_subscr_request_update_location;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010078
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +010079int __wrap_gprs_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
80 return (*subscr_request_update_location_cb)(mmctx);
81};
82
83/* override, requires '-Wl,--wrap=gprs_subscr_request_auth_info' */
84int __real_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx);
85int (*subscr_request_auth_info_cb)(struct sgsn_mm_ctx *mmctx) =
86 &__real_gprs_subscr_request_auth_info;
87
88int __wrap_gprs_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
89 return (*subscr_request_auth_info_cb)(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +010090};
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +010091
Jacob Erlbeckc157ee72015-01-09 15:07:16 +010092/* override, requires '-Wl,--wrap=gprs_gsup_client_send' */
93int __real_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
94int (*gprs_gsup_client_send_cb)(struct gprs_gsup_client *gsupc, struct msgb *msg) =
95 &__real_gprs_gsup_client_send;
96
97int __wrap_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
98{
99 return (*gprs_gsup_client_send_cb)(gsupc, msg);
100};
101
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200102static int count(struct llist_head *head)
103{
104 struct llist_head *cur;
105 int count = 0;
106
107 llist_for_each(cur, head)
108 count += 1;
109
110 return count;
111}
112
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200113static struct msgb *create_msg(const uint8_t *data, size_t len)
114{
115 struct msgb *msg = msgb_alloc(len + 8, "test message");
116 msg->l1h = msgb_put(msg, 8);
117 msg->l2h = msgb_put(msg, len);
118 memcpy(msg->l2h, data, len);
119
120 msgb_bcid(msg) = msg->l1h;
121 msgb_gmmh(msg) = msg->l2h;
122 return msg;
123}
124
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100125/*
126 * Create a context and search for it
127 */
128static struct sgsn_mm_ctx *alloc_mm_ctx(uint32_t tlli, struct gprs_ra_id *raid)
129{
130 struct sgsn_mm_ctx *ctx, *ictx;
131 struct gprs_llc_lle *lle;
132 int old_count = count(gprs_llme_list());
133
134 lle = gprs_lle_get_or_create(tlli, 3);
135 ctx = sgsn_mm_ctx_alloc(tlli, raid);
136 ctx->mm_state = GMM_REGISTERED_NORMAL;
137 ctx->llme = lle->llme;
138
139 ictx = sgsn_mm_ctx_by_tlli(tlli, raid);
140 OSMO_ASSERT(ictx == ctx);
141
142 OSMO_ASSERT(count(gprs_llme_list()) == old_count + 1);
143
144 return ctx;
145}
146
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100147static void send_0408_message(struct gprs_llc_llme *llme, uint32_t tlli,
148 const uint8_t *data, size_t data_len)
149{
150 struct msgb *msg;
151
152 sgsn_tx_counter = 0;
153
154 msg = create_msg(data, data_len);
155 msgb_tlli(msg) = tlli;
156 gsm0408_gprs_rcvmsg(msg, llme);
157 msgb_free(msg);
158}
159
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200160static void test_llme(void)
161{
162 struct gprs_llc_lle *lle, *lle_copy;
163 uint32_t local_tlli;
164 uint32_t foreign_tlli;
165
166 printf("Testing LLME allocations\n");
167 local_tlli = gprs_tmsi2tlli(0x234, TLLI_LOCAL);
168 foreign_tlli = gprs_tmsi2tlli(0x234, TLLI_FOREIGN);
169
170 /* initial state */
171 OSMO_ASSERT(count(gprs_llme_list()) == 0);
172
173 /* Create a new entry */
174 lle = gprs_lle_get_or_create(local_tlli, 3);
175 OSMO_ASSERT(lle);
176 OSMO_ASSERT(count(gprs_llme_list()) == 1);
177
178 /* No new entry is created */
179 lle_copy = gprs_lle_get_or_create(local_tlli, 3);
180 OSMO_ASSERT(lle == lle_copy);
181 OSMO_ASSERT(count(gprs_llme_list()) == 1);
182 lle_copy = gprs_lle_get_or_create(foreign_tlli, 3);
183 OSMO_ASSERT(lle == lle_copy);
184 OSMO_ASSERT(count(gprs_llme_list()) == 1);
185
186 /* unassign which should delete it*/
187 gprs_llgmm_assign(lle->llme, lle->llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
188
189 /* Check that everything was cleaned up */
190 OSMO_ASSERT(count(gprs_llme_list()) == 0);
191}
192
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100193struct gsm_subscriber *last_updated_subscr = NULL;
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100194void my_dummy_sgsn_update_subscriber_data(struct sgsn_mm_ctx *mmctx)
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100195{
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100196 OSMO_ASSERT(mmctx);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100197 fprintf(stderr, "Called %s, mmctx = %p, subscr = %p\n",
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100198 __func__, mmctx, mmctx->subscr);
199 last_updated_subscr = mmctx->subscr;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100200}
201
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100202static void assert_subscr(const struct gsm_subscriber *subscr, const char *imsi)
203{
204 struct gsm_subscriber *sfound;
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100205 OSMO_ASSERT(subscr);
206 OSMO_ASSERT(strcmp(subscr->imsi, imsi) == 0);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100207
208 sfound = gprs_subscr_get_by_imsi(imsi);
209 OSMO_ASSERT(sfound == subscr);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100210
Jacob Erlbeck6be9ffa2015-01-19 08:57:07 +0100211 subscr_put(sfound);
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100212}
213
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100214static void show_subscrs(FILE *out)
215{
216 struct gsm_subscriber *subscr;
217
218 llist_for_each_entry(subscr, &active_subscribers, entry) {
219 fprintf(out, " Subscriber: %s, "
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100220 "use count: %d\n",
221 subscr->imsi, subscr->use_count);
Jacob Erlbeck058bc262015-01-13 11:46:32 +0100222 }
223}
224
225static void assert_no_subscrs()
226{
227 show_subscrs(stdout);
228 fflush(stdout);
229 OSMO_ASSERT(llist_empty(&active_subscribers));
230}
231
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100232static void test_subscriber(void)
233{
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100234 struct gsm_subscriber *s1, *s2, *s3, *sfound;
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100235 const char *imsi1 = "1234567890";
236 const char *imsi2 = "9876543210";
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100237 const char *imsi3 = "5656565656";
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100238
239 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
240
241 printf("Testing core subscriber data API\n");
242
243 /* Check for emptiness */
244 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
245 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100246 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100247
248 /* Allocate entry 1 */
249 s1 = gprs_subscr_get_or_create(imsi1);
250 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100251 assert_subscr(s1, imsi1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100252 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100253
254 /* Allocate entry 2 */
255 s2 = gprs_subscr_get_or_create(imsi2);
256 s2->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100257
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100258 /* Allocate entry 3 */
259 s3 = gprs_subscr_get_or_create(imsi3);
260
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100261 /* Check entries */
262 assert_subscr(s1, imsi1);
263 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100264 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100265
266 /* Update entry 1 */
267 last_updated_subscr = NULL;
268 gprs_subscr_update(s1);
Jacob Erlbeck555b2e52015-01-26 13:52:42 +0100269 OSMO_ASSERT(last_updated_subscr == NULL);
270 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
271 OSMO_ASSERT((s1->flags & GSM_SUBSCRIBER_FIRST_CONTACT) == 0);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100272
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100273 /* There is no subscriber cache. Verify it */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100274 gprs_subscr_cleanup(s1);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100275 subscr_put(s1);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100276 s1 = NULL;
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100277 sfound = gprs_subscr_get_by_imsi(imsi1);
278 OSMO_ASSERT(sfound == NULL);
279
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100280 assert_subscr(s2, imsi2);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100281 assert_subscr(s3, imsi3);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100282
Jacob Erlbeckb8fb1402015-01-09 11:59:50 +0100283 /* Free entry 2 (GSM_SUBSCRIBER_FIRST_CONTACT is set) */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100284 gprs_subscr_cleanup(s2);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100285 subscr_put(s2);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100286 s2 = NULL;
287 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
288 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi2) == NULL);
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100289 assert_subscr(s3, imsi3);
290
291 /* Try to delete entry 3 */
Jacob Erlbeck3e4e58f2015-01-26 11:07:24 +0100292 gprs_subscr_cleanup(s3);
Jacob Erlbeck37139e52015-01-23 13:52:55 +0100293 subscr_put(s3);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +0100294 s3 = NULL;
Jacob Erlbeck0f47b8f2015-01-06 16:32:41 +0100295 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi3) == NULL);
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +0100296
297 OSMO_ASSERT(llist_empty(&active_subscribers));
298
299 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
300}
301
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100302static void test_auth_triplets(void)
303{
304 struct gsm_subscriber *s1, *s1found;
305 const char *imsi1 = "1234567890";
306 struct gsm_auth_tuple *at;
307 struct sgsn_mm_ctx *ctx;
308 struct gprs_ra_id raid = { 0, };
309 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100310
311 printf("Testing authentication triplet handling\n");
312
313 /* Check for emptiness */
314 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
315
316 /* Allocate entry 1 */
317 s1 = gprs_subscr_get_or_create(imsi1);
318 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
319 s1found = gprs_subscr_get_by_imsi(imsi1);
320 OSMO_ASSERT(s1found == s1);
321 subscr_put(s1found);
322
323 /* Create a context */
324 OSMO_ASSERT(count(gprs_llme_list()) == 0);
325 ctx = alloc_mm_ctx(local_tlli, &raid);
326
327 /* Attach s1 to ctx */
328 ctx->subscr = subscr_get(s1);
329 ctx->subscr->sgsn_data->mm = ctx;
330
331 /* Try to get auth tuple */
332 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
333 OSMO_ASSERT(at == NULL);
334
335 /* Add triplets */
336 s1->sgsn_data->auth_triplets[0].key_seq = 0;
337 s1->sgsn_data->auth_triplets[1].key_seq = 1;
338 s1->sgsn_data->auth_triplets[2].key_seq = 2;
339
340 /* Try to get auth tuple */
341 at = sgsn_auth_get_tuple(ctx, GSM_KEY_SEQ_INVAL);
342 OSMO_ASSERT(at != NULL);
343 OSMO_ASSERT(at->key_seq == 0);
344 OSMO_ASSERT(at->use_count == 1);
345 at = sgsn_auth_get_tuple(ctx, at->key_seq);
346 OSMO_ASSERT(at != NULL);
347 OSMO_ASSERT(at->key_seq == 1);
348 OSMO_ASSERT(at->use_count == 1);
349 at = sgsn_auth_get_tuple(ctx, at->key_seq);
350 OSMO_ASSERT(at != NULL);
351 OSMO_ASSERT(at->key_seq == 2);
352 OSMO_ASSERT(at->use_count == 1);
353 at = sgsn_auth_get_tuple(ctx, at->key_seq);
354 OSMO_ASSERT(at == NULL);
355
356 /* Free MM context and subscriber */
357 subscr_put(s1);
Jacob Erlbecke671d252015-01-26 14:43:07 +0100358 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100359 s1found = gprs_subscr_get_by_imsi(imsi1);
360 OSMO_ASSERT(s1found == NULL);
Jacob Erlbeck7921ab12014-12-08 15:52:00 +0100361}
362
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100363#define TEST_GSUP_IMSI1_IE 0x01, 0x05, 0x21, 0x43, 0x65, 0x87, 0x09
364
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100365static int rx_gsup_message(const uint8_t *data, size_t data_len)
366{
367 struct msgb *msg;
368 int rc;
369
370 msg = msgb_alloc(1024, __func__);
371 msg->l2h = msgb_put(msg, data_len);
372 OSMO_ASSERT(msg->l2h != NULL);
373 memcpy(msg->l2h, data, data_len);
374 rc = gprs_subscr_rx_gsup_message(msg);
375 msgb_free(msg);
376
377 return rc;
378}
379
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100380static void test_subscriber_gsup(void)
381{
382 struct gsm_subscriber *s1, *s1found;
383 const char *imsi1 = "1234567890";
384 struct sgsn_mm_ctx *ctx;
385 struct gprs_ra_id raid = { 0, };
386 uint32_t local_tlli = 0xffeeddcc;
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100387 struct sgsn_subscriber_pdp_data *pdpd;
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100388 int rc;
389
390 static const uint8_t send_auth_info_res[] = {
391 0x0a,
392 TEST_GSUP_IMSI1_IE,
393 0x03, 0x22, /* Auth tuple */
394 0x20, 0x10,
395 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
396 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
397 0x21, 0x04,
398 0x21, 0x22, 0x23, 0x24,
399 0x22, 0x08,
400 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
401 0x03, 0x22, /* Auth tuple */
402 0x20, 0x10,
403 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
404 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
405 0x21, 0x04,
406 0xa1, 0xa2, 0xa3, 0xa4,
407 0x22, 0x08,
408 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8,
409 };
410
411 static const uint8_t send_auth_info_err[] = {
412 0x09,
413 TEST_GSUP_IMSI1_IE,
414 0x02, 0x01, 0x07 /* GPRS not allowed */
415 };
416
417 static const uint8_t update_location_res[] = {
418 0x06,
419 TEST_GSUP_IMSI1_IE,
420 0x04, 0x00, /* PDP info complete */
421 0x05, 0x12,
422 0x10, 0x01, 0x01,
423 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
424 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
425 0x05, 0x11,
426 0x10, 0x01, 0x02,
427 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
428 0x12, 0x08, 0x03, 'f', 'o', 'o', 0x03, 'a', 'p', 'n',
429 };
430
431 static const uint8_t update_location_err[] = {
432 0x05,
433 TEST_GSUP_IMSI1_IE,
434 0x02, 0x01, 0x07 /* GPRS not allowed */
435 };
436
437 static const uint8_t location_cancellation_req[] = {
438 0x1c,
439 TEST_GSUP_IMSI1_IE,
440 0x06, 0x01, 0x00,
441 };
442
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100443 static const uint8_t location_cancellation_req_other[] = {
444 0x1c,
445 0x01, 0x05, 0x11, 0x11, 0x11, 0x11, 0x01,
446 0x06, 0x01, 0x00,
447 };
448
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100449 static const uint8_t purge_ms_err[] = {
450 0x0d,
451 TEST_GSUP_IMSI1_IE,
452 0x02, 0x01, 0x02, /* IMSI unknown in HLR */
453 };
454
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100455 static const uint8_t purge_ms_err_no_cause[] = {
456 0x0d,
457 TEST_GSUP_IMSI1_IE,
458 };
459
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100460 static const uint8_t purge_ms_res[] = {
461 0x0e,
462 TEST_GSUP_IMSI1_IE,
463 0x07, 0x00,
464 };
465
466
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100467 static const uint8_t insert_data_req[] = {
468 0x10,
469 TEST_GSUP_IMSI1_IE,
470 0x05, 0x11,
471 0x10, 0x01, 0x03,
472 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
473 0x12, 0x08, 0x03, 'b', 'a', 'r', 0x03, 'a', 'p', 'n',
474 };
475
476 static const uint8_t delete_data_req[] = {
477 0x14,
478 TEST_GSUP_IMSI1_IE,
479 0x10, 0x01, 0x03,
480 };
481
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100482 printf("Testing subcriber GSUP handling\n");
483
484 update_subscriber_data_cb = my_dummy_sgsn_update_subscriber_data;
485
486 /* Check for emptiness */
487 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
488
489 /* Allocate entry 1 */
490 s1 = gprs_subscr_get_or_create(imsi1);
491 s1->flags |= GSM_SUBSCRIBER_FIRST_CONTACT;
492 s1found = gprs_subscr_get_by_imsi(imsi1);
493 OSMO_ASSERT(s1found == s1);
494 subscr_put(s1found);
495
496 /* Create a context */
497 OSMO_ASSERT(count(gprs_llme_list()) == 0);
498 ctx = alloc_mm_ctx(local_tlli, &raid);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100499
500 /* Attach s1 to ctx */
501 ctx->subscr = subscr_get(s1);
502 ctx->subscr->sgsn_data->mm = ctx;
503
504 /* Inject SendAuthInfoReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100505 rc = rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100506 OSMO_ASSERT(rc >= 0);
507 OSMO_ASSERT(last_updated_subscr == s1);
508
509 /* Check triplets */
510 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == 0);
511 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == 1);
512 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
513
514 /* Inject SendAuthInfoErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100515 rc = rx_gsup_message(send_auth_info_err, sizeof(send_auth_info_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100516 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100517 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100518 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100519
520 /* Check triplets */
521 OSMO_ASSERT(s1->sgsn_data->auth_triplets[0].key_seq == GSM_KEY_SEQ_INVAL);
522 OSMO_ASSERT(s1->sgsn_data->auth_triplets[1].key_seq == GSM_KEY_SEQ_INVAL);
523 OSMO_ASSERT(s1->sgsn_data->auth_triplets[2].key_seq == GSM_KEY_SEQ_INVAL);
524
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100525 /* Inject UpdateLocRes GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100526 rc = rx_gsup_message(update_location_res, sizeof(update_location_res));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100527 OSMO_ASSERT(rc >= 0);
528 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100529 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100530 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbeck0e8add62014-12-17 14:03:35 +0100531 OSMO_ASSERT(!llist_empty(&s1->sgsn_data->pdp_list));
532 pdpd = llist_entry(s1->sgsn_data->pdp_list.next,
533 struct sgsn_subscriber_pdp_data, list);
534 OSMO_ASSERT(strcmp(pdpd->apn_str, "test.apn") == 0);
535 pdpd = llist_entry(pdpd->list.next,
536 struct sgsn_subscriber_pdp_data, list);
537 OSMO_ASSERT(strcmp(pdpd->apn_str, "foo.apn") == 0);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100538
539 /* Check authorization */
540 OSMO_ASSERT(s1->authorized == 1);
541
542 /* Inject UpdateLocErr GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100543 rc = rx_gsup_message(update_location_err, sizeof(update_location_err));
Jacob Erlbeckbce20612015-01-05 18:57:32 +0100544 OSMO_ASSERT(rc == -GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100545 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100546 OSMO_ASSERT(s1->sgsn_data->error_cause == GMM_CAUSE_GPRS_NOTALLOWED);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100547
548 /* Check authorization */
549 OSMO_ASSERT(s1->authorized == 0);
550
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100551 /* Inject InsertSubscrData GSUP message */
552 last_updated_subscr = NULL;
553 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
554 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
555 OSMO_ASSERT(last_updated_subscr == NULL);
556
557 /* Inject DeleteSubscrData GSUP message */
558 last_updated_subscr = NULL;
559 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
560 OSMO_ASSERT(rc == -GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL);
561 OSMO_ASSERT(last_updated_subscr == NULL);
562
Jacob Erlbeck87c7ffc2015-01-08 15:29:01 +0100563 /* Inject wrong LocCancelReq GSUP message */
564 last_updated_subscr = NULL;
565 rc = rx_gsup_message(location_cancellation_req_other,
566 sizeof(location_cancellation_req_other));
567 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
568 OSMO_ASSERT(last_updated_subscr == NULL);
569
570 /* Check cancellation result */
571 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_CANCELLED));
572 OSMO_ASSERT(s1->sgsn_data->mm != NULL);
573
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100574 /* Inject LocCancelReq GSUP message */
Jacob Erlbecke21e1842014-12-19 18:19:50 +0100575 rc = rx_gsup_message(location_cancellation_req,
576 sizeof(location_cancellation_req));
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100577 OSMO_ASSERT(rc >= 0);
578 OSMO_ASSERT(last_updated_subscr == s1);
Jacob Erlbeckbaf0f942015-01-29 14:55:34 +0100579 OSMO_ASSERT(s1->sgsn_data->error_cause == SGSN_ERROR_CAUSE_NONE);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100580
581 /* Check cancellation result */
582 OSMO_ASSERT(s1->flags & GPRS_SUBSCRIBER_CANCELLED);
583 OSMO_ASSERT(s1->sgsn_data->mm == NULL);
584
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100585 /* Inject PurgeMsRes GSUP message */
586 rc = rx_gsup_message(purge_ms_res,
587 sizeof(purge_ms_res));
588 OSMO_ASSERT(rc >= 0);
589 OSMO_ASSERT(!(s1->flags & GPRS_SUBSCRIBER_ENABLE_PURGE));
590
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100591 /* Free MM context and subscriber */
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +0100592 OSMO_ASSERT(ctx->subscr == NULL);
593 sgsn_mm_ctx_cleanup_free(ctx);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100594 subscr_put(s1);
595 s1found = gprs_subscr_get_by_imsi(imsi1);
596 OSMO_ASSERT(s1found == NULL);
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100597
Jacob Erlbeck466cedd2015-01-29 14:12:29 +0100598 /* Inject PurgeMsRes GSUP message */
599 rc = rx_gsup_message(purge_ms_res,
600 sizeof(purge_ms_res));
601 OSMO_ASSERT(rc >= 0);
602
603 /* Inject PurgeMsErr(IMSI unknown in HLR) GSUP message */
604 rc = rx_gsup_message(purge_ms_err,
605 sizeof(purge_ms_err));
606 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
607
Jacob Erlbeck9ff82892015-01-29 14:17:51 +0100608 /* Inject PurgeMsErr() GSUP message */
609 rc = rx_gsup_message(purge_ms_err_no_cause,
610 sizeof(purge_ms_err_no_cause));
611 OSMO_ASSERT(rc == -GMM_CAUSE_NET_FAIL);
612
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100613 /* Inject InsertSubscrData GSUP message (unknown IMSI) */
614 last_updated_subscr = NULL;
615 rc = rx_gsup_message(insert_data_req, sizeof(insert_data_req));
Jacob Erlbeck4dedb272015-01-15 17:50:16 +0100616 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
Jacob Erlbeck9999fd92015-01-15 17:08:30 +0100617 OSMO_ASSERT(last_updated_subscr == NULL);
618
619 /* Inject DeleteSubscrData GSUP message (unknown IMSI) */
620 rc = rx_gsup_message(delete_data_req, sizeof(delete_data_req));
621 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
622 OSMO_ASSERT(last_updated_subscr == NULL);
623
624 /* Inject LocCancelReq GSUP message (unknown IMSI) */
625 rc = rx_gsup_message(location_cancellation_req,
626 sizeof(location_cancellation_req));
627 OSMO_ASSERT(rc == -GMM_CAUSE_IMSI_UNKNOWN);
628 OSMO_ASSERT(last_updated_subscr == NULL);
629
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +0100630 update_subscriber_data_cb = __real_sgsn_update_subscriber_data;
631}
632
Jacob Erlbeckf81cacc2015-01-08 16:23:25 +0100633int my_gprs_gsup_client_send_dummy(struct gprs_gsup_client *gsupc, struct msgb *msg)
634{
635 msgb_free(msg);
636 return 0;
637};
638
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200639/*
640 * Test that a GMM Detach will remove the MMCTX and the
641 * associated LLME.
642 */
643static void test_gmm_detach(void)
644{
645 struct gprs_ra_id raid = { 0, };
646 struct sgsn_mm_ctx *ctx, *ictx;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200647 uint32_t local_tlli;
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200648
649 printf("Testing GMM detach\n");
650
651 /* DTAP - Detach Request (MO) */
652 /* normal detach, power_off = 0 */
653 static const unsigned char detach_req[] = {
654 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
655 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
656 };
657
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200658 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200659
Jacob Erlbeckabc16a52014-10-27 13:23:49 +0100660 /* Create a context */
661 OSMO_ASSERT(count(gprs_llme_list()) == 0);
662 ctx = alloc_mm_ctx(local_tlli, &raid);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200663
664 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100665 send_0408_message(ctx->llme, local_tlli,
666 detach_req, ARRAY_SIZE(detach_req));
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200667
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100668 /* verify that a single message (hopefully the Detach Accept) has been
669 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100670 OSMO_ASSERT(sgsn_tx_counter == 1);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100671
672 /* verify that things are gone */
673 OSMO_ASSERT(count(gprs_llme_list()) == 0);
674 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
675 OSMO_ASSERT(!ictx);
676}
677
678/*
679 * Test that a GMM Detach will remove the MMCTX and the associated LLME but
680 * will not sent a Detach Accept message (power_off = 1)
681 */
682static void test_gmm_detach_power_off(void)
683{
684 struct gprs_ra_id raid = { 0, };
685 struct sgsn_mm_ctx *ctx, *ictx;
686 uint32_t local_tlli;
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100687
688 printf("Testing GMM detach (power off)\n");
689
690 /* DTAP - Detach Request (MO) */
691 /* normal detach, power_off = 1 */
692 static const unsigned char detach_req[] = {
693 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
694 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
695 };
696
697 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
698
699 /* Create a context */
700 OSMO_ASSERT(count(gprs_llme_list()) == 0);
701 ctx = alloc_mm_ctx(local_tlli, &raid);
702
703 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100704 send_0408_message(ctx->llme, local_tlli,
705 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100706
707 /* verify that no message (and therefore no Detach Accept) has been
708 * sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100709 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck189999d2014-10-27 14:34:13 +0100710
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200711 /* verify that things are gone */
712 OSMO_ASSERT(count(gprs_llme_list()) == 0);
713 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
Jacob Erlbeck258ce3d2014-09-30 13:51:45 +0200714 OSMO_ASSERT(!ictx);
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +0200715}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +0200716
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200717/*
718 * Test that a GMM Detach will remove the associated LLME if there is no MMCTX.
719 */
720static void test_gmm_detach_no_mmctx(void)
721{
722 struct gprs_llc_lle *lle;
723 uint32_t local_tlli;
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200724
725 printf("Testing GMM detach (no MMCTX)\n");
726
727 /* DTAP - Detach Request (MO) */
728 /* normal detach, power_off = 0 */
729 static const unsigned char detach_req[] = {
730 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
731 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
732 };
733
734 /* Create an LLME */
735 OSMO_ASSERT(count(gprs_llme_list()) == 0);
736 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
737 lle = gprs_lle_get_or_create(local_tlli, 3);
738
739 OSMO_ASSERT(count(gprs_llme_list()) == 1);
740
741 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100742 send_0408_message(lle->llme, local_tlli,
743 detach_req, ARRAY_SIZE(detach_req));
Jacob Erlbeck5a38f642014-10-21 13:09:55 +0200744
745 /* verify that the LLME is gone */
746 OSMO_ASSERT(count(gprs_llme_list()) == 0);
747}
748
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100749/*
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +0100750 * Test that a single GMM Detach Accept message will not cause the SGSN to send
751 * any message or leave an MM context at the SGSN.
752 */
753static void test_gmm_detach_accept_unexpected(void)
754{
755 struct gprs_llc_lle *lle;
756 uint32_t local_tlli;
757
758 printf("Testing GMM detach accept (unexpected)\n");
759
760 /* DTAP - Detach Accept (MT) */
761 /* normal detach */
762 static const unsigned char detach_acc[] = {
763 0x08, 0x06
764 };
765
766 /* Create an LLME */
767 OSMO_ASSERT(count(gprs_llme_list()) == 0);
768 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
769 lle = gprs_lle_get_or_create(local_tlli, 3);
770
771 /* inject the detach */
772 send_0408_message(lle->llme, local_tlli,
773 detach_acc, ARRAY_SIZE(detach_acc));
774
775 /* verify that no message (and therefore no Status or XID reset) has been
776 * sent by the SGSN */
777 OSMO_ASSERT(sgsn_tx_counter == 0);
778
779 /* verify that things are gone */
780 OSMO_ASSERT(count(gprs_llme_list()) == 0);
781}
782
783/*
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100784 * Test that a GMM Status will remove the associated LLME if there is no MMCTX.
785 */
786static void test_gmm_status_no_mmctx(void)
787{
788 struct gprs_llc_lle *lle;
789 uint32_t local_tlli;
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100790
791 printf("Testing GMM Status (no MMCTX)\n");
792
793 /* DTAP - GMM Status, protocol error */
794 static const unsigned char gmm_status[] = {
795 0x08, 0x20, 0x6f
796 };
797
798 /* Create an LLME */
799 OSMO_ASSERT(count(gprs_llme_list()) == 0);
800 local_tlli = gprs_tmsi2tlli(0x23, TLLI_LOCAL);
801 lle = gprs_lle_get_or_create(local_tlli, 3);
802
803 OSMO_ASSERT(count(gprs_llme_list()) == 1);
804
805 /* inject the detach */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100806 send_0408_message(lle->llme, local_tlli,
807 gmm_status, ARRAY_SIZE(gmm_status));
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100808
809 /* verify that no message has been sent by the SGSN */
Jacob Erlbeck94ef1c02014-10-29 10:31:18 +0100810 OSMO_ASSERT(sgsn_tx_counter == 0);
Jacob Erlbeck14ae5822014-10-28 09:47:03 +0100811
812 /* verify that the LLME is gone */
813 OSMO_ASSERT(count(gprs_llme_list()) == 0);
814}
815
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100816/*
817 * Test the GMM Attach procedure
818 */
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100819static void test_gmm_attach(int retry)
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100820{
821 struct gprs_ra_id raid = { 0, };
822 struct sgsn_mm_ctx *ctx = NULL;
823 struct sgsn_mm_ctx *ictx;
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100824 uint32_t ptmsi1;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100825 uint32_t foreign_tlli;
826 uint32_t local_tlli = 0;
827 struct gprs_llc_lle *lle;
828
829 /* DTAP - Attach Request */
830 /* The P-TMSI is not known by the SGSN */
831 static const unsigned char attach_req[] = {
832 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
833 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
834 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
835 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
836 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
837 };
838
839 /* DTAP - Identity Response IMEI */
840 static const unsigned char ident_resp_imei[] = {
841 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
842 0x56
843 };
844
845 /* DTAP - Identity Response IMSI */
846 static const unsigned char ident_resp_imsi[] = {
847 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
848 0x54
849 };
850
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100851 /* DTAP - Authentication and Ciphering Resp */
852 static const unsigned char auth_ciph_resp[] = {
853 0x08, 0x13, 0x00, 0x22, 0x51, 0xe5, 0x51, 0xe5, 0x23, 0x09,
854 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x01
855 };
856
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100857 /* DTAP - Attach Complete */
858 static const unsigned char attach_compl[] = {
859 0x08, 0x03
860 };
861
862 /* DTAP - Detach Request (MO) */
863 /* normal detach, power_off = 0 */
864 static const unsigned char detach_req[] = {
865 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xeb, 0x8b,
866 0x45, 0x67, 0x19, 0x03, 0xb9, 0x97, 0xcb
867 };
868
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100869 printf("Testing GMM attach%s\n", retry ? " with retry" : "");
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100870
871 /* reset the PRNG used by sgsn_alloc_ptmsi */
872 srand(1);
873
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100874 ptmsi1 = sgsn_alloc_ptmsi();
875 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
876
877 /* reset the PRNG, so that the same P-TMSI sequence will be generated
878 * again */
879 srand(1);
880
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100881 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
882
883 /* Create a LLE/LLME */
884 OSMO_ASSERT(count(gprs_llme_list()) == 0);
885 lle = gprs_lle_get_or_create(foreign_tlli, 3);
886 OSMO_ASSERT(count(gprs_llme_list()) == 1);
887
888 /* inject the attach request */
889 send_0408_message(lle->llme, foreign_tlli,
890 attach_req, ARRAY_SIZE(attach_req));
891
892 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
893 OSMO_ASSERT(ctx != NULL);
894 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
895
896 /* we expect an identity request (IMEI) */
897 OSMO_ASSERT(sgsn_tx_counter == 1);
898
899 /* inject the identity response (IMEI) */
900 send_0408_message(ctx->llme, foreign_tlli,
901 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
902
903 /* we expect an identity request (IMSI) */
904 OSMO_ASSERT(sgsn_tx_counter == 1);
905
906 /* inject the identity response (IMSI) */
907 send_0408_message(ctx->llme, foreign_tlli,
908 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
909
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100910 /* check that the MM context has not been removed due to a failed
911 * authorization */
912 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
913
Jacob Erlbeck0074a772014-10-28 16:23:46 +0100914 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100915
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100916retry_attach_req:
917
918 if (retry && sgsn_tx_counter == 0) {
919 fprintf(stderr, "Retrying attach request\n");
920 /* re-inject the attach request */
921 send_0408_message(lle->llme, foreign_tlli,
922 attach_req, ARRAY_SIZE(attach_req));
923 }
924
925 if (ctx->auth_state == SGSN_AUTH_AUTHENTICATE && sgsn_tx_counter == 1) {
926 /* we got an auth & ciph request */
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100927
928 /* inject the auth & ciph response */
929 send_0408_message(ctx->llme, foreign_tlli,
930 auth_ciph_resp, ARRAY_SIZE(auth_ciph_resp));
931
932 /* check that the MM context has not been removed due to a
933 * failed authorization */
934 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
935 }
936
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100937 if (retry && sgsn_tx_counter == 0)
938 goto retry_attach_req;
939
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100940 /* we expect an attach accept/reject */
941 OSMO_ASSERT(sgsn_tx_counter == 1);
942
943 /* this has been randomly assigned by the SGSN */
Jacob Erlbeckaec03a12014-11-24 14:40:28 +0100944 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +0100945
946 /* inject the attach complete */
947 send_0408_message(ctx->llme, local_tlli,
948 attach_compl, ARRAY_SIZE(attach_compl));
949
950 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
951
952 /* we don't expect a response */
953 OSMO_ASSERT(sgsn_tx_counter == 0);
954
955 /* inject the detach */
956 send_0408_message(ctx->llme, local_tlli,
957 detach_req, ARRAY_SIZE(detach_req));
958
959 /* verify that things are gone */
960 OSMO_ASSERT(count(gprs_llme_list()) == 0);
961 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
962 OSMO_ASSERT(!ictx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100963}
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100964
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100965static void test_gmm_attach_acl(void)
966{
967 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
968
969 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_CLOSED;
970 sgsn_acl_add("123456789012345", &sgsn->cfg);
971 printf("Auth policy 'closed': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +0100972 test_gmm_attach(0);
Jacob Erlbeck0c06f982014-10-29 22:12:20 +0100973 sgsn_acl_del("123456789012345", &sgsn->cfg);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100974
975 sgsn->cfg.auth_policy = saved_auth_policy;
976}
977
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100978int my_subscr_request_update_location(struct sgsn_mm_ctx *mmctx) {
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100979 int rc;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100980 rc = __real_gprs_subscr_request_update_location(mmctx);
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100981 if (rc == -ENOTSUP) {
982 OSMO_ASSERT(mmctx->subscr);
983 gprs_subscr_update(mmctx->subscr);
984 }
985 return rc;
986};
987
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100988int my_subscr_request_auth_info(struct sgsn_mm_ctx *mmctx) {
989 gprs_subscr_update(mmctx->subscr);
990 return 0;
991};
992
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +0100993static void test_gmm_attach_subscr(void)
994{
995 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
996 struct gsm_subscriber *subscr;
997
998 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +0100999 subscr_request_update_location_cb = my_subscr_request_update_location;
1000 subscr_request_auth_info_cb = my_subscr_request_auth_info;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001001
1002 subscr = gprs_subscr_get_or_create("123456789012345");
1003 subscr->authorized = 1;
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001004
1005 printf("Auth policy 'remote': ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001006 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001007 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001008 assert_no_subscrs();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01001009
1010 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001011 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1012 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001013}
1014
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001015int my_subscr_request_auth_info_fake_auth(struct sgsn_mm_ctx *mmctx)
1016{
1017 /* Fake an authentication */
1018 OSMO_ASSERT(mmctx->subscr);
1019 mmctx->is_authenticated = 1;
1020 gprs_subscr_update_auth_info(mmctx->subscr);
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001021
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001022 return 0;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001023};
1024
1025static void test_gmm_attach_subscr_fake_auth(void)
1026{
1027 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1028 struct gsm_subscriber *subscr;
1029
1030 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001031 subscr_request_update_location_cb = my_subscr_request_update_location;
1032 subscr_request_auth_info_cb = my_subscr_request_auth_info_fake_auth;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001033
1034 subscr = gprs_subscr_get_or_create("123456789012345");
1035 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001036 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001037 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001038
1039 printf("Auth policy 'remote', auth faked: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001040 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001041 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001042 assert_no_subscrs();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001043
1044 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001045 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1046 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
1047}
1048
1049int my_subscr_request_auth_info_real_auth(struct sgsn_mm_ctx *mmctx)
1050{
1051 struct gsm_auth_tuple at = {
1052 .sres = {0x51, 0xe5, 0x51, 0xe5},
1053 .key_seq = 0
1054 };
1055
1056 /* Fake an authentication */
1057 OSMO_ASSERT(mmctx->subscr);
1058 mmctx->subscr->sgsn_data->auth_triplets[0] = at;
1059
1060 gprs_subscr_update_auth_info(mmctx->subscr);
1061
1062 return 0;
1063};
1064
1065static void test_gmm_attach_subscr_real_auth(void)
1066{
1067 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1068 struct gsm_subscriber *subscr;
1069
1070 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1071 subscr_request_update_location_cb = my_subscr_request_update_location;
1072 subscr_request_auth_info_cb = my_subscr_request_auth_info_real_auth;
1073
1074 subscr = gprs_subscr_get_or_create("123456789012345");
1075 subscr->authorized = 1;
Jacob Erlbeck9d4f46c2014-12-17 13:20:08 +01001076 sgsn->cfg.require_authentication = 1;
Jacob Erlbeck771573c2014-12-19 18:08:48 +01001077 sgsn->cfg.require_update_location = 1;
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001078
1079 printf("Auth policy 'remote', triplet based auth: ");
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001080
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001081 test_gmm_attach(0);
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001082 subscr_put(subscr);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001083 assert_no_subscrs();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01001084
1085 sgsn->cfg.auth_policy = saved_auth_policy;
1086 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1087 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01001088}
1089
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001090#define TEST_GSUP_IMSI_LONG_IE 0x01, 0x08, \
1091 0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5
1092
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001093static int auth_info_skip = 0;
1094static int upd_loc_skip = 0;
1095
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001096int my_subscr_request_auth_info_gsup_auth(struct sgsn_mm_ctx *mmctx)
1097{
1098 static const uint8_t send_auth_info_res[] = {
1099 0x0a,
1100 TEST_GSUP_IMSI_LONG_IE,
1101 0x03, 0x22, /* Auth tuple */
1102 0x20, 0x10,
1103 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
1104 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
1105 0x21, 0x04,
1106 0x51, 0xe5, 0x51, 0xe5,
1107 0x22, 0x08,
1108 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
1109 };
1110
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001111 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001112
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001113 if (auth_info_skip > 0) {
1114 auth_info_skip -= 1;
1115 return -EAGAIN;
1116 }
1117
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001118 /* Fake an SendAuthInfoRes */
1119 rx_gsup_message(send_auth_info_res, sizeof(send_auth_info_res));
1120
1121 return 0;
1122};
1123
1124int my_subscr_request_update_gsup_auth(struct sgsn_mm_ctx *mmctx) {
1125 static const uint8_t update_location_res[] = {
1126 0x06,
1127 TEST_GSUP_IMSI_LONG_IE,
1128 0x04, 0x00, /* PDP info complete */
1129 0x05, 0x12,
1130 0x10, 0x01, 0x01,
1131 0x11, 0x02, 0xf1, 0x21, /* IPv4 */
1132 0x12, 0x09, 0x04, 't', 'e', 's', 't', 0x03, 'a', 'p', 'n',
1133 };
1134
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001135 OSMO_ASSERT(!mmctx || mmctx->subscr);
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001136
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001137 if (upd_loc_skip > 0) {
1138 upd_loc_skip -= 1;
1139 return -EAGAIN;
1140 }
1141
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001142 /* Fake an UpdateLocRes */
1143 return rx_gsup_message(update_location_res, sizeof(update_location_res));
1144};
1145
1146
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001147static void test_gmm_attach_subscr_gsup_auth(int retry)
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001148{
1149 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1150 struct gsm_subscriber *subscr;
1151
1152 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_REMOTE;
1153 subscr_request_update_location_cb = my_subscr_request_update_gsup_auth;
1154 subscr_request_auth_info_cb = my_subscr_request_auth_info_gsup_auth;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001155 if (retry) {
1156 upd_loc_skip = 3;
1157 auth_info_skip = 3;
1158 }
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001159
1160 subscr = gprs_subscr_get_or_create("123456789012345");
1161 subscr->authorized = 1;
1162 sgsn->cfg.require_authentication = 1;
1163 sgsn->cfg.require_update_location = 1;
1164 subscr_put(subscr);
1165
1166 printf("Auth policy 'remote', GSUP based auth: ");
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001167 test_gmm_attach(retry);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001168 assert_no_subscrs();
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001169
1170 sgsn->cfg.auth_policy = saved_auth_policy;
1171 subscr_request_update_location_cb = __real_gprs_subscr_request_update_location;
1172 subscr_request_auth_info_cb = __real_gprs_subscr_request_auth_info;
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01001173 upd_loc_skip = 0;
1174 auth_info_skip = 0;
Jacob Erlbeck3d722452014-12-19 18:26:09 +01001175}
1176
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001177int my_gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
1178{
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001179 struct gprs_gsup_message to_peer = {0};
1180 struct gprs_gsup_message from_peer = {0};
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001181 struct msgb *reply_msg;
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001182 int rc;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001183
1184 /* Simulate the GSUP peer */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001185 rc = gprs_gsup_decode(msgb_data(msg), msgb_length(msg), &to_peer);
1186 OSMO_ASSERT(rc >= 0);
1187 OSMO_ASSERT(to_peer.imsi[0] != 0);
1188 strncpy(from_peer.imsi, to_peer.imsi, sizeof(from_peer.imsi));
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001189
1190 /* This invalidates the pointers in to_peer */
1191 msgb_free(msg);
1192
1193 switch (to_peer.message_type) {
1194 case GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST:
1195 /* Send UPDATE_LOCATION_RESULT */
1196 return my_subscr_request_update_gsup_auth(NULL);
1197
1198 case GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST:
1199 /* Send SEND_AUTH_INFO_RESULT */
1200 return my_subscr_request_auth_info_gsup_auth(NULL);
1201
1202 case GPRS_GSUP_MSGT_PURGE_MS_REQUEST:
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001203 from_peer.message_type = GPRS_GSUP_MSGT_PURGE_MS_RESULT;
1204 break;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001205
1206 default:
1207 if ((to_peer.message_type & 0b00000011) == 0) {
1208 /* Unhandled request */
Jacob Erlbeck65fa3f72015-01-06 16:32:41 +01001209 /* Send error(NOT_IMPL) */
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001210 from_peer.message_type = to_peer.message_type + 1;
1211 from_peer.cause = GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL;
1212 break;
1213 }
1214
1215 /* Ignore it */
1216 return 0;
1217 }
1218
1219 reply_msg = gprs_gsup_msgb_alloc();
1220 reply_msg->l2h = reply_msg->data;
1221 gprs_gsup_encode(reply_msg, &from_peer);
1222 gprs_subscr_rx_gsup_message(reply_msg);
1223 msgb_free(reply_msg);
1224
1225 return 0;
1226};
1227
1228static void test_gmm_attach_subscr_real_gsup_auth(int retry)
1229{
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;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001234 gprs_gsup_client_send_cb = my_gprs_gsup_client_send;
1235
1236 sgsn->gsup_client = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
1237
1238 if (retry) {
1239 upd_loc_skip = 3;
1240 auth_info_skip = 3;
1241 }
1242
1243 printf("Auth policy 'remote', real GSUP based auth: ");
1244 test_gmm_attach(retry);
1245
1246 subscr = gprs_subscr_get_by_imsi("123456789012345");
Holger Hans Peter Freyther1d778fd2015-01-20 21:14:03 +01001247 OSMO_ASSERT(subscr == NULL);
Jacob Erlbeck058bc262015-01-13 11:46:32 +01001248 assert_no_subscrs();
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001249
1250 sgsn->cfg.auth_policy = saved_auth_policy;
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01001251 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1252 upd_loc_skip = 0;
1253 auth_info_skip = 0;
1254 talloc_free(sgsn->gsup_client);
1255 sgsn->gsup_client = NULL;
1256}
1257
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01001258/*
1259 * Test the GMM Rejects
1260 */
1261static void test_gmm_reject(void)
1262{
1263 struct gprs_ra_id raid = { 0, };
1264 struct sgsn_mm_ctx *ctx = NULL;
1265 uint32_t foreign_tlli;
1266 struct gprs_llc_lle *lle;
1267 int idx;
1268
1269 /* DTAP - Attach Request */
1270 /* Invalid MI length */
1271 static const unsigned char attach_req_inv_mi_len[] = {
1272 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x09, 0xf4,
1273 0xfb, 0xc5, 0x46, 0x79, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
1274 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25,
1275 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00,
1276 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1277 };
1278
1279 /* DTAP - Attach Request */
1280 /* Invalid MI type (IMEI) */
1281 static const unsigned char attach_req_inv_mi_type[] = {
1282 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf2,
1283 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1284 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1285 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1286 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1287 };
1288
1289 /* DTAP - Routing Area Update Request */
1290 static const unsigned char dtap_ra_upd_req[] = {
1291 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1292 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1293 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1294 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1295 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1296 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1297 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1298 };
1299
1300 /* DTAP - Routing Area Update Request */
1301 /* Invalid type: GPRS_UPD_T_RA_LA_IMSI_ATT */
1302 static const unsigned char dtap_ra_upd_req_inv_type[] = {
1303 0x08, 0x08, 0x12, 0x11, 0x22, 0x33, 0x40, 0x50,
1304 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1305 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1306 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1307 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1308 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1309 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1310 };
1311
1312 /* DTAP - Routing Area Update Request */
1313 /* Invalid cap length */
1314 static const unsigned char dtap_ra_upd_req_inv_cap_len[] = {
1315 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1316 0x60, 0x3d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1317 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1318 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1319 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1320 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1321 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1322 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1323 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1324 };
1325
1326 struct test {
1327 const char *title;
1328 const unsigned char *msg;
1329 unsigned msg_len;
1330 unsigned num_resp;
1331
1332 };
1333 static struct test tests[] = {
1334 {
1335 .title = "Attach Request (invalid MI length)",
1336 .msg = attach_req_inv_mi_len,
1337 .msg_len = sizeof(attach_req_inv_mi_len),
1338 .num_resp = 1 /* Reject */
1339
1340 },
1341 {
1342 .title = "Attach Request (invalid MI type)",
1343 .msg = attach_req_inv_mi_type,
1344 .msg_len = sizeof(attach_req_inv_mi_type),
1345 .num_resp = 1 /* Reject */
1346 },
1347 {
1348 .title = "Routing Area Update Request (valid)",
1349 .msg = dtap_ra_upd_req,
1350 .msg_len = sizeof(dtap_ra_upd_req),
1351 .num_resp = 2 /* XID Reset + Reject */
1352 },
1353 {
1354 .title = "Routing Area Update Request (invalid type)",
1355 .msg = dtap_ra_upd_req_inv_type,
1356 .msg_len = sizeof(dtap_ra_upd_req_inv_type),
1357 .num_resp = 1 /* Reject */
1358 },
1359 {
1360 .title = "Routing Area Update Request (invalid CAP length)",
1361 .msg = dtap_ra_upd_req_inv_cap_len,
1362 .msg_len = sizeof(dtap_ra_upd_req_inv_cap_len),
1363 .num_resp = 1 /* Reject */
1364 },
1365 };
1366
1367 printf("Testing GMM reject\n");
1368
1369 /* reset the PRNG used by sgsn_alloc_ptmsi */
1370 srand(1);
1371
1372 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1373
1374 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1375
1376 for (idx = 0; idx < ARRAY_SIZE(tests); idx++) {
1377 const struct test *test = &tests[idx];
1378 printf(" - %s\n", test->title);
1379
1380 /* Create a LLE/LLME */
1381 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1382 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1383
1384 /* Inject the Request message */
1385 send_0408_message(lle->llme, foreign_tlli,
1386 test->msg, test->msg_len);
1387
1388 /* We expect a Reject message */
1389 fprintf(stderr, "sgsn_tx_counter = %d (expected %d)\n",
1390 sgsn_tx_counter, test->num_resp);
1391 OSMO_ASSERT(sgsn_tx_counter == test->num_resp);
1392
1393 /* verify that LLME/MM are removed */
1394 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1395 OSMO_ASSERT(ctx == NULL);
1396 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1397 }
1398}
1399
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001400/*
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001401 * Test cancellation of attached MM contexts
1402 */
1403static void test_gmm_cancel(void)
1404{
1405 struct gprs_ra_id raid = { 0, };
1406 struct sgsn_mm_ctx *ctx = NULL;
1407 struct sgsn_mm_ctx *ictx;
1408 uint32_t ptmsi1;
1409 uint32_t foreign_tlli;
1410 uint32_t local_tlli = 0;
1411 struct gprs_llc_lle *lle;
1412 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1413
1414 /* DTAP - Attach Request */
1415 /* The P-TMSI is not known by the SGSN */
1416 static const unsigned char attach_req[] = {
1417 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02, 0x05, 0xf4,
1418 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
1419 0x19, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
1420 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
1421 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00
1422 };
1423
1424 /* DTAP - Identity Response IMEI */
1425 static const unsigned char ident_resp_imei[] = {
1426 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1427 0x56
1428 };
1429
1430 /* DTAP - Identity Response IMSI */
1431 static const unsigned char ident_resp_imsi[] = {
1432 0x08, 0x16, 0x08, 0x19, 0x32, 0x54, 0x76, 0x98, 0x10, 0x32,
1433 0x54
1434 };
1435
1436 /* DTAP - Attach Complete */
1437 static const unsigned char attach_compl[] = {
1438 0x08, 0x03
1439 };
1440
1441 printf("Testing cancellation\n");
1442
1443 sgsn_inst.cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1444
1445 /* reset the PRNG used by sgsn_alloc_ptmsi */
1446 srand(1);
1447
1448 ptmsi1 = sgsn_alloc_ptmsi();
1449 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1450
1451 /* reset the PRNG, so that the same P-TMSI sequence will be generated
1452 * again */
1453 srand(1);
1454
1455 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1456
1457 /* Create a LLE/LLME */
1458 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1459 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1460 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1461
1462 /* inject the attach request */
1463 send_0408_message(lle->llme, foreign_tlli,
1464 attach_req, ARRAY_SIZE(attach_req));
1465
1466 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1467 OSMO_ASSERT(ctx != NULL);
1468 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1469
1470 /* we expect an identity request (IMEI) */
1471 OSMO_ASSERT(sgsn_tx_counter == 1);
1472
1473 /* inject the identity response (IMEI) */
1474 send_0408_message(ctx->llme, foreign_tlli,
1475 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1476
1477 /* we expect an identity request (IMSI) */
1478 OSMO_ASSERT(sgsn_tx_counter == 1);
1479
1480 /* inject the identity response (IMSI) */
1481 send_0408_message(ctx->llme, foreign_tlli,
1482 ident_resp_imsi, ARRAY_SIZE(ident_resp_imsi));
1483
1484 /* check that the MM context has not been removed due to a failed
1485 * authorization */
1486 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1487
1488 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1489
1490 /* we expect an attach accept/reject */
1491 OSMO_ASSERT(sgsn_tx_counter == 1);
1492
1493 /* this has been randomly assigned by the SGSN */
1494 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1495
1496 /* inject the attach complete */
1497 send_0408_message(ctx->llme, local_tlli,
1498 attach_compl, ARRAY_SIZE(attach_compl));
1499
1500 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1501
1502 /* we don't expect a response */
1503 OSMO_ASSERT(sgsn_tx_counter == 0);
1504
1505 /* cancel */
Jacob Erlbeckaf3d5c52015-01-05 17:51:17 +01001506 gsm0408_gprs_access_cancelled(ctx, 0);
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01001507
1508 /* verify that things are gone */
1509 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1510 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1511 OSMO_ASSERT(!ictx);
1512
1513 sgsn->cfg.auth_policy = saved_auth_policy;
1514}
1515
1516/*
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01001517 * Test the dynamic allocation of P-TMSIs
1518 */
1519static void test_gmm_ptmsi_allocation(void)
1520{
1521 struct gprs_ra_id raid = { 0, };
1522 struct sgsn_mm_ctx *ctx = NULL;
1523 struct sgsn_mm_ctx *ictx;
1524 uint32_t foreign_tlli;
1525 uint32_t ptmsi1;
1526 uint32_t ptmsi2;
1527 uint32_t old_ptmsi;
1528 uint32_t local_tlli = 0;
1529 struct gprs_llc_lle *lle;
1530 const enum sgsn_auth_policy saved_auth_policy = sgsn->cfg.auth_policy;
1531
1532 /* DTAP - Attach Request (IMSI 12131415161718) */
1533 static const unsigned char attach_req[] = {
1534 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
1535 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1536 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
1537 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
1538 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
1539 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
1540 0x00,
1541 };
1542
1543 /* DTAP - Identity Response IMEI */
1544 static const unsigned char ident_resp_imei[] = {
1545 0x08, 0x16, 0x08, 0x9a, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78,
1546 0x56
1547 };
1548
1549 /* DTAP - Attach Complete */
1550 static const unsigned char attach_compl[] = {
1551 0x08, 0x03
1552 };
1553
1554 /* DTAP - Routing Area Update Request */
1555 static const unsigned char ra_upd_req[] = {
1556 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
1557 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
1558 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
1559 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
1560 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
1561 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
1562 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
1563 };
1564
1565 /* DTAP - Routing Area Update Complete */
1566 static const unsigned char ra_upd_complete[] = {
1567 0x08, 0x0a
1568 };
1569
1570 /* DTAP - Detach Request (MO) */
1571 /* normal detach, power_off = 1 */
1572 static const unsigned char detach_req[] = {
1573 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
1574 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
1575 };
1576
1577 sgsn->cfg.auth_policy = SGSN_AUTH_POLICY_OPEN;
1578
1579 printf("Testing P-TMSI allocation\n");
1580
1581 printf(" - sgsn_alloc_ptmsi\n");
1582
1583 /* reset the PRNG used by sgsn_alloc_ptmsi */
1584 srand(1);
1585
1586 ptmsi1 = sgsn_alloc_ptmsi();
1587 OSMO_ASSERT(ptmsi1 != GSM_RESERVED_TMSI);
1588
1589 ptmsi2 = sgsn_alloc_ptmsi();
1590 OSMO_ASSERT(ptmsi2 != GSM_RESERVED_TMSI);
1591
1592 OSMO_ASSERT(ptmsi1 != ptmsi2);
1593
1594 printf(" - Repeated Attach Request\n");
1595
1596 /* reset the PRNG, so that the same P-TMSI will be generated
1597 * again */
1598 srand(1);
1599
1600 foreign_tlli = gprs_tmsi2tlli(0xc0000023, TLLI_FOREIGN);
1601
1602 /* Create a LLE/LLME */
1603 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1604 lle = gprs_lle_get_or_create(foreign_tlli, 3);
1605 OSMO_ASSERT(count(gprs_llme_list()) == 1);
1606
1607 /* inject the attach request */
1608 send_0408_message(lle->llme, foreign_tlli,
1609 attach_req, ARRAY_SIZE(attach_req));
1610
1611 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1612 OSMO_ASSERT(ctx != NULL);
1613 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1614 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1615
1616 old_ptmsi = ctx->p_tmsi_old;
1617
1618 /* we expect an identity request (IMEI) */
1619 OSMO_ASSERT(sgsn_tx_counter == 1);
1620
1621 /* inject the identity response (IMEI) */
1622 send_0408_message(ctx->llme, foreign_tlli,
1623 ident_resp_imei, ARRAY_SIZE(ident_resp_imei));
1624
1625 /* check that the MM context has not been removed due to a failed
1626 * authorization */
1627 OSMO_ASSERT(ctx == sgsn_mm_ctx_by_tlli(foreign_tlli, &raid));
1628
1629 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1630 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1631
1632 /* we expect an attach accept */
1633 OSMO_ASSERT(sgsn_tx_counter == 1);
1634
1635 /* we ignore this and send the attach again */
1636 send_0408_message(lle->llme, foreign_tlli,
1637 attach_req, ARRAY_SIZE(attach_req));
1638
1639 /* the allocated P-TMSI should be the same */
1640 ctx = sgsn_mm_ctx_by_tlli(foreign_tlli, &raid);
1641 OSMO_ASSERT(ctx != NULL);
1642 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1643 OSMO_ASSERT(ctx->p_tmsi_old == old_ptmsi);
1644 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1645
1646 /* inject the attach complete */
1647 local_tlli = gprs_tmsi2tlli(ptmsi1, TLLI_LOCAL);
1648 send_0408_message(ctx->llme, local_tlli,
1649 attach_compl, ARRAY_SIZE(attach_compl));
1650
1651 /* we don't expect a response */
1652 OSMO_ASSERT(sgsn_tx_counter == 0);
1653
1654 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1655 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1656 OSMO_ASSERT(ctx->p_tmsi == ptmsi1);
1657
1658 printf(" - Repeated RA Update Request\n");
1659
1660 /* inject the RA update request */
1661 send_0408_message(ctx->llme, local_tlli,
1662 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1663
1664 /* we expect an RA update accept */
1665 OSMO_ASSERT(sgsn_tx_counter == 1);
1666
1667 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1668 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1669 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1670
1671 /* repeat the RA update request */
1672 send_0408_message(ctx->llme, local_tlli,
1673 ra_upd_req, ARRAY_SIZE(ra_upd_req));
1674
1675 /* we expect an RA update accept */
1676 OSMO_ASSERT(sgsn_tx_counter == 1);
1677
1678 OSMO_ASSERT(ctx->mm_state == GMM_COMMON_PROC_INIT);
1679 OSMO_ASSERT(ctx->p_tmsi_old == ptmsi1);
1680 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1681
1682 /* inject the RA update complete */
1683 local_tlli = gprs_tmsi2tlli(ptmsi2, TLLI_LOCAL);
1684 send_0408_message(ctx->llme, local_tlli,
1685 ra_upd_complete, ARRAY_SIZE(ra_upd_complete));
1686
1687 /* we don't expect a response */
1688 OSMO_ASSERT(sgsn_tx_counter == 0);
1689
1690 OSMO_ASSERT(ctx->mm_state == GMM_REGISTERED_NORMAL);
1691 OSMO_ASSERT(ctx->p_tmsi_old == 0);
1692 OSMO_ASSERT(ctx->p_tmsi == ptmsi2);
1693
1694 /* inject the detach */
1695 send_0408_message(ctx->llme, local_tlli,
1696 detach_req, ARRAY_SIZE(detach_req));
1697
1698 /* verify that things are gone */
1699 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1700 ictx = sgsn_mm_ctx_by_tlli(local_tlli, &raid);
1701 OSMO_ASSERT(!ictx);
1702
1703 sgsn->cfg.auth_policy = saved_auth_policy;
1704}
1705
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01001706static void test_apn_matching(void)
1707{
1708 struct apn_ctx *actx, *actxs[9];
1709
1710 printf("Testing APN matching\n");
1711
1712 actxs[0] = sgsn_apn_ctx_find_alloc("*.test", "");
1713 actxs[1] = sgsn_apn_ctx_find_alloc("*.def.test", "");
1714 actxs[2] = sgsn_apn_ctx_find_alloc("abc.def.test", "");
1715 actxs[3] = NULL;
1716
1717 actxs[4] = sgsn_apn_ctx_find_alloc("abc.def.test", "456");
1718 actxs[5] = sgsn_apn_ctx_find_alloc("abc.def.test", "456123");
1719 actxs[6] = sgsn_apn_ctx_find_alloc("*.def.test", "456");
1720 actxs[7] = sgsn_apn_ctx_find_alloc("*.def.test", "456123");
1721
1722 actxs[8] = sgsn_apn_ctx_find_alloc("ghi.def.test", "456");
1723
1724 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1725 OSMO_ASSERT(actx == actxs[2]);
1726 actx = sgsn_apn_ctx_match("aBc.dEf.test", "12345678");
1727 OSMO_ASSERT(actx == actxs[2]);
1728 actx = sgsn_apn_ctx_match("xyz.def.test", "12345678");
1729 OSMO_ASSERT(actx == actxs[1]);
1730 actx = sgsn_apn_ctx_match("xyz.dEf.test", "12345678");
1731 OSMO_ASSERT(actx == actxs[1]);
1732 actx = sgsn_apn_ctx_match("xyz.uvw.test", "12345678");
1733 OSMO_ASSERT(actx == actxs[0]);
1734 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1735 OSMO_ASSERT(actx == NULL);
1736
1737 actxs[3] = sgsn_apn_ctx_find_alloc("*", "");
1738 actx = sgsn_apn_ctx_match("xyz.uvw.foo", "12345678");
1739 OSMO_ASSERT(actx == actxs[3]);
1740
1741 actx = sgsn_apn_ctx_match("abc.def.test", "45699900");
1742 OSMO_ASSERT(actx == actxs[4]);
1743
1744 actx = sgsn_apn_ctx_match("xyz.def.test", "45699900");
1745 OSMO_ASSERT(actx == actxs[6]);
1746
1747 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1748 OSMO_ASSERT(actx == actxs[5]);
1749
1750 actx = sgsn_apn_ctx_match("xyz.def.test", "45612300");
1751 OSMO_ASSERT(actx == actxs[7]);
1752
1753 actx = sgsn_apn_ctx_match("ghi.def.test", "45699900");
1754 OSMO_ASSERT(actx == actxs[8]);
1755
1756 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1757 OSMO_ASSERT(actx == actxs[7]);
1758
1759 /* Free APN contexts and check how the matching changes */
1760
1761 sgsn_apn_ctx_free(actxs[7]);
1762 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1763 OSMO_ASSERT(actx == actxs[8]);
1764
1765 sgsn_apn_ctx_free(actxs[8]);
1766 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1767 OSMO_ASSERT(actx == actxs[6]);
1768
1769 sgsn_apn_ctx_free(actxs[6]);
1770 actx = sgsn_apn_ctx_match("ghi.def.test", "45612300");
1771 OSMO_ASSERT(actx == actxs[1]);
1772
1773 sgsn_apn_ctx_free(actxs[5]);
1774 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1775 OSMO_ASSERT(actx == actxs[4]);
1776
1777 sgsn_apn_ctx_free(actxs[4]);
1778 actx = sgsn_apn_ctx_match("abc.def.test", "45612300");
1779 OSMO_ASSERT(actx == actxs[2]);
1780
1781 sgsn_apn_ctx_free(actxs[2]);
1782 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1783 OSMO_ASSERT(actx == actxs[1]);
1784
1785 sgsn_apn_ctx_free(actxs[1]);
1786 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1787 OSMO_ASSERT(actx == actxs[0]);
1788
1789 sgsn_apn_ctx_free(actxs[0]);
1790 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1791 OSMO_ASSERT(actx == actxs[3]);
1792
1793 sgsn_apn_ctx_free(actxs[3]);
1794 actx = sgsn_apn_ctx_match("abc.def.test", "12345678");
1795 OSMO_ASSERT(actx == NULL);
1796}
1797
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01001798struct sgsn_subscriber_pdp_data* sgsn_subscriber_pdp_data_alloc(
1799 struct sgsn_subscriber_data *sdata);
1800
1801static void test_ggsn_selection(void)
1802{
1803 struct apn_ctx *actxs[4];
1804 struct sgsn_ggsn_ctx *ggc, *ggcs[3];
1805 struct gsm_subscriber *s1;
1806 const char *imsi1 = "1234567890";
1807 struct sgsn_mm_ctx *ctx;
1808 struct gprs_ra_id raid = { 0, };
1809 uint32_t local_tlli = 0xffeeddcc;
1810 enum gsm48_gsm_cause gsm_cause;
1811 struct tlv_parsed tp;
1812 uint8_t apn_enc[GSM_APN_LENGTH + 10];
1813 struct sgsn_subscriber_pdp_data *pdp_data;
1814
1815 printf("Testing GGSN selection\n");
1816
1817 gprs_gsup_client_send_cb = my_gprs_gsup_client_send_dummy;
1818
1819 /* Check for emptiness */
1820 OSMO_ASSERT(gprs_subscr_get_by_imsi(imsi1) == NULL);
1821
1822 /* Create a context */
1823 OSMO_ASSERT(count(gprs_llme_list()) == 0);
1824 ctx = alloc_mm_ctx(local_tlli, &raid);
1825 strncpy(ctx->imsi, imsi1, sizeof(ctx->imsi) - 1);
1826
1827 /* Allocate and attach a subscriber */
1828 s1 = gprs_subscr_get_or_create_by_mmctx(ctx);
1829 assert_subscr(s1, imsi1);
1830
1831 tp.lv[GSM48_IE_GSM_APN].len = 0;
1832 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1833
1834 /* TODO: Add PDP info entries to s1 */
1835
1836 ggcs[0] = sgsn_ggsn_ctx_find_alloc(0);
1837 ggcs[1] = sgsn_ggsn_ctx_find_alloc(1);
1838 ggcs[2] = sgsn_ggsn_ctx_find_alloc(2);
1839
1840 actxs[0] = sgsn_apn_ctx_find_alloc("test.apn", "123456");
1841 actxs[0]->ggsn = ggcs[0];
1842 actxs[1] = sgsn_apn_ctx_find_alloc("*.apn", "123456");
1843 actxs[1]->ggsn = ggcs[1];
1844 actxs[2] = sgsn_apn_ctx_find_alloc("*", "456789");
1845 actxs[2]->ggsn = ggcs[2];
1846
1847 /* Resolve GGSNs */
1848
1849 tp.lv[GSM48_IE_GSM_APN].len =
1850 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
1851
1852 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1853 OSMO_ASSERT(ggc != NULL);
1854 OSMO_ASSERT(ggc->id == 0);
1855
1856 tp.lv[GSM48_IE_GSM_APN].len =
1857 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
1858
1859 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1860 OSMO_ASSERT(ggc != NULL);
1861 OSMO_ASSERT(ggc->id == 1);
1862
1863 tp.lv[GSM48_IE_GSM_APN].len = 0;
1864 tp.lv[GSM48_IE_GSM_APN].val = NULL;
1865
1866 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1867 OSMO_ASSERT(ggc != NULL);
1868 OSMO_ASSERT(ggc->id == 0);
1869
1870 actxs[3] = sgsn_apn_ctx_find_alloc("*", "123456");
1871 actxs[3]->ggsn = ggcs[2];
1872 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1873 OSMO_ASSERT(ggc != NULL);
1874 OSMO_ASSERT(ggc->id == 2);
1875
1876 sgsn_apn_ctx_free(actxs[3]);
1877 tp.lv[GSM48_IE_GSM_APN].val = apn_enc;
1878
1879 tp.lv[GSM48_IE_GSM_APN].len =
1880 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Foo.Bar");
1881
1882 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1883 OSMO_ASSERT(ggc == NULL);
1884 OSMO_ASSERT(gsm_cause == GSM_CAUSE_MISSING_APN);
1885
1886 tp.lv[GSM48_IE_GSM_APN].len = sizeof(apn_enc);
1887 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1888 OSMO_ASSERT(ggc == NULL);
1889 OSMO_ASSERT(gsm_cause == GSM_CAUSE_INV_MAND_INFO);
1890
1891 /* Add PDP data entry to subscriber */
1892
1893 pdp_data = sgsn_subscriber_pdp_data_alloc(s1->sgsn_data);
1894 pdp_data->context_id = 1;
1895
1896 pdp_data->pdp_type = 0x0121;
1897 strncpy(pdp_data->apn_str, "Test.Apn", sizeof(pdp_data->apn_str)-1);
1898
1899 tp.lv[GSM48_IE_GSM_APN].len =
1900 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Test.Apn");
1901
1902 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1903 OSMO_ASSERT(ggc != NULL);
1904 OSMO_ASSERT(ggc->id == 0);
1905
1906 tp.lv[GSM48_IE_GSM_APN].len =
1907 gprs_str_to_apn(apn_enc, sizeof(apn_enc), "Other.Apn");
1908
1909 ggc = sgsn_mm_ctx_find_ggsn_ctx(ctx, &tp, &gsm_cause);
1910 OSMO_ASSERT(ggc == NULL);
1911 OSMO_ASSERT(gsm_cause == GSM_CAUSE_REQ_SERV_OPT_NOTSUB);
1912
1913 /* Cleanup */
1914
1915 subscr_put(s1);
1916 sgsn_mm_ctx_cleanup_free(ctx);
1917
1918 assert_no_subscrs();
1919
1920 sgsn_apn_ctx_free(actxs[0]);
1921 sgsn_apn_ctx_free(actxs[1]);
1922 sgsn_apn_ctx_free(actxs[2]);
1923
1924 sgsn_ggsn_ctx_free(ggcs[0]);
1925 sgsn_ggsn_ctx_free(ggcs[1]);
1926 sgsn_ggsn_ctx_free(ggcs[2]);
1927
1928 gprs_gsup_client_send_cb = __real_gprs_gsup_client_send;
1929}
1930
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001931static struct log_info_cat gprs_categories[] = {
1932 [DMM] = {
1933 .name = "DMM",
1934 .description = "Layer3 Mobility Management (MM)",
1935 .color = "\033[1;33m",
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001936 .enabled = 1, .loglevel = LOGL_DEBUG,
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001937 },
1938 [DPAG] = {
1939 .name = "DPAG",
1940 .description = "Paging Subsystem",
1941 .color = "\033[1;38m",
1942 .enabled = 1, .loglevel = LOGL_NOTICE,
1943 },
1944 [DMEAS] = {
1945 .name = "DMEAS",
1946 .description = "Radio Measurement Processing",
1947 .enabled = 0, .loglevel = LOGL_NOTICE,
1948 },
1949 [DREF] = {
1950 .name = "DREF",
1951 .description = "Reference Counting",
1952 .enabled = 0, .loglevel = LOGL_NOTICE,
1953 },
1954 [DGPRS] = {
1955 .name = "DGPRS",
1956 .description = "GPRS Packet Service",
1957 .enabled = 1, .loglevel = LOGL_DEBUG,
1958 },
1959 [DNS] = {
1960 .name = "DNS",
1961 .description = "GPRS Network Service (NS)",
1962 .enabled = 1, .loglevel = LOGL_INFO,
1963 },
1964 [DBSSGP] = {
1965 .name = "DBSSGP",
1966 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1967 .enabled = 1, .loglevel = LOGL_DEBUG,
1968 },
1969 [DLLC] = {
1970 .name = "DLLC",
1971 .description = "GPRS Logical Link Control Protocol (LLC)",
1972 .enabled = 1, .loglevel = LOGL_DEBUG,
1973 },
1974 [DSNDCP] = {
1975 .name = "DSNDCP",
1976 .description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
1977 .enabled = 1, .loglevel = LOGL_DEBUG,
1978 },
1979};
1980
1981static struct log_info info = {
1982 .cat = gprs_categories,
1983 .num_cat = ARRAY_SIZE(gprs_categories),
1984};
1985
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02001986int main(int argc, char **argv)
1987{
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01001988 void *osmo_sgsn_ctx;
1989
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001990 osmo_init_logging(&info);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01001991 osmo_sgsn_ctx = talloc_named_const(NULL, 0, "osmo_sgsn");
1992 tall_bsc_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "bsc");
1993 tall_msgb_ctx = talloc_named_const(osmo_sgsn_ctx, 0, "msgb");
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001994
Jacob Erlbecka0b6efb2014-11-13 10:48:39 +01001995 sgsn_auth_init();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001996 gprs_subscr_init(sgsn);
Jacob Erlbeck27cb4d52014-10-29 12:11:58 +01001997
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02001998 test_llme();
Jacob Erlbeck33b6dad2014-11-12 10:12:11 +01001999 test_subscriber();
Jacob Erlbeck7921ab12014-12-08 15:52:00 +01002000 test_auth_triplets();
Jacob Erlbecka6ddc2d2014-12-12 15:01:37 +01002001 test_subscriber_gsup();
Holger Hans Peter Freytherfe921332014-10-02 22:24:47 +02002002 test_gmm_detach();
Jacob Erlbeck189999d2014-10-27 14:34:13 +01002003 test_gmm_detach_power_off();
Jacob Erlbeck5a38f642014-10-21 13:09:55 +02002004 test_gmm_detach_no_mmctx();
Jacob Erlbeckde4bbc72014-11-24 15:04:15 +01002005 test_gmm_detach_accept_unexpected();
Jacob Erlbeck14ae5822014-10-28 09:47:03 +01002006 test_gmm_status_no_mmctx();
Jacob Erlbeckbe2c8d92014-11-12 10:18:09 +01002007 test_gmm_attach_acl();
2008 test_gmm_attach_subscr();
Jacob Erlbeck2e5e94c2014-12-08 15:26:47 +01002009 test_gmm_attach_subscr_fake_auth();
Jacob Erlbeck98a95ac2014-11-28 14:55:25 +01002010 test_gmm_attach_subscr_real_auth();
Jacob Erlbeck7660ffa2014-12-19 18:30:41 +01002011 test_gmm_attach_subscr_gsup_auth(0);
2012 test_gmm_attach_subscr_gsup_auth(1);
Jacob Erlbeckc157ee72015-01-09 15:07:16 +01002013 test_gmm_attach_subscr_real_gsup_auth(0);
Jacob Erlbeck80d07e32014-11-06 13:43:41 +01002014 test_gmm_reject();
Jacob Erlbeck98647ca2014-11-11 14:47:38 +01002015 test_gmm_cancel();
Jacob Erlbeckf6e7d992014-11-06 15:43:10 +01002016 test_gmm_ptmsi_allocation();
Jacob Erlbeckcb1db8b2015-02-03 13:47:53 +01002017 test_apn_matching();
Jacob Erlbeck277b71e2015-02-02 18:03:05 +01002018 test_ggsn_selection();
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002019 printf("Done\n");
Jacob Erlbeck07de92e2015-01-13 11:46:32 +01002020
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002021 talloc_report_full(osmo_sgsn_ctx, stderr);
Jacob Erlbeckf0b06d82015-01-13 11:56:28 +01002022 OSMO_ASSERT(talloc_total_blocks(tall_msgb_ctx) == 1);
Jacob Erlbeck4b2d02d2015-01-30 11:57:25 +01002023 OSMO_ASSERT(talloc_total_blocks(tall_bsc_ctx) == 1);
Holger Hans Peter Freyther68c6f882014-09-30 09:10:25 +02002024 return 0;
2025}
Holger Hans Peter Freyther4299c052014-10-02 21:27:24 +02002026
2027
2028/* stubs */
2029struct osmo_prim_hdr;
2030int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
2031{
2032 abort();
2033}