blob: 8edb1714836bf7856b837473a75c1a61580a9f34 [file] [log] [blame]
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001/* test routines for gbproxy
2 * send NS messages to the gbproxy and dumps what happens
3 * (C) 2013 by sysmocom s.f.m.c. GmbH
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 */
6
7#undef _GNU_SOURCE
8#define _GNU_SOURCE
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <stdint.h>
13#include <string.h>
14#include <getopt.h>
15#include <dlfcn.h>
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020016#include <time.h>
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020017#include <sys/types.h>
18#include <sys/socket.h>
19
20#include <osmocom/core/msgb.h>
21#include <osmocom/core/application.h>
22#include <osmocom/core/utils.h>
23#include <osmocom/core/logging.h>
24#include <osmocom/core/talloc.h>
25#include <osmocom/core/signal.h>
26#include <osmocom/core/rate_ctr.h>
Jacob Erlbeck077abce2014-07-01 12:41:13 +020027#include <osmocom/gsm/tlv.h>
Jacob Erlbeck31132872014-08-11 17:26:21 +020028#include <osmocom/gsm/gsm_utils.h>
Harald Welte35ade5e2016-04-20 17:11:43 +020029#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020030#include <osmocom/gprs/gprs_msgb.h>
31#include <osmocom/gprs/gprs_ns.h>
32#include <osmocom/gprs/gprs_bssgp.h>
33
Neels Hofmeyr4b4c5862017-09-04 15:13:25 +020034#include <osmocom/sgsn/gb_proxy.h>
35#include <osmocom/sgsn/gprs_utils.h>
36#include <osmocom/sgsn/gprs_llc.h>
37#include <osmocom/sgsn/gprs_gb_parse.h>
38#include <osmocom/sgsn/debug.h>
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020039
40#define REMOTE_BSS_ADDR 0x01020304
41#define REMOTE_SGSN_ADDR 0x05060708
42
Jacob Erlbeck45017722013-10-18 13:04:47 +020043#define SGSN_NSEI 0x0100
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020044
Jacob Erlbeck12356062014-08-27 12:44:25 +020045#define REMOTE_SGSN2_ADDR 0x15161718
46#define SGSN2_NSEI 0x0102
47
Jacob Erlbecka4b5e892014-09-22 18:54:34 +020048#define MATCH_ANY (-1)
49
Neels Hofmeyr62507c52017-07-13 02:03:50 +020050void *tall_bsc_ctx;
51
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +020052struct gbproxy_config gbcfg = {0};
53
Jacob Erlbecka4b5e892014-09-22 18:54:34 +020054struct llist_head *received_messages = NULL;
55
Maxca7be8a2017-11-01 13:28:38 +010056/* override, requires '-Wl,--wrap=osmo_get_rand_id' */
57int __real_osmo_get_rand_id(uint8_t *data, size_t len);
58int mock_osmo_get_rand_id(uint8_t *data, size_t len);
59int (*osmo_get_rand_id_cb)(uint8_t *, size_t) =
60 &mock_osmo_get_rand_id;
Daniel Willmann2b10af32015-10-12 19:36:35 +020061
Maxca7be8a2017-11-01 13:28:38 +010062int __wrap_osmo_get_rand_id(uint8_t *buf, size_t num)
Daniel Willmann2b10af32015-10-12 19:36:35 +020063{
Maxca7be8a2017-11-01 13:28:38 +010064 return (*osmo_get_rand_id_cb)(buf, num);
Daniel Willmann2b10af32015-10-12 19:36:35 +020065}
66
67static int rand_seq_num = 0;
Maxca7be8a2017-11-01 13:28:38 +010068int mock_osmo_get_rand_id(uint8_t *buf, size_t num)
Daniel Willmann2b10af32015-10-12 19:36:35 +020069{
70 uint32_t val;
71
72 OSMO_ASSERT(num == sizeof(val));
Daniel Willmann2b10af32015-10-12 19:36:35 +020073
74 val = 0x00dead00 + rand_seq_num;
75
76 rand_seq_num++;
77
78 memcpy(buf, &val, num);
79
80 return 1;
81}
82
Daniel Willmann1e0b0002015-10-12 19:36:34 +020083static void cleanup_test()
84{
Daniel Willmann2b10af32015-10-12 19:36:35 +020085 rand_seq_num = 0;
Daniel Willmann1e0b0002015-10-12 19:36:34 +020086}
87
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020088static int dump_global(FILE *stream, int indent)
89{
90 unsigned int i;
91 const struct rate_ctr_group_desc *desc;
92 int rc;
93
94 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
95 if (rc < 0)
96 return rc;
97
98 desc = gbcfg.ctrg->desc;
99
100 for (i = 0; i < desc->num_ctr; i++) {
101 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
102 if (ctr->current) {
103 rc = fprintf(stream, "%*s %s: %llu\n",
104 indent, "",
105 desc->ctr_desc[i].description,
106 (long long)ctr->current);
107
108 if (rc < 0)
109 return rc;
110 }
111 }
112
113 return 0;
114}
115
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200116static int dump_peers(FILE *stream, int indent, time_t now,
117 struct gbproxy_config *cfg)
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200118{
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +0200119 struct gbproxy_peer *peer;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200120 struct gprs_ra_id raid;
121 unsigned int i;
122 const struct rate_ctr_group_desc *desc;
123 int rc;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200124
125 rc = fprintf(stream, "%*sPeers:\n", indent, "");
126 if (rc < 0)
127 return rc;
128
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +0200129 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200130 struct gbproxy_link_info *link_info;
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +0200131 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200132 gsm48_parse_ra(&raid, peer->ra);
133
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +0100134 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, RAI %s\n",
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200135 indent, "",
136 peer->nsei, peer->bvci,
137 peer->blocked ? "" : "not ",
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +0100138 osmo_rai_name(&raid));
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200139
140 if (rc < 0)
141 return rc;
142
143 desc = peer->ctrg->desc;
144
145 for (i = 0; i < desc->num_ctr; i++) {
146 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
147 if (ctr->current) {
148 rc = fprintf(stream, "%*s %s: %llu\n",
149 indent, "",
150 desc->ctr_desc[i].description,
151 (long long)ctr->current);
152
153 if (rc < 0)
154 return rc;
155 }
156 }
157
158 fprintf(stream, "%*s TLLI-Cache: %d\n",
Jacob Erlbeck485e28c2014-09-19 16:03:07 +0200159 indent, "", state->logical_link_count);
160 llist_for_each_entry(link_info, &state->logical_links, list) {
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200161 char mi_buf[200];
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200162 time_t age = now ? now - link_info->timestamp : 0;
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +0200163 int stored_msgs = 0;
164 struct llist_head *iter;
Jacob Erlbeckf4290b02014-09-25 11:17:31 +0200165 enum gbproxy_match_id match_id;
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200166 llist_for_each(iter, &link_info->stored_msgs)
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +0200167 stored_msgs++;
168
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200169 if (link_info->imsi_len > 0) {
Jacob Erlbeck9ac42ba2014-08-06 18:55:15 +0200170 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
171 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200172 link_info->imsi,
173 link_info->imsi_len);
Jacob Erlbeck9ac42ba2014-08-06 18:55:15 +0200174 } else {
175 snprintf(mi_buf, sizeof(mi_buf), "(none)");
176 }
Jacob Erlbeck31132872014-08-11 17:26:21 +0200177 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200178 indent, "", link_info->tlli.current);
179 if (link_info->tlli.assigned)
180 fprintf(stream, "/%08x", link_info->tlli.assigned);
181 if (link_info->sgsn_tlli.current) {
Jacob Erlbeck383c8412014-08-12 16:30:30 +0200182 fprintf(stream, " -> %08x",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200183 link_info->sgsn_tlli.current);
184 if (link_info->sgsn_tlli.assigned)
Jacob Erlbeck383c8412014-08-12 16:30:30 +0200185 fprintf(stream, "/%08x",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200186 link_info->sgsn_tlli.assigned);
Jacob Erlbeck383c8412014-08-12 16:30:30 +0200187 }
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +0200188 fprintf(stream, ", IMSI %s, AGE %d",
189 mi_buf, (int)age);
190
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +0200191 if (stored_msgs)
192 fprintf(stream, ", STORED %d", stored_msgs);
193
Jacob Erlbeckf4290b02014-09-25 11:17:31 +0200194 for (match_id = 0; match_id < ARRAY_SIZE(cfg->matches);
195 ++match_id) {
196 if (cfg->matches[match_id].enable &&
197 link_info->is_matching[match_id]) {
198 fprintf(stream, ", IMSI matches");
199 break;
200 }
201 }
Jacob Erlbeck12356062014-08-27 12:44:25 +0200202
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200203 if (link_info->imsi_acq_pending)
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +0200204 fprintf(stream, ", IMSI acquisition in progress");
205
Jacob Erlbeckd918f522014-09-17 10:56:38 +0200206 if (cfg->route_to_sgsn2)
207 fprintf(stream, ", SGSN NSEI %d",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200208 link_info->sgsn_nsei);
Jacob Erlbeckd918f522014-09-17 10:56:38 +0200209
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +0200210 if (link_info->is_deregistered)
Jacob Erlbeckf9038d92014-09-12 15:09:56 +0200211 fprintf(stream, ", DE-REGISTERED");
212
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +0200213 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200214 if (rc < 0)
215 return rc;
216 }
217 }
218
219 return 0;
220}
221
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +0200222const uint8_t *convert_ra(struct gprs_ra_id *raid)
223{
Max9f13b142018-01-08 14:43:53 +0100224 static struct gsm48_ra_id r;
225 gsm48_encode_ra(&r, raid);
226 return (const uint8_t *)&r;
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +0200227}
228
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200229/* DTAP - Attach Request */
230static const unsigned char dtap_attach_req[] = {
231 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
232 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
233 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
234 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
235 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
236 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200237};
238
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +0200239/* DTAP - Attach Request (invalid RAI) */
240static const unsigned char dtap_attach_req2[] = {
241 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
242 0x05, 0xf4, 0xfb, 0x00, 0xbe, 0xef, 0x99, 0x99,
243 0x99, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
244 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
245 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
246 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
247};
248
Jacob Erlbeck2c74e442014-09-15 14:18:09 +0200249/* DTAP - Attach Request (P-TMSI 0x3f32b700) */
250static const unsigned char dtap_attach_req3[] = {
251 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
252 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x11, 0x22,
253 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
254 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
255 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
256 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
257};
258
Jacob Erlbeckb0f61292014-10-31 10:43:44 +0100259/* DTAP - Attach Request (IMSI 12131415161718) */
260static const unsigned char dtap_attach_req4[] = {
261 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
262 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
263 0x18, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19,
264 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00,
265 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60,
266 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80,
267 0x00,
268};
269
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200270/* DTAP - Identity Request */
271static const unsigned char dtap_identity_req[] = {
272 0x08, 0x15, 0x01
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +0200273};
274
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200275/* DTAP - Identity Response */
276static const unsigned char dtap_identity_resp[] = {
277 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
278 0x16, 0x17, 0x18
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +0200279};
280
Jacob Erlbeck12356062014-08-27 12:44:25 +0200281/* DTAP - Identity Response, IMSI 2 */
282static const unsigned char dtap_identity2_resp[] = {
283 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
284 0x16, 0x17, 0x18
285};
286
Jacob Erlbeckd1056b32014-09-17 12:09:25 +0200287/* DTAP - Identity Response, IMSI 3 */
288static const unsigned char dtap_identity3_resp[] = {
289 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
290 0x26, 0x27, 0x28
291};
292
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200293/* DTAP - Attach Accept */
294static const unsigned char dtap_attach_acc[] = {
295 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
296 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
297 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200298};
299
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +0200300/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeck12356062014-08-27 12:44:25 +0200301static const unsigned char dtap_attach_acc2[] = {
302 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
303 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
304 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
305};
306
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200307/* DTAP - Attach Complete */
308static const unsigned char dtap_attach_complete[] = {
309 0x08, 0x03
Jacob Erlbeck31132872014-08-11 17:26:21 +0200310};
311
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +0200312/* DTAP - Attach Reject (GPRS services not allowed) */
313static const unsigned char dtap_attach_rej7[] = {
314 0x08, 0x04, 0x07
315};
316
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200317/* DTAP - GMM Information */
318static const unsigned char dtap_gmm_information[] = {
319 0x08, 0x21
Jacob Erlbeckab7366f2014-06-06 18:47:36 +0200320};
321
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200322/* DTAP - Routing Area Update Request */
323static const unsigned char dtap_ra_upd_req[] = {
324 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
325 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
326 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
327 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
328 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
329 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
330 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200331};
332
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200333/* DTAP - Routing Area Update Accept */
334static const unsigned char dtap_ra_upd_acc[] = {
335 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
336 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
337 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200338};
339
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +0200340/* DTAP - Routing Area Update Accept, P-TMSI 2 */
341static const unsigned char dtap_ra_upd_acc2[] = {
342 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
343 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
344 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
345};
346
347/* DTAP - Routing Area Update Accept, P-TMSI 3 */
348static const unsigned char dtap_ra_upd_acc3[] = {
349 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
350 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
351 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
352};
353
354/* DTAP - Routing Area Update Complete */
355static const unsigned char dtap_ra_upd_complete[] = {
356 0x08, 0x0a
357};
358
Jacob Erlbeck2c74e442014-09-15 14:18:09 +0200359/* DTAP - Routing Area Update Reject */
360/* cause = 10 ("Implicitly detached"), force_standby = 0 */
361static const unsigned char dtap_ra_upd_rej[] = {
362 0x08, 0x0b, 0x0a, 0x00,
363};
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +0200364
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200365/* DTAP - Activate PDP Context Request */
366static const unsigned char dtap_act_pdp_ctx_req[] = {
367 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200368 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
370 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
371 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
372 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200373 0x00
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200374};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200375
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200376/* DTAP - Detach Request (MO) */
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200377/* normal detach, power_off = 1 */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200378static const unsigned char dtap_detach_po_req[] = {
379 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
380 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200381};
382
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200383/* DTAP - Detach Request (MO) */
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200384/* normal detach, power_off = 0 */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200385static const unsigned char dtap_detach_req[] = {
386 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
387 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +0200388};
389
Jacob Erlbeck2c74e442014-09-15 14:18:09 +0200390/* DTAP - Detach Accept (MO) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200391static const unsigned char dtap_detach_acc[] = {
392 0x08, 0x06, 0x00
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +0200393};
394
Jacob Erlbeck2c74e442014-09-15 14:18:09 +0200395/* DTAP - Detach Request (MT) */
396/* normal detach, reattach required, implicitly detached */
397static const unsigned char dtap_mt_detach_rea_req[] = {
398 0x08, 0x05, 0x01, 0x25, 0x0a
399};
400
401/* DTAP - Detach Request (MT) */
402/* normal detach, reattach not required, implicitly detached */
403static const unsigned char dtap_mt_detach_req[] = {
404 0x08, 0x05, 0x02, 0x25, 0x0a
405};
406
407/* DTAP - Detach Accept (MT) */
408static const unsigned char dtap_mt_detach_acc[] = {
409 0x08, 0x06
410};
411
Jacob Erlbeck70e00de2014-08-15 17:20:06 +0200412/* GPRS-LLC - SAPI: LLGMM, U, XID */
413static const unsigned char llc_u_xid_ul[] = {
414 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
415 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
416};
417
418/* GPRS-LLC - SAPI: LLGMM, U, XID */
419static const unsigned char llc_u_xid_dl[] = {
420 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
421 0xe4, 0xa9, 0x1a, 0x9e
422};
423
424/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
425static const unsigned char llc_ui_ll11_dns_query_ul[] = {
426 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
427 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
428 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
429 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
430 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
431 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
432 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
433 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
434 0x8f, 0x07
435};
436
437/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
438static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
439 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
440 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
441 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
442 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
443 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
444 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
445 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
446 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
447 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
448 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
449 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
450 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
451 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
452 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
453 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
454 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
455 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
456 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
457 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
458 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
459 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
460 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
461 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
462 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
463 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
464 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
465};
466
Jacob Erlbeck45017722013-10-18 13:04:47 +0200467static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
468 struct sockaddr_in *peer, const unsigned char* data,
469 size_t data_len);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200470
471static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
472 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
473{
474 /* GPRS Network Service, PDU type: NS_RESET,
475 */
476 unsigned char msg[12] = {
477 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
478 0x04, 0x82, 0x11, 0x22
479 };
480
481 msg[3] = cause;
482 msg[6] = nsvci / 256;
483 msg[7] = nsvci % 256;
484 msg[10] = nsei / 256;
485 msg[11] = nsei % 256;
486
487 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
488}
489
Jacob Erlbeck45017722013-10-18 13:04:47 +0200490static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
491 uint16_t nsvci, uint16_t nsei)
492{
493 /* GPRS Network Service, PDU type: NS_RESET_ACK,
494 */
495 unsigned char msg[9] = {
496 0x03, 0x01, 0x82, 0x11, 0x22,
497 0x04, 0x82, 0x11, 0x22
498 };
499
500 msg[3] = nsvci / 256;
501 msg[4] = nsvci % 256;
502 msg[7] = nsei / 256;
503 msg[8] = nsei % 256;
504
505 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
506}
507
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200508static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
509{
510 /* GPRS Network Service, PDU type: NS_ALIVE */
511 unsigned char msg[1] = {
512 0x0a
513 };
514
515 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
516}
517
518static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
519{
520 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
521 unsigned char msg[1] = {
522 0x0b
523 };
524
525 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
526}
527
528static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
529{
530 /* GPRS Network Service, PDU type: NS_UNBLOCK */
531 unsigned char msg[1] = {
532 0x06
533 };
534
535 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
536}
537
Jacob Erlbeck45017722013-10-18 13:04:47 +0200538static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
539{
540 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
541 unsigned char msg[1] = {
542 0x07
543 };
544
545 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
546}
547
548static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
549 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200550 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
551{
552 /* GPRS Network Service, PDU type: NS_UNITDATA */
553 unsigned char msg[4096] = {
554 0x00, 0x00, 0x00, 0x00
555 };
556
557 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
558
559 msg[2] = nsbvci / 256;
560 msg[3] = nsbvci % 256;
561 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
562
Jacob Erlbeck45017722013-10-18 13:04:47 +0200563 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200564}
565
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200566static void send_bssgp_ul_unitdata(
567 struct gprs_ns_inst *nsi, const char *text,
568 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
569 struct gprs_ra_id *raid, uint16_t cell_id,
570 const uint8_t *llc_msg, size_t llc_msg_size)
571{
572 /* GPRS Network Service, PDU type: NS_UNITDATA */
573 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
574 unsigned char msg[4096] = {
575 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
576 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
577 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
578 };
579
580 size_t bssgp_msg_size = 23 + llc_msg_size;
581
582 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
583
Max9f13b142018-01-08 14:43:53 +0100584 gsm48_encode_ra((struct gsm48_ra_id *)(msg + 10), raid);
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200585 msg[1] = (uint8_t)(tlli >> 24);
586 msg[2] = (uint8_t)(tlli >> 16);
587 msg[3] = (uint8_t)(tlli >> 8);
588 msg[4] = (uint8_t)(tlli >> 0);
589 msg[16] = cell_id / 256;
590 msg[17] = cell_id % 256;
591 msg[21] = llc_msg_size / 256;
592 msg[22] = llc_msg_size % 256;
593 memcpy(msg + 23, llc_msg, llc_msg_size);
594
595 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
596 src_addr, nsbvci, msg, bssgp_msg_size);
597}
598
599static void send_bssgp_dl_unitdata(
600 struct gprs_ns_inst *nsi, const char *text,
601 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
602 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
603 const uint8_t *llc_msg, size_t llc_msg_size)
604{
605 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
606 unsigned char msg[4096] = {
607 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
608 0x16, 0x82, 0x02, 0x58,
609 };
610 unsigned char racap_drx[] = {
611 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
612 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
613 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
614 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
615 };
616
617 size_t bssgp_msg_size = 0;
618
619 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
620
621 msg[1] = (uint8_t)(tlli >> 24);
622 msg[2] = (uint8_t)(tlli >> 16);
623 msg[3] = (uint8_t)(tlli >> 8);
624 msg[4] = (uint8_t)(tlli >> 0);
625
626 bssgp_msg_size = 12;
627
628 if (with_racap_drx) {
629 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
630 bssgp_msg_size += sizeof(racap_drx);
631 }
632
633 if (imsi) {
634 OSMO_ASSERT(imsi_size <= 127);
635 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
636 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
637 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
638 bssgp_msg_size += 2 + imsi_size;
639 }
640
641 if ((bssgp_msg_size % 4) != 0) {
642 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
643 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
644 msg[bssgp_msg_size + 1] = 0x80 | abytes;
645 memset(msg + bssgp_msg_size + 2, 0, abytes);
646 bssgp_msg_size += 2 + abytes;
647 }
648
649 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
650 if (llc_msg_size < 128) {
651 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
652 bssgp_msg_size += 2;
653 } else {
654 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
655 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
656 bssgp_msg_size += 3;
657 }
658 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
659 bssgp_msg_size += llc_msg_size;
660
661
662 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
663 src_addr, nsbvci, msg, bssgp_msg_size);
664}
665
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200666static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
667 uint16_t bvci)
668{
669 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
670 * BSSGP RESET */
Jacob Erlbeck8a600ae2014-08-06 12:38:10 +0200671 unsigned char msg[18] = {
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200672 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeck3f086322014-06-02 10:48:59 +0200673 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
674 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200675 };
676
677 msg[3] = bvci / 256;
678 msg[4] = bvci % 256;
679
Jacob Erlbeck45017722013-10-18 13:04:47 +0200680 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
681}
682
683static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
684 struct sockaddr_in *src_addr, uint16_t bvci)
685{
686 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
687 * BSSGP RESET_ACK */
688 static unsigned char msg[5] = {
689 0x23, 0x04, 0x82, 0x00,
690 0x00
691 };
692
693 msg[3] = bvci / 256;
694 msg[4] = bvci % 256;
695
696 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200697}
698
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200699static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
700 struct sockaddr_in *src_addr,
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200701 uint32_t tlli,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200702 struct gprs_ra_id *raid)
703{
704 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
705 unsigned char msg[15] = {
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200706 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
707 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200708 };
709
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200710 msg[3] = (uint8_t)(tlli >> 24);
711 msg[4] = (uint8_t)(tlli >> 16);
712 msg[5] = (uint8_t)(tlli >> 8);
713 msg[6] = (uint8_t)(tlli >> 0);
714
Max9f13b142018-01-08 14:43:53 +0100715 gsm48_encode_ra((struct gsm48_ra_id *)(msg + 9), raid);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200716
717 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
718}
719
720static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
721 struct sockaddr_in *src_addr,
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200722 uint32_t tlli,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200723 struct gprs_ra_id *raid)
724{
725 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
726 unsigned char msg[18] = {
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200727 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
728 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200729 0x81, 0x01
730 };
731
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200732 msg[3] = (uint8_t)(tlli >> 24);
733 msg[4] = (uint8_t)(tlli >> 16);
734 msg[5] = (uint8_t)(tlli >> 8);
735 msg[6] = (uint8_t)(tlli >> 0);
736
Max9f13b142018-01-08 14:43:53 +0100737 gsm48_encode_ra((struct gsm48_ra_id *)(msg + 9), raid);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200738
739 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
740}
741
Jacob Erlbeck2937b512014-08-21 16:34:18 +0200742static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
743 struct sockaddr_in *src_addr,
744 uint16_t bvci, uint32_t tlli,
745 unsigned n_frames, unsigned n_octets)
746{
747 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
748 unsigned char msg[] = {
749 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
750 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
751 /* n octets */ 0xff, 0xff, 0xff
752 };
753
754 msg[3] = (uint8_t)(tlli >> 24);
755 msg[4] = (uint8_t)(tlli >> 16);
756 msg[5] = (uint8_t)(tlli >> 8);
757 msg[6] = (uint8_t)(tlli >> 0);
758 msg[9] = (uint8_t)(n_frames);
759 msg[12] = (uint8_t)(bvci >> 8);
760 msg[13] = (uint8_t)(bvci >> 0);
761 msg[16] = (uint8_t)(n_octets >> 16);
762 msg[17] = (uint8_t)(n_octets >> 8);
763 msg[18] = (uint8_t)(n_octets >> 0);
764
765 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
766}
767
Jacob Erlbeckd5f24fd2014-09-30 13:49:43 +0200768static void send_bssgp_paging(struct gprs_ns_inst *nsi,
769 struct sockaddr_in *src_addr,
770 const uint8_t *imsi, size_t imsi_size,
771 struct gprs_ra_id *raid, uint32_t ptmsi)
772{
773 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
774 unsigned char msg[100] = {
775 0x06,
776 };
777
778 const unsigned char drx_ie[] = {0x0a, 0x82, 0x07, 0x04};
779 const unsigned char qos_ie[] = {0x18, 0x83, 0x00, 0x00, 0x00};
780
781 size_t bssgp_msg_size = 1;
782
783 if (imsi) {
784 OSMO_ASSERT(imsi_size <= 127);
785 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
786 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
787 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
788 bssgp_msg_size += 2 + imsi_size;
789 }
790
791 memcpy(msg + bssgp_msg_size, drx_ie, sizeof(drx_ie));
792 bssgp_msg_size += sizeof(drx_ie);
793
794 if (raid) {
795 msg[bssgp_msg_size] = BSSGP_IE_ROUTEING_AREA;
796 msg[bssgp_msg_size+1] = 0x86;
Max9f13b142018-01-08 14:43:53 +0100797 gsm48_encode_ra((struct gsm48_ra_id *)(msg + bssgp_msg_size + 2), raid);
Jacob Erlbeckd5f24fd2014-09-30 13:49:43 +0200798 bssgp_msg_size += 8;
799 }
800
801 memcpy(msg + bssgp_msg_size, qos_ie, sizeof(qos_ie));
802 bssgp_msg_size += sizeof(qos_ie);
803
804 if (ptmsi != GSM_RESERVED_TMSI) {
805 const uint32_t ptmsi_be = htonl(ptmsi);
806 msg[bssgp_msg_size] = BSSGP_IE_TMSI;
807 msg[bssgp_msg_size+1] = 0x84;
808 memcpy(msg + bssgp_msg_size + 2, &ptmsi_be, 4);
809 bssgp_msg_size += 6;
810 }
811
812 send_ns_unitdata(nsi, "PAGING_PS", src_addr, 0, msg, bssgp_msg_size);
813}
814
Jacob Erlbeck12356062014-08-27 12:44:25 +0200815static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
816 struct sockaddr_in *src_addr,
817 uint16_t bvci, uint8_t tag)
818{
819 /* GPRS Network Service, PDU type: NS_UNITDATA,
820 * BSSGP FLOW_CONTROL_BVC */
821 unsigned char msg[] = {
822 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
823 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
824 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
825 };
826
827 msg[3] = tag;
828
829 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
830 msg, sizeof(msg));
831}
832
833static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
834 struct sockaddr_in *src_addr,
835 uint16_t bvci, uint8_t tag)
836{
837 /* GPRS Network Service, PDU type: NS_UNITDATA,
838 * BSSGP FLOW_CONTROL_BVC_ACK */
839 unsigned char msg[] = {
840 0x27, 0x1e, 0x81, /* Tag */ 0xce
841 };
842
843 msg[3] = tag;
844
845 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
846 msg, sizeof(msg));
847}
848
Jacob Erlbeck322d9f92014-08-15 14:56:28 +0200849static void send_llc_ul_ui(
850 struct gprs_ns_inst *nsi, const char *text,
851 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
852 struct gprs_ra_id *raid, uint16_t cell_id,
853 unsigned sapi, unsigned nu,
854 const uint8_t *msg, size_t msg_size)
855{
856 unsigned char llc_msg[4096] = {
857 0x00, 0xc0, 0x01
858 };
859
860 size_t llc_msg_size = 3 + msg_size + 3;
861 uint8_t e_bit = 0;
862 uint8_t pm_bit = 1;
863 unsigned fcs;
864
865 nu &= 0x01ff;
866
867 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
868
869 llc_msg[0] = (sapi & 0x0f);
870 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
871 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
872
873 memcpy(llc_msg + 3, msg, msg_size);
874
875 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
876 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
877 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
878 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
879
880 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
881 src_addr, nsbvci, tlli, raid, cell_id,
882 llc_msg, llc_msg_size);
883}
884
885static void send_llc_dl_ui(
886 struct gprs_ns_inst *nsi, const char *text,
887 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
888 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
889 unsigned sapi, unsigned nu,
890 const uint8_t *msg, size_t msg_size)
891{
892 /* GPRS Network Service, PDU type: NS_UNITDATA */
893 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
894 unsigned char llc_msg[4096] = {
895 0x00, 0x00, 0x01
896 };
897
898 size_t llc_msg_size = 3 + msg_size + 3;
899 uint8_t e_bit = 0;
900 uint8_t pm_bit = 1;
901 unsigned fcs;
902
903 nu &= 0x01ff;
904
905 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
906
907 llc_msg[0] = 0x40 | (sapi & 0x0f);
908 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
909 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
910
911 memcpy(llc_msg + 3, msg, msg_size);
912
913 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
914 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
915 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
916 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
917
918 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
919 src_addr, nsbvci, tlli,
920 with_racap_drx, imsi, imsi_size,
921 llc_msg, llc_msg_size);
922}
923
924
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200925static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
926 uint16_t nsvci, uint16_t nsei)
927{
928 printf("Setup NS-VC: remote 0x%08x:%d, "
929 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
930 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
931 nsvci, nsvci, nsei, nsei);
932
933 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
934 send_ns_alive(nsi, src_addr);
935 send_ns_unblock(nsi, src_addr);
936 send_ns_alive_ack(nsi, src_addr);
937}
938
939static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
940 uint16_t bvci)
941{
942 printf("Setup BSSGP: remote 0x%08x:%d, "
943 "BVCI 0x%04x(%d)\n\n",
944 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
945 bvci, bvci);
946
947 send_bssgp_reset(nsi, src_addr, bvci);
948}
949
Jacob Erlbeck12356062014-08-27 12:44:25 +0200950static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
951 uint32_t sgsn_nsei)
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200952{
Jacob Erlbeck12356062014-08-27 12:44:25 +0200953 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
954 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200955 send_ns_alive_ack(nsi, sgsn_peer);
956 send_ns_unblock_ack(nsi, sgsn_peer);
957 send_ns_alive(nsi, sgsn_peer);
958}
959
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200960static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
961{
962 sgsn_peer->sin_family = AF_INET;
963 sgsn_peer->sin_port = htons(32000);
964 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
965}
966
Jacob Erlbeck12356062014-08-27 12:44:25 +0200967static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
968{
969 sgsn_peer->sin_family = AF_INET;
970 sgsn_peer->sin_port = htons(32001);
971 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
972}
973
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200974static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
975{
976 size_t i;
977
978 for (i = 0; i < size; ++i) {
979 bss_peers[i].sin_family = AF_INET;
980 bss_peers[i].sin_port = htons((i + 1) * 1111);
981 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
982 }
983}
984
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200985int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
986 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
987
988/* override */
989int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
990 struct msgb *msg, uint16_t bvci)
991{
Holger Hans Peter Freytherc3b9cf62015-08-03 09:28:41 +0200992 printf("CALLBACK, event %d, msg length %zu, bvci 0x%04x\n%s\n\n",
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200993 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200994 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200995
996 switch (event) {
997 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +0200998 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200999 default:
1000 break;
1001 }
1002 return 0;
1003}
1004
1005/* override */
1006ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
1007 const struct sockaddr *dest_addr, socklen_t addrlen)
1008{
1009 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
1010 const struct sockaddr *, socklen_t);
1011 static sendto_t real_sendto = NULL;
1012 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001013 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001014
1015 if (!real_sendto)
1016 real_sendto = dlsym(RTLD_NEXT, "sendto");
1017
1018 if (dest_host == REMOTE_BSS_ADDR)
Holger Hans Peter Freyther844f4b82015-04-23 11:55:23 -04001019 printf("MESSAGE to BSS at 0x%08x:%d, msg length %zu\n%s\n\n",
Jacob Erlbeck45017722013-10-18 13:04:47 +02001020 dest_host, dest_port,
1021 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001022 else if (dest_host == REMOTE_SGSN_ADDR)
Holger Hans Peter Freyther844f4b82015-04-23 11:55:23 -04001023 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %zu\n%s\n\n",
Jacob Erlbeck45017722013-10-18 13:04:47 +02001024 dest_host, dest_port,
1025 len, osmo_hexdump(buf, len));
Jacob Erlbeck12356062014-08-27 12:44:25 +02001026 else if (dest_host == REMOTE_SGSN2_ADDR)
Holger Hans Peter Freyther844f4b82015-04-23 11:55:23 -04001027 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %zu\n%s\n\n",
Jacob Erlbeck12356062014-08-27 12:44:25 +02001028 dest_host, dest_port,
1029 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001030 else
1031 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
1032
1033 return len;
1034}
1035
1036/* override */
1037int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
1038{
Jacob Erlbeck45017722013-10-18 13:04:47 +02001039 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
1040 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001041 uint16_t bvci = msgb_bvci(msg);
1042 uint16_t nsei = msgb_nsei(msg);
1043
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001044 size_t len = msgb_length(msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001045
Jacob Erlbeck45017722013-10-18 13:04:47 +02001046 if (!real_gprs_ns_sendmsg)
1047 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
1048
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001049 if (nsei == SGSN_NSEI)
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001050 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
Holger Hans Peter Freyther844f4b82015-04-23 11:55:23 -04001051 "msg length %zu (%s)\n",
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001052 bvci, len, __func__);
Jacob Erlbeck12356062014-08-27 12:44:25 +02001053 else if (nsei == SGSN2_NSEI)
1054 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
Holger Hans Peter Freyther844f4b82015-04-23 11:55:23 -04001055 "msg length %zu (%s)\n",
Jacob Erlbeck12356062014-08-27 12:44:25 +02001056 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001057 else
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001058 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
Holger Hans Peter Freyther844f4b82015-04-23 11:55:23 -04001059 "msg length %zu (%s)\n",
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001060 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001061
Jacob Erlbecka4b5e892014-09-22 18:54:34 +02001062 if (received_messages) {
1063 struct msgb *msg_copy;
1064 msg_copy = gprs_msgb_copy(msg, "received_messages");
1065 llist_add_tail(&msg_copy->list, received_messages);
1066 }
1067
Jacob Erlbeck45017722013-10-18 13:04:47 +02001068 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001069}
1070
Jacob Erlbecka4b5e892014-09-22 18:54:34 +02001071/* Get the next message from the receive FIFO
1072 *
1073 * \returns a pointer to the message which will be invalidated at the next call
1074 * to expect_msg. Returns NULL, if there is no message left.
1075 */
1076static struct msgb *expect_msg(void)
1077{
1078 static struct msgb *msg = NULL;
1079
1080 msgb_free(msg);
1081 msg = NULL;
1082
1083 if (!received_messages)
1084 return NULL;
1085
1086 if (llist_empty(received_messages))
1087 return NULL;
1088
1089 msg = llist_entry(received_messages->next, struct msgb, list);
1090 llist_del(&msg->list);
1091
1092 return msg;
1093}
1094
1095struct expect_result {
1096 struct msgb *msg;
1097 struct gprs_gb_parse_context parse_ctx;
1098};
1099
1100static struct expect_result *expect_bssgp_msg(
1101 int match_nsei, int match_bvci, int match_pdu_type)
1102{
1103 static struct expect_result result;
1104 static const struct expect_result empty_result = {0,};
1105 static struct msgb *msg;
1106 uint16_t nsei;
1107 int rc;
1108
1109 memcpy(&result, &empty_result, sizeof(result));
1110
1111 msg = expect_msg();
1112 if (!msg)
1113 return NULL;
1114
1115 nsei = msgb_nsei(msg);
1116
1117 if (match_nsei != MATCH_ANY && match_nsei != nsei) {
1118 fprintf(stderr, "%s: NSEI mismatch (expected %u, got %u)\n",
1119 __func__, match_nsei, nsei);
1120 return NULL;
1121 }
1122
1123 if (match_bvci != MATCH_ANY && match_bvci != msgb_bvci(msg)) {
1124 fprintf(stderr, "%s: BVCI mismatch (expected %u, got %u)\n",
1125 __func__, match_bvci, msgb_bvci(msg));
1126 return NULL;
1127 }
1128
1129 result.msg = msg;
1130
1131 result.parse_ctx.to_bss = nsei != SGSN_NSEI && nsei != SGSN2_NSEI;
1132 result.parse_ctx.peer_nsei = nsei;
1133
1134 if (!msgb_bssgph(msg)) {
1135 fprintf(stderr, "%s: Expected BSSGP\n", __func__);
1136 return NULL;
1137 }
1138
1139 rc = gprs_gb_parse_bssgp(msgb_bssgph(msg), msgb_bssgp_len(msg),
1140 &result.parse_ctx);
1141
1142 if (!rc) {
1143 fprintf(stderr, "%s: Failed to parse message\n", __func__);
1144 return NULL;
1145 }
1146
1147 if (match_pdu_type != MATCH_ANY &&
1148 match_pdu_type != result.parse_ctx.pdu_type) {
1149 fprintf(stderr, "%s: PDU type mismatch (expected %u, got %u)\n",
1150 __func__, match_pdu_type, result.parse_ctx.pdu_type);
1151 return NULL;
1152 }
1153
1154 return &result;
1155}
1156
1157static struct expect_result *expect_llc_msg(
1158 int match_nsei, int match_bvci, int match_sapi, int match_type)
1159{
1160 static struct expect_result *result;
1161
1162 result = expect_bssgp_msg(match_nsei, match_bvci, MATCH_ANY);
1163 if (!result)
1164 return NULL;
1165
1166 if (!result->parse_ctx.llc) {
1167 fprintf(stderr, "%s: Expected LLC message\n", __func__);
1168 return NULL;
1169 }
1170
1171 if (match_sapi != MATCH_ANY &&
1172 match_sapi != result->parse_ctx.llc_hdr_parsed.sapi) {
1173 fprintf(stderr, "%s: LLC SAPI mismatch (expected %u, got %u)\n",
1174 __func__, match_sapi, result->parse_ctx.llc_hdr_parsed.sapi);
1175 return NULL;
1176 }
1177
1178 if (match_type != MATCH_ANY &&
1179 match_type != result->parse_ctx.llc_hdr_parsed.cmd) {
1180 fprintf(stderr,
1181 "%s: LLC command/type mismatch (expected %u, got %u)\n",
1182 __func__, match_type, result->parse_ctx.llc_hdr_parsed.cmd);
1183 return NULL;
1184 }
1185
1186 return result;
1187}
1188
1189static struct expect_result *expect_gmm_msg(int match_nsei, int match_bvci,
1190 int match_type)
1191{
1192 static struct expect_result *result;
1193
1194 result = expect_llc_msg(match_nsei, match_bvci, GPRS_SAPI_GMM, GPRS_LLC_UI);
1195 if (!result)
1196 return NULL;
1197
1198 if (!result->parse_ctx.g48_hdr) {
1199 fprintf(stderr, "%s: Expected GSM 04.08 message\n", __func__);
1200 return NULL;
1201 }
1202
1203 if (match_type != MATCH_ANY &&
1204 match_type != result->parse_ctx.g48_hdr->msg_type) {
1205 fprintf(stderr,
1206 "%s: GSM 04.08 message type mismatch (expected %u, got %u)\n",
1207 __func__, match_type, result->parse_ctx.g48_hdr->msg_type);
1208 return NULL;
1209 }
1210
1211 return result;
1212}
1213
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001214static void dump_rate_ctr_group(FILE *stream, const char *prefix,
1215 struct rate_ctr_group *ctrg)
1216{
1217 unsigned int i;
1218
1219 for (i = 0; i < ctrg->desc->num_ctr; i++) {
1220 struct rate_ctr *ctr = &ctrg->ctr[i];
1221 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
1222 fprintf(stream, " %s%s: %llu%s",
1223 prefix, ctrg->desc->ctr_desc[i].description,
1224 (long long)ctr->current,
1225 "\n");
1226 };
1227}
1228
1229/* Signal handler for signals from NS layer */
1230static int test_signal(unsigned int subsys, unsigned int signal,
1231 void *handler_data, void *signal_data)
1232{
1233 struct ns_signal_data *nssd = signal_data;
1234 int rc;
1235
1236 if (subsys != SS_L_NS)
1237 return 0;
1238
1239 switch (signal) {
1240 case S_NS_RESET:
1241 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
1242 nssd->nsvc->nsvci,
1243 gprs_ns_ll_str(nssd->nsvc));
1244 break;
1245
1246 case S_NS_ALIVE_EXP:
1247 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
1248 nssd->nsvc->nsvci,
1249 gprs_ns_ll_str(nssd->nsvc));
1250 break;
1251
1252 case S_NS_BLOCK:
1253 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
1254 nssd->nsvc->nsvci,
1255 gprs_ns_ll_str(nssd->nsvc));
1256 break;
1257
1258 case S_NS_UNBLOCK:
1259 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
1260 nssd->nsvc->nsvci,
1261 gprs_ns_ll_str(nssd->nsvc));
1262 break;
1263
1264 case S_NS_REPLACED:
1265 printf("==> got signal NS_REPLACED: 0x%04x/%s",
1266 nssd->nsvc->nsvci,
1267 gprs_ns_ll_str(nssd->nsvc));
1268 printf(" -> 0x%04x/%s\n",
1269 nssd->old_nsvc->nsvci,
1270 gprs_ns_ll_str(nssd->old_nsvc));
1271 break;
1272
1273 default:
1274 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
1275 nssd->nsvc->nsvci,
1276 gprs_ns_ll_str(nssd->nsvc));
1277 break;
1278 }
1279 printf("\n");
1280 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
1281 return rc;
1282}
1283
1284static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
1285{
1286 struct msgb *msg;
1287 int ret;
1288 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
Holger Hans Peter Freyther844f4b82015-04-23 11:55:23 -04001289 fprintf(stderr, "message too long: %zu\n", data_len);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001290 return -1;
1291 }
1292
1293 msg = gprs_ns_msgb_alloc();
Neels Hofmeyrc871c852016-04-14 15:21:33 +02001294 OSMO_ASSERT(msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001295 memmove(msg->data, data, data_len);
1296 msg->l2h = msg->data;
1297 msgb_put(msg, data_len);
1298
1299 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
1300 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1301 osmo_hexdump(data, data_len));
1302
1303 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
1304
1305 printf("result (%s) = %d\n\n", text, ret);
1306
1307 msgb_free(msg);
1308
1309 return ret;
1310}
1311
1312static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
1313{
1314 struct gprs_nsvc *nsvc;
1315
1316 printf("Current NS-VCIs:\n");
1317 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1318 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001319 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001320 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck45017722013-10-18 13:04:47 +02001321 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1322 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1323 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001324 );
1325 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1326 }
1327 printf("\n");
1328}
1329
1330static void test_gbproxy()
1331{
1332 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1333 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck45017722013-10-18 13:04:47 +02001334 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001335
1336 bssgp_nsi = nsi;
1337 gbcfg.nsi = bssgp_nsi;
1338 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1339
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001340 configure_sgsn_peer(&sgsn_peer);
1341 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001342
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001343 printf("=== %s ===\n", __func__);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001344 printf("--- Initialise SGSN ---\n\n");
1345
Jacob Erlbeck12356062014-08-27 12:44:25 +02001346 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001347 gprs_dump_nsi(nsi);
1348
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001349 printf("--- Initialise BSS 1 ---\n\n");
1350
1351 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1352 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1353 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001354 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001355
Jacob Erlbeck45017722013-10-18 13:04:47 +02001356 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1357
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001358 printf("--- Initialise BSS 2 ---\n\n");
1359
1360 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1361 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1362 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001363 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001364
Jacob Erlbeck45017722013-10-18 13:04:47 +02001365 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1366
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001367 printf("--- Move BSS 1 to new port ---\n\n");
1368
1369 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1370 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001371 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001372
1373 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1374
1375 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1376 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001377 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001378
1379 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1380
1381 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1382 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001383 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001384
1385 printf("--- Move BSS 2 to new port ---\n\n");
1386
1387 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1388 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001389 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001390
1391 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1392
1393 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1394 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001395 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001396
Jacob Erlbeck45017722013-10-18 13:04:47 +02001397 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1398
1399 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1400 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001401 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001402
1403 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1404
1405 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1406 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001407 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001408
1409 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1410
1411 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1412
1413 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1414 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001415 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001416
1417 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1418
1419 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1420
1421 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1422 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001423 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001424
1425 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1426
1427 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1428
1429 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1430
1431 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1432
1433 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1434
1435 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1436
1437 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1438
1439 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1440
1441 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1442
1443 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1444
1445 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1446
1447 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1448
1449 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1450
1451 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1452
1453 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1454 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001455 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +02001456
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001457 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001458
Jacob Erlbeck45017722013-10-18 13:04:47 +02001459 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1460
1461 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1462
1463 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1464
1465 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1466
1467 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1468
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001469 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1470
1471 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1472
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02001473 /* Find peer */
1474 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1475 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1476 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1477 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1478 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1479 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1480
1481
1482 /* Cleanup */
1483 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1484 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1485 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1486 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1487 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1488
1489 dump_peers(stdout, 0, 0, &gbcfg);
1490
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001491 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +02001492
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001493 gbprox_reset(&gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001494 gprs_ns_destroy(nsi);
1495 nsi = NULL;
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001496}
1497
1498static void test_gbproxy_ident_changes()
1499{
1500 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1501 struct sockaddr_in bss_peer[1] = {{0},};
1502 struct sockaddr_in sgsn_peer= {0};
1503 uint16_t nsei[2] = {0x1000, 0x2000};
1504 uint16_t nsvci[2] = {0x1001, 0x2001};
1505 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1506
1507 bssgp_nsi = nsi;
1508 gbcfg.nsi = bssgp_nsi;
1509 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1510
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001511 configure_sgsn_peer(&sgsn_peer);
1512 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001513
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001514 printf("=== %s ===\n", __func__);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001515 printf("--- Initialise SGSN ---\n\n");
1516
Jacob Erlbeck12356062014-08-27 12:44:25 +02001517 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001518 gprs_dump_nsi(nsi);
1519
1520 printf("--- Initialise BSS 1 ---\n\n");
1521
1522 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1523 gprs_dump_nsi(nsi);
1524
1525 printf("--- Setup BVCI 1 ---\n\n");
1526
1527 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1528 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001529 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001530
1531 printf("--- Setup BVCI 2 ---\n\n");
1532
1533 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1534 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001535 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001536
1537 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1538
1539 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1540 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1541
1542 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1543
1544 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1545 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1546
1547 printf("--- Change NSEI ---\n\n");
1548
1549 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1550 gprs_dump_nsi(nsi);
1551
1552 printf("--- Setup BVCI 1 ---\n\n");
1553
1554 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1555 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001556 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001557
1558 printf("--- Setup BVCI 3 ---\n\n");
1559
1560 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1561 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001562 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001563
1564 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1565
1566 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1567 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1568
1569 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1570 " (should fail) ---\n\n");
1571
1572 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001573 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001574 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001575 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001576
1577 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1578
1579 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1580 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1581
1582 printf("--- Change NSVCI ---\n\n");
1583
1584 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1585 gprs_dump_nsi(nsi);
1586
1587 printf("--- Setup BVCI 1 ---\n\n");
1588
1589 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1590 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001591 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001592
1593 printf("--- Setup BVCI 4 ---\n\n");
1594
1595 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1596 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001597 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001598
1599 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1600
1601 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1602 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1603
1604 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1605 " (should fail) ---\n\n");
1606
1607 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001608 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001609 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001610 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001611
1612 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1613
1614 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1615 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1616
1617 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1618
1619 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1620 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1621
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001622 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001623 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001624
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001625 gbprox_reset(&gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001626 gprs_ns_destroy(nsi);
1627 nsi = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001628}
1629
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001630static void test_gbproxy_ra_patching()
1631{
1632 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1633 struct sockaddr_in bss_peer[1] = {{0},};
1634 struct sockaddr_in sgsn_peer= {0};
1635 struct gprs_ra_id rai_bss =
1636 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1637 struct gprs_ra_id rai_sgsn =
1638 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1639 struct gprs_ra_id rai_unknown =
1640 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001641 uint16_t cell_id = 0x7530;
Jacob Erlbeck43037632014-06-06 18:49:23 +02001642 const char *err_msg = NULL;
Jacob Erlbeck31132872014-08-11 17:26:21 +02001643 const uint32_t ptmsi = 0xefe2b700;
1644 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001645 const uint32_t foreign_tlli = 0xbbc54679;
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02001646 const uint32_t foreign_tlli2 = 0xbb00beef;
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001647 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02001648 const char *patch_re = "^9898|^121314";
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001649 struct gbproxy_link_info *link_info;
Jacob Erlbeck31132872014-08-11 17:26:21 +02001650 struct gbproxy_peer *peer;
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001651 LLIST_HEAD(rcv_list);
Jacob Erlbeck4c70e712014-10-10 09:48:12 +02001652 struct expect_result *expect_res;
Jacob Erlbeck31132872014-08-11 17:26:21 +02001653
1654 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001655
1656 bssgp_nsi = nsi;
1657 gbcfg.nsi = bssgp_nsi;
1658 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +01001659 gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +02001660 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freyther2d10ad12014-08-04 14:22:13 +02001661 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck383c8412014-08-12 16:30:30 +02001662 gbcfg.patch_ptmsi = 0;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001663
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +02001664 configure_sgsn_peer(&sgsn_peer);
1665 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001666
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02001667 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING],
1668 patch_re, &err_msg) != 0) {
Jacob Erlbeck43037632014-06-06 18:49:23 +02001669 fprintf(stderr, "Failed to compile RE '%s': %s\n",
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02001670 patch_re, err_msg);
Jacob Erlbeck43037632014-06-06 18:49:23 +02001671 exit(1);
1672 }
1673
1674
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001675 printf("=== %s ===\n", __func__);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001676 printf("--- Initialise SGSN ---\n\n");
1677
Jacob Erlbeck12356062014-08-27 12:44:25 +02001678 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001679 gprs_dump_nsi(nsi);
1680
1681 printf("--- Initialise BSS 1 ---\n\n");
1682
1683 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001684
1685 received_messages = &rcv_list;
1686
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001687 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1688 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001689 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001690
Jacob Erlbeck040fabc2014-08-21 10:01:30 +02001691 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001692 OSMO_ASSERT(peer != NULL);
1693
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001694 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_BVC_RESET));
1695
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001696 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1697
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001698 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_BVC_RESET_ACK));
1699
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001700 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001701
1702 OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_SUSPEND));
1703
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001704 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001705
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001706 OSMO_ASSERT(expect_bssgp_msg(0x1000, 0, BSSGP_PDUT_SUSPEND_ACK));
1707
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001708 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001709 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001710
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001711 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1712 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1713
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001714 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1715
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001716 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1717 foreign_tlli, &rai_bss, cell_id,
1718 GPRS_SAPI_GMM, 0,
1719 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001720
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001721 OSMO_ASSERT(4 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001722 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001723
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001724 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1725 foreign_tlli, 0, NULL, 0,
1726 GPRS_SAPI_GMM, 0,
1727 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +02001728
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001729 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
1730
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001731 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1732 foreign_tlli, &rai_bss, cell_id,
1733 GPRS_SAPI_GMM, 3,
1734 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +02001735
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001736 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
1737
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001738 OSMO_ASSERT(5 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1739 OSMO_ASSERT(1 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1740
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001741 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1742 foreign_tlli, 1, imsi, sizeof(imsi),
1743 GPRS_SAPI_GMM, 1,
1744 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001745
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001746 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
1747
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001748 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1749
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02001750 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1751 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1752 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1753
1754 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1755 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1756 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1757
1758 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1759 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1760 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1761
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001762 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1763 OSMO_ASSERT(link_info);
1764 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1765 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1766 OSMO_ASSERT(!link_info->tlli.bss_validated);
1767 OSMO_ASSERT(!link_info->tlli.net_validated);
1768 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1769 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1770 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
1771 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001772
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001773 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1774 local_tlli, &rai_bss, cell_id,
1775 GPRS_SAPI_GMM, 4,
1776 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck31132872014-08-11 17:26:21 +02001777
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001778 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
1779
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001780 OSMO_ASSERT(6 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1781
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001782 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1783 OSMO_ASSERT(link_info);
1784 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1785 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1786 OSMO_ASSERT(link_info->tlli.bss_validated);
1787 OSMO_ASSERT(!link_info->tlli.net_validated);
1788 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1789 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1790 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1791 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001792
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001793 /* Replace APN (1) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001794 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1795 local_tlli, &rai_bss, cell_id,
1796 GPRS_SAPI_GMM, 3,
1797 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001798
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001799 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1800
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001801 OSMO_ASSERT(7 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1802
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001803 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1804 OSMO_ASSERT(link_info);
1805 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
1806 OSMO_ASSERT(link_info->tlli.current != local_tlli);
1807 OSMO_ASSERT(link_info->tlli.bss_validated);
1808 OSMO_ASSERT(!link_info->tlli.net_validated);
1809 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_tlli);
1810 OSMO_ASSERT(link_info->sgsn_tlli.current != local_tlli);
1811 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
1812 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001813
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001814 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1815 local_tlli, 1, imsi, sizeof(imsi),
1816 GPRS_SAPI_GMM, 2,
1817 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeckab7366f2014-06-06 18:47:36 +02001818
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001819 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
1820
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001821 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1822
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001823 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
1824 OSMO_ASSERT(link_info);
1825 OSMO_ASSERT(link_info->tlli.assigned == 0);
1826 OSMO_ASSERT(link_info->tlli.current == local_tlli);
1827 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
1828 OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck31132872014-08-11 17:26:21 +02001829
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001830 /* Replace APN (2) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001831 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1832 local_tlli, &rai_bss, cell_id,
1833 GPRS_SAPI_GMM, 3,
1834 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001835
Jacob Erlbeck4c70e712014-10-10 09:48:12 +02001836 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1837 OSMO_ASSERT(expect_res != NULL);
1838 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == gbcfg.core_apn_size + 2);
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001839
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001840 OSMO_ASSERT(8 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1841
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +02001842 gbcfg.core_apn[0] = 0;
1843 gbcfg.core_apn_size = 0;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001844
1845 /* Remove APN */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001846 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1847 local_tlli, &rai_bss, cell_id,
1848 GPRS_SAPI_GMM, 3,
1849 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001850
Jacob Erlbeck4c70e712014-10-10 09:48:12 +02001851 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1852 OSMO_ASSERT(expect_res != NULL);
1853 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0);
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001854
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001855 OSMO_ASSERT(9 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1856
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001857 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001858
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001859 /* Detach */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001860 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1861 local_tlli, &rai_bss, cell_id,
1862 GPRS_SAPI_GMM, 6,
1863 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001864
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001865 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1866
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001867 OSMO_ASSERT(10 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1868 OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1869
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001870 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1871 local_tlli, 1, imsi, sizeof(imsi),
1872 GPRS_SAPI_GMM, 5,
1873 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001874
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001875 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
1876
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001877 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001878
1879 printf("--- RA update ---\n\n");
1880
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001881 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1882 foreign_tlli, &rai_bss, 0x7080,
1883 GPRS_SAPI_GMM, 5,
1884 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001885
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001886 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
1887
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001888 OSMO_ASSERT(12 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1889
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001890 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1891 foreign_tlli, 1, imsi, sizeof(imsi),
1892 GPRS_SAPI_GMM, 6,
1893 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001894
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001895 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_ACK));
1896
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001897 OSMO_ASSERT(3 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
1898
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001899 /* Remove APN */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001900 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1901 local_tlli, &rai_bss, cell_id,
1902 GPRS_SAPI_GMM, 3,
1903 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001904
Jacob Erlbeck4c70e712014-10-10 09:48:12 +02001905 expect_res = expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ);
1906 OSMO_ASSERT(expect_res != NULL);
1907 OSMO_ASSERT(expect_res->parse_ctx.apn_ie_len == 0);
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001908
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001909 OSMO_ASSERT(13 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1910
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001911 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001912
Jacob Erlbeckf95340d2014-08-11 15:07:37 +02001913 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001914 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1915 local_tlli, &rai_bss, cell_id,
1916 GPRS_SAPI_GMM, 6,
1917 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001918
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001919 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
1920
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001921 OSMO_ASSERT(14 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1922
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001923 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001924 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001925
1926 printf("--- Bad cases ---\n\n");
1927
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02001928 /* The RAI in the Attach Request message differs from the RAI in the
1929 * BSSGP message, only patch the latter */
1930
1931 send_llc_ul_ui(nsi, "ATTACH REQUEST (foreign RAI)", &bss_peer[0], 0x1002,
1932 foreign_tlli2, &rai_bss, cell_id,
1933 GPRS_SAPI_GMM, 0,
1934 dtap_attach_req2, sizeof(dtap_attach_req2));
1935
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001936 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
1937
Jacob Erlbeck550898a2014-09-11 15:22:18 +02001938 OSMO_ASSERT(15 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_BSS].current);
1939
Jacob Erlbeck43037632014-06-06 18:49:23 +02001940 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeck322d9f92014-08-15 14:56:28 +02001941 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1942 local_tlli, &rai_bss, cell_id,
1943 GPRS_SAPI_GMM, 3,
1944 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001945
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001946 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GSM_ACT_PDP_REQ));
1947
Jacob Erlbeck90a1fd12014-05-27 13:49:04 +02001948 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck2937b512014-08-21 16:34:18 +02001949 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001950
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001951 /* TODO: The following breaks with the current libosmocore, enable it
1952 * again (and remove the plain expect_msg), when the msgb_bssgph patch
1953 * is integrated */
1954 /* OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_STATUS)); */
1955 OSMO_ASSERT(expect_msg());
1956
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001957 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001958 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001959
Jacob Erlbecke4b5f382014-09-23 14:56:38 +02001960 OSMO_ASSERT(!expect_msg());
1961 received_messages = NULL;
1962
Jacob Erlbeck8fbf44a2014-09-25 11:21:34 +02001963 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_PATCHING]);
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001964 gbprox_reset(&gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001965 gprs_ns_destroy(nsi);
1966 nsi = NULL;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001967}
1968
Jacob Erlbeck571aec32014-09-18 09:21:20 +02001969static void test_gbproxy_ptmsi_assignment()
1970{
1971 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1972 struct sockaddr_in bss_peer[1] = {{0},};
1973 struct sockaddr_in sgsn_peer= {0};
1974 struct gprs_ra_id rai_bss =
1975 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1976 struct gprs_ra_id rai_unknown =
1977 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1978 uint16_t cell_id = 0x1234;
1979
1980 const uint32_t ptmsi = 0xefe2b700;
1981 const uint32_t local_tlli = 0xefe2b700;
1982
1983 const uint32_t foreign_tlli1 = 0x8000dead;
1984 const uint32_t foreign_tlli2 = 0x8000beef;
1985
1986 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1987 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
1988
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02001989 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck571aec32014-09-18 09:21:20 +02001990 struct gbproxy_peer *peer;
1991 unsigned bss_nu = 0;
1992 unsigned sgsn_nu = 0;
1993
1994 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
1995
1996 bssgp_nsi = nsi;
1997 gbcfg.nsi = bssgp_nsi;
1998 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +01001999 gbcfg.core_plmn = (struct osmo_plmn_id){};
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002000 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2001 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2002 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002003
2004 configure_sgsn_peer(&sgsn_peer);
2005 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2006
2007 printf("=== %s ===\n", __func__);
2008 printf("--- Initialise SGSN ---\n\n");
2009
2010 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
2011
2012 printf("--- Initialise BSS 1 ---\n\n");
2013
2014 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2015 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2016
2017 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2018 OSMO_ASSERT(peer != NULL);
2019
2020 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2021
2022 gprs_dump_nsi(nsi);
2023 dump_global(stdout, 0);
2024 dump_peers(stdout, 0, 0, &gbcfg);
2025
2026 printf("--- Establish first LLC connection ---\n\n");
2027
2028 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2029 foreign_tlli1, &rai_unknown, cell_id,
2030 GPRS_SAPI_GMM, bss_nu++,
2031 dtap_attach_req, sizeof(dtap_attach_req));
2032
2033 dump_peers(stdout, 0, 0, &gbcfg);
2034
2035 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2036 foreign_tlli1, 0, NULL, 0,
2037 GPRS_SAPI_GMM, sgsn_nu++,
2038 dtap_identity_req, sizeof(dtap_identity_req));
2039
2040 dump_peers(stdout, 0, 0, &gbcfg);
2041
2042 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2043 foreign_tlli1, &rai_bss, cell_id,
2044 GPRS_SAPI_GMM, bss_nu++,
2045 dtap_identity_resp, sizeof(dtap_identity_resp));
2046
2047 dump_peers(stdout, 0, 0, &gbcfg);
2048
2049 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2050 foreign_tlli1, 1, imsi1, sizeof(imsi1),
2051 GPRS_SAPI_GMM, sgsn_nu++,
2052 dtap_attach_acc, sizeof(dtap_attach_acc));
2053
2054 dump_peers(stdout, 0, 0, &gbcfg);
2055
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002056 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli1);
2057 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2058 OSMO_ASSERT(link_info);
2059 OSMO_ASSERT(link_info == link_info2);
2060 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2061 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
2062 OSMO_ASSERT(!link_info->tlli.bss_validated);
2063 OSMO_ASSERT(!link_info->tlli.net_validated);
2064 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002065
2066 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2067 local_tlli, &rai_bss, cell_id,
2068 GPRS_SAPI_GMM, bss_nu++,
2069 dtap_attach_complete, sizeof(dtap_attach_complete));
2070
2071 dump_peers(stdout, 0, 0, &gbcfg);
2072
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002073 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2074 OSMO_ASSERT(link_info);
2075 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2076 OSMO_ASSERT(link_info->tlli.current == foreign_tlli1);
2077 OSMO_ASSERT(link_info->tlli.bss_validated);
2078 OSMO_ASSERT(!link_info->tlli.net_validated);
2079 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002080
2081
2082 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2083 local_tlli, 1, imsi1, sizeof(imsi1),
2084 GPRS_SAPI_GMM, sgsn_nu++,
2085 dtap_gmm_information, sizeof(dtap_gmm_information));
2086
2087 dump_peers(stdout, 0, 0, &gbcfg);
2088
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002089 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
2090 OSMO_ASSERT(link_info);
2091 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2092 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2)));
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002093
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002094 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2095 OSMO_ASSERT(link_info == link_info2);
2096 OSMO_ASSERT(link_info->tlli.assigned == 0);
2097 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2098 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002099
2100 printf("--- Establish second LLC connection with the same P-TMSI ---\n\n");
2101
2102 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2103 foreign_tlli2, &rai_unknown, cell_id,
2104 GPRS_SAPI_GMM, bss_nu++,
2105 dtap_attach_req, sizeof(dtap_attach_req));
2106
2107 dump_peers(stdout, 0, 0, &gbcfg);
2108
2109 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2110 foreign_tlli2, 0, NULL, 0,
2111 GPRS_SAPI_GMM, sgsn_nu++,
2112 dtap_identity_req, sizeof(dtap_identity_req));
2113
2114 dump_peers(stdout, 0, 0, &gbcfg);
2115
2116 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2117 foreign_tlli2, &rai_bss, cell_id,
2118 GPRS_SAPI_GMM, bss_nu++,
2119 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2120
2121 dump_peers(stdout, 0, 0, &gbcfg);
2122
2123 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2124 foreign_tlli2, 1, imsi2, sizeof(imsi2),
2125 GPRS_SAPI_GMM, sgsn_nu++,
2126 dtap_attach_acc, sizeof(dtap_attach_acc));
2127
2128 dump_peers(stdout, 0, 0, &gbcfg);
2129
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002130 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli2);
2131 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2132 OSMO_ASSERT(link_info);
2133 OSMO_ASSERT(link_info == link_info2);
2134 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2135 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2136 OSMO_ASSERT(!link_info->tlli.bss_validated);
2137 OSMO_ASSERT(!link_info->tlli.net_validated);
2138 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002139
2140 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2141 local_tlli, &rai_bss, cell_id,
2142 GPRS_SAPI_GMM, bss_nu++,
2143 dtap_attach_complete, sizeof(dtap_attach_complete));
2144
2145 dump_peers(stdout, 0, 0, &gbcfg);
2146
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002147 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
2148 OSMO_ASSERT(link_info);
2149 OSMO_ASSERT(link_info->tlli.assigned == local_tlli);
2150 OSMO_ASSERT(link_info->tlli.current == foreign_tlli2);
2151 OSMO_ASSERT(link_info->tlli.bss_validated);
2152 OSMO_ASSERT(!link_info->tlli.net_validated);
2153 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002154
2155 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2156 local_tlli, 1, imsi2, sizeof(imsi2),
2157 GPRS_SAPI_GMM, sgsn_nu++,
2158 dtap_gmm_information, sizeof(dtap_gmm_information));
2159
2160 dump_peers(stdout, 0, 0, &gbcfg);
2161
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002162 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
2163 OSMO_ASSERT(link_info);
2164 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
2165 OSMO_ASSERT(!gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1)));
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002166
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002167 link_info2 = gbproxy_link_info_by_tlli(peer, local_tlli);
2168 OSMO_ASSERT(link_info == link_info2);
2169 OSMO_ASSERT(link_info->tlli.assigned == 0);
2170 OSMO_ASSERT(link_info->tlli.current == local_tlli);
2171 OSMO_ASSERT(link_info->tlli.ptmsi == ptmsi);
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002172
2173 dump_global(stdout, 0);
2174
2175 gbprox_reset(&gbcfg);
2176 gprs_ns_destroy(nsi);
2177 nsi = NULL;
Daniel Willmann1e0b0002015-10-12 19:36:34 +02002178
2179 cleanup_test();
Jacob Erlbeck571aec32014-09-18 09:21:20 +02002180}
2181
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002182static void test_gbproxy_ptmsi_patching()
2183{
2184 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2185 struct sockaddr_in bss_peer[1] = {{0},};
2186 struct sockaddr_in sgsn_peer= {0};
2187 struct gprs_ra_id rai_bss =
2188 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2189 struct gprs_ra_id rai_sgsn =
2190 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002191 struct gprs_ra_id rai_wrong_mcc_sgsn =
2192 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002193 struct gprs_ra_id rai_unknown =
2194 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2195 uint16_t cell_id = 0x1234;
2196
2197 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002198 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2199 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002200 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002201 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2202 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Daniel Willmann2b10af32015-10-12 19:36:35 +02002203 const uint32_t random_sgsn_tlli = 0x78dead00;
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02002204 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002205
Daniel Willmann2b10af32015-10-12 19:36:35 +02002206 const uint32_t bss_ptmsi = 0xc0dead01;
2207 const uint32_t bss_ptmsi2 = 0xc0dead02;
2208 const uint32_t bss_ptmsi3 = 0xc0dead03;
2209 const uint32_t local_bss_tlli = 0xc0dead01;
2210 const uint32_t local_bss_tlli2 = 0xc0dead02;
2211 const uint32_t local_bss_tlli3 = 0xc0dead03;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002212 const uint32_t foreign_bss_tlli = 0x8000dead;
2213
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02002214
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002215 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002216 struct gbproxy_link_info *link_info;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002217 struct gbproxy_peer *peer;
2218 unsigned bss_nu = 0;
2219 unsigned sgsn_nu = 0;
Jacob Erlbeckd5f24fd2014-09-30 13:49:43 +02002220 int old_ctr;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002221
2222 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002223 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2224 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
2225 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2226 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
2227 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002228
2229 bssgp_nsi = nsi;
2230 gbcfg.nsi = bssgp_nsi;
2231 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +01002232 gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002233 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2234 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2235 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002236
2237 configure_sgsn_peer(&sgsn_peer);
2238 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2239
2240 printf("=== %s ===\n", __func__);
2241 printf("--- Initialise SGSN ---\n\n");
2242
Jacob Erlbeck12356062014-08-27 12:44:25 +02002243 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002244
2245 printf("--- Initialise BSS 1 ---\n\n");
2246
2247 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2248 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2249
Jacob Erlbeck040fabc2014-08-21 10:01:30 +02002250 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002251 OSMO_ASSERT(peer != NULL);
2252
2253 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2254
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002255 gprs_dump_nsi(nsi);
2256 dump_global(stdout, 0);
2257 dump_peers(stdout, 0, 0, &gbcfg);
2258
2259 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2260
2261 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2262 foreign_bss_tlli, &rai_unknown, cell_id,
2263 GPRS_SAPI_GMM, bss_nu++,
2264 dtap_attach_req, sizeof(dtap_attach_req));
2265
2266 dump_peers(stdout, 0, 0, &gbcfg);
2267
2268 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2269 random_sgsn_tlli, 0, NULL, 0,
2270 GPRS_SAPI_GMM, sgsn_nu++,
2271 dtap_identity_req, sizeof(dtap_identity_req));
2272
2273 dump_peers(stdout, 0, 0, &gbcfg);
2274
2275 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2276 foreign_bss_tlli, &rai_bss, cell_id,
2277 GPRS_SAPI_GMM, bss_nu++,
2278 dtap_identity_resp, sizeof(dtap_identity_resp));
2279
2280 dump_peers(stdout, 0, 0, &gbcfg);
2281
2282 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2283 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2284 GPRS_SAPI_GMM, sgsn_nu++,
2285 dtap_attach_acc, sizeof(dtap_attach_acc));
2286
2287 dump_peers(stdout, 0, 0, &gbcfg);
2288
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002289 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2290 OSMO_ASSERT(link_info);
2291 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2292 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2293 OSMO_ASSERT(!link_info->tlli.bss_validated);
2294 OSMO_ASSERT(!link_info->tlli.net_validated);
2295 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2296 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2297 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2298 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2299 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2300 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002301
2302 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2303 local_bss_tlli, &rai_bss, cell_id,
2304 GPRS_SAPI_GMM, bss_nu++,
2305 dtap_attach_complete, sizeof(dtap_attach_complete));
2306
2307 dump_peers(stdout, 0, 0, &gbcfg);
2308
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002309 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2310 OSMO_ASSERT(link_info);
2311 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2312 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2313 OSMO_ASSERT(link_info->tlli.bss_validated);
2314 OSMO_ASSERT(!link_info->tlli.net_validated);
2315 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2316 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2317 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2318 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002319
2320 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2321 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2322 GPRS_SAPI_GMM, sgsn_nu++,
2323 dtap_gmm_information, sizeof(dtap_gmm_information));
2324
2325 dump_peers(stdout, 0, 0, &gbcfg);
2326
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002327 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2328 OSMO_ASSERT(link_info);
2329 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2330 OSMO_ASSERT(link_info->tlli.assigned == 0);
2331 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2332 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002333
Jacob Erlbeck03e02ac2014-09-05 18:08:12 +02002334 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
2335 local_bss_tlli, &rai_bss, cell_id,
2336 GPRS_SAPI_GMM, bss_nu++,
2337 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
2338
2339 dump_peers(stdout, 0, 0, &gbcfg);
2340
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002341 /* Non-DTAP */
2342 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2343 local_bss_tlli, &rai_bss, cell_id,
2344 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2345
2346 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2347 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2348 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2349
2350 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2351 local_bss_tlli, &rai_bss, cell_id,
2352 llc_ui_ll11_dns_query_ul,
2353 sizeof(llc_ui_ll11_dns_query_ul));
2354
2355 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2356 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2357 llc_ui_ll11_dns_resp_dl,
2358 sizeof(llc_ui_ll11_dns_resp_dl));
2359
2360 dump_peers(stdout, 0, 0, &gbcfg);
2361
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002362 /* Repeated RA Update Requests */
2363 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
2364 local_bss_tlli, &rai_bss, 0x7080,
2365 GPRS_SAPI_GMM, bss_nu++,
2366 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2367
2368 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
2369 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2370 GPRS_SAPI_GMM, sgsn_nu++,
2371 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
2372
2373 dump_peers(stdout, 0, 0, &gbcfg);
2374
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002375 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) != NULL);
2376 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2377 OSMO_ASSERT(link_info);
2378 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
2379 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2380 OSMO_ASSERT(!link_info->tlli.bss_validated);
2381 OSMO_ASSERT(!link_info->tlli.net_validated);
2382 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
2383 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2384 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2385 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2386 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2387 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002388
2389 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
2390 local_bss_tlli2, &rai_bss, 0x7080,
2391 GPRS_SAPI_GMM, bss_nu++,
2392 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2393
2394 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
2395 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
2396 GPRS_SAPI_GMM, sgsn_nu++,
2397 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
2398
2399 dump_peers(stdout, 0, 0, &gbcfg);
2400
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002401 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI) == NULL);
2402 OSMO_ASSERT(gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI) != NULL);
2403 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2404 OSMO_ASSERT(link_info);
2405 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
2406 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2407 OSMO_ASSERT(!link_info->tlli.bss_validated);
2408 OSMO_ASSERT(!link_info->tlli.net_validated);
2409 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
2410 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli3);
2411 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2412 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2413 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2414 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002415
2416 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
2417 local_bss_tlli3, &rai_bss, 0x7080,
2418 GPRS_SAPI_GMM, bss_nu++,
2419 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
2420
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002421 link_info = gbproxy_link_info_by_tlli(peer, local_bss_tlli3);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002422
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002423 OSMO_ASSERT(link_info);
2424 OSMO_ASSERT(link_info->tlli.bss_validated);
2425 OSMO_ASSERT(!link_info->tlli.net_validated);
2426 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2427 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002428
2429 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2430 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
2431 GPRS_SAPI_GMM, sgsn_nu++,
2432 dtap_gmm_information, sizeof(dtap_gmm_information));
2433
2434 dump_peers(stdout, 0, 0, &gbcfg);
2435
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002436 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli3, SGSN_NSEI);
2437 OSMO_ASSERT(link_info);
2438 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
2439 OSMO_ASSERT(link_info->tlli.assigned == 0);
2440 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli3);
2441 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002442
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002443 /* Other messages */
2444 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002445 local_bss_tlli3, 1, 12);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002446
2447 dump_peers(stdout, 0, 0, &gbcfg);
2448
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002449 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002450
2451 dump_peers(stdout, 0, 0, &gbcfg);
2452
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002453 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002454
2455 dump_peers(stdout, 0, 0, &gbcfg);
2456
Jacob Erlbeckd5f24fd2014-09-30 13:49:43 +02002457 old_ctr = peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current;
2458
2459 send_bssgp_paging(nsi, &sgsn_peer, imsi, sizeof(imsi), &rai_bss, sgsn_ptmsi3);
2460
2461 dump_peers(stdout, 0, 0, &gbcfg);
2462
2463 OSMO_ASSERT(old_ctr + 1 ==
2464 peer->ctrg->ctr[GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN].current);
2465
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002466 /* Bad case: Invalid BVCI */
2467 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002468 local_bss_tlli3, 1, 12);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002469 dump_global(stdout, 0);
2470
2471 /* Bad case: Invalid RAI */
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002472 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002473
2474 dump_global(stdout, 0);
2475
2476 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002477 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002478 &rai_wrong_mcc_sgsn);
2479
2480 dump_global(stdout, 0);
2481
Jacob Erlbeckdab8a6d2014-09-04 11:08:50 +02002482 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
2483 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2484 unknown_sgsn_tlli, 1, NULL, 0,
2485 GPRS_SAPI_GMM, 2,
2486 dtap_gmm_information, sizeof(dtap_gmm_information));
2487
2488 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
2489 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2490 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
2491 GPRS_SAPI_GMM, 3,
2492 dtap_gmm_information, sizeof(dtap_gmm_information));
2493
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002494 /* Detach */
2495 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002496 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002497 GPRS_SAPI_GMM, bss_nu++,
2498 dtap_detach_req, sizeof(dtap_detach_req));
2499
2500 dump_peers(stdout, 0, 0, &gbcfg);
2501
2502 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck96f8bc12014-09-04 13:45:56 +02002503 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002504 GPRS_SAPI_GMM, sgsn_nu++,
2505 dtap_detach_acc, sizeof(dtap_detach_acc));
2506
2507 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2937b512014-08-21 16:34:18 +02002508
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002509 dump_global(stdout, 0);
2510
2511 gbprox_reset(&gbcfg);
2512 gprs_ns_destroy(nsi);
2513 nsi = NULL;
Daniel Willmann1e0b0002015-10-12 19:36:34 +02002514
2515 cleanup_test();
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02002516}
2517
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002518static void test_gbproxy_ptmsi_patching_bad_cases()
2519{
2520 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2521 struct sockaddr_in bss_peer[1] = {{0},};
2522 struct sockaddr_in sgsn_peer= {0};
2523 struct gprs_ra_id rai_bss =
2524 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2525 struct gprs_ra_id rai_unknown =
2526 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2527 uint16_t cell_id = 0x1234;
2528
2529 const uint32_t sgsn_ptmsi = 0xefe2b700;
2530 const uint32_t local_sgsn_tlli = 0xefe2b700;
Daniel Willmann2b10af32015-10-12 19:36:35 +02002531 const uint32_t random_sgsn_tlli = 0x78dead00;
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002532
Daniel Willmann2b10af32015-10-12 19:36:35 +02002533 const uint32_t bss_ptmsi = 0xc0dead01;
2534 const uint32_t local_bss_tlli = 0xc0dead01;
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002535 const uint32_t foreign_bss_tlli = 0x8000dead;
2536
2537
2538 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2539 struct gbproxy_link_info *link_info;
2540 struct gbproxy_peer *peer;
2541 unsigned bss_nu = 0;
2542 unsigned sgsn_nu = 0;
2543
2544 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2545 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
2546
2547 bssgp_nsi = nsi;
2548 gbcfg.nsi = bssgp_nsi;
2549 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +01002550 gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002551 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2552 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2553 gbcfg.patch_ptmsi = 1;
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002554
2555 configure_sgsn_peer(&sgsn_peer);
2556 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2557
2558 printf("=== %s ===\n", __func__);
2559 printf("--- Initialise SGSN ---\n\n");
2560
2561 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
2562
2563 printf("--- Initialise BSS 1 ---\n\n");
2564
2565 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2566 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2567
2568 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2569 OSMO_ASSERT(peer != NULL);
2570
2571 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2572
2573 gprs_dump_nsi(nsi);
2574 dump_global(stdout, 0);
2575 dump_peers(stdout, 0, 0, &gbcfg);
2576
2577 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2578
2579 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2580 foreign_bss_tlli, &rai_unknown, cell_id,
2581 GPRS_SAPI_GMM, bss_nu++,
2582 dtap_attach_req, sizeof(dtap_attach_req));
2583
2584 dump_peers(stdout, 0, 0, &gbcfg);
2585
2586 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2587 random_sgsn_tlli, 0, NULL, 0,
2588 GPRS_SAPI_GMM, sgsn_nu++,
2589 dtap_identity_req, sizeof(dtap_identity_req));
2590
2591 dump_peers(stdout, 0, 0, &gbcfg);
2592
2593 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2594 foreign_bss_tlli, &rai_bss, cell_id,
2595 GPRS_SAPI_GMM, bss_nu++,
2596 dtap_identity_resp, sizeof(dtap_identity_resp));
2597
2598 dump_peers(stdout, 0, 0, &gbcfg);
2599
2600 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2601 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2602 GPRS_SAPI_GMM, sgsn_nu++,
2603 dtap_attach_acc, sizeof(dtap_attach_acc));
2604
2605 dump_peers(stdout, 0, 0, &gbcfg);
2606
2607 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2608 OSMO_ASSERT(link_info);
2609 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2610 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2611 OSMO_ASSERT(!link_info->tlli.bss_validated);
2612 OSMO_ASSERT(!link_info->tlli.net_validated);
2613 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2614 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2615 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2616 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2617 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2618 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2619
2620 send_llc_dl_ui(nsi, "ATTACH ACCEPT (duplicated)", &sgsn_peer, 0x1002,
2621 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2622 GPRS_SAPI_GMM, sgsn_nu++,
2623 dtap_attach_acc, sizeof(dtap_attach_acc));
2624
2625 dump_peers(stdout, 0, 0, &gbcfg);
2626
2627 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2628 OSMO_ASSERT(link_info);
Jacob Erlbeck0d1ad5e2014-10-20 16:30:06 +02002629 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002630 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2631 OSMO_ASSERT(!link_info->tlli.bss_validated);
2632 OSMO_ASSERT(!link_info->tlli.net_validated);
Jacob Erlbeck0d1ad5e2014-10-20 16:30:06 +02002633 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002634 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2635 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2636 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2637 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2638 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2639
2640 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2641 local_bss_tlli, &rai_bss, cell_id,
2642 GPRS_SAPI_GMM, bss_nu++,
2643 dtap_attach_complete, sizeof(dtap_attach_complete));
2644
2645 dump_peers(stdout, 0, 0, &gbcfg);
2646
2647 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2648 OSMO_ASSERT(link_info);
Jacob Erlbeck0d1ad5e2014-10-20 16:30:06 +02002649 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002650 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
Jacob Erlbeck0d1ad5e2014-10-20 16:30:06 +02002651 OSMO_ASSERT(link_info->tlli.bss_validated);
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002652 OSMO_ASSERT(!link_info->tlli.net_validated);
2653 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2654 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
Jacob Erlbeck0d1ad5e2014-10-20 16:30:06 +02002655 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002656 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2657
2658 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2659 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2660 GPRS_SAPI_GMM, sgsn_nu++,
2661 dtap_gmm_information, sizeof(dtap_gmm_information));
2662
2663 dump_peers(stdout, 0, 0, &gbcfg);
2664
2665 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2666 OSMO_ASSERT(link_info);
Jacob Erlbeck0d1ad5e2014-10-20 16:30:06 +02002667 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2668 OSMO_ASSERT(link_info->tlli.assigned == 0);
2669 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2670 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002671
2672 /* Detach */
2673 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2674 local_bss_tlli, &rai_bss, cell_id,
2675 GPRS_SAPI_GMM, bss_nu++,
2676 dtap_detach_req, sizeof(dtap_detach_req));
2677
2678 dump_peers(stdout, 0, 0, &gbcfg);
2679
2680 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2681 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2682 GPRS_SAPI_GMM, sgsn_nu++,
2683 dtap_detach_acc, sizeof(dtap_detach_acc));
2684
2685 dump_peers(stdout, 0, 0, &gbcfg);
2686
2687 dump_global(stdout, 0);
2688
2689 gbprox_reset(&gbcfg);
2690 gprs_ns_destroy(nsi);
2691 nsi = NULL;
Daniel Willmann1e0b0002015-10-12 19:36:34 +02002692
2693 cleanup_test();
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02002694}
2695
2696
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002697static void test_gbproxy_imsi_acquisition()
2698{
2699 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2700 struct sockaddr_in bss_peer[1] = {{0},};
2701 struct sockaddr_in sgsn_peer= {0};
2702 struct gprs_ra_id rai_bss =
2703 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2704 struct gprs_ra_id rai_sgsn =
2705 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2706 struct gprs_ra_id rai_wrong_mcc_sgsn =
2707 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
2708 struct gprs_ra_id rai_unknown =
2709 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2710 uint16_t cell_id = 0x1234;
2711
2712 const uint32_t sgsn_ptmsi = 0xefe2b700;
2713 const uint32_t local_sgsn_tlli = 0xefe2b700;
Daniel Willmann2b10af32015-10-12 19:36:35 +02002714 const uint32_t random_sgsn_tlli = 0x78dead00;
2715 const uint32_t random_sgsn_tlli2 = 0x78dead02;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002716
Daniel Willmann2b10af32015-10-12 19:36:35 +02002717 const uint32_t bss_ptmsi = 0xc0dead01;
2718 const uint32_t local_bss_tlli = 0xc0dead01;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002719 const uint32_t foreign_bss_tlli = 0x8000dead;
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02002720 const uint32_t other_bss_tlli = 0x8000beef;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002721
2722 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002723 struct gbproxy_link_info *link_info;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002724 struct gbproxy_peer *peer;
2725 unsigned bss_nu = 0;
2726 unsigned sgsn_nu = 0;
2727
2728 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2729
2730 bssgp_nsi = nsi;
2731 gbcfg.nsi = bssgp_nsi;
2732 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +01002733 gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002734 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2735 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2736 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +02002737 gbcfg.acquire_imsi = 1;
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002738
2739 configure_sgsn_peer(&sgsn_peer);
2740 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2741
2742 printf("=== %s ===\n", __func__);
2743 printf("--- Initialise SGSN ---\n\n");
2744
Jacob Erlbeck12356062014-08-27 12:44:25 +02002745 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002746
2747 printf("--- Initialise BSS 1 ---\n\n");
2748
2749 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2750 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2751
2752 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2753 OSMO_ASSERT(peer != NULL);
2754
2755 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
2756
2757 gprs_dump_nsi(nsi);
2758 dump_global(stdout, 0);
2759 dump_peers(stdout, 0, 0, &gbcfg);
2760
2761 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
2762
2763 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02002764 foreign_bss_tlli, &rai_bss, cell_id,
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002765 GPRS_SAPI_GMM, bss_nu++,
2766 dtap_attach_req, sizeof(dtap_attach_req));
2767
2768 dump_peers(stdout, 0, 0, &gbcfg);
2769
Jacob Erlbeck4c0f6982014-08-22 17:10:01 +02002770 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2771 foreign_bss_tlli, &rai_bss, cell_id,
2772 GPRS_SAPI_GMM, bss_nu++,
2773 dtap_identity_resp, sizeof(dtap_identity_resp));
2774
2775 dump_peers(stdout, 0, 0, &gbcfg);
2776
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002777 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
2778 random_sgsn_tlli, 0, NULL, 0,
2779 GPRS_SAPI_GMM, sgsn_nu++,
2780 dtap_identity_req, sizeof(dtap_identity_req));
2781
2782 dump_peers(stdout, 0, 0, &gbcfg);
2783
2784 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2785 foreign_bss_tlli, &rai_bss, cell_id,
2786 GPRS_SAPI_GMM, bss_nu++,
2787 dtap_identity_resp, sizeof(dtap_identity_resp));
2788
2789 dump_peers(stdout, 0, 0, &gbcfg);
2790
2791 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
2792 random_sgsn_tlli, 1, imsi, sizeof(imsi),
2793 GPRS_SAPI_GMM, sgsn_nu++,
2794 dtap_attach_acc, sizeof(dtap_attach_acc));
2795
2796 dump_peers(stdout, 0, 0, &gbcfg);
2797
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002798 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
2799 OSMO_ASSERT(link_info);
2800 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2801 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2802 OSMO_ASSERT(!link_info->tlli.bss_validated);
2803 OSMO_ASSERT(!link_info->tlli.net_validated);
2804 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
2805 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2806 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2807 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
2808 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
2809 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002810
2811 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2812 local_bss_tlli, &rai_bss, cell_id,
2813 GPRS_SAPI_GMM, bss_nu++,
2814 dtap_attach_complete, sizeof(dtap_attach_complete));
2815
2816 dump_peers(stdout, 0, 0, &gbcfg);
2817
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002818 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2819 OSMO_ASSERT(link_info);
2820 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
2821 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
2822 OSMO_ASSERT(link_info->tlli.bss_validated);
2823 OSMO_ASSERT(!link_info->tlli.net_validated);
2824 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
2825 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
2826 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
2827 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002828
2829 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2830 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2831 GPRS_SAPI_GMM, sgsn_nu++,
2832 dtap_gmm_information, sizeof(dtap_gmm_information));
2833
2834 dump_peers(stdout, 0, 0, &gbcfg);
2835
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02002836 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
2837 OSMO_ASSERT(link_info);
2838 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
2839 OSMO_ASSERT(link_info->tlli.assigned == 0);
2840 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
2841 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002842
2843 /* Non-DTAP */
2844 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2845 local_bss_tlli, &rai_bss, cell_id,
2846 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2847
2848 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2849 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2850 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2851
2852 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2853 local_bss_tlli, &rai_bss, cell_id,
2854 llc_ui_ll11_dns_query_ul,
2855 sizeof(llc_ui_ll11_dns_query_ul));
2856
2857 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2858 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2859 llc_ui_ll11_dns_resp_dl,
2860 sizeof(llc_ui_ll11_dns_resp_dl));
2861
2862 dump_peers(stdout, 0, 0, &gbcfg);
2863
2864 /* Other messages */
2865 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2866 local_bss_tlli, 1, 12);
2867
2868 dump_peers(stdout, 0, 0, &gbcfg);
2869
2870 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2871 local_sgsn_tlli, 1, 12);
2872
2873 dump_peers(stdout, 0, 0, &gbcfg);
2874
2875 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2876
2877 dump_peers(stdout, 0, 0, &gbcfg);
2878
2879 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2880
2881 dump_peers(stdout, 0, 0, &gbcfg);
2882
2883 /* Bad case: Invalid BVCI */
2884 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2885 local_bss_tlli, 1, 12);
2886 dump_global(stdout, 0);
2887
2888 /* Bad case: Invalid RAI */
2889 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2890
2891 dump_global(stdout, 0);
2892
2893 /* Bad case: Invalid MCC (LAC ok) */
2894 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2895 &rai_wrong_mcc_sgsn);
2896
2897 dump_global(stdout, 0);
2898
2899 /* Detach */
2900 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2901 local_bss_tlli, &rai_bss, cell_id,
2902 GPRS_SAPI_GMM, bss_nu++,
2903 dtap_detach_req, sizeof(dtap_detach_req));
2904
2905 dump_peers(stdout, 0, 0, &gbcfg);
2906
2907 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2908 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2909 GPRS_SAPI_GMM, sgsn_nu++,
2910 dtap_detach_acc, sizeof(dtap_detach_acc));
2911
2912 dump_peers(stdout, 0, 0, &gbcfg);
2913
Jacob Erlbeck9e9051f2014-09-18 09:57:47 +02002914 /* RA Update request */
2915
2916 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2917 foreign_bss_tlli, &rai_unknown, 0x7080,
2918 GPRS_SAPI_GMM, bss_nu++,
2919 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2920
2921 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2922 foreign_bss_tlli, &rai_bss, cell_id,
2923 GPRS_SAPI_GMM, bss_nu++,
2924 dtap_identity_resp, sizeof(dtap_identity_resp));
2925
2926 dump_peers(stdout, 0, 0, &gbcfg);
2927
2928 send_llc_dl_ui(nsi, "RA UDP ACC", &sgsn_peer, 0x1002,
2929 random_sgsn_tlli2, 1, imsi, sizeof(imsi),
2930 GPRS_SAPI_GMM, sgsn_nu++,
2931 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
2932
2933 dump_peers(stdout, 0, 0, &gbcfg);
2934
2935 /* Detach */
2936
2937 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2938 local_bss_tlli, &rai_bss, cell_id,
2939 GPRS_SAPI_GMM, bss_nu++,
2940 dtap_detach_req, sizeof(dtap_detach_req));
2941
2942 dump_peers(stdout, 0, 0, &gbcfg);
2943
2944 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2945 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2946 GPRS_SAPI_GMM, sgsn_nu++,
2947 dtap_detach_acc, sizeof(dtap_detach_acc));
2948
2949 dump_peers(stdout, 0, 0, &gbcfg);
2950
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +02002951 /* Special case: Repeated Attach Requests */
2952
2953 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2954 foreign_bss_tlli, &rai_unknown, cell_id,
2955 GPRS_SAPI_GMM, bss_nu++,
2956 dtap_attach_req, sizeof(dtap_attach_req));
2957
2958 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2959 foreign_bss_tlli, &rai_unknown, cell_id,
2960 GPRS_SAPI_GMM, bss_nu++,
2961 dtap_attach_req, sizeof(dtap_attach_req));
2962
Jacob Erlbeck89aa65b2014-09-12 10:33:38 +02002963 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2964 foreign_bss_tlli, &rai_bss, cell_id,
2965 GPRS_SAPI_GMM, bss_nu++,
2966 dtap_detach_req, sizeof(dtap_detach_req));
2967
2968 dump_peers(stdout, 0, 0, &gbcfg);
2969
2970 /* Special case: Detach from an unknown TLLI */
2971
2972 send_llc_ul_ui(nsi, "DETACH REQ (unknown TLLI)", &bss_peer[0], 0x1002,
2973 other_bss_tlli, &rai_bss, cell_id,
2974 GPRS_SAPI_GMM, bss_nu++,
2975 dtap_detach_req, sizeof(dtap_detach_req));
2976
Jacob Erlbeck0c0747f2014-09-02 14:40:11 +02002977 dump_peers(stdout, 0, 0, &gbcfg);
2978
Jacob Erlbeck9e9051f2014-09-18 09:57:47 +02002979 /* Special case: Repeated RA Update Requests */
2980
2981 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2982 foreign_bss_tlli, &rai_unknown, 0x7080,
2983 GPRS_SAPI_GMM, bss_nu++,
2984 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2985
2986 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
2987 foreign_bss_tlli, &rai_unknown, 0x7080,
2988 GPRS_SAPI_GMM, bss_nu++,
2989 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
2990
2991 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2992 foreign_bss_tlli, &rai_bss, cell_id,
2993 GPRS_SAPI_GMM, bss_nu++,
2994 dtap_detach_req, sizeof(dtap_detach_req));
2995
2996 dump_peers(stdout, 0, 0, &gbcfg);
2997
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02002998 dump_global(stdout, 0);
2999
3000 gbprox_reset(&gbcfg);
3001 gprs_ns_destroy(nsi);
3002 nsi = NULL;
Daniel Willmann1e0b0002015-10-12 19:36:34 +02003003
3004 cleanup_test();
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02003005}
3006
Jacob Erlbeck12356062014-08-27 12:44:25 +02003007static void test_gbproxy_secondary_sgsn()
3008{
3009 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3010 struct sockaddr_in bss_peer[1] = {{0},};
3011 struct sockaddr_in sgsn_peer[2]= {{0},};
3012 struct gprs_ra_id rai_bss =
3013 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3014 struct gprs_ra_id rai_sgsn =
3015 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
3016 struct gprs_ra_id rai_unknown =
3017 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
3018 uint16_t cell_id = 0x1234;
3019
3020 const uint32_t sgsn_ptmsi = 0xefe2b700;
3021 const uint32_t local_sgsn_tlli = 0xefe2b700;
Daniel Willmann2b10af32015-10-12 19:36:35 +02003022 const uint32_t random_sgsn_tlli = 0x78dead00;
Jacob Erlbeck12356062014-08-27 12:44:25 +02003023
Daniel Willmann2b10af32015-10-12 19:36:35 +02003024 const uint32_t bss_ptmsi = 0xc0dead01;
3025 const uint32_t local_bss_tlli = 0xc0dead01;
Jacob Erlbeck12356062014-08-27 12:44:25 +02003026 const uint32_t foreign_bss_tlli = 0x8000dead;
3027
3028 const uint32_t sgsn_ptmsi2 = 0xe0987654;
3029 const uint32_t local_sgsn_tlli2 = 0xe0987654;
Daniel Willmann2b10af32015-10-12 19:36:35 +02003030 const uint32_t random_sgsn_tlli2 = 0x78dead02;
3031 const uint32_t bss_ptmsi2 = 0xc0dead03;
3032 const uint32_t local_bss_tlli2 = 0xc0dead03;
Jacob Erlbeck12356062014-08-27 12:44:25 +02003033 const uint32_t foreign_bss_tlli2 = 0x8000beef;
3034
Daniel Willmann2b10af32015-10-12 19:36:35 +02003035 const uint32_t random_sgsn_tlli3 = 0x78dead04;
3036 const uint32_t bss_ptmsi3 = 0xc0dead05;
3037 const uint32_t local_bss_tlli3 = 0xc0dead05;
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003038 const uint32_t foreign_bss_tlli3 = 0x8000feed;
3039
Jacob Erlbeck12356062014-08-27 12:44:25 +02003040 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
3041 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003042 const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0x28};
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003043 struct gbproxy_link_info *link_info;
3044 struct gbproxy_link_info *other_info;
Jacob Erlbeck12356062014-08-27 12:44:25 +02003045 struct gbproxy_peer *peer;
3046 unsigned bss_nu = 0;
3047 unsigned sgsn_nu = 0;
3048
3049 const char *err_msg = NULL;
3050 const char *filter_re = "999999";
3051
3052 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
3053 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
3054
3055 bssgp_nsi = nsi;
3056 gbcfg.nsi = bssgp_nsi;
3057 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +01003058 gbcfg.core_plmn = (struct osmo_plmn_id){ .mcc = 123, .mnc = 456 };
Jacob Erlbeck12356062014-08-27 12:44:25 +02003059 gbcfg.core_apn = talloc_zero_size(NULL, 100);
3060 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
3061 gbcfg.patch_ptmsi = 1;
3062 gbcfg.acquire_imsi = 1;
Daniel Willmann2b10af32015-10-12 19:36:35 +02003063
Jacob Erlbeck12356062014-08-27 12:44:25 +02003064 gbcfg.route_to_sgsn2 = 1;
3065 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
3066
Jacob Erlbeck3d805272014-09-25 13:21:48 +02003067 if (gbproxy_set_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING],
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02003068 filter_re, &err_msg) != 0) {
Jacob Erlbeck12356062014-08-27 12:44:25 +02003069 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
3070 err_msg);
3071 OSMO_ASSERT(err_msg == NULL);
3072 }
3073
3074 configure_sgsn_peer(&sgsn_peer[0]);
3075 configure_sgsn2_peer(&sgsn_peer[1]);
3076 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3077
3078 printf("=== %s ===\n", __func__);
3079 printf("--- Initialise SGSN 1 ---\n\n");
3080
3081 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
3082
3083 printf("--- Initialise SGSN 2 ---\n\n");
3084
3085 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
3086
3087 printf("--- Initialise BSS 1 ---\n\n");
3088
3089 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3090 setup_bssgp(nsi, &bss_peer[0], 0x0);
3091 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
3092 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3093 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
3094 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
3095
3096 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3097 OSMO_ASSERT(peer != NULL);
3098
3099 gprs_dump_nsi(nsi);
3100 dump_global(stdout, 0);
3101 dump_peers(stdout, 0, 0, &gbcfg);
3102
3103 printf("--- Flow control ---\n\n");
3104
3105 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
3106 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
3107 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
3108
3109 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
3110
3111 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3112 foreign_bss_tlli, &rai_unknown, cell_id,
3113 GPRS_SAPI_GMM, bss_nu++,
3114 dtap_attach_req, sizeof(dtap_attach_req));
3115
3116 dump_peers(stdout, 0, 0, &gbcfg);
3117
3118 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3119 foreign_bss_tlli, &rai_bss, cell_id,
3120 GPRS_SAPI_GMM, bss_nu++,
3121 dtap_identity_resp, sizeof(dtap_identity_resp));
3122
3123 dump_peers(stdout, 0, 0, &gbcfg);
3124
3125 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
3126 random_sgsn_tlli, 0, NULL, 0,
3127 GPRS_SAPI_GMM, sgsn_nu++,
3128 dtap_identity_req, sizeof(dtap_identity_req));
3129
3130 dump_peers(stdout, 0, 0, &gbcfg);
3131
3132 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3133 foreign_bss_tlli, &rai_bss, cell_id,
3134 GPRS_SAPI_GMM, bss_nu++,
3135 dtap_identity_resp, sizeof(dtap_identity_resp));
3136
3137 dump_peers(stdout, 0, 0, &gbcfg);
3138
3139 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
3140 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3141 GPRS_SAPI_GMM, sgsn_nu++,
3142 dtap_attach_acc, sizeof(dtap_attach_acc));
3143
3144 dump_peers(stdout, 0, 0, &gbcfg);
3145
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003146 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
3147 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli, SGSN_NSEI);
3148 OSMO_ASSERT(link_info);
3149 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
3150 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
3151 OSMO_ASSERT(!link_info->tlli.bss_validated);
3152 OSMO_ASSERT(!link_info->tlli.net_validated);
3153 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi);
3154 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3155 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
3156 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3157 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3158 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeck12356062014-08-27 12:44:25 +02003159
3160 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3161 local_bss_tlli, &rai_bss, cell_id,
3162 GPRS_SAPI_GMM, bss_nu++,
3163 dtap_attach_complete, sizeof(dtap_attach_complete));
3164
3165 dump_peers(stdout, 0, 0, &gbcfg);
3166
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003167 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
3168 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
3169 OSMO_ASSERT(link_info);
3170 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli);
3171 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli);
3172 OSMO_ASSERT(link_info->tlli.bss_validated);
3173 OSMO_ASSERT(!link_info->tlli.net_validated);
3174 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3175 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli);
3176 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3177 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck12356062014-08-27 12:44:25 +02003178
3179 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
3180 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3181 GPRS_SAPI_GMM, sgsn_nu++,
3182 dtap_gmm_information, sizeof(dtap_gmm_information));
3183
3184 dump_peers(stdout, 0, 0, &gbcfg);
3185
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003186 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI));
3187 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
3188 OSMO_ASSERT(link_info);
3189 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli);
3190 OSMO_ASSERT(link_info->tlli.assigned == 0);
3191 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3192 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck12356062014-08-27 12:44:25 +02003193
3194 /* Non-DTAP */
3195 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3196 local_bss_tlli, &rai_bss, cell_id,
3197 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3198
3199 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
3200 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3201 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3202
3203 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3204 local_bss_tlli, &rai_bss, cell_id,
3205 llc_ui_ll11_dns_query_ul,
3206 sizeof(llc_ui_ll11_dns_query_ul));
3207
3208 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
3209 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3210 llc_ui_ll11_dns_resp_dl,
3211 sizeof(llc_ui_ll11_dns_resp_dl));
3212
3213 dump_peers(stdout, 0, 0, &gbcfg);
3214
3215 /* Other messages */
3216 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3217 local_bss_tlli, 1, 12);
3218
3219 dump_peers(stdout, 0, 0, &gbcfg);
3220
3221 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
3222 local_sgsn_tlli, 1, 12);
3223
3224 dump_peers(stdout, 0, 0, &gbcfg);
3225
3226 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
3227
3228 dump_peers(stdout, 0, 0, &gbcfg);
3229
3230 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
3231
3232 dump_peers(stdout, 0, 0, &gbcfg);
3233
3234 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
3235
3236 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3237 foreign_bss_tlli2, &rai_unknown, cell_id,
3238 GPRS_SAPI_GMM, bss_nu++,
3239 dtap_attach_req, sizeof(dtap_attach_req));
3240
3241 dump_peers(stdout, 0, 0, &gbcfg);
3242
3243 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3244 foreign_bss_tlli2, &rai_bss, cell_id,
3245 GPRS_SAPI_GMM, bss_nu++,
3246 dtap_identity2_resp, sizeof(dtap_identity2_resp));
3247
3248 dump_peers(stdout, 0, 0, &gbcfg);
3249
3250 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3251 random_sgsn_tlli2, 0, NULL, 0,
3252 GPRS_SAPI_GMM, sgsn_nu++,
3253 dtap_identity_req, sizeof(dtap_identity_req));
3254
3255 dump_peers(stdout, 0, 0, &gbcfg);
3256
3257 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3258 foreign_bss_tlli2, &rai_bss, cell_id,
3259 GPRS_SAPI_GMM, bss_nu++,
Jacob Erlbeck9aa21cd2014-09-17 12:05:08 +02003260 dtap_identity2_resp, sizeof(dtap_identity2_resp));
Jacob Erlbeck12356062014-08-27 12:44:25 +02003261
3262 dump_peers(stdout, 0, 0, &gbcfg);
3263
3264 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
3265 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3266 GPRS_SAPI_GMM, sgsn_nu++,
3267 dtap_attach_acc2, sizeof(dtap_attach_acc2));
3268
3269 dump_peers(stdout, 0, 0, &gbcfg);
3270
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003271 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN_NSEI));
3272 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli2, SGSN2_NSEI);
3273 OSMO_ASSERT(link_info);
3274 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3275 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3276 OSMO_ASSERT(!link_info->tlli.bss_validated);
3277 OSMO_ASSERT(!link_info->tlli.net_validated);
3278 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi2);
3279 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3280 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3281 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3282 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3283 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
Jacob Erlbeck12356062014-08-27 12:44:25 +02003284
3285 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3286 local_bss_tlli2, &rai_bss, cell_id,
3287 GPRS_SAPI_GMM, bss_nu++,
3288 dtap_attach_complete, sizeof(dtap_attach_complete));
3289
3290 dump_peers(stdout, 0, 0, &gbcfg);
3291
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003292 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3293 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3294 OSMO_ASSERT(link_info);
3295 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli2);
3296 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli2);
3297 OSMO_ASSERT(link_info->tlli.bss_validated);
3298 OSMO_ASSERT(!link_info->tlli.net_validated);
3299 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli2);
3300 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli2);
3301 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3302 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeck12356062014-08-27 12:44:25 +02003303
3304 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3305 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3306 GPRS_SAPI_GMM, sgsn_nu++,
3307 dtap_gmm_information, sizeof(dtap_gmm_information));
3308
3309 dump_peers(stdout, 0, 0, &gbcfg);
3310
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003311 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN_NSEI));
3312 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli2, SGSN2_NSEI);
3313 OSMO_ASSERT(link_info);
3314 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli2);
3315 OSMO_ASSERT(link_info->tlli.assigned == 0);
3316 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli2);
3317 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeck12356062014-08-27 12:44:25 +02003318
3319 /* Non-DTAP */
3320 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
3321 local_bss_tlli2, &rai_bss, cell_id,
3322 llc_u_xid_ul, sizeof(llc_u_xid_ul));
3323
3324 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
3325 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3326 llc_u_xid_dl, sizeof(llc_u_xid_dl));
3327
3328 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
3329 local_bss_tlli2, &rai_bss, cell_id,
3330 llc_ui_ll11_dns_query_ul,
3331 sizeof(llc_ui_ll11_dns_query_ul));
3332
3333 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
3334 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3335 llc_ui_ll11_dns_resp_dl,
3336 sizeof(llc_ui_ll11_dns_resp_dl));
3337
3338 dump_peers(stdout, 0, 0, &gbcfg);
3339
3340 /* Other messages */
3341 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
3342 local_bss_tlli2, 1, 12);
3343
3344 dump_peers(stdout, 0, 0, &gbcfg);
3345
3346 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
3347 local_sgsn_tlli2, 1, 12);
3348
3349 dump_peers(stdout, 0, 0, &gbcfg);
3350
3351 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
3352
3353 dump_peers(stdout, 0, 0, &gbcfg);
3354
3355 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
3356
3357 dump_peers(stdout, 0, 0, &gbcfg);
3358
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003359 printf("--- Establish GPRS connection (SGSN 2, P-TMSI collision) ---\n\n");
3360
3361 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3362 foreign_bss_tlli3, &rai_unknown, cell_id,
3363 GPRS_SAPI_GMM, bss_nu++,
3364 dtap_attach_req, sizeof(dtap_attach_req));
3365
3366 dump_peers(stdout, 0, 0, &gbcfg);
3367
3368 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3369 foreign_bss_tlli3, &rai_bss, cell_id,
3370 GPRS_SAPI_GMM, bss_nu++,
3371 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3372
3373 dump_peers(stdout, 0, 0, &gbcfg);
3374
3375 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
3376 random_sgsn_tlli3, 0, NULL, 0,
3377 GPRS_SAPI_GMM, sgsn_nu++,
3378 dtap_identity_req, sizeof(dtap_identity_req));
3379
3380 dump_peers(stdout, 0, 0, &gbcfg);
3381
3382 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3383 foreign_bss_tlli3, &rai_bss, cell_id,
3384 GPRS_SAPI_GMM, bss_nu++,
3385 dtap_identity3_resp, sizeof(dtap_identity3_resp));
3386
3387 dump_peers(stdout, 0, 0, &gbcfg);
3388
3389 send_llc_dl_ui(nsi, "ATTACH ACCEPT (P-TMSI 1)", &sgsn_peer[1], 0x1002,
3390 random_sgsn_tlli3, 1, imsi3, sizeof(imsi3),
3391 GPRS_SAPI_GMM, sgsn_nu++,
3392 dtap_attach_acc, sizeof(dtap_attach_acc));
3393
3394 dump_peers(stdout, 0, 0, &gbcfg);
3395
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003396 OSMO_ASSERT(!gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN_NSEI));
3397 link_info = gbproxy_link_info_by_sgsn_tlli(peer, random_sgsn_tlli3, SGSN2_NSEI);
3398 OSMO_ASSERT(link_info);
3399 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3400 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3401 OSMO_ASSERT(!link_info->tlli.bss_validated);
3402 OSMO_ASSERT(!link_info->tlli.net_validated);
3403 OSMO_ASSERT(link_info->tlli.ptmsi == bss_ptmsi3);
3404 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3405 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3406 OSMO_ASSERT(!link_info->sgsn_tlli.bss_validated);
3407 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
3408 OSMO_ASSERT(link_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003409
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003410 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3411 local_bss_tlli3, &rai_bss, cell_id,
3412 GPRS_SAPI_GMM, bss_nu++,
3413 dtap_attach_complete, sizeof(dtap_attach_complete));
3414
3415 dump_peers(stdout, 0, 0, &gbcfg);
3416
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003417 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003418 OSMO_ASSERT(other_info);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003419 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3420 OSMO_ASSERT(link_info);
3421 OSMO_ASSERT(link_info != other_info);
3422 OSMO_ASSERT(link_info->tlli.assigned == local_bss_tlli3);
3423 OSMO_ASSERT(link_info->tlli.current == foreign_bss_tlli3);
3424 OSMO_ASSERT(link_info->tlli.bss_validated);
3425 OSMO_ASSERT(!link_info->tlli.net_validated);
3426 OSMO_ASSERT(link_info->sgsn_tlli.assigned == local_sgsn_tlli);
3427 OSMO_ASSERT(link_info->sgsn_tlli.current == random_sgsn_tlli3);
3428 OSMO_ASSERT(link_info->sgsn_tlli.bss_validated);
3429 OSMO_ASSERT(!link_info->sgsn_tlli.net_validated);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003430
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003431 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
3432 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3433 GPRS_SAPI_GMM, sgsn_nu++,
3434 dtap_gmm_information, sizeof(dtap_gmm_information));
3435
3436 dump_peers(stdout, 0, 0, &gbcfg);
3437
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003438 other_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN_NSEI);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003439 OSMO_ASSERT(other_info);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003440 link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_sgsn_tlli, SGSN2_NSEI);
3441 OSMO_ASSERT(link_info);
3442 OSMO_ASSERT(link_info != other_info);
3443 OSMO_ASSERT(link_info->tlli.current == local_bss_tlli3);
3444 OSMO_ASSERT(link_info->tlli.assigned == 0);
3445 OSMO_ASSERT(link_info->sgsn_tlli.current == local_sgsn_tlli);
3446 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
Jacob Erlbeckd918f522014-09-17 10:56:38 +02003447
3448
Jacob Erlbeck12356062014-08-27 12:44:25 +02003449 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
3450
3451 /* Detach */
3452 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3453 local_bss_tlli, &rai_bss, cell_id,
3454 GPRS_SAPI_GMM, bss_nu++,
3455 dtap_detach_req, sizeof(dtap_detach_req));
3456
3457 dump_peers(stdout, 0, 0, &gbcfg);
3458
3459 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
3460 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
3461 GPRS_SAPI_GMM, sgsn_nu++,
3462 dtap_detach_acc, sizeof(dtap_detach_acc));
3463
3464 dump_peers(stdout, 0, 0, &gbcfg);
3465
3466 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
3467
3468 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3469 local_bss_tlli2, &rai_bss, cell_id,
3470 GPRS_SAPI_GMM, bss_nu++,
3471 dtap_detach_req, sizeof(dtap_detach_req));
3472
3473 dump_peers(stdout, 0, 0, &gbcfg);
3474
3475 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3476 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
3477 GPRS_SAPI_GMM, sgsn_nu++,
3478 dtap_detach_acc, sizeof(dtap_detach_acc));
3479
3480 dump_peers(stdout, 0, 0, &gbcfg);
3481
Jacob Erlbeckd1056b32014-09-17 12:09:25 +02003482 printf("--- Shutdown GPRS connection (SGSN 2, P-TMSI 1) ---\n\n");
3483
3484 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3485 local_bss_tlli3, &rai_bss, cell_id,
3486 GPRS_SAPI_GMM, bss_nu++,
3487 dtap_detach_req, sizeof(dtap_detach_req));
3488
3489 dump_peers(stdout, 0, 0, &gbcfg);
3490
3491 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
3492 local_sgsn_tlli, 1, imsi3, sizeof(imsi3),
3493 GPRS_SAPI_GMM, sgsn_nu++,
3494 dtap_detach_acc, sizeof(dtap_detach_acc));
3495
3496 dump_peers(stdout, 0, 0, &gbcfg);
3497
Jacob Erlbeck12356062014-08-27 12:44:25 +02003498 dump_global(stdout, 0);
3499
Jacob Erlbeck3d805272014-09-25 13:21:48 +02003500 gbproxy_clear_patch_filter(&gbcfg.matches[GBPROX_MATCH_ROUTING]);
Jacob Erlbeck12356062014-08-27 12:44:25 +02003501 gbprox_reset(&gbcfg);
3502 gprs_ns_destroy(nsi);
3503 nsi = NULL;
Daniel Willmann1e0b0002015-10-12 19:36:34 +02003504
3505 cleanup_test();
Jacob Erlbeck12356062014-08-27 12:44:25 +02003506}
3507
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003508static void test_gbproxy_keep_info()
3509{
3510 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
3511 struct sockaddr_in bss_peer[1] = {{0},};
3512 struct sockaddr_in sgsn_peer= {0};
3513 struct gprs_ra_id rai_bss =
3514 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
3515 uint16_t cell_id = 0x1234;
3516
3517 const uint32_t ptmsi = 0xefe2b700;
3518 const uint32_t local_tlli = 0xefe2b700;
3519 const uint32_t foreign_tlli = 0xafe2b700;
3520
3521 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003522 struct gbproxy_link_info *link_info, *link_info2;
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003523 struct gbproxy_peer *peer;
3524 unsigned bss_nu = 0;
3525 unsigned sgsn_nu = 0;
3526
Jacob Erlbecka926e542014-09-22 19:16:06 +02003527 LLIST_HEAD(rcv_list);
3528
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003529 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
3530
3531 bssgp_nsi = nsi;
3532 gbcfg.nsi = bssgp_nsi;
3533 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
3534 gbcfg.patch_ptmsi = 0;
3535 gbcfg.acquire_imsi = 1;
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +01003536 gbcfg.core_plmn = (struct osmo_plmn_id){};
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003537 gbcfg.core_apn = NULL;
3538 gbcfg.core_apn_size = 0;
3539 gbcfg.route_to_sgsn2 = 0;
3540 gbcfg.nsip_sgsn2_nsei = 0xffff;
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003541 gbcfg.keep_link_infos = GBPROX_KEEP_ALWAYS;
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003542
3543 configure_sgsn_peer(&sgsn_peer);
3544 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
3545
3546 printf("=== %s ===\n", __func__);
3547 printf("--- Initialise SGSN ---\n\n");
3548
3549 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
3550
3551 printf("--- Initialise BSS 1 ---\n\n");
3552
3553 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
3554 setup_bssgp(nsi, &bss_peer[0], 0x1002);
3555
3556 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
3557 OSMO_ASSERT(peer != NULL);
3558
3559 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
3560
3561 gprs_dump_nsi(nsi);
3562 dump_global(stdout, 0);
3563 dump_peers(stdout, 0, 0, &gbcfg);
3564
3565 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
3566
Jacob Erlbecka926e542014-09-22 19:16:06 +02003567 received_messages = &rcv_list;
3568
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003569 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3570 foreign_tlli, &rai_bss, cell_id,
3571 GPRS_SAPI_GMM, bss_nu++,
3572 dtap_attach_req, sizeof(dtap_attach_req));
3573
Jacob Erlbecka926e542014-09-22 19:16:06 +02003574 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3575
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003576 dump_peers(stdout, 0, 0, &gbcfg);
3577
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003578 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3579 OSMO_ASSERT(link_info);
3580 OSMO_ASSERT(link_info->imsi_len == 0);
3581 OSMO_ASSERT(!link_info->is_deregistered);
3582 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003583
3584 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3585 foreign_tlli, &rai_bss, cell_id,
3586 GPRS_SAPI_GMM, bss_nu++,
3587 dtap_identity_resp, sizeof(dtap_identity_resp));
3588
Jacob Erlbecka926e542014-09-22 19:16:06 +02003589 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3590
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003591 dump_peers(stdout, 0, 0, &gbcfg);
3592
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003593 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3594 OSMO_ASSERT(link_info);
3595 OSMO_ASSERT(link_info->imsi_len > 0);
3596 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeckb0f61292014-10-31 10:43:44 +01003597 OSMO_ASSERT(gprs_tlli_type(link_info->sgsn_tlli.current) == TLLI_FOREIGN);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003598
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003599 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
3600 foreign_tlli, 0, NULL, 0,
3601 GPRS_SAPI_GMM, sgsn_nu++,
3602 dtap_identity_req, sizeof(dtap_identity_req));
3603
Jacob Erlbecka926e542014-09-22 19:16:06 +02003604 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3605
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003606 dump_peers(stdout, 0, 0, &gbcfg);
3607
3608 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3609 foreign_tlli, &rai_bss, cell_id,
3610 GPRS_SAPI_GMM, bss_nu++,
3611 dtap_identity_resp, sizeof(dtap_identity_resp));
3612
Jacob Erlbecka926e542014-09-22 19:16:06 +02003613 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ID_RESP));
3614
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003615 dump_peers(stdout, 0, 0, &gbcfg);
3616
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003617 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3618 OSMO_ASSERT(link_info);
3619 OSMO_ASSERT(link_info->imsi_len > 0);
3620 OSMO_ASSERT(gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi)));
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003621
3622 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3623 foreign_tlli, 1, imsi, sizeof(imsi),
3624 GPRS_SAPI_GMM, sgsn_nu++,
3625 dtap_attach_acc, sizeof(dtap_attach_acc));
3626
Jacob Erlbecka926e542014-09-22 19:16:06 +02003627 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3628
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003629 dump_peers(stdout, 0, 0, &gbcfg);
3630
3631 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3632 local_tlli, &rai_bss, cell_id,
3633 GPRS_SAPI_GMM, bss_nu++,
3634 dtap_attach_complete, sizeof(dtap_attach_complete));
3635
Jacob Erlbecka926e542014-09-22 19:16:06 +02003636 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3637
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003638 dump_peers(stdout, 0, 0, &gbcfg);
3639
3640 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
3641 local_tlli, 1, imsi, sizeof(imsi),
3642 GPRS_SAPI_GMM, sgsn_nu++,
3643 dtap_gmm_information, sizeof(dtap_gmm_information));
3644
Jacob Erlbecka926e542014-09-22 19:16:06 +02003645 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
3646
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003647 dump_peers(stdout, 0, 0, &gbcfg);
3648
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003649 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3650 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003651
3652 /* Detach (MO) */
3653 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
3654 local_tlli, &rai_bss, cell_id,
3655 GPRS_SAPI_GMM, bss_nu++,
3656 dtap_detach_req, sizeof(dtap_detach_req));
3657
Jacob Erlbecka926e542014-09-22 19:16:06 +02003658 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3659
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003660 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3661 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003662
3663 dump_peers(stdout, 0, 0, &gbcfg);
3664
3665 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
3666 local_tlli, 1, imsi, sizeof(imsi),
3667 GPRS_SAPI_GMM, sgsn_nu++,
3668 dtap_detach_acc, sizeof(dtap_detach_acc));
3669
Jacob Erlbecka926e542014-09-22 19:16:06 +02003670 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3671
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003672 dump_peers(stdout, 0, 0, &gbcfg);
3673
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003674 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3675 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3676 OSMO_ASSERT(link_info);
3677 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003678
Jacob Erlbecka926e542014-09-22 19:16:06 +02003679 OSMO_ASSERT(!expect_msg());
3680
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003681 /* Re-Attach */
3682 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3683 foreign_tlli, &rai_bss, cell_id,
3684 GPRS_SAPI_GMM, bss_nu++,
3685 dtap_attach_req3, sizeof(dtap_attach_req3));
3686
Jacob Erlbecka926e542014-09-22 19:16:06 +02003687 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3688
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003689 dump_peers(stdout, 0, 0, &gbcfg);
3690
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003691 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3692 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3693 OSMO_ASSERT(link_info);
3694 OSMO_ASSERT(link_info == link_info2);
3695 OSMO_ASSERT(link_info->imsi_len != 0);
3696 OSMO_ASSERT(!link_info->is_deregistered);
3697 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeckb0f61292014-10-31 10:43:44 +01003698 OSMO_ASSERT(gprs_tlli_type(link_info->sgsn_tlli.current) == TLLI_FOREIGN);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003699
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003700 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3701 foreign_tlli, 1, imsi, sizeof(imsi),
3702 GPRS_SAPI_GMM, sgsn_nu++,
3703 dtap_attach_acc, sizeof(dtap_attach_acc));
3704
Jacob Erlbecka926e542014-09-22 19:16:06 +02003705 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3706
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003707 dump_peers(stdout, 0, 0, &gbcfg);
3708
3709 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3710 local_tlli, &rai_bss, cell_id,
3711 GPRS_SAPI_GMM, bss_nu++,
3712 dtap_attach_complete, sizeof(dtap_attach_complete));
3713
Jacob Erlbecka926e542014-09-22 19:16:06 +02003714 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3715
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003716 dump_peers(stdout, 0, 0, &gbcfg);
3717
3718 /* Detach (MT) */
3719 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
3720 local_tlli, 1, imsi, sizeof(imsi),
3721 GPRS_SAPI_GMM, sgsn_nu++,
3722 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
3723
Jacob Erlbecka926e542014-09-22 19:16:06 +02003724 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3725
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003726 dump_peers(stdout, 0, 0, &gbcfg);
3727
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003728 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3729 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003730
Jacob Erlbecka926e542014-09-22 19:16:06 +02003731 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003732 local_tlli, &rai_bss, cell_id,
3733 GPRS_SAPI_GMM, bss_nu++,
3734 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3735
Jacob Erlbecka926e542014-09-22 19:16:06 +02003736 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3737 OSMO_ASSERT(!expect_msg());
3738
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003739 dump_peers(stdout, 0, 0, &gbcfg);
3740
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003741 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3742 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3743 OSMO_ASSERT(link_info);
3744 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003745
3746 /* Re-Attach */
3747 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3748 foreign_tlli, &rai_bss, cell_id,
3749 GPRS_SAPI_GMM, bss_nu++,
3750 dtap_attach_req3, sizeof(dtap_attach_req3));
3751
Jacob Erlbecka926e542014-09-22 19:16:06 +02003752 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3753
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003754 dump_peers(stdout, 0, 0, &gbcfg);
3755
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003756 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3757 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3758 OSMO_ASSERT(link_info);
3759 OSMO_ASSERT(link_info == link_info2);
3760 OSMO_ASSERT(link_info->imsi_len != 0);
3761 OSMO_ASSERT(!link_info->is_deregistered);
3762 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003763
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003764 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3765 foreign_tlli, 1, imsi, sizeof(imsi),
3766 GPRS_SAPI_GMM, sgsn_nu++,
3767 dtap_attach_acc, sizeof(dtap_attach_acc));
3768
Jacob Erlbecka926e542014-09-22 19:16:06 +02003769 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3770
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003771 dump_peers(stdout, 0, 0, &gbcfg);
3772
3773 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3774 local_tlli, &rai_bss, cell_id,
3775 GPRS_SAPI_GMM, bss_nu++,
3776 dtap_attach_complete, sizeof(dtap_attach_complete));
3777
Jacob Erlbecka926e542014-09-22 19:16:06 +02003778 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3779
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003780 dump_peers(stdout, 0, 0, &gbcfg);
3781
3782 /* Detach (MT) */
3783 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3784 local_tlli, 1, imsi, sizeof(imsi),
3785 GPRS_SAPI_GMM, sgsn_nu++,
3786 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3787
Jacob Erlbecka926e542014-09-22 19:16:06 +02003788 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3789
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003790 dump_peers(stdout, 0, 0, &gbcfg);
3791
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003792 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3793 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003794
Jacob Erlbecka926e542014-09-22 19:16:06 +02003795 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003796 local_tlli, &rai_bss, cell_id,
3797 GPRS_SAPI_GMM, bss_nu++,
3798 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3799
Jacob Erlbecka926e542014-09-22 19:16:06 +02003800 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3801 OSMO_ASSERT(!expect_msg());
3802
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003803 dump_peers(stdout, 0, 0, &gbcfg);
3804
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003805 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3806 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3807 OSMO_ASSERT(link_info);
3808 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003809
Jacob Erlbeckb0f61292014-10-31 10:43:44 +01003810 /* Re-Attach with IMSI */
3811 send_llc_ul_ui(nsi, "ATTACH REQUEST (IMSI)", &bss_peer[0], 0x1002,
3812 foreign_tlli, &rai_bss, cell_id,
3813 GPRS_SAPI_GMM, bss_nu++,
3814 dtap_attach_req4, sizeof(dtap_attach_req4));
3815
3816 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3817
3818 dump_peers(stdout, 0, 0, &gbcfg);
3819
3820 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3821 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3822 OSMO_ASSERT(link_info);
3823 OSMO_ASSERT(link_info == link_info2);
3824 OSMO_ASSERT(link_info->imsi_len != 0);
3825 OSMO_ASSERT(!link_info->is_deregistered);
3826 OSMO_ASSERT(!link_info->imsi_acq_pending);
3827 OSMO_ASSERT(link_info->sgsn_tlli.current == foreign_tlli);
3828
3829 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3830 foreign_tlli, 1, imsi, sizeof(imsi),
3831 GPRS_SAPI_GMM, sgsn_nu++,
3832 dtap_attach_acc, sizeof(dtap_attach_acc));
3833
3834 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3835
3836 dump_peers(stdout, 0, 0, &gbcfg);
3837
3838 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3839 local_tlli, &rai_bss, cell_id,
3840 GPRS_SAPI_GMM, bss_nu++,
3841 dtap_attach_complete, sizeof(dtap_attach_complete));
3842
3843 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3844
3845 dump_peers(stdout, 0, 0, &gbcfg);
3846
3847 /* Detach (MT) */
3848 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3849 local_tlli, 1, imsi, sizeof(imsi),
3850 GPRS_SAPI_GMM, sgsn_nu++,
3851 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3852
3853 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
3854
3855 dump_peers(stdout, 0, 0, &gbcfg);
3856
3857 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
3858 OSMO_ASSERT(link_info);
3859
3860 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
3861 local_tlli, &rai_bss, cell_id,
3862 GPRS_SAPI_GMM, bss_nu++,
3863 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
3864
3865 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
3866 OSMO_ASSERT(!expect_msg());
3867
3868 dump_peers(stdout, 0, 0, &gbcfg);
3869
3870 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3871 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3872 OSMO_ASSERT(link_info);
3873 OSMO_ASSERT(link_info->is_deregistered);
3874
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003875 /* Re-Attach */
3876 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3877 foreign_tlli, &rai_bss, cell_id,
3878 GPRS_SAPI_GMM, bss_nu++,
3879 dtap_attach_req3, sizeof(dtap_attach_req3));
3880
Jacob Erlbecka926e542014-09-22 19:16:06 +02003881 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3882
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003883 dump_peers(stdout, 0, 0, &gbcfg);
3884
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003885 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3886 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3887 OSMO_ASSERT(link_info);
3888 OSMO_ASSERT(link_info == link_info2);
3889 OSMO_ASSERT(link_info->imsi_len != 0);
3890 OSMO_ASSERT(!link_info->is_deregistered);
3891 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003892
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003893 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3894 foreign_tlli, 1, imsi, sizeof(imsi),
3895 GPRS_SAPI_GMM, sgsn_nu++,
3896 dtap_attach_acc, sizeof(dtap_attach_acc));
3897
Jacob Erlbecka926e542014-09-22 19:16:06 +02003898 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3899
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003900 dump_peers(stdout, 0, 0, &gbcfg);
3901
3902 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3903 local_tlli, &rai_bss, cell_id,
3904 GPRS_SAPI_GMM, bss_nu++,
3905 dtap_attach_complete, sizeof(dtap_attach_complete));
3906
Jacob Erlbecka926e542014-09-22 19:16:06 +02003907 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3908
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003909 dump_peers(stdout, 0, 0, &gbcfg);
3910
3911 /* RA update procedure (reject -> Detach) */
3912 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
3913 local_tlli, &rai_bss, 0x7080,
3914 GPRS_SAPI_GMM, bss_nu++,
3915 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
3916
Jacob Erlbecka926e542014-09-22 19:16:06 +02003917 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_RA_UPD_REQ));
3918
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003919 send_llc_dl_ui(nsi, "RA UDP REJ", &sgsn_peer, 0x1002,
3920 local_tlli, 1, imsi, sizeof(imsi),
3921 GPRS_SAPI_GMM, sgsn_nu++,
3922 dtap_ra_upd_rej, sizeof(dtap_ra_upd_rej));
3923
Jacob Erlbecka926e542014-09-22 19:16:06 +02003924 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_RA_UPD_REJ));
3925 OSMO_ASSERT(!expect_msg());
3926
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003927 dump_peers(stdout, 0, 0, &gbcfg);
3928
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003929 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
3930 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3931 OSMO_ASSERT(link_info);
3932 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003933
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003934 /* Bad case: Re-Attach with wrong (initial) P-TMSI */
3935 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
3936 foreign_tlli, &rai_bss, cell_id,
3937 GPRS_SAPI_GMM, bss_nu++,
3938 dtap_attach_req, sizeof(dtap_attach_req));
3939
Jacob Erlbecka926e542014-09-22 19:16:06 +02003940 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
3941
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003942 dump_peers(stdout, 0, 0, &gbcfg);
3943
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003944 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3945 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3946 OSMO_ASSERT(link_info);
3947 OSMO_ASSERT(link_info != link_info2);
3948 OSMO_ASSERT(link_info->imsi_len == 0);
3949 OSMO_ASSERT(!link_info->is_deregistered);
3950 OSMO_ASSERT(link_info->imsi_acq_pending);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003951
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02003952 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
3953 foreign_tlli, &rai_bss, cell_id,
3954 GPRS_SAPI_GMM, bss_nu++,
3955 dtap_identity_resp, sizeof(dtap_identity_resp));
3956
Jacob Erlbecka926e542014-09-22 19:16:06 +02003957 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
3958
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02003959 dump_peers(stdout, 0, 0, &gbcfg);
3960
3961 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3962 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3963 OSMO_ASSERT(link_info);
3964 OSMO_ASSERT(link_info == link_info2);
3965 OSMO_ASSERT(link_info->imsi_len != 0);
3966 OSMO_ASSERT(!link_info->is_deregistered);
3967 OSMO_ASSERT(!link_info->imsi_acq_pending);
3968
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003969 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
3970 foreign_tlli, 1, imsi, sizeof(imsi),
3971 GPRS_SAPI_GMM, sgsn_nu++,
3972 dtap_attach_acc, sizeof(dtap_attach_acc));
3973
Jacob Erlbecka926e542014-09-22 19:16:06 +02003974 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
3975
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003976 dump_peers(stdout, 0, 0, &gbcfg);
3977
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02003978 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
3979 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
3980 OSMO_ASSERT(link_info);
3981 OSMO_ASSERT(link_info == link_info2);
Jacob Erlbeck99b41132014-09-22 09:28:27 +02003982 OSMO_ASSERT(link_info->imsi_len > 0);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02003983
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003984 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
3985 local_tlli, &rai_bss, cell_id,
3986 GPRS_SAPI_GMM, bss_nu++,
3987 dtap_attach_complete, sizeof(dtap_attach_complete));
3988
Jacob Erlbecka926e542014-09-22 19:16:06 +02003989 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
3990
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02003991 dump_peers(stdout, 0, 0, &gbcfg);
3992
3993 /* Detach (MT) */
3994 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
3995 local_tlli, 1, imsi, sizeof(imsi),
3996 GPRS_SAPI_GMM, sgsn_nu++,
3997 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
3998
Jacob Erlbecka926e542014-09-22 19:16:06 +02003999 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
4000
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02004001 dump_peers(stdout, 0, 0, &gbcfg);
4002
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004003 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
4004 OSMO_ASSERT(link_info);
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02004005
Jacob Erlbecka926e542014-09-22 19:16:06 +02004006 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02004007 local_tlli, &rai_bss, cell_id,
4008 GPRS_SAPI_GMM, bss_nu++,
4009 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
4010
Jacob Erlbecka926e542014-09-22 19:16:06 +02004011 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
4012
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02004013 dump_peers(stdout, 0, 0, &gbcfg);
4014
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004015 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
4016 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4017 OSMO_ASSERT(link_info);
4018 OSMO_ASSERT(link_info->is_deregistered);
Jacob Erlbeckf9038d92014-09-12 15:09:56 +02004019
Jacob Erlbecka926e542014-09-22 19:16:06 +02004020 OSMO_ASSERT(!expect_msg());
4021
Jacob Erlbeckb0f61292014-10-31 10:43:44 +01004022 /* Bad case: Re-Attach with local TLLI */
4023 send_llc_ul_ui(nsi, "ATTACH REQUEST (local TLLI)", &bss_peer[0], 0x1002,
4024 local_tlli, &rai_bss, cell_id,
4025 GPRS_SAPI_GMM, bss_nu++,
4026 dtap_attach_req3, sizeof(dtap_attach_req3));
4027
4028 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
4029
4030 dump_peers(stdout, 0, 0, &gbcfg);
4031
4032 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4033 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
4034 OSMO_ASSERT(link_info);
4035 OSMO_ASSERT(link_info == link_info2);
4036 OSMO_ASSERT(link_info->imsi_len != 0);
4037 OSMO_ASSERT(!link_info->is_deregistered);
4038 OSMO_ASSERT(!link_info->imsi_acq_pending);
4039 OSMO_ASSERT(link_info->sgsn_tlli.current == local_tlli);
4040
4041 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
4042 local_tlli, 1, imsi, sizeof(imsi),
4043 GPRS_SAPI_GMM, sgsn_nu++,
4044 dtap_attach_acc, sizeof(dtap_attach_acc));
4045
4046 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
4047
4048 dump_peers(stdout, 0, 0, &gbcfg);
4049
4050 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
4051 local_tlli, &rai_bss, cell_id,
4052 GPRS_SAPI_GMM, bss_nu++,
4053 dtap_attach_complete, sizeof(dtap_attach_complete));
4054
4055 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
4056
4057 dump_peers(stdout, 0, 0, &gbcfg);
4058
4059 /* Detach (MT) */
4060 send_llc_dl_ui(nsi, "DETACH REQ (re-attach)", &sgsn_peer, 0x1002,
4061 local_tlli, 1, imsi, sizeof(imsi),
4062 GPRS_SAPI_GMM, sgsn_nu++,
4063 dtap_mt_detach_rea_req, sizeof(dtap_mt_detach_rea_req));
4064
4065 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
4066
4067 dump_peers(stdout, 0, 0, &gbcfg);
4068
4069 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
4070 OSMO_ASSERT(link_info);
4071
4072 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
4073 local_tlli, &rai_bss, cell_id,
4074 GPRS_SAPI_GMM, bss_nu++,
4075 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
4076
4077 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
4078 OSMO_ASSERT(!expect_msg());
4079
4080 dump_peers(stdout, 0, 0, &gbcfg);
4081
4082 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
4083 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4084 OSMO_ASSERT(link_info);
4085 OSMO_ASSERT(link_info->is_deregistered);
4086
4087 /* Bad case: Unexpected Re-Attach with IMSI after completed attachment
4088 * procedure */
4089 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
4090 foreign_tlli, &rai_bss, cell_id,
4091 GPRS_SAPI_GMM, bss_nu++,
4092 dtap_attach_req3, sizeof(dtap_attach_req3));
4093
4094 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
4095
4096 dump_peers(stdout, 0, 0, &gbcfg);
4097
4098 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4099 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
4100 OSMO_ASSERT(link_info);
4101 OSMO_ASSERT(link_info == link_info2);
4102 OSMO_ASSERT(link_info->imsi_len != 0);
4103 OSMO_ASSERT(!link_info->is_deregistered);
4104 OSMO_ASSERT(!link_info->imsi_acq_pending);
4105
4106 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
4107 foreign_tlli, 1, imsi, sizeof(imsi),
4108 GPRS_SAPI_GMM, sgsn_nu++,
4109 dtap_attach_acc, sizeof(dtap_attach_acc));
4110
4111 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
4112
4113 dump_peers(stdout, 0, 0, &gbcfg);
4114
4115 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
4116 local_tlli, &rai_bss, cell_id,
4117 GPRS_SAPI_GMM, bss_nu++,
4118 dtap_attach_complete, sizeof(dtap_attach_complete));
4119
4120 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
4121
4122 dump_peers(stdout, 0, 0, &gbcfg);
4123
4124 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
4125 local_tlli, 1, imsi, sizeof(imsi),
4126 GPRS_SAPI_GMM, sgsn_nu++,
4127 dtap_gmm_information, sizeof(dtap_gmm_information));
4128
4129 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
4130
4131 dump_peers(stdout, 0, 0, &gbcfg);
4132
4133 send_llc_ul_ui(nsi, "ATTACH REQUEST (unexpected, IMSI)",
4134 &bss_peer[0], 0x1002,
4135 foreign_tlli, &rai_bss, cell_id,
4136 GPRS_SAPI_GMM, bss_nu++,
4137 dtap_attach_req4, sizeof(dtap_attach_req4));
4138
4139 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
4140
4141 dump_peers(stdout, 0, 0, &gbcfg);
4142
4143 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4144 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
Jacob Erlbeck0bc746f2014-10-30 17:15:43 +01004145 OSMO_ASSERT(link_info);
Jacob Erlbeckb0f61292014-10-31 10:43:44 +01004146 OSMO_ASSERT(link_info == link_info2);
4147 OSMO_ASSERT(link_info->imsi_len != 0);
4148 OSMO_ASSERT(!link_info->is_deregistered);
4149 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck0bc746f2014-10-30 17:15:43 +01004150 OSMO_ASSERT(link_info->sgsn_tlli.current == foreign_tlli);
Jacob Erlbeckb0f61292014-10-31 10:43:44 +01004151 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
4152
4153 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
4154 foreign_tlli, 1, imsi, sizeof(imsi),
4155 GPRS_SAPI_GMM, sgsn_nu++,
4156 dtap_attach_acc, sizeof(dtap_attach_acc));
4157
4158 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
4159
4160 dump_peers(stdout, 0, 0, &gbcfg);
4161
4162 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
4163 local_tlli, &rai_bss, cell_id,
4164 GPRS_SAPI_GMM, bss_nu++,
4165 dtap_attach_complete, sizeof(dtap_attach_complete));
4166
4167 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
4168
4169 dump_peers(stdout, 0, 0, &gbcfg);
4170
4171 /* Detach (MT) */
4172 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
4173 local_tlli, 1, imsi, sizeof(imsi),
4174 GPRS_SAPI_GMM, sgsn_nu++,
4175 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
4176
4177 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
4178
4179 dump_peers(stdout, 0, 0, &gbcfg);
4180
4181 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
4182 OSMO_ASSERT(link_info);
4183
4184 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
4185 local_tlli, &rai_bss, cell_id,
4186 GPRS_SAPI_GMM, bss_nu++,
4187 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
4188
4189 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
4190 OSMO_ASSERT(!expect_msg());
4191
4192 dump_peers(stdout, 0, 0, &gbcfg);
4193
4194 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
4195 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4196 OSMO_ASSERT(link_info);
4197 OSMO_ASSERT(link_info->is_deregistered);
4198
4199 /* Bad case: Unexpected Re-Attach with P-TMSI after completed attachment
4200 * procedure */
4201 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
4202 foreign_tlli, &rai_bss, cell_id,
4203 GPRS_SAPI_GMM, bss_nu++,
4204 dtap_attach_req3, sizeof(dtap_attach_req3));
4205
4206 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
4207
4208 dump_peers(stdout, 0, 0, &gbcfg);
4209
4210 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4211 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
4212 OSMO_ASSERT(link_info);
4213 OSMO_ASSERT(link_info == link_info2);
4214 OSMO_ASSERT(link_info->imsi_len != 0);
4215 OSMO_ASSERT(!link_info->is_deregistered);
4216 OSMO_ASSERT(!link_info->imsi_acq_pending);
4217
4218 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
4219 foreign_tlli, 1, imsi, sizeof(imsi),
4220 GPRS_SAPI_GMM, sgsn_nu++,
4221 dtap_attach_acc, sizeof(dtap_attach_acc));
4222
4223 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
4224
4225 dump_peers(stdout, 0, 0, &gbcfg);
4226
4227 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
4228 local_tlli, &rai_bss, cell_id,
4229 GPRS_SAPI_GMM, bss_nu++,
4230 dtap_attach_complete, sizeof(dtap_attach_complete));
4231
4232 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
4233
4234 dump_peers(stdout, 0, 0, &gbcfg);
4235
4236 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
4237 local_tlli, 1, imsi, sizeof(imsi),
4238 GPRS_SAPI_GMM, sgsn_nu++,
4239 dtap_gmm_information, sizeof(dtap_gmm_information));
4240
4241 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_INFO));
4242
4243 dump_peers(stdout, 0, 0, &gbcfg);
4244
4245 send_llc_ul_ui(nsi, "ATTACH REQUEST (unexpected)", &bss_peer[0], 0x1002,
4246 foreign_tlli, &rai_bss, cell_id,
4247 GPRS_SAPI_GMM, bss_nu++,
4248 dtap_attach_req3, sizeof(dtap_attach_req3));
4249
4250 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
4251
4252 dump_peers(stdout, 0, 0, &gbcfg);
4253
4254 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4255 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
Jacob Erlbeck0bc746f2014-10-30 17:15:43 +01004256 OSMO_ASSERT(link_info);
Jacob Erlbeckb0f61292014-10-31 10:43:44 +01004257 OSMO_ASSERT(link_info == link_info2);
4258 OSMO_ASSERT(link_info->imsi_len != 0);
4259 OSMO_ASSERT(!link_info->is_deregistered);
4260 OSMO_ASSERT(!link_info->imsi_acq_pending);
Jacob Erlbeck0bc746f2014-10-30 17:15:43 +01004261 OSMO_ASSERT(link_info->sgsn_tlli.current == foreign_tlli);
Jacob Erlbeckb0f61292014-10-31 10:43:44 +01004262 OSMO_ASSERT(link_info->sgsn_tlli.assigned == 0);
4263
4264 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
4265 foreign_tlli, 1, imsi, sizeof(imsi),
4266 GPRS_SAPI_GMM, sgsn_nu++,
4267 dtap_attach_acc, sizeof(dtap_attach_acc));
4268
4269 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_ACK));
4270
4271 dump_peers(stdout, 0, 0, &gbcfg);
4272
4273 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
4274 local_tlli, &rai_bss, cell_id,
4275 GPRS_SAPI_GMM, bss_nu++,
4276 dtap_attach_complete, sizeof(dtap_attach_complete));
4277
4278 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_COMPL));
4279
4280 dump_peers(stdout, 0, 0, &gbcfg);
4281
4282 /* Detach (MT) */
4283 send_llc_dl_ui(nsi, "DETACH REQ", &sgsn_peer, 0x1002,
4284 local_tlli, 1, imsi, sizeof(imsi),
4285 GPRS_SAPI_GMM, sgsn_nu++,
4286 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
4287
4288 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
4289
4290 dump_peers(stdout, 0, 0, &gbcfg);
4291
4292 link_info = gbproxy_link_info_by_tlli(peer, local_tlli);
4293 OSMO_ASSERT(link_info);
4294
4295 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
4296 local_tlli, &rai_bss, cell_id,
4297 GPRS_SAPI_GMM, bss_nu++,
4298 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
4299
4300 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
4301 OSMO_ASSERT(!expect_msg());
4302
4303 dump_peers(stdout, 0, 0, &gbcfg);
4304
4305 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, local_tlli));
4306 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4307 OSMO_ASSERT(link_info);
4308 OSMO_ASSERT(link_info->is_deregistered);
4309
4310
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004311 /* Attach rejected */
4312
4313 gbproxy_delete_link_infos(peer);
4314
4315 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
4316 foreign_tlli, &rai_bss, cell_id,
4317 GPRS_SAPI_GMM, bss_nu++,
4318 dtap_attach_req, sizeof(dtap_attach_req));
4319
Jacob Erlbecka926e542014-09-22 19:16:06 +02004320 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
4321
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004322 dump_peers(stdout, 0, 0, &gbcfg);
4323
4324 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
4325 OSMO_ASSERT(link_info);
4326 OSMO_ASSERT(link_info->imsi_len == 0);
4327 OSMO_ASSERT(!link_info->is_deregistered);
4328 OSMO_ASSERT(link_info->imsi_acq_pending);
4329
4330 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
4331 foreign_tlli, &rai_bss, cell_id,
4332 GPRS_SAPI_GMM, bss_nu++,
4333 dtap_identity_resp, sizeof(dtap_identity_resp));
4334
Jacob Erlbecka926e542014-09-22 19:16:06 +02004335 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
4336
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004337 dump_peers(stdout, 0, 0, &gbcfg);
4338
4339 link_info2 = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4340 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
4341 OSMO_ASSERT(link_info);
4342 OSMO_ASSERT(link_info == link_info2);
4343 OSMO_ASSERT(link_info->imsi_len != 0);
4344 OSMO_ASSERT(!link_info->is_deregistered);
4345 OSMO_ASSERT(!link_info->imsi_acq_pending);
4346
4347 send_llc_dl_ui(nsi, "ATTACH REJECT", &sgsn_peer, 0x1002,
4348 foreign_tlli, 1, imsi, sizeof(imsi),
4349 GPRS_SAPI_GMM, sgsn_nu++,
4350 dtap_attach_rej7, sizeof(dtap_attach_rej7));
4351
Jacob Erlbecka926e542014-09-22 19:16:06 +02004352 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ATTACH_REJ));
4353
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004354 dump_peers(stdout, 0, 0, &gbcfg);
4355
Jacob Erlbeck538bee02014-09-22 10:42:05 +02004356 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
4357
Jacob Erlbecka926e542014-09-22 19:16:06 +02004358 OSMO_ASSERT(!expect_msg());
4359
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004360 /* Attach (incomplete) and Detach (MO) */
4361
4362 gbproxy_delete_link_infos(peer);
4363
4364 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
4365 foreign_tlli, &rai_bss, cell_id,
4366 GPRS_SAPI_GMM, bss_nu++,
4367 dtap_attach_req, sizeof(dtap_attach_req));
4368
Jacob Erlbecka926e542014-09-22 19:16:06 +02004369 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
4370
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004371 dump_peers(stdout, 0, 0, &gbcfg);
4372
4373 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
4374 OSMO_ASSERT(link_info);
4375 OSMO_ASSERT(link_info->imsi_len == 0);
4376 OSMO_ASSERT(!link_info->is_deregistered);
4377 OSMO_ASSERT(link_info->imsi_acq_pending);
4378
4379 send_llc_ul_ui(nsi, "DETACH REQ (MO)", &bss_peer[0], 0x1002,
4380 foreign_tlli, &rai_bss, cell_id,
4381 GPRS_SAPI_GMM, bss_nu++,
4382 dtap_detach_req, sizeof(dtap_detach_req));
4383
Jacob Erlbecka926e542014-09-22 19:16:06 +02004384 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_ACK));
4385
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004386 dump_peers(stdout, 0, 0, &gbcfg);
4387
Jacob Erlbecka926e542014-09-22 19:16:06 +02004388 OSMO_ASSERT(!expect_msg());
4389
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004390 /* Attach (incomplete) and Detach (MT) */
4391
4392 gbproxy_delete_link_infos(peer);
4393
4394 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
4395 foreign_tlli, &rai_bss, cell_id,
4396 GPRS_SAPI_GMM, bss_nu++,
4397 dtap_attach_req, sizeof(dtap_attach_req));
4398
Jacob Erlbecka926e542014-09-22 19:16:06 +02004399 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_ID_REQ));
4400
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004401 dump_peers(stdout, 0, 0, &gbcfg);
4402
4403 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
4404 OSMO_ASSERT(link_info);
4405 OSMO_ASSERT(link_info->imsi_len == 0);
4406 OSMO_ASSERT(!link_info->is_deregistered);
4407 OSMO_ASSERT(link_info->imsi_acq_pending);
4408
4409 send_llc_dl_ui(nsi, "DETACH REQ (MT)", &sgsn_peer, 0x1002,
4410 foreign_tlli, 1, imsi, sizeof(imsi),
4411 GPRS_SAPI_GMM, sgsn_nu++,
4412 dtap_mt_detach_req, sizeof(dtap_mt_detach_req));
4413
Jacob Erlbecka926e542014-09-22 19:16:06 +02004414 OSMO_ASSERT(expect_gmm_msg(0x1000, 0x1002, GSM48_MT_GMM_DETACH_REQ));
4415
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004416 dump_peers(stdout, 0, 0, &gbcfg);
4417
4418 link_info = gbproxy_link_info_by_tlli(peer, foreign_tlli);
4419 OSMO_ASSERT(link_info);
4420
Jacob Erlbecka926e542014-09-22 19:16:06 +02004421 send_llc_ul_ui(nsi, "DETACH ACC", &bss_peer[0], 0x1002,
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004422 foreign_tlli, &rai_bss, cell_id,
4423 GPRS_SAPI_GMM, bss_nu++,
4424 dtap_mt_detach_acc, sizeof(dtap_mt_detach_acc));
4425
Jacob Erlbecka926e542014-09-22 19:16:06 +02004426 /* TODO: The stored messaged should be cleaned when receiving a Detach
4427 * Ack. Remove the first OSMO_ASSERT when this is fixed. */
4428 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_ATTACH_REQ));
4429 OSMO_ASSERT(expect_gmm_msg(SGSN_NSEI, 0x1002, GSM48_MT_GMM_DETACH_ACK));
4430
Jacob Erlbeck73e4f5f2014-09-22 11:26:58 +02004431 dump_peers(stdout, 0, 0, &gbcfg);
4432
4433 OSMO_ASSERT(!gbproxy_link_info_by_tlli(peer, foreign_tlli));
4434 link_info = gbproxy_link_info_by_imsi(peer, imsi, sizeof(imsi));
4435 OSMO_ASSERT(link_info);
4436 OSMO_ASSERT(link_info->is_deregistered);
4437
Jacob Erlbecka926e542014-09-22 19:16:06 +02004438 OSMO_ASSERT(!expect_msg());
4439 received_messages = NULL;
4440
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02004441 dump_global(stdout, 0);
4442
4443 gbprox_reset(&gbcfg);
4444 gprs_ns_destroy(nsi);
4445 nsi = NULL;
Daniel Willmann1e0b0002015-10-12 19:36:34 +02004446
4447 cleanup_test();
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02004448}
4449
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004450struct gbproxy_link_info *register_tlli(
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004451 struct gbproxy_peer *peer, uint32_t tlli,
4452 const uint8_t *imsi, size_t imsi_len, time_t now)
4453{
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004454 struct gbproxy_link_info *link_info;
Jacob Erlbeck070702b2014-09-19 13:17:55 +02004455 int imsi_matches = -1;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004456 int tlli_already_known = 0;
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004457 struct gbproxy_config *cfg = peer->cfg;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004458
4459 /* Check, whether the IMSI matches */
4460 if (gprs_is_mi_imsi(imsi, imsi_len)) {
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004461 imsi_matches = gbproxy_check_imsi(
4462 &cfg->matches[GBPROX_MATCH_PATCHING], imsi, imsi_len);
Jacob Erlbeck070702b2014-09-19 13:17:55 +02004463 if (imsi_matches < 0)
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004464 return NULL;
4465 }
4466
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004467 link_info = gbproxy_link_info_by_tlli(peer, tlli);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004468
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004469 if (!link_info) {
4470 link_info = gbproxy_link_info_by_imsi(peer, imsi, imsi_len);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004471
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004472 if (link_info) {
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004473 /* TLLI has changed somehow, adjust it */
4474 LOGP(DGPRS, LOGL_INFO,
4475 "The TLLI has changed from %08x to %08x\n",
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004476 link_info->tlli.current, tlli);
4477 link_info->tlli.current = tlli;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004478 }
4479 }
4480
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004481 if (!link_info) {
4482 link_info = gbproxy_link_info_alloc(peer);
4483 link_info->tlli.current = tlli;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004484 } else {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004485 gbproxy_detach_link_info(peer, link_info);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004486 tlli_already_known = 1;
4487 }
4488
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004489 OSMO_ASSERT(link_info != NULL);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004490
4491 if (!tlli_already_known)
4492 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
4493
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004494 gbproxy_attach_link_info(peer, now, link_info);
4495 gbproxy_update_link_info(link_info, imsi, imsi_len);
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004496
Jacob Erlbeck070702b2014-09-19 13:17:55 +02004497 if (imsi_matches >= 0)
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004498 link_info->is_matching[GBPROX_MATCH_PATCHING] = imsi_matches;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004499
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004500 return link_info;
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004501}
4502
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004503static void test_gbproxy_tlli_expire(void)
4504{
4505 struct gbproxy_config cfg = {0};
4506 struct gbproxy_peer *peer;
4507 const char *err_msg = NULL;
4508 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
4509 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004510 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004511 const uint32_t tlli1 = 1234 | 0xc0000000;
4512 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004513 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004514 const char *filter_re = ".*";
Jacob Erlbeckc404c082014-08-08 08:37:37 +02004515 time_t now = 1407479214;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004516
4517 printf("Test TLLI info expiry\n\n");
4518
4519 gbproxy_init_config(&cfg);
4520
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004521 if (gbproxy_set_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING],
4522 filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004523 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
4524 err_msg);
4525 OSMO_ASSERT(err_msg == NULL);
4526 }
4527
4528 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004529 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004530
4531 printf("Test TLLI replacement:\n");
4532
4533 cfg.tlli_max_len = 0;
4534 cfg.tlli_max_age = 0;
4535 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004536 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004537
4538 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004539 link_info = register_tlli(peer, tlli1,
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004540 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004541 OSMO_ASSERT(link_info);
4542 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004543 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004544
4545 /* replace the old entry */
4546 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004547 link_info = register_tlli(peer, tlli2,
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004548 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004549 OSMO_ASSERT(link_info);
4550 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004551 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004552
Jacob Erlbeckc404c082014-08-08 08:37:37 +02004553 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004554
4555 /* verify that 5678 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004556 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4557 OSMO_ASSERT(link_info);
4558 OSMO_ASSERT(link_info->tlli.current == tlli2);
4559 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4560 OSMO_ASSERT(!link_info);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004561
4562 printf("\n");
4563
4564 gbproxy_peer_free(peer);
4565 }
4566
4567 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004568 struct gbproxy_link_info *link_info;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004569
4570 printf("Test IMSI replacement:\n");
4571
4572 cfg.tlli_max_len = 0;
4573 cfg.tlli_max_age = 0;
4574 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004575 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004576
4577 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004578 link_info = register_tlli(peer, tlli1,
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004579 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004580 OSMO_ASSERT(link_info);
4581 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004582 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004583
4584 /* try to replace the old entry */
4585 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004586 link_info = register_tlli(peer, tlli1,
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004587 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004588 OSMO_ASSERT(link_info);
4589 OSMO_ASSERT(link_info->tlli.current == tlli1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004590 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004591
Jacob Erlbeckc404c082014-08-08 08:37:37 +02004592 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004593
4594 /* verify that 5678 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004595 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4596 OSMO_ASSERT(!link_info);
4597 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4598 OSMO_ASSERT(link_info);
4599 OSMO_ASSERT(link_info->tlli.current == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004600
4601 printf("\n");
4602
4603 gbproxy_peer_free(peer);
4604 }
4605
4606 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004607 struct gbproxy_link_info *link_info;
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02004608 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004609
4610 printf("Test TLLI expiry, max_len == 1:\n");
4611
4612 cfg.tlli_max_len = 1;
4613 cfg.tlli_max_age = 0;
4614 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004615 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004616
4617 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004618 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004619 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004620
4621 /* replace the old entry */
4622 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004623 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004624 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02004625
Jacob Erlbeckc4fb4c22014-09-19 16:40:21 +02004626 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02004627 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004628 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004629
Jacob Erlbeckc404c082014-08-08 08:37:37 +02004630 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004631
4632 /* verify that 5678 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004633 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4634 OSMO_ASSERT(!link_info);
4635 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4636 OSMO_ASSERT(link_info);
4637 OSMO_ASSERT(link_info->tlli.current == tlli2);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004638
4639 printf("\n");
4640
4641 gbproxy_peer_free(peer);
4642 }
4643
4644 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004645 struct gbproxy_link_info *link_info;
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02004646 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004647
4648 printf("Test TLLI expiry, max_age == 1:\n");
4649
4650 cfg.tlli_max_len = 0;
4651 cfg.tlli_max_age = 1;
4652 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004653 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004654
4655 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004656 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004657 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004658
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004659 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004660 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004661 now + 1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004662 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004663
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004664 num_removed = gbproxy_remove_stale_link_infos(peer, now + 2);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004665 OSMO_ASSERT(num_removed == 1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004666 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004667
4668 dump_peers(stdout, 2, now + 2, &cfg);
4669
Jacob Erlbeck383c8412014-08-12 16:30:30 +02004670 /* verify that 5678 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004671 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4672 OSMO_ASSERT(!link_info);
4673 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4674 OSMO_ASSERT(link_info);
4675 OSMO_ASSERT(link_info->tlli.current == tlli2);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02004676
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004677 printf("\n");
4678
4679 gbproxy_peer_free(peer);
4680 }
4681
4682 {
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004683 struct gbproxy_link_info *link_info;
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004684 int num_removed;
4685
4686 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
4687
4688 cfg.tlli_max_len = 0;
4689 cfg.tlli_max_age = 1;
4690 peer = gbproxy_peer_alloc(&cfg, 20);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004691 OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004692
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004693 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004694 register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004695 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004696
4697 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004698 register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004699 now + 1);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004700 OSMO_ASSERT(peer->patch_state.logical_link_count == 2);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004701
4702 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeckc68f66c2014-09-12 14:15:02 +02004703 register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004704 now + 2);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004705 OSMO_ASSERT(peer->patch_state.logical_link_count == 3);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004706
4707 dump_peers(stdout, 2, now + 2, &cfg);
4708
4709 printf(" Remove stale TLLIs\n");
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004710 num_removed = gbproxy_remove_stale_link_infos(peer, now + 3);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004711 OSMO_ASSERT(num_removed == 2);
Jacob Erlbeck485e28c2014-09-19 16:03:07 +02004712 OSMO_ASSERT(peer->patch_state.logical_link_count == 1);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02004713
4714 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004715
Jacob Erlbeck383c8412014-08-12 16:30:30 +02004716 /* verify that tlli3 has survived */
Jacob Erlbeck2b2406a2014-09-19 15:07:27 +02004717 link_info = gbproxy_link_info_by_imsi(peer, imsi1, ARRAY_SIZE(imsi1));
4718 OSMO_ASSERT(!link_info);
4719 link_info = gbproxy_link_info_by_imsi(peer, imsi2, ARRAY_SIZE(imsi2));
4720 OSMO_ASSERT(!link_info);
4721 link_info = gbproxy_link_info_by_imsi(peer, imsi3, ARRAY_SIZE(imsi3));
4722 OSMO_ASSERT(link_info);
4723 OSMO_ASSERT(link_info->tlli.current == tlli3);
Jacob Erlbeck383c8412014-08-12 16:30:30 +02004724
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004725 printf("\n");
4726
4727 gbproxy_peer_free(peer);
4728 }
Jacob Erlbeck8fbf44a2014-09-25 11:21:34 +02004729 gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]);
4730 gbprox_reset(&cfg);
Daniel Willmann1e0b0002015-10-12 19:36:34 +02004731
4732 cleanup_test();
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004733}
4734
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004735static void test_gbproxy_imsi_matching(void)
4736{
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004737 const char *err_msg = NULL;
4738 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
4739 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4740 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
4741 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
4742 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
4743 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
4744 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
4745 const char *filter_re1 = ".*";
4746 const char *filter_re2 = "^1234";
4747 const char *filter_re3 = "^4321";
4748 const char *filter_re4_bad = "^12[";
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004749 struct gbproxy_match match = {0,};
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004750
4751 printf("=== Test IMSI/TMSI matching ===\n\n");
4752
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004753 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004754
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004755 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re1, &err_msg) == 0);
4756 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004757
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004758 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4759 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004760
4761 err_msg = NULL;
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004762 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004763 OSMO_ASSERT(err_msg != NULL);
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004764 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004765
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004766 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4767 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004768
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004769 OSMO_ASSERT(gbproxy_set_patch_filter(&match, NULL, &err_msg) == 0);
4770 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004771
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004772 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4773 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeck581728f2014-08-14 08:57:04 +02004774
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004775 gbproxy_clear_patch_filter(&match);
4776 OSMO_ASSERT(match.enable == 0);
Jacob Erlbeck581728f2014-08-14 08:57:04 +02004777
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004778 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re2, &err_msg) == 0);
4779 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004780
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004781 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 1);
4782 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004783 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeckcf11e932014-08-19 12:21:01 +02004784 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004785 * case. */
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004786 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4787 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4788 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4789 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4790 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004791
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004792 OSMO_ASSERT(gbproxy_set_patch_filter(&match, filter_re3, &err_msg) == 0);
4793 OSMO_ASSERT(match.enable == 1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004794
Jacob Erlbeckf4290b02014-09-25 11:17:31 +02004795 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi1, ARRAY_SIZE(imsi1)) == 0);
4796 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi2, ARRAY_SIZE(imsi2)) == 0);
4797 OSMO_ASSERT(gbproxy_check_imsi(&match, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
4798 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
4799 OSMO_ASSERT(gbproxy_check_imsi(&match, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
4800 OSMO_ASSERT(gbproxy_check_imsi(&match, imei1, ARRAY_SIZE(imei1)) == -1);
4801 OSMO_ASSERT(gbproxy_check_imsi(&match, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004802
4803 /* TODO: Check correct length but wrong type with is_mi_tmsi */
Jacob Erlbeck8fbf44a2014-09-25 11:21:34 +02004804
4805 gbproxy_clear_patch_filter(&match);
4806 OSMO_ASSERT(match.enable == 0);
Daniel Willmann1e0b0002015-10-12 19:36:34 +02004807
4808 cleanup_test();
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004809}
4810
Daniel Willmann9f98d7b2016-11-08 15:29:30 +01004811static void test_gbproxy_stored_messages()
4812{
4813 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
4814 struct sockaddr_in bss_peer[1] = {{0},};
4815 struct sockaddr_in sgsn_peer= {0};
4816 struct gprs_ra_id rai_bss =
4817 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
4818 struct gprs_ra_id rai_unknown =
4819 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
4820 uint16_t cell_id = 0x1234;
4821
4822 const uint32_t ptmsi = 0xefe2b700;
4823 const uint32_t local_tlli = 0xefe2b700;
4824
4825 const uint32_t foreign_tlli1 = 0x8000dead;
4826
4827 struct gbproxy_peer *peer;
4828 unsigned bss_nu = 0;
4829 unsigned sgsn_nu = 0;
4830
4831 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
4832
4833 bssgp_nsi = nsi;
4834 gbcfg.nsi = bssgp_nsi;
4835 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Neels Hofmeyr6179f0c2018-02-21 00:39:36 +01004836 gbcfg.core_plmn = (struct osmo_plmn_id){};
Daniel Willmann9f98d7b2016-11-08 15:29:30 +01004837 gbcfg.core_apn = talloc_zero_size(NULL, 100);
4838 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
4839 gbcfg.patch_ptmsi = 0;
4840 gbcfg.acquire_imsi = 1;
4841 gbcfg.keep_link_infos = 0;
4842
4843 configure_sgsn_peer(&sgsn_peer);
4844 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
4845
4846 printf("=== %s ===\n", __func__);
4847 printf("--- Initialise SGSN ---\n\n");
4848
4849 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
4850
4851 printf("--- Initialise BSS 1 ---\n\n");
4852
4853 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
4854 setup_bssgp(nsi, &bss_peer[0], 0x1002);
4855
4856 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
4857 OSMO_ASSERT(peer != NULL);
4858
4859 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
4860
4861 gprs_dump_nsi(nsi);
4862 dump_global(stdout, 0);
4863 dump_peers(stdout, 0, 0, &gbcfg);
4864
4865 printf("--- Establish first LLC connection ---\n\n");
4866
4867 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
4868 foreign_tlli1, &rai_unknown, cell_id,
4869 GPRS_SAPI_GMM, bss_nu++,
4870 dtap_attach_req, sizeof(dtap_attach_req));
4871
4872 dump_peers(stdout, 0, 0, &gbcfg);
4873
4874 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
4875 foreign_tlli1, 0, NULL, 0,
4876 GPRS_SAPI_GMM, sgsn_nu++,
4877 dtap_identity_req, sizeof(dtap_identity_req));
4878
4879 dump_peers(stdout, 0, 0, &gbcfg);
4880
4881 send_llc_ul_ui(nsi, "DETACH ACCEPT", &bss_peer[0], 0x1002,
4882 foreign_tlli1, &rai_bss, cell_id,
4883 GPRS_SAPI_GMM, bss_nu++,
4884 dtap_detach_acc, sizeof(dtap_detach_acc));
4885
4886 dump_peers(stdout, 0, 0, &gbcfg);
4887
4888 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
4889 foreign_tlli1, &rai_bss, cell_id,
4890 GPRS_SAPI_GMM, bss_nu++,
4891 dtap_identity_resp, sizeof(dtap_identity_resp));
4892
4893 dump_peers(stdout, 0, 0, &gbcfg);
4894
4895 dump_global(stdout, 0);
4896
4897 gbprox_reset(&gbcfg);
4898 gprs_ns_destroy(nsi);
4899 nsi = NULL;
4900
4901 cleanup_test();
4902}
4903
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02004904static struct log_info_cat gprs_categories[] = {
4905 [DGPRS] = {
4906 .name = "DGPRS",
4907 .description = "GPRS Packet Service",
4908 .enabled = 1, .loglevel = LOGL_DEBUG,
4909 },
4910 [DNS] = {
4911 .name = "DNS",
4912 .description = "GPRS Network Service (NS)",
4913 .enabled = 1, .loglevel = LOGL_INFO,
4914 },
4915 [DBSSGP] = {
4916 .name = "DBSSGP",
4917 .description = "GPRS BSS Gateway Protocol (BSSGP)",
4918 .enabled = 1, .loglevel = LOGL_DEBUG,
4919 },
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02004920};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004921
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02004922static struct log_info info = {
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02004923 .cat = gprs_categories,
4924 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02004925};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004926
4927int main(int argc, char **argv)
4928{
Neels Hofmeyr20215f12016-09-16 02:31:17 +02004929 msgb_talloc_ctx_init(NULL, 0);
4930
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004931 osmo_init_logging(&info);
4932 log_set_use_color(osmo_stderr_target, 0);
4933 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02004934 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004935
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02004936 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02004937 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
4938 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02004939
4940 rate_ctr_init(NULL);
4941
4942 setlinebuf(stdout);
4943
4944 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther5eaf1a22014-08-04 11:10:09 +02004945 gbproxy_init_config(&gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004946 test_gbproxy();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02004947 test_gbproxy_ident_changes();
Jacob Erlbeckb6799772014-08-07 10:46:29 +02004948 test_gbproxy_imsi_matching();
Jacob Erlbeck571aec32014-09-18 09:21:20 +02004949 test_gbproxy_ptmsi_assignment();
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02004950 test_gbproxy_ra_patching();
Jacob Erlbeck70e00de2014-08-15 17:20:06 +02004951 test_gbproxy_ptmsi_patching();
Jacob Erlbeckf7d1b4e2014-10-20 16:25:01 +02004952 test_gbproxy_ptmsi_patching_bad_cases();
Jacob Erlbeckbfed3b22014-08-26 13:33:36 +02004953 test_gbproxy_imsi_acquisition();
Jacob Erlbeck12356062014-08-27 12:44:25 +02004954 test_gbproxy_secondary_sgsn();
Jacob Erlbeck2c74e442014-09-15 14:18:09 +02004955 test_gbproxy_keep_info();
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02004956 test_gbproxy_tlli_expire();
Daniel Willmann9f98d7b2016-11-08 15:29:30 +01004957 test_gbproxy_stored_messages();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02004958 printf("===== GbProxy test END\n\n");
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02004959
4960 exit(EXIT_SUCCESS);
4961}