blob: 4e40f330143f9074eb862da963010a8eb5a41f9b [file] [log] [blame]
Jacob Erlbeck51a869c2013-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 Freytherb9004592014-08-04 11:26:54 +020016#include <time.h>
Jacob Erlbeck51a869c2013-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 Erlbeckb1381062014-07-01 12:41:13 +020027#include <osmocom/gsm/tlv.h>
Jacob Erlbeck59748e62014-08-11 17:26:21 +020028#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020029#include <osmocom/gprs/gprs_msgb.h>
30#include <osmocom/gprs/gprs_ns.h>
31#include <osmocom/gprs/gprs_bssgp.h>
32
33#include <openbsc/gb_proxy.h>
Holger Hans Peter Freyther7127b022014-08-04 11:52:52 +020034#include <openbsc/gprs_utils.h>
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +020035#include <openbsc/gprs_llc.h>
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020036#include <openbsc/debug.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020037
38#define REMOTE_BSS_ADDR 0x01020304
39#define REMOTE_SGSN_ADDR 0x05060708
40
Jacob Erlbeck2082afa2013-10-18 13:04:47 +020041#define SGSN_NSEI 0x0100
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020042
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +020043#define REMOTE_SGSN2_ADDR 0x15161718
44#define SGSN2_NSEI 0x0102
45
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020046struct gbproxy_config gbcfg = {0};
47
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020048static int dump_global(FILE *stream, int indent)
49{
50 unsigned int i;
51 const struct rate_ctr_group_desc *desc;
52 int rc;
53
54 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
55 if (rc < 0)
56 return rc;
57
58 desc = gbcfg.ctrg->desc;
59
60 for (i = 0; i < desc->num_ctr; i++) {
61 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
62 if (ctr->current) {
63 rc = fprintf(stream, "%*s %s: %llu\n",
64 indent, "",
65 desc->ctr_desc[i].description,
66 (long long)ctr->current);
67
68 if (rc < 0)
69 return rc;
70 }
71 }
72
73 return 0;
74}
75
Jacob Erlbeck7b821d02014-08-08 08:37:37 +020076static int dump_peers(FILE *stream, int indent, time_t now,
77 struct gbproxy_config *cfg)
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020078{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020079 struct gbproxy_peer *peer;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020080 struct gprs_ra_id raid;
81 unsigned int i;
82 const struct rate_ctr_group_desc *desc;
83 int rc;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020084
85 rc = fprintf(stream, "%*sPeers:\n", indent, "");
86 if (rc < 0)
87 return rc;
88
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +020089 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020090 struct gbproxy_tlli_info *tlli_info;
91 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020092 gsm48_parse_ra(&raid, peer->ra);
93
94 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
95 "RAI %u-%u-%u-%u\n",
96 indent, "",
97 peer->nsei, peer->bvci,
98 peer->blocked ? "" : "not ",
99 raid.mcc, raid.mnc, raid.lac, raid.rac);
100
101 if (rc < 0)
102 return rc;
103
104 desc = peer->ctrg->desc;
105
106 for (i = 0; i < desc->num_ctr; i++) {
107 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
108 if (ctr->current) {
109 rc = fprintf(stream, "%*s %s: %llu\n",
110 indent, "",
111 desc->ctr_desc[i].description,
112 (long long)ctr->current);
113
114 if (rc < 0)
115 return rc;
116 }
117 }
118
119 fprintf(stream, "%*s TLLI-Cache: %d\n",
120 indent, "", state->enabled_tllis_count);
121 llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
122 char mi_buf[200];
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200123 time_t age = now ? now - tlli_info->timestamp : 0;
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200124 int stored_msgs = 0;
125 struct llist_head *iter;
126 llist_for_each(iter, &tlli_info->stored_msgs)
127 stored_msgs++;
128
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200129 if (tlli_info->mi_data_len > 0) {
130 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
131 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
132 tlli_info->mi_data,
133 tlli_info->mi_data_len);
134 } else {
135 snprintf(mi_buf, sizeof(mi_buf), "(none)");
136 }
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200137 fprintf(stream, "%*s TLLI %08x",
Jacob Erlbeck9057bc32014-08-12 16:30:30 +0200138 indent, "", tlli_info->tlli.current);
139 if (tlli_info->tlli.assigned)
140 fprintf(stream, "/%08x", tlli_info->tlli.assigned);
141 if (tlli_info->sgsn_tlli.current) {
142 fprintf(stream, " -> %08x",
143 tlli_info->sgsn_tlli.current);
144 if (tlli_info->sgsn_tlli.assigned)
145 fprintf(stream, "/%08x",
146 tlli_info->sgsn_tlli.assigned);
147 }
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200148 fprintf(stream, ", IMSI %s, AGE %d",
149 mi_buf, (int)age);
150
Jacob Erlbeckea1698e2014-09-02 14:40:11 +0200151 if (stored_msgs)
152 fprintf(stream, ", STORED %d", stored_msgs);
153
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200154 if (cfg->check_imsi && tlli_info->enable_patching)
155 fprintf(stream, ", IMSI matches");
156
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200157 if (tlli_info->imsi_acq_pending)
158 fprintf(stream, ", IMSI acquisition in progress");
159
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200160 rc = fprintf(stream, "\n");
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200161 if (rc < 0)
162 return rc;
163 }
164 }
165
166 return 0;
167}
168
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +0200169const uint8_t *convert_ra(struct gprs_ra_id *raid)
170{
171 static uint8_t buf[6];
172 gsm48_construct_ra(buf, raid);
173 return buf;
174}
175
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200176/* DTAP - Attach Request */
177static const unsigned char dtap_attach_req[] = {
178 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21, 0x08, 0x02,
179 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79, 0x11, 0x22,
180 0x33, 0x40, 0x50, 0x60, 0x19, 0x18, 0xb3, 0x43,
181 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80, 0x9a,
182 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba, 0xc8,
183 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200184};
185
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200186/* DTAP - Identity Request */
187static const unsigned char dtap_identity_req[] = {
188 0x08, 0x15, 0x01
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200189};
190
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200191/* DTAP - Identity Response */
192static const unsigned char dtap_identity_resp[] = {
193 0x08, 0x16, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15,
194 0x16, 0x17, 0x18
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200195};
196
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200197/* DTAP - Identity Response, IMSI 2 */
198static const unsigned char dtap_identity2_resp[] = {
199 0x08, 0x16, 0x08, 0x11, 0x12, 0x99, 0x99, 0x99,
200 0x16, 0x17, 0x18
201};
202
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200203/* DTAP - Attach Accept */
204static const unsigned char dtap_attach_acc[] = {
205 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
206 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
207 0x16, 0x18, 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200208};
209
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200210/* DTAP - Attach Accept, P-TMSI 2 */
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200211static const unsigned char dtap_attach_acc2[] = {
212 0x08, 0x02, 0x01, 0x49, 0x04, 0x21, 0x63, 0x54,
213 0x40, 0x50, 0x60, 0x19, 0xcd, 0xd7, 0x08, 0x17,
214 0x16, 0x18, 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54
215};
216
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200217/* DTAP - Attach Complete */
218static const unsigned char dtap_attach_complete[] = {
219 0x08, 0x03
Jacob Erlbeck59748e62014-08-11 17:26:21 +0200220};
221
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200222/* DTAP - GMM Information */
223static const unsigned char dtap_gmm_information[] = {
224 0x08, 0x21
Jacob Erlbeck11669742014-06-06 18:47:36 +0200225};
226
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200227/* DTAP - Routing Area Update Request */
228static const unsigned char dtap_ra_upd_req[] = {
229 0x08, 0x08, 0x10, 0x11, 0x22, 0x33, 0x40, 0x50,
230 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33, 0x57, 0x2b,
231 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48, 0x50, 0xc8,
232 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8, 0x48, 0x02,
233 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02, 0x00, 0x19,
234 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27, 0x07, 0x04,
235 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02, 0x20, 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200236};
237
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200238/* DTAP - Routing Area Update Accept */
239static const unsigned char dtap_ra_upd_acc[] = {
240 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
241 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
242 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200243};
244
Jacob Erlbeck52f070a2014-09-04 13:45:56 +0200245/* DTAP - Routing Area Update Accept, P-TMSI 2 */
246static const unsigned char dtap_ra_upd_acc2[] = {
247 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
248 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
249 0x05, 0xf4, 0xe0, 0x98, 0x76, 0x54, 0x17, 0x16,
250};
251
252/* DTAP - Routing Area Update Accept, P-TMSI 3 */
253static const unsigned char dtap_ra_upd_acc3[] = {
254 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
255 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
256 0x05, 0xf4, 0xe0, 0x54, 0x32, 0x10, 0x17, 0x16,
257};
258
259/* DTAP - Routing Area Update Complete */
260static const unsigned char dtap_ra_upd_complete[] = {
261 0x08, 0x0a
262};
263
264
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200265/* DTAP - Activate PDP Context Request */
266static const unsigned char dtap_act_pdp_ctx_req[] = {
267 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200268 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
270 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
271 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
272 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200273 0x00
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200274};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200275
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200276/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200277/* normal detach, power_off = 1 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200278static const unsigned char dtap_detach_po_req[] = {
279 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4, 0xef, 0xe2,
280 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200281};
282
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200283/* DTAP - Detach Request (MO) */
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200284/* normal detach, power_off = 0 */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200285static const unsigned char dtap_detach_req[] = {
286 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4, 0xef, 0xe2,
287 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97, 0xcb
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200288};
289
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200290/* DTAP - Detach Accept */
291static const unsigned char dtap_detach_acc[] = {
292 0x08, 0x06, 0x00
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200293};
294
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +0200295/* GPRS-LLC - SAPI: LLGMM, U, XID */
296static const unsigned char llc_u_xid_ul[] = {
297 0x41, 0xfb, 0x01, 0x00, 0x0e, 0x00, 0x64, 0x11,
298 0x05, 0x16, 0x01, 0x90, 0x66, 0xb3, 0x28
299};
300
301/* GPRS-LLC - SAPI: LLGMM, U, XID */
302static const unsigned char llc_u_xid_dl[] = {
303 0x41, 0xfb, 0x30, 0x84, 0x10, 0x61, 0xb6, 0x64,
304 0xe4, 0xa9, 0x1a, 0x9e
305};
306
307/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
308static const unsigned char llc_ui_ll11_dns_query_ul[] = {
309 0x0b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
310 0x00, 0x00, 0x38, 0x95, 0x72, 0x00, 0x00, 0x45,
311 0x11, 0x20, 0x85, 0x0a, 0xc0, 0x07, 0xe4, 0xac,
312 0x10, 0x01, 0x0a, 0xad, 0xab, 0x00, 0x35, 0x00,
313 0x24, 0x0e, 0x1c, 0x3b, 0xe0, 0x01, 0x00, 0x00,
314 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
315 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
316 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0x47,
317 0x8f, 0x07
318};
319
320/* GPRS-LLC - SAPI: LL11, UI, NSAPI 5, DNS query */
321static const unsigned char llc_ui_ll11_dns_resp_dl[] = {
322 0x4b, 0xc0, 0x01, 0x65, 0x00, 0x00, 0x00, 0x45,
323 0x00, 0x00, 0xc6, 0x00, 0x00, 0x40, 0x00, 0x3e,
324 0x11, 0x7c, 0x69, 0xac, 0x10, 0x01, 0x0a, 0x0a,
325 0xc0, 0x07, 0xe4, 0x00, 0x35, 0xad, 0xab, 0x00,
326 0xb2, 0x74, 0x4e, 0x3b, 0xe0, 0x81, 0x80, 0x00,
327 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x01,
328 0x6d, 0x05, 0x68, 0x65, 0x69, 0x73, 0x65, 0x02,
329 0x64, 0x65, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
330 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
331 0x10, 0x00, 0x04, 0xc1, 0x63, 0x90, 0x58, 0xc0,
332 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
333 0x10, 0x00, 0x16, 0x03, 0x6e, 0x73, 0x32, 0x0c,
334 0x70, 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e,
335 0x6f, 0x76, 0x65, 0x72, 0x03, 0x6e, 0x65, 0x74,
336 0x00, 0xc0, 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00,
337 0x00, 0x0e, 0x10, 0x00, 0x10, 0x02, 0x6e, 0x73,
338 0x01, 0x73, 0x08, 0x70, 0x6c, 0x75, 0x73, 0x6c,
339 0x69, 0x6e, 0x65, 0xc0, 0x14, 0xc0, 0x0e, 0x00,
340 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00,
341 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x0e, 0xc0, 0x0e,
342 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10,
343 0x00, 0x05, 0x02, 0x6e, 0x73, 0xc0, 0x5f, 0xc0,
344 0x0e, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x0e,
345 0x10, 0x00, 0x12, 0x02, 0x6e, 0x73, 0x0c, 0x70,
346 0x6f, 0x70, 0x2d, 0x68, 0x61, 0x6e, 0x6e, 0x6f,
347 0x76, 0x65, 0x72, 0xc0, 0x14, 0xaa, 0xdf, 0x31
348};
349
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200350static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
351 struct sockaddr_in *peer, const unsigned char* data,
352 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200353
354static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
355 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
356{
357 /* GPRS Network Service, PDU type: NS_RESET,
358 */
359 unsigned char msg[12] = {
360 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
361 0x04, 0x82, 0x11, 0x22
362 };
363
364 msg[3] = cause;
365 msg[6] = nsvci / 256;
366 msg[7] = nsvci % 256;
367 msg[10] = nsei / 256;
368 msg[11] = nsei % 256;
369
370 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
371}
372
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200373static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
374 uint16_t nsvci, uint16_t nsei)
375{
376 /* GPRS Network Service, PDU type: NS_RESET_ACK,
377 */
378 unsigned char msg[9] = {
379 0x03, 0x01, 0x82, 0x11, 0x22,
380 0x04, 0x82, 0x11, 0x22
381 };
382
383 msg[3] = nsvci / 256;
384 msg[4] = nsvci % 256;
385 msg[7] = nsei / 256;
386 msg[8] = nsei % 256;
387
388 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
389}
390
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200391static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
392{
393 /* GPRS Network Service, PDU type: NS_ALIVE */
394 unsigned char msg[1] = {
395 0x0a
396 };
397
398 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
399}
400
401static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
402{
403 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
404 unsigned char msg[1] = {
405 0x0b
406 };
407
408 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
409}
410
411static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
412{
413 /* GPRS Network Service, PDU type: NS_UNBLOCK */
414 unsigned char msg[1] = {
415 0x06
416 };
417
418 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
419}
420
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200421static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
422{
423 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
424 unsigned char msg[1] = {
425 0x07
426 };
427
428 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
429}
430
431static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
432 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200433 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
434{
435 /* GPRS Network Service, PDU type: NS_UNITDATA */
436 unsigned char msg[4096] = {
437 0x00, 0x00, 0x00, 0x00
438 };
439
440 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
441
442 msg[2] = nsbvci / 256;
443 msg[3] = nsbvci % 256;
444 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
445
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200446 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200447}
448
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200449static void send_bssgp_ul_unitdata(
450 struct gprs_ns_inst *nsi, const char *text,
451 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
452 struct gprs_ra_id *raid, uint16_t cell_id,
453 const uint8_t *llc_msg, size_t llc_msg_size)
454{
455 /* GPRS Network Service, PDU type: NS_UNITDATA */
456 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
457 unsigned char msg[4096] = {
458 0x01, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
459 0x08, 0x88, /* RAI */ 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
460 /* CELL ID */ 0x00, 0x00, 0x00, 0x80, 0x0e, /* LLC LEN */ 0x00, 0x00,
461 };
462
463 size_t bssgp_msg_size = 23 + llc_msg_size;
464
465 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg));
466
467 gsm48_construct_ra(msg + 10, raid);
468 msg[1] = (uint8_t)(tlli >> 24);
469 msg[2] = (uint8_t)(tlli >> 16);
470 msg[3] = (uint8_t)(tlli >> 8);
471 msg[4] = (uint8_t)(tlli >> 0);
472 msg[16] = cell_id / 256;
473 msg[17] = cell_id % 256;
474 msg[21] = llc_msg_size / 256;
475 msg[22] = llc_msg_size % 256;
476 memcpy(msg + 23, llc_msg, llc_msg_size);
477
478 send_ns_unitdata(nsi, text ? text : "BSSGP UL UNITDATA",
479 src_addr, nsbvci, msg, bssgp_msg_size);
480}
481
482static void send_bssgp_dl_unitdata(
483 struct gprs_ns_inst *nsi, const char *text,
484 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
485 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
486 const uint8_t *llc_msg, size_t llc_msg_size)
487{
488 /* Base Station Subsystem GPRS Protocol: DL_UNITDATA */
489 unsigned char msg[4096] = {
490 0x00, /* TLLI */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x20,
491 0x16, 0x82, 0x02, 0x58,
492 };
493 unsigned char racap_drx[] = {
494 0x13, 0x99, 0x18, 0xb3, 0x43, 0x2b, 0x25, 0x96,
495 0x62, 0x00, 0x60, 0x80, 0x9a, 0xc2, 0xc6, 0x62,
496 0x00, 0x60, 0x80, 0xba, 0xc8, 0xc6, 0x62, 0x00,
497 0x60, 0x80, 0x00, 0x0a, 0x82, 0x08, 0x02
498 };
499
500 size_t bssgp_msg_size = 0;
501
502 OSMO_ASSERT(51 + imsi_size + llc_msg_size <= sizeof(msg));
503
504 msg[1] = (uint8_t)(tlli >> 24);
505 msg[2] = (uint8_t)(tlli >> 16);
506 msg[3] = (uint8_t)(tlli >> 8);
507 msg[4] = (uint8_t)(tlli >> 0);
508
509 bssgp_msg_size = 12;
510
511 if (with_racap_drx) {
512 memcpy(msg + bssgp_msg_size, racap_drx, sizeof(racap_drx));
513 bssgp_msg_size += sizeof(racap_drx);
514 }
515
516 if (imsi) {
517 OSMO_ASSERT(imsi_size <= 127);
518 msg[bssgp_msg_size] = BSSGP_IE_IMSI;
519 msg[bssgp_msg_size + 1] = 0x80 | imsi_size;
520 memcpy(msg + bssgp_msg_size + 2, imsi, imsi_size);
521 bssgp_msg_size += 2 + imsi_size;
522 }
523
524 if ((bssgp_msg_size % 4) != 0) {
525 size_t abytes = (4 - (bssgp_msg_size + 2) % 4) % 4;
526 msg[bssgp_msg_size] = BSSGP_IE_ALIGNMENT;
527 msg[bssgp_msg_size + 1] = 0x80 | abytes;
528 memset(msg + bssgp_msg_size + 2, 0, abytes);
529 bssgp_msg_size += 2 + abytes;
530 }
531
532 msg[bssgp_msg_size] = BSSGP_IE_LLC_PDU;
533 if (llc_msg_size < 128) {
534 msg[bssgp_msg_size + 1] = 0x80 | llc_msg_size;
535 bssgp_msg_size += 2;
536 } else {
537 msg[bssgp_msg_size + 1] = llc_msg_size / 256;
538 msg[bssgp_msg_size + 2] = llc_msg_size % 256;
539 bssgp_msg_size += 3;
540 }
541 memcpy(msg + bssgp_msg_size, llc_msg, llc_msg_size);
542 bssgp_msg_size += llc_msg_size;
543
544
545 send_ns_unitdata(nsi, text ? text : "BSSGP DL UNITDATA",
546 src_addr, nsbvci, msg, bssgp_msg_size);
547}
548
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200549static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
550 uint16_t bvci)
551{
552 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
553 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200554 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200555 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200556 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
557 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200558 };
559
560 msg[3] = bvci / 256;
561 msg[4] = bvci % 256;
562
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200563 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
564}
565
566static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
567 struct sockaddr_in *src_addr, uint16_t bvci)
568{
569 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
570 * BSSGP RESET_ACK */
571 static unsigned char msg[5] = {
572 0x23, 0x04, 0x82, 0x00,
573 0x00
574 };
575
576 msg[3] = bvci / 256;
577 msg[4] = bvci % 256;
578
579 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200580}
581
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200582static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
583 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200584 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200585 struct gprs_ra_id *raid)
586{
587 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
588 unsigned char msg[15] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200589 0x0b, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
590 0x86, /* RAI */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200591 };
592
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200593 msg[3] = (uint8_t)(tlli >> 24);
594 msg[4] = (uint8_t)(tlli >> 16);
595 msg[5] = (uint8_t)(tlli >> 8);
596 msg[6] = (uint8_t)(tlli >> 0);
597
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200598 gsm48_construct_ra(msg + 9, raid);
599
600 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
601}
602
603static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
604 struct sockaddr_in *src_addr,
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200605 uint32_t tlli,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200606 struct gprs_ra_id *raid)
607{
608 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
609 unsigned char msg[18] = {
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200610 0x0c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x1b,
611 0x86, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200612 0x81, 0x01
613 };
614
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200615 msg[3] = (uint8_t)(tlli >> 24);
616 msg[4] = (uint8_t)(tlli >> 16);
617 msg[5] = (uint8_t)(tlli >> 8);
618 msg[6] = (uint8_t)(tlli >> 0);
619
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200620 gsm48_construct_ra(msg + 9, raid);
621
622 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
623}
624
Jacob Erlbeck299389a2014-08-21 16:34:18 +0200625static void send_bssgp_llc_discarded(struct gprs_ns_inst *nsi,
626 struct sockaddr_in *src_addr,
627 uint16_t bvci, uint32_t tlli,
628 unsigned n_frames, unsigned n_octets)
629{
630 /* Base Station Subsystem GPRS Protocol: LLC-DISCARDED (0x2c) */
631 unsigned char msg[] = {
632 0x2c, 0x1f, 0x84, /* TLLI */ 0xff, 0xff, 0xff, 0xff, 0x0f,
633 0x81, /* n frames */ 0xff, 0x04, 0x82, /* BVCI */ 0xff, 0xff, 0x25, 0x83,
634 /* n octets */ 0xff, 0xff, 0xff
635 };
636
637 msg[3] = (uint8_t)(tlli >> 24);
638 msg[4] = (uint8_t)(tlli >> 16);
639 msg[5] = (uint8_t)(tlli >> 8);
640 msg[6] = (uint8_t)(tlli >> 0);
641 msg[9] = (uint8_t)(n_frames);
642 msg[12] = (uint8_t)(bvci >> 8);
643 msg[13] = (uint8_t)(bvci >> 0);
644 msg[16] = (uint8_t)(n_octets >> 16);
645 msg[17] = (uint8_t)(n_octets >> 8);
646 msg[18] = (uint8_t)(n_octets >> 0);
647
648 send_ns_unitdata(nsi, "LLC_DISCARDED", src_addr, 0, msg, sizeof(msg));
649}
650
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200651static void send_bssgp_flow_control_bvc(struct gprs_ns_inst *nsi,
652 struct sockaddr_in *src_addr,
653 uint16_t bvci, uint8_t tag)
654{
655 /* GPRS Network Service, PDU type: NS_UNITDATA,
656 * BSSGP FLOW_CONTROL_BVC */
657 unsigned char msg[] = {
658 0x26, 0x1e, 0x81, /* Tag */ 0xff, 0x05, 0x82, 0x01, 0xdc,
659 0x03, 0x82, 0x02, 0x76, 0x01, 0x82, 0x00, 0x50,
660 0x1c, 0x82, 0x02, 0x58, 0x06, 0x82, 0x00, 0x03
661 };
662
663 msg[3] = tag;
664
665 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC", src_addr, bvci,
666 msg, sizeof(msg));
667}
668
669static void send_bssgp_flow_control_bvc_ack(struct gprs_ns_inst *nsi,
670 struct sockaddr_in *src_addr,
671 uint16_t bvci, uint8_t tag)
672{
673 /* GPRS Network Service, PDU type: NS_UNITDATA,
674 * BSSGP FLOW_CONTROL_BVC_ACK */
675 unsigned char msg[] = {
676 0x27, 0x1e, 0x81, /* Tag */ 0xce
677 };
678
679 msg[3] = tag;
680
681 send_ns_unitdata(nsi, "FLOW_CONTROL_BVC_ACK", src_addr, bvci,
682 msg, sizeof(msg));
683}
684
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +0200685static void send_llc_ul_ui(
686 struct gprs_ns_inst *nsi, const char *text,
687 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
688 struct gprs_ra_id *raid, uint16_t cell_id,
689 unsigned sapi, unsigned nu,
690 const uint8_t *msg, size_t msg_size)
691{
692 unsigned char llc_msg[4096] = {
693 0x00, 0xc0, 0x01
694 };
695
696 size_t llc_msg_size = 3 + msg_size + 3;
697 uint8_t e_bit = 0;
698 uint8_t pm_bit = 1;
699 unsigned fcs;
700
701 nu &= 0x01ff;
702
703 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
704
705 llc_msg[0] = (sapi & 0x0f);
706 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
707 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
708
709 memcpy(llc_msg + 3, msg, msg_size);
710
711 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
712 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
713 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
714 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
715
716 send_bssgp_ul_unitdata(nsi, text ? text : "LLC UI",
717 src_addr, nsbvci, tlli, raid, cell_id,
718 llc_msg, llc_msg_size);
719}
720
721static void send_llc_dl_ui(
722 struct gprs_ns_inst *nsi, const char *text,
723 struct sockaddr_in *src_addr, uint16_t nsbvci, uint32_t tlli,
724 int with_racap_drx, const uint8_t *imsi, size_t imsi_size,
725 unsigned sapi, unsigned nu,
726 const uint8_t *msg, size_t msg_size)
727{
728 /* GPRS Network Service, PDU type: NS_UNITDATA */
729 /* Base Station Subsystem GPRS Protocol: UL_UNITDATA */
730 unsigned char llc_msg[4096] = {
731 0x00, 0x00, 0x01
732 };
733
734 size_t llc_msg_size = 3 + msg_size + 3;
735 uint8_t e_bit = 0;
736 uint8_t pm_bit = 1;
737 unsigned fcs;
738
739 nu &= 0x01ff;
740
741 OSMO_ASSERT(llc_msg_size <= sizeof(llc_msg));
742
743 llc_msg[0] = 0x40 | (sapi & 0x0f);
744 llc_msg[1] = 0xc0 | (nu >> 6); /* UI frame */
745 llc_msg[2] = (nu << 2) | ((e_bit & 1) << 1) | (pm_bit & 1);
746
747 memcpy(llc_msg + 3, msg, msg_size);
748
749 fcs = gprs_llc_fcs(llc_msg, msg_size + 3);
750 llc_msg[3 + msg_size + 0] = (uint8_t)(fcs >> 0);
751 llc_msg[3 + msg_size + 1] = (uint8_t)(fcs >> 8);
752 llc_msg[3 + msg_size + 2] = (uint8_t)(fcs >> 16);
753
754 send_bssgp_dl_unitdata(nsi, text ? text : "LLC UI",
755 src_addr, nsbvci, tlli,
756 with_racap_drx, imsi, imsi_size,
757 llc_msg, llc_msg_size);
758}
759
760
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200761static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
762 uint16_t nsvci, uint16_t nsei)
763{
764 printf("Setup NS-VC: remote 0x%08x:%d, "
765 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
766 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
767 nsvci, nsvci, nsei, nsei);
768
769 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
770 send_ns_alive(nsi, src_addr);
771 send_ns_unblock(nsi, src_addr);
772 send_ns_alive_ack(nsi, src_addr);
773}
774
775static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
776 uint16_t bvci)
777{
778 printf("Setup BSSGP: remote 0x%08x:%d, "
779 "BVCI 0x%04x(%d)\n\n",
780 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
781 bvci, bvci);
782
783 send_bssgp_reset(nsi, src_addr, bvci);
784}
785
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200786static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer,
787 uint32_t sgsn_nsei)
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200788{
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200789 gprs_ns_nsip_connect(nsi, sgsn_peer, sgsn_nsei, sgsn_nsei+1);
790 send_ns_reset_ack(nsi, sgsn_peer, sgsn_nsei+1, sgsn_nsei);
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200791 send_ns_alive_ack(nsi, sgsn_peer);
792 send_ns_unblock_ack(nsi, sgsn_peer);
793 send_ns_alive(nsi, sgsn_peer);
794}
795
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200796static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
797{
798 sgsn_peer->sin_family = AF_INET;
799 sgsn_peer->sin_port = htons(32000);
800 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
801}
802
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200803static void configure_sgsn2_peer(struct sockaddr_in *sgsn_peer)
804{
805 sgsn_peer->sin_family = AF_INET;
806 sgsn_peer->sin_port = htons(32001);
807 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN2_ADDR);
808}
809
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200810static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
811{
812 size_t i;
813
814 for (i = 0; i < size; ++i) {
815 bss_peers[i].sin_family = AF_INET;
816 bss_peers[i].sin_port = htons((i + 1) * 1111);
817 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
818 }
819}
820
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200821int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
822 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
823
824/* override */
825int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
826 struct msgb *msg, uint16_t bvci)
827{
828 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
829 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200830 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200831
832 switch (event) {
833 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200834 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200835 default:
836 break;
837 }
838 return 0;
839}
840
841/* override */
842ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
843 const struct sockaddr *dest_addr, socklen_t addrlen)
844{
845 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
846 const struct sockaddr *, socklen_t);
847 static sendto_t real_sendto = NULL;
848 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200849 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200850
851 if (!real_sendto)
852 real_sendto = dlsym(RTLD_NEXT, "sendto");
853
854 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200855 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
856 dest_host, dest_port,
857 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200858 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200859 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
860 dest_host, dest_port,
861 len, osmo_hexdump(buf, len));
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200862 else if (dest_host == REMOTE_SGSN2_ADDR)
863 printf("MESSAGE to SGSN 2 at 0x%08x:%d, msg length %d\n%s\n\n",
864 dest_host, dest_port,
865 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200866 else
867 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
868
869 return len;
870}
871
872/* override */
873int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
874{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200875 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
876 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200877 uint16_t bvci = msgb_bvci(msg);
878 uint16_t nsei = msgb_nsei(msg);
879
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200880 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200881
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200882 if (!real_gprs_ns_sendmsg)
883 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
884
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200885 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200886 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
887 "msg length %d (%s)\n",
888 bvci, len, __func__);
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +0200889 else if (nsei == SGSN2_NSEI)
890 printf("NS UNITDATA MESSAGE to SGSN 2, BVCI 0x%04x, "
891 "msg length %d (%s)\n",
892 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200893 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200894 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
895 "msg length %d (%s)\n",
896 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200897
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200898 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200899}
900
901static void dump_rate_ctr_group(FILE *stream, const char *prefix,
902 struct rate_ctr_group *ctrg)
903{
904 unsigned int i;
905
906 for (i = 0; i < ctrg->desc->num_ctr; i++) {
907 struct rate_ctr *ctr = &ctrg->ctr[i];
908 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
909 fprintf(stream, " %s%s: %llu%s",
910 prefix, ctrg->desc->ctr_desc[i].description,
911 (long long)ctr->current,
912 "\n");
913 };
914}
915
916/* Signal handler for signals from NS layer */
917static int test_signal(unsigned int subsys, unsigned int signal,
918 void *handler_data, void *signal_data)
919{
920 struct ns_signal_data *nssd = signal_data;
921 int rc;
922
923 if (subsys != SS_L_NS)
924 return 0;
925
926 switch (signal) {
927 case S_NS_RESET:
928 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
929 nssd->nsvc->nsvci,
930 gprs_ns_ll_str(nssd->nsvc));
931 break;
932
933 case S_NS_ALIVE_EXP:
934 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
935 nssd->nsvc->nsvci,
936 gprs_ns_ll_str(nssd->nsvc));
937 break;
938
939 case S_NS_BLOCK:
940 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
941 nssd->nsvc->nsvci,
942 gprs_ns_ll_str(nssd->nsvc));
943 break;
944
945 case S_NS_UNBLOCK:
946 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
947 nssd->nsvc->nsvci,
948 gprs_ns_ll_str(nssd->nsvc));
949 break;
950
951 case S_NS_REPLACED:
952 printf("==> got signal NS_REPLACED: 0x%04x/%s",
953 nssd->nsvc->nsvci,
954 gprs_ns_ll_str(nssd->nsvc));
955 printf(" -> 0x%04x/%s\n",
956 nssd->old_nsvc->nsvci,
957 gprs_ns_ll_str(nssd->old_nsvc));
958 break;
959
960 default:
961 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
962 nssd->nsvc->nsvci,
963 gprs_ns_ll_str(nssd->nsvc));
964 break;
965 }
966 printf("\n");
967 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
968 return rc;
969}
970
971static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
972{
973 struct msgb *msg;
974 int ret;
975 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
976 fprintf(stderr, "message too long: %d\n", data_len);
977 return -1;
978 }
979
980 msg = gprs_ns_msgb_alloc();
981 memmove(msg->data, data, data_len);
982 msg->l2h = msg->data;
983 msgb_put(msg, data_len);
984
985 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
986 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
987 osmo_hexdump(data, data_len));
988
989 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
990
991 printf("result (%s) = %d\n\n", text, ret);
992
993 msgb_free(msg);
994
995 return ret;
996}
997
998static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
999{
1000 struct gprs_nsvc *nsvc;
1001
1002 printf("Current NS-VCIs:\n");
1003 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
1004 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001005 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001006 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001007 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
1008 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
1009 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001010 );
1011 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
1012 }
1013 printf("\n");
1014}
1015
1016static void test_gbproxy()
1017{
1018 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1019 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001020 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001021
1022 bssgp_nsi = nsi;
1023 gbcfg.nsi = bssgp_nsi;
1024 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1025
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001026 configure_sgsn_peer(&sgsn_peer);
1027 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001028
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001029 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001030 printf("--- Initialise SGSN ---\n\n");
1031
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001032 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001033 gprs_dump_nsi(nsi);
1034
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001035 printf("--- Initialise BSS 1 ---\n\n");
1036
1037 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1038 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1039 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001040 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001041
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001042 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1043
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001044 printf("--- Initialise BSS 2 ---\n\n");
1045
1046 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
1047 setup_bssgp(nsi, &bss_peer[1], 0x2002);
1048 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001049 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001050
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001051 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
1052
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001053 printf("--- Move BSS 1 to new port ---\n\n");
1054
1055 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
1056 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001057 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001058
1059 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1060
1061 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1062 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001063 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001064
1065 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
1066
1067 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
1068 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001069 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001070
1071 printf("--- Move BSS 2 to new port ---\n\n");
1072
1073 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
1074 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001075 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001076
1077 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
1078
1079 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
1080 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001081 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001082
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001083 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
1084
1085 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1086 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001087 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001088
1089 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
1090
1091 setup_bssgp(nsi, &bss_peer[0], 0x1012);
1092 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001093 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001094
1095 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
1096
1097 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
1098
1099 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1100 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001101 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001102
1103 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1104
1105 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
1106
1107 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1108 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001109 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001110
1111 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1112
1113 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
1114
1115 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1116
1117 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
1118
1119 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1120
1121 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1122
1123 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1124
1125 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1126
1127 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1128
1129 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
1130
1131 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
1132
1133 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
1134
1135 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
1136
1137 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
1138
1139 setup_bssgp(nsi, &bss_peer[2], 0x1002);
1140 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001141 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001142
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001143 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001144
Jacob Erlbeck2082afa2013-10-18 13:04:47 +02001145 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1146
1147 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1148
1149 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
1150
1151 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
1152
1153 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
1154
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001155 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
1156
1157 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
1158
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001159 /* Find peer */
1160 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
1161 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
1162 OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
1163 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
1164 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
1165 OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
1166
1167
1168 /* Cleanup */
1169 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
1170 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
1171 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
1172 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
1173 OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
1174
1175 dump_peers(stdout, 0, 0, &gbcfg);
1176
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001177 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +02001178
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001179 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001180 gprs_ns_destroy(nsi);
1181 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001182}
1183
1184static void test_gbproxy_ident_changes()
1185{
1186 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1187 struct sockaddr_in bss_peer[1] = {{0},};
1188 struct sockaddr_in sgsn_peer= {0};
1189 uint16_t nsei[2] = {0x1000, 0x2000};
1190 uint16_t nsvci[2] = {0x1001, 0x2001};
1191 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
1192
1193 bssgp_nsi = nsi;
1194 gbcfg.nsi = bssgp_nsi;
1195 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1196
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001197 configure_sgsn_peer(&sgsn_peer);
1198 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001199
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001200 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001201 printf("--- Initialise SGSN ---\n\n");
1202
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001203 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001204 gprs_dump_nsi(nsi);
1205
1206 printf("--- Initialise BSS 1 ---\n\n");
1207
1208 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
1209 gprs_dump_nsi(nsi);
1210
1211 printf("--- Setup BVCI 1 ---\n\n");
1212
1213 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1214 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001215 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001216
1217 printf("--- Setup BVCI 2 ---\n\n");
1218
1219 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
1220 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001221 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001222
1223 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1224
1225 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1226 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1227
1228 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
1229
1230 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
1231 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
1232
1233 printf("--- Change NSEI ---\n\n");
1234
1235 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
1236 gprs_dump_nsi(nsi);
1237
1238 printf("--- Setup BVCI 1 ---\n\n");
1239
1240 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1241 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001242 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001243
1244 printf("--- Setup BVCI 3 ---\n\n");
1245
1246 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
1247 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001248 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001249
1250 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1251
1252 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1253 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1254
1255 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1256 " (should fail) ---\n\n");
1257
1258 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001259 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001260 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001261 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001262
1263 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1264
1265 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1266 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1267
1268 printf("--- Change NSVCI ---\n\n");
1269
1270 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
1271 gprs_dump_nsi(nsi);
1272
1273 printf("--- Setup BVCI 1 ---\n\n");
1274
1275 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
1276 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001277 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001278
1279 printf("--- Setup BVCI 4 ---\n\n");
1280
1281 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
1282 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001283 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001284
1285 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
1286
1287 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
1288 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
1289
1290 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
1291 " (should fail) ---\n\n");
1292
1293 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001294 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001295 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001296 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001297
1298 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
1299
1300 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
1301 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
1302
1303 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
1304
1305 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
1306 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
1307
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001308 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001309 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001310
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001311 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001312 gprs_ns_destroy(nsi);
1313 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001314}
1315
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001316static void test_gbproxy_ra_patching()
1317{
1318 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1319 struct sockaddr_in bss_peer[1] = {{0},};
1320 struct sockaddr_in sgsn_peer= {0};
1321 struct gprs_ra_id rai_bss =
1322 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1323 struct gprs_ra_id rai_sgsn =
1324 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1325 struct gprs_ra_id rai_unknown =
1326 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001327 uint16_t cell_id = 0x7530;
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001328 const char *err_msg = NULL;
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001329 const uint32_t ptmsi = 0xefe2b700;
1330 const uint32_t local_tlli = 0xefe2b700;
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001331 const uint32_t foreign_tlli = 0xbbc54679;
1332 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001333 struct gbproxy_tlli_info *tlli_info;
1334 struct gbproxy_peer *peer;
1335
1336 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001337
1338 bssgp_nsi = nsi;
1339 gbcfg.nsi = bssgp_nsi;
1340 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +02001341 gbcfg.core_mcc = 123;
1342 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +02001343 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +02001344 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001345 gbcfg.patch_ptmsi = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001346
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +02001347 configure_sgsn_peer(&sgsn_peer);
1348 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001349
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001350 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001351 if (gbproxy_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001352 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1353 gbcfg.match_re, err_msg);
1354 exit(1);
1355 }
1356
1357
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001358 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001359 printf("--- Initialise SGSN ---\n\n");
1360
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001361 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001362 gprs_dump_nsi(nsi);
1363
1364 printf("--- Initialise BSS 1 ---\n\n");
1365
1366 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1367 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1368 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001369 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001370
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001371 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001372 OSMO_ASSERT(peer != NULL);
1373
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001374 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1375
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001376 send_bssgp_suspend(nsi, &bss_peer[0], 0xccd1758b, &rai_bss);
1377 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_sgsn);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001378
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001379 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001380 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001381
1382 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1383
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001384 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1385 foreign_tlli, &rai_bss, cell_id,
1386 GPRS_SAPI_GMM, 0,
1387 dtap_attach_req, sizeof(dtap_attach_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001388
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001389 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1390 foreign_tlli, 0, NULL, 0,
1391 GPRS_SAPI_GMM, 0,
1392 dtap_identity_req, sizeof(dtap_identity_req));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001393
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001394 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1395 foreign_tlli, &rai_bss, cell_id,
1396 GPRS_SAPI_GMM, 3,
1397 dtap_identity_resp, sizeof(dtap_identity_resp));
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001398
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001399 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1400 foreign_tlli, 1, imsi, sizeof(imsi),
1401 GPRS_SAPI_GMM, 1,
1402 dtap_attach_acc, sizeof(dtap_attach_acc));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001403
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001404 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1405 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1406 OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1407
1408 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
1409 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
1410 OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1411
1412 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
1413 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
1414 OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
1415
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001416 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001417 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001418 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1419 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1420 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1421 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1422 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1423 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1424 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1425 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001426
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001427 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1428 local_tlli, &rai_bss, cell_id,
1429 GPRS_SAPI_GMM, 4,
1430 dtap_attach_complete, sizeof(dtap_attach_complete));
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001431
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001432 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001433 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001434 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1435 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1436 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1437 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1438 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1439 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1440 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1441 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001442
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001443 /* Replace APN (1) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001444 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1445 local_tlli, &rai_bss, cell_id,
1446 GPRS_SAPI_GMM, 3,
1447 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001448
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001449 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001450 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001451 OSMO_ASSERT(tlli_info->tlli.assigned == local_tlli);
1452 OSMO_ASSERT(tlli_info->tlli.current != local_tlli);
1453 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1454 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1455 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_tlli);
1456 OSMO_ASSERT(tlli_info->sgsn_tlli.current != local_tlli);
1457 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1458 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001459
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001460 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1461 local_tlli, 1, imsi, sizeof(imsi),
1462 GPRS_SAPI_GMM, 2,
1463 dtap_gmm_information, sizeof(dtap_gmm_information));
Jacob Erlbeck11669742014-06-06 18:47:36 +02001464
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001465 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001466 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02001467 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1468 OSMO_ASSERT(tlli_info->tlli.current == local_tlli);
1469 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1470 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_tlli);
Jacob Erlbeck59748e62014-08-11 17:26:21 +02001471
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001472 /* Replace APN (2) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001473 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1474 local_tlli, &rai_bss, cell_id,
1475 GPRS_SAPI_GMM, 3,
1476 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001477
Jacob Erlbeck73685282014-05-23 20:48:07 +02001478 gbcfg.core_apn[0] = 0;
1479 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001480
1481 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001482 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1483 local_tlli, &rai_bss, cell_id,
1484 GPRS_SAPI_GMM, 3,
1485 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001486
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001487 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001488
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001489 /* Detach */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001490 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1491 local_tlli, &rai_bss, cell_id,
1492 GPRS_SAPI_GMM, 6,
1493 dtap_detach_req, sizeof(dtap_detach_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001494
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001495 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1496 local_tlli, 1, imsi, sizeof(imsi),
1497 GPRS_SAPI_GMM, 5,
1498 dtap_detach_acc, sizeof(dtap_detach_acc));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001499
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001500 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001501
1502 printf("--- RA update ---\n\n");
1503
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001504 send_llc_ul_ui(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1505 foreign_tlli, &rai_bss, 0x7080,
1506 GPRS_SAPI_GMM, 5,
1507 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001508
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001509 send_llc_dl_ui(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1510 foreign_tlli, 1, imsi, sizeof(imsi),
1511 GPRS_SAPI_GMM, 6,
1512 dtap_ra_upd_acc, sizeof(dtap_ra_upd_acc));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001513
1514 /* Remove APN */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001515 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REMOVE APN)", &bss_peer[0], 0x1002,
1516 local_tlli, &rai_bss, cell_id,
1517 GPRS_SAPI_GMM, 3,
1518 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001519
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001520 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001521
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001522 /* Detach (power off -> no Detach Accept) */
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001523 send_llc_ul_ui(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1524 local_tlli, &rai_bss, cell_id,
1525 GPRS_SAPI_GMM, 6,
1526 dtap_detach_po_req, sizeof(dtap_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001527
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001528 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001529 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001530
1531 printf("--- Bad cases ---\n\n");
1532
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001533 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckc53f2a62014-08-15 14:56:28 +02001534 send_llc_ul_ui(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1535 local_tlli, &rai_bss, cell_id,
1536 GPRS_SAPI_GMM, 3,
1537 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001538
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001539 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001540 send_bssgp_suspend_ack(nsi, &sgsn_peer, 0xccd1758b, &rai_unknown);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001541
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001542 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001543 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001544
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001545 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001546 gprs_ns_destroy(nsi);
1547 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001548}
1549
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001550static void test_gbproxy_ptmsi_patching()
1551{
1552 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1553 struct sockaddr_in bss_peer[1] = {{0},};
1554 struct sockaddr_in sgsn_peer= {0};
1555 struct gprs_ra_id rai_bss =
1556 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1557 struct gprs_ra_id rai_sgsn =
1558 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001559 struct gprs_ra_id rai_wrong_mcc_sgsn =
1560 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001561 struct gprs_ra_id rai_unknown =
1562 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1563 uint16_t cell_id = 0x1234;
1564
1565 const uint32_t sgsn_ptmsi = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001566 const uint32_t sgsn_ptmsi2 = 0xe0987654;
1567 const uint32_t sgsn_ptmsi3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001568 const uint32_t local_sgsn_tlli = 0xefe2b700;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001569 const uint32_t local_sgsn_tlli2 = 0xe0987654;
1570 const uint32_t local_sgsn_tlli3 = 0xe0543210;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001571 const uint32_t random_sgsn_tlli = 0x7c69fb81;
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001572 const uint32_t unknown_sgsn_tlli = 0xeebadbad;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001573
1574 const uint32_t bss_ptmsi = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001575 const uint32_t bss_ptmsi2 = 0xe656aa1f;
1576 const uint32_t bss_ptmsi3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001577 const uint32_t local_bss_tlli = 0xc00f7304;
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001578 const uint32_t local_bss_tlli2 = 0xe656aa1f;
1579 const uint32_t local_bss_tlli3 = 0xead4775a;
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001580 const uint32_t foreign_bss_tlli = 0x8000dead;
1581
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001582
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001583 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1584 struct gbproxy_tlli_info *tlli_info;
1585 struct gbproxy_peer *peer;
1586 unsigned bss_nu = 0;
1587 unsigned sgsn_nu = 0;
1588
1589 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001590 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
1591 OSMO_ASSERT(local_sgsn_tlli3 == gprs_tmsi2tlli(sgsn_ptmsi3, TLLI_LOCAL));
1592 OSMO_ASSERT(local_bss_tlli == gprs_tmsi2tlli(bss_ptmsi, TLLI_LOCAL));
1593 OSMO_ASSERT(local_bss_tlli2 == gprs_tmsi2tlli(bss_ptmsi2, TLLI_LOCAL));
1594 OSMO_ASSERT(local_bss_tlli3 == gprs_tmsi2tlli(bss_ptmsi3, TLLI_LOCAL));
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001595
1596 bssgp_nsi = nsi;
1597 gbcfg.nsi = bssgp_nsi;
1598 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1599 gbcfg.core_mcc = 123;
1600 gbcfg.core_mnc = 456;
1601 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1602 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1603 gbcfg.patch_ptmsi = 1;
1604 gbcfg.bss_ptmsi_state = 0;
1605 gbcfg.sgsn_tlli_state = 1;
1606
1607 configure_sgsn_peer(&sgsn_peer);
1608 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1609
1610 printf("=== %s ===\n", __func__);
1611 printf("--- Initialise SGSN ---\n\n");
1612
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001613 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001614
1615 printf("--- Initialise BSS 1 ---\n\n");
1616
1617 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1618 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1619
Jacob Erlbeck5f1faa32014-08-21 10:01:30 +02001620 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001621 OSMO_ASSERT(peer != NULL);
1622
1623 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1624
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001625 gprs_dump_nsi(nsi);
1626 dump_global(stdout, 0);
1627 dump_peers(stdout, 0, 0, &gbcfg);
1628
1629 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1630
1631 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1632 foreign_bss_tlli, &rai_unknown, cell_id,
1633 GPRS_SAPI_GMM, bss_nu++,
1634 dtap_attach_req, sizeof(dtap_attach_req));
1635
1636 dump_peers(stdout, 0, 0, &gbcfg);
1637
1638 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1639 random_sgsn_tlli, 0, NULL, 0,
1640 GPRS_SAPI_GMM, sgsn_nu++,
1641 dtap_identity_req, sizeof(dtap_identity_req));
1642
1643 dump_peers(stdout, 0, 0, &gbcfg);
1644
1645 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1646 foreign_bss_tlli, &rai_bss, cell_id,
1647 GPRS_SAPI_GMM, bss_nu++,
1648 dtap_identity_resp, sizeof(dtap_identity_resp));
1649
1650 dump_peers(stdout, 0, 0, &gbcfg);
1651
1652 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1653 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1654 GPRS_SAPI_GMM, sgsn_nu++,
1655 dtap_attach_acc, sizeof(dtap_attach_acc));
1656
1657 dump_peers(stdout, 0, 0, &gbcfg);
1658
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001659 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001660 OSMO_ASSERT(tlli_info);
1661 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1662 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1663 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1664 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1665 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1666 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1667 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1668 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1669 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1670 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1671
1672 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1673 local_bss_tlli, &rai_bss, cell_id,
1674 GPRS_SAPI_GMM, bss_nu++,
1675 dtap_attach_complete, sizeof(dtap_attach_complete));
1676
1677 dump_peers(stdout, 0, 0, &gbcfg);
1678
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001679 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001680 OSMO_ASSERT(tlli_info);
1681 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1682 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1683 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1684 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1685 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1686 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1687 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1688 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1689
1690 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1691 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1692 GPRS_SAPI_GMM, sgsn_nu++,
1693 dtap_gmm_information, sizeof(dtap_gmm_information));
1694
1695 dump_peers(stdout, 0, 0, &gbcfg);
1696
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001697 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001698 OSMO_ASSERT(tlli_info);
1699 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1700 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1701 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1702 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1703
Jacob Erlbeck82add782014-09-05 18:08:12 +02001704 send_llc_ul_ui(nsi, "ACT PDP CTX REQ (REPLACE APN)", &bss_peer[0], 0x1002,
1705 local_bss_tlli, &rai_bss, cell_id,
1706 GPRS_SAPI_GMM, bss_nu++,
1707 dtap_act_pdp_ctx_req, sizeof(dtap_act_pdp_ctx_req));
1708
1709 dump_peers(stdout, 0, 0, &gbcfg);
1710
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001711 /* Non-DTAP */
1712 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
1713 local_bss_tlli, &rai_bss, cell_id,
1714 llc_u_xid_ul, sizeof(llc_u_xid_ul));
1715
1716 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
1717 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1718 llc_u_xid_dl, sizeof(llc_u_xid_dl));
1719
1720 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
1721 local_bss_tlli, &rai_bss, cell_id,
1722 llc_ui_ll11_dns_query_ul,
1723 sizeof(llc_ui_ll11_dns_query_ul));
1724
1725 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
1726 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1727 llc_ui_ll11_dns_resp_dl,
1728 sizeof(llc_ui_ll11_dns_resp_dl));
1729
1730 dump_peers(stdout, 0, 0, &gbcfg);
1731
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001732 /* Repeated RA Update Requests */
1733 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 2)", &bss_peer[0], 0x1002,
1734 local_bss_tlli, &rai_bss, 0x7080,
1735 GPRS_SAPI_GMM, bss_nu++,
1736 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1737
1738 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 2)", &sgsn_peer, 0x1002,
1739 local_sgsn_tlli, 1, imsi, sizeof(imsi),
1740 GPRS_SAPI_GMM, sgsn_nu++,
1741 dtap_ra_upd_acc2, sizeof(dtap_ra_upd_acc2));
1742
1743 dump_peers(stdout, 0, 0, &gbcfg);
1744
1745 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) != NULL);
1746 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1747 OSMO_ASSERT(tlli_info);
1748 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
1749 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1750 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1751 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1752 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
1753 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
1754 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1755 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1756 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1757 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
1758
1759 send_llc_ul_ui(nsi, "RA UPD REQ (P-TMSI 3)", &bss_peer[0], 0x1002,
1760 local_bss_tlli2, &rai_bss, 0x7080,
1761 GPRS_SAPI_GMM, bss_nu++,
1762 dtap_ra_upd_req, sizeof(dtap_ra_upd_req));
1763
1764 send_llc_dl_ui(nsi, "RA UDP ACC (P-TMSI 3)", &sgsn_peer, 0x1002,
1765 local_sgsn_tlli2, 1, imsi, sizeof(imsi),
1766 GPRS_SAPI_GMM, sgsn_nu++,
1767 dtap_ra_upd_acc3, sizeof(dtap_ra_upd_acc3));
1768
1769 dump_peers(stdout, 0, 0, &gbcfg);
1770
1771 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2) == NULL);
1772 OSMO_ASSERT(gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3) != NULL);
1773 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
1774 OSMO_ASSERT(tlli_info);
1775 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli3);
1776 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
1777 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1778 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1779 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi3);
1780 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli3);
1781 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
1782 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1783 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1784 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi3);
1785
1786 send_llc_ul_ui(nsi, "RA UPD COMPLETE", &bss_peer[0], 0x1002,
1787 local_bss_tlli3, &rai_bss, 0x7080,
1788 GPRS_SAPI_GMM, bss_nu++,
1789 dtap_ra_upd_complete, sizeof(dtap_ra_upd_complete));
1790
1791 tlli_info = gbproxy_find_tlli(peer, local_bss_tlli3);
1792
1793 OSMO_ASSERT(tlli_info);
1794 OSMO_ASSERT(tlli_info->tlli.bss_validated);
1795 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1796 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
1797 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1798
1799 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1800 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
1801 GPRS_SAPI_GMM, sgsn_nu++,
1802 dtap_gmm_information, sizeof(dtap_gmm_information));
1803
1804 dump_peers(stdout, 0, 0, &gbcfg);
1805
1806 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli3);
1807 OSMO_ASSERT(tlli_info);
1808 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli3);
1809 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
1810 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli3);
1811 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
1812
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001813 /* Other messages */
1814 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001815 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001816
1817 dump_peers(stdout, 0, 0, &gbcfg);
1818
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001819 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli3, &rai_bss);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001820
1821 dump_peers(stdout, 0, 0, &gbcfg);
1822
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001823 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_sgsn);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001824
1825 dump_peers(stdout, 0, 0, &gbcfg);
1826
1827 /* Bad case: Invalid BVCI */
1828 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001829 local_bss_tlli3, 1, 12);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001830 dump_global(stdout, 0);
1831
1832 /* Bad case: Invalid RAI */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001833 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3, &rai_unknown);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001834
1835 dump_global(stdout, 0);
1836
1837 /* Bad case: Invalid MCC (LAC ok) */
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001838 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli3,
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001839 &rai_wrong_mcc_sgsn);
1840
1841 dump_global(stdout, 0);
1842
Jacob Erlbeck7fb26c22014-09-04 11:08:50 +02001843 /* Bad case: Invalid TLLI from SGSN (IMSI unknown) */
1844 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1845 unknown_sgsn_tlli, 1, NULL, 0,
1846 GPRS_SAPI_GMM, 2,
1847 dtap_gmm_information, sizeof(dtap_gmm_information));
1848
1849 /* Bad case: Invalid TLLI from SGSN (IMSI known) */
1850 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1851 unknown_sgsn_tlli, 1, imsi, sizeof(imsi),
1852 GPRS_SAPI_GMM, 3,
1853 dtap_gmm_information, sizeof(dtap_gmm_information));
1854
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001855 /* Detach */
1856 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001857 local_bss_tlli3, &rai_bss, cell_id,
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001858 GPRS_SAPI_GMM, bss_nu++,
1859 dtap_detach_req, sizeof(dtap_detach_req));
1860
1861 dump_peers(stdout, 0, 0, &gbcfg);
1862
1863 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck52f070a2014-09-04 13:45:56 +02001864 local_sgsn_tlli3, 1, imsi, sizeof(imsi),
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001865 GPRS_SAPI_GMM, sgsn_nu++,
1866 dtap_detach_acc, sizeof(dtap_detach_acc));
1867
1868 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck299389a2014-08-21 16:34:18 +02001869
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02001870 dump_global(stdout, 0);
1871
1872 gbprox_reset(&gbcfg);
1873 gprs_ns_destroy(nsi);
1874 nsi = NULL;
1875}
1876
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001877static void test_gbproxy_imsi_acquisition()
1878{
1879 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
1880 struct sockaddr_in bss_peer[1] = {{0},};
1881 struct sockaddr_in sgsn_peer= {0};
1882 struct gprs_ra_id rai_bss =
1883 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
1884 struct gprs_ra_id rai_sgsn =
1885 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
1886 struct gprs_ra_id rai_wrong_mcc_sgsn =
1887 {.mcc = 999, .mnc = 456, .lac = 16464, .rac = 96};
1888 struct gprs_ra_id rai_unknown =
1889 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
1890 uint16_t cell_id = 0x1234;
1891
1892 const uint32_t sgsn_ptmsi = 0xefe2b700;
1893 const uint32_t local_sgsn_tlli = 0xefe2b700;
1894 const uint32_t random_sgsn_tlli = 0x7c69fb81;
1895
1896 const uint32_t bss_ptmsi = 0xc00f7304;
1897 const uint32_t local_bss_tlli = 0xc00f7304;
1898 const uint32_t foreign_bss_tlli = 0x8000dead;
1899
1900 const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
1901 struct gbproxy_tlli_info *tlli_info;
1902 struct gbproxy_peer *peer;
1903 unsigned bss_nu = 0;
1904 unsigned sgsn_nu = 0;
1905
1906 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
1907
1908 bssgp_nsi = nsi;
1909 gbcfg.nsi = bssgp_nsi;
1910 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
1911 gbcfg.core_mcc = 123;
1912 gbcfg.core_mnc = 456;
1913 gbcfg.core_apn = talloc_zero_size(NULL, 100);
1914 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
1915 gbcfg.patch_ptmsi = 1;
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001916 gbcfg.acquire_imsi = 1;
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001917 gbcfg.bss_ptmsi_state = 0;
1918 gbcfg.sgsn_tlli_state = 1;
1919
1920 configure_sgsn_peer(&sgsn_peer);
1921 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
1922
1923 printf("=== %s ===\n", __func__);
1924 printf("--- Initialise SGSN ---\n\n");
1925
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02001926 connect_sgsn(nsi, &sgsn_peer, SGSN_NSEI);
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001927
1928 printf("--- Initialise BSS 1 ---\n\n");
1929
1930 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1931 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1932
1933 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
1934 OSMO_ASSERT(peer != NULL);
1935
1936 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1937
1938 gprs_dump_nsi(nsi);
1939 dump_global(stdout, 0);
1940 dump_peers(stdout, 0, 0, &gbcfg);
1941
1942 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1943
1944 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
1945 foreign_bss_tlli, &rai_unknown, cell_id,
1946 GPRS_SAPI_GMM, bss_nu++,
1947 dtap_attach_req, sizeof(dtap_attach_req));
1948
1949 dump_peers(stdout, 0, 0, &gbcfg);
1950
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +02001951 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1952 foreign_bss_tlli, &rai_bss, cell_id,
1953 GPRS_SAPI_GMM, bss_nu++,
1954 dtap_identity_resp, sizeof(dtap_identity_resp));
1955
1956 dump_peers(stdout, 0, 0, &gbcfg);
1957
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02001958 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1959 random_sgsn_tlli, 0, NULL, 0,
1960 GPRS_SAPI_GMM, sgsn_nu++,
1961 dtap_identity_req, sizeof(dtap_identity_req));
1962
1963 dump_peers(stdout, 0, 0, &gbcfg);
1964
1965 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1966 foreign_bss_tlli, &rai_bss, cell_id,
1967 GPRS_SAPI_GMM, bss_nu++,
1968 dtap_identity_resp, sizeof(dtap_identity_resp));
1969
1970 dump_peers(stdout, 0, 0, &gbcfg);
1971
1972 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
1973 random_sgsn_tlli, 1, imsi, sizeof(imsi),
1974 GPRS_SAPI_GMM, sgsn_nu++,
1975 dtap_attach_acc, sizeof(dtap_attach_acc));
1976
1977 dump_peers(stdout, 0, 0, &gbcfg);
1978
1979 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
1980 OSMO_ASSERT(tlli_info);
1981 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
1982 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
1983 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
1984 OSMO_ASSERT(!tlli_info->tlli.net_validated);
1985 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
1986 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
1987 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
1988 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
1989 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
1990 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
1991
1992 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1993 local_bss_tlli, &rai_bss, cell_id,
1994 GPRS_SAPI_GMM, bss_nu++,
1995 dtap_attach_complete, sizeof(dtap_attach_complete));
1996
1997 dump_peers(stdout, 0, 0, &gbcfg);
1998
1999 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2000 OSMO_ASSERT(tlli_info);
2001 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2002 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2003 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2004 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2005 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2006 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2007 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2008 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2009
2010 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer, 0x1002,
2011 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2012 GPRS_SAPI_GMM, sgsn_nu++,
2013 dtap_gmm_information, sizeof(dtap_gmm_information));
2014
2015 dump_peers(stdout, 0, 0, &gbcfg);
2016
2017 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2018 OSMO_ASSERT(tlli_info);
2019 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2020 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2021 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2022 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2023
2024 /* Non-DTAP */
2025 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2026 local_bss_tlli, &rai_bss, cell_id,
2027 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2028
2029 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer, 0x1002,
2030 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2031 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2032
2033 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2034 local_bss_tlli, &rai_bss, cell_id,
2035 llc_ui_ll11_dns_query_ul,
2036 sizeof(llc_ui_ll11_dns_query_ul));
2037
2038 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer, 0x1002,
2039 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2040 llc_ui_ll11_dns_resp_dl,
2041 sizeof(llc_ui_ll11_dns_resp_dl));
2042
2043 dump_peers(stdout, 0, 0, &gbcfg);
2044
2045 /* Other messages */
2046 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2047 local_bss_tlli, 1, 12);
2048
2049 dump_peers(stdout, 0, 0, &gbcfg);
2050
2051 send_bssgp_llc_discarded(nsi, &sgsn_peer, 0x1002,
2052 local_sgsn_tlli, 1, 12);
2053
2054 dump_peers(stdout, 0, 0, &gbcfg);
2055
2056 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2057
2058 dump_peers(stdout, 0, 0, &gbcfg);
2059
2060 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_sgsn);
2061
2062 dump_peers(stdout, 0, 0, &gbcfg);
2063
2064 /* Bad case: Invalid BVCI */
2065 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0xeee1,
2066 local_bss_tlli, 1, 12);
2067 dump_global(stdout, 0);
2068
2069 /* Bad case: Invalid RAI */
2070 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli, &rai_unknown);
2071
2072 dump_global(stdout, 0);
2073
2074 /* Bad case: Invalid MCC (LAC ok) */
2075 send_bssgp_suspend_ack(nsi, &sgsn_peer, local_sgsn_tlli,
2076 &rai_wrong_mcc_sgsn);
2077
2078 dump_global(stdout, 0);
2079
2080 /* Detach */
2081 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2082 local_bss_tlli, &rai_bss, cell_id,
2083 GPRS_SAPI_GMM, bss_nu++,
2084 dtap_detach_req, sizeof(dtap_detach_req));
2085
2086 dump_peers(stdout, 0, 0, &gbcfg);
2087
2088 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
2089 local_sgsn_tlli, 1, imsi, sizeof(imsi),
2090 GPRS_SAPI_GMM, sgsn_nu++,
2091 dtap_detach_acc, sizeof(dtap_detach_acc));
2092
2093 dump_peers(stdout, 0, 0, &gbcfg);
2094
Jacob Erlbeckea1698e2014-09-02 14:40:11 +02002095 /* Special case: Repeated Attach Requests */
2096
2097 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2098 foreign_bss_tlli, &rai_unknown, cell_id,
2099 GPRS_SAPI_GMM, bss_nu++,
2100 dtap_attach_req, sizeof(dtap_attach_req));
2101
2102 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2103 foreign_bss_tlli, &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
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02002109 dump_global(stdout, 0);
2110
2111 gbprox_reset(&gbcfg);
2112 gprs_ns_destroy(nsi);
2113 nsi = NULL;
2114}
2115
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02002116static void test_gbproxy_secondary_sgsn()
2117{
2118 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
2119 struct sockaddr_in bss_peer[1] = {{0},};
2120 struct sockaddr_in sgsn_peer[2]= {{0},};
2121 struct gprs_ra_id rai_bss =
2122 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
2123 struct gprs_ra_id rai_sgsn =
2124 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
2125 struct gprs_ra_id rai_unknown =
2126 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
2127 uint16_t cell_id = 0x1234;
2128
2129 const uint32_t sgsn_ptmsi = 0xefe2b700;
2130 const uint32_t local_sgsn_tlli = 0xefe2b700;
2131 const uint32_t random_sgsn_tlli = 0x7c69fb81;
2132
2133 const uint32_t bss_ptmsi = 0xc00f7304;
2134 const uint32_t local_bss_tlli = 0xc00f7304;
2135 const uint32_t foreign_bss_tlli = 0x8000dead;
2136
2137 const uint32_t sgsn_ptmsi2 = 0xe0987654;
2138 const uint32_t local_sgsn_tlli2 = 0xe0987654;
2139 const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
2140 const uint32_t bss_ptmsi2 = 0xe656aa1f;
2141 const uint32_t local_bss_tlli2 = 0xe656aa1f;
2142 const uint32_t foreign_bss_tlli2 = 0x8000beef;
2143
2144 const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
2145 const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0x18};
2146 struct gbproxy_tlli_info *tlli_info;
2147 struct gbproxy_peer *peer;
2148 unsigned bss_nu = 0;
2149 unsigned sgsn_nu = 0;
2150
2151 const char *err_msg = NULL;
2152 const char *filter_re = "999999";
2153
2154 OSMO_ASSERT(local_sgsn_tlli == gprs_tmsi2tlli(sgsn_ptmsi, TLLI_LOCAL));
2155 OSMO_ASSERT(local_sgsn_tlli2 == gprs_tmsi2tlli(sgsn_ptmsi2, TLLI_LOCAL));
2156
2157 bssgp_nsi = nsi;
2158 gbcfg.nsi = bssgp_nsi;
2159 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
2160 gbcfg.core_mcc = 123;
2161 gbcfg.core_mnc = 456;
2162 gbcfg.core_apn = talloc_zero_size(NULL, 100);
2163 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
2164 gbcfg.patch_ptmsi = 1;
2165 gbcfg.acquire_imsi = 1;
2166 gbcfg.bss_ptmsi_state = 0;
2167 gbcfg.sgsn_tlli_state = 1;
2168 gbcfg.route_to_sgsn2 = 1;
2169 gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
2170
2171 if (gbproxy_set_patch_filter(&gbcfg, filter_re, &err_msg) != 0) {
2172 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2173 err_msg);
2174 OSMO_ASSERT(err_msg == NULL);
2175 }
2176
2177 configure_sgsn_peer(&sgsn_peer[0]);
2178 configure_sgsn2_peer(&sgsn_peer[1]);
2179 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
2180
2181 printf("=== %s ===\n", __func__);
2182 printf("--- Initialise SGSN 1 ---\n\n");
2183
2184 connect_sgsn(nsi, &sgsn_peer[0], SGSN_NSEI);
2185
2186 printf("--- Initialise SGSN 2 ---\n\n");
2187
2188 connect_sgsn(nsi, &sgsn_peer[1], SGSN2_NSEI);
2189
2190 printf("--- Initialise BSS 1 ---\n\n");
2191
2192 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
2193 setup_bssgp(nsi, &bss_peer[0], 0x0);
2194 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x0);
2195 setup_bssgp(nsi, &bss_peer[0], 0x1002);
2196 send_bssgp_reset_ack(nsi, &sgsn_peer[0], 0x1002);
2197 send_bssgp_reset_ack(nsi, &sgsn_peer[1], 0x1002);
2198
2199 peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
2200 OSMO_ASSERT(peer != NULL);
2201
2202 gprs_dump_nsi(nsi);
2203 dump_global(stdout, 0);
2204 dump_peers(stdout, 0, 0, &gbcfg);
2205
2206 printf("--- Flow control ---\n\n");
2207
2208 send_bssgp_flow_control_bvc(nsi, &bss_peer[0], 0x1002, 1);
2209 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[0], 0x1002, 1);
2210 send_bssgp_flow_control_bvc_ack(nsi, &sgsn_peer[1], 0x1002, 1);
2211
2212 printf("--- Establish GPRS connection (SGSN 1) ---\n\n");
2213
2214 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2215 foreign_bss_tlli, &rai_unknown, cell_id,
2216 GPRS_SAPI_GMM, bss_nu++,
2217 dtap_attach_req, sizeof(dtap_attach_req));
2218
2219 dump_peers(stdout, 0, 0, &gbcfg);
2220
2221 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2222 foreign_bss_tlli, &rai_bss, cell_id,
2223 GPRS_SAPI_GMM, bss_nu++,
2224 dtap_identity_resp, sizeof(dtap_identity_resp));
2225
2226 dump_peers(stdout, 0, 0, &gbcfg);
2227
2228 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[0], 0x1002,
2229 random_sgsn_tlli, 0, NULL, 0,
2230 GPRS_SAPI_GMM, sgsn_nu++,
2231 dtap_identity_req, sizeof(dtap_identity_req));
2232
2233 dump_peers(stdout, 0, 0, &gbcfg);
2234
2235 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2236 foreign_bss_tlli, &rai_bss, cell_id,
2237 GPRS_SAPI_GMM, bss_nu++,
2238 dtap_identity_resp, sizeof(dtap_identity_resp));
2239
2240 dump_peers(stdout, 0, 0, &gbcfg);
2241
2242 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[0], 0x1002,
2243 random_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2244 GPRS_SAPI_GMM, sgsn_nu++,
2245 dtap_attach_acc, sizeof(dtap_attach_acc));
2246
2247 dump_peers(stdout, 0, 0, &gbcfg);
2248
2249 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli);
2250 OSMO_ASSERT(tlli_info);
2251 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2252 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2253 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2254 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2255 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi);
2256 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2257 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2258 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2259 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2260 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi);
2261
2262 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2263 local_bss_tlli, &rai_bss, cell_id,
2264 GPRS_SAPI_GMM, bss_nu++,
2265 dtap_attach_complete, sizeof(dtap_attach_complete));
2266
2267 dump_peers(stdout, 0, 0, &gbcfg);
2268
2269 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2270 OSMO_ASSERT(tlli_info);
2271 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli);
2272 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli);
2273 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2274 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2275 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli);
2276 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli);
2277 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2278 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2279
2280 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[0], 0x1002,
2281 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2282 GPRS_SAPI_GMM, sgsn_nu++,
2283 dtap_gmm_information, sizeof(dtap_gmm_information));
2284
2285 dump_peers(stdout, 0, 0, &gbcfg);
2286
2287 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli);
2288 OSMO_ASSERT(tlli_info);
2289 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli);
2290 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2291 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli);
2292 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2293
2294 /* Non-DTAP */
2295 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2296 local_bss_tlli, &rai_bss, cell_id,
2297 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2298
2299 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[0], 0x1002,
2300 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2301 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2302
2303 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2304 local_bss_tlli, &rai_bss, cell_id,
2305 llc_ui_ll11_dns_query_ul,
2306 sizeof(llc_ui_ll11_dns_query_ul));
2307
2308 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[0], 0x1002,
2309 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2310 llc_ui_ll11_dns_resp_dl,
2311 sizeof(llc_ui_ll11_dns_resp_dl));
2312
2313 dump_peers(stdout, 0, 0, &gbcfg);
2314
2315 /* Other messages */
2316 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2317 local_bss_tlli, 1, 12);
2318
2319 dump_peers(stdout, 0, 0, &gbcfg);
2320
2321 send_bssgp_llc_discarded(nsi, &sgsn_peer[0], 0x1002,
2322 local_sgsn_tlli, 1, 12);
2323
2324 dump_peers(stdout, 0, 0, &gbcfg);
2325
2326 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli, &rai_bss);
2327
2328 dump_peers(stdout, 0, 0, &gbcfg);
2329
2330 send_bssgp_suspend_ack(nsi, &sgsn_peer[0], local_sgsn_tlli, &rai_sgsn);
2331
2332 dump_peers(stdout, 0, 0, &gbcfg);
2333
2334 printf("--- Establish GPRS connection (SGSN 2) ---\n\n");
2335
2336 send_llc_ul_ui(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
2337 foreign_bss_tlli2, &rai_unknown, cell_id,
2338 GPRS_SAPI_GMM, bss_nu++,
2339 dtap_attach_req, sizeof(dtap_attach_req));
2340
2341 dump_peers(stdout, 0, 0, &gbcfg);
2342
2343 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2344 foreign_bss_tlli2, &rai_bss, cell_id,
2345 GPRS_SAPI_GMM, bss_nu++,
2346 dtap_identity2_resp, sizeof(dtap_identity2_resp));
2347
2348 dump_peers(stdout, 0, 0, &gbcfg);
2349
2350 send_llc_dl_ui(nsi, "IDENT REQUEST", &sgsn_peer[1], 0x1002,
2351 random_sgsn_tlli2, 0, NULL, 0,
2352 GPRS_SAPI_GMM, sgsn_nu++,
2353 dtap_identity_req, sizeof(dtap_identity_req));
2354
2355 dump_peers(stdout, 0, 0, &gbcfg);
2356
2357 send_llc_ul_ui(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
2358 foreign_bss_tlli2, &rai_bss, cell_id,
2359 GPRS_SAPI_GMM, bss_nu++,
2360 dtap_identity_resp, sizeof(dtap_identity_resp));
2361
2362 dump_peers(stdout, 0, 0, &gbcfg);
2363
2364 send_llc_dl_ui(nsi, "ATTACH ACCEPT", &sgsn_peer[1], 0x1002,
2365 random_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2366 GPRS_SAPI_GMM, sgsn_nu++,
2367 dtap_attach_acc2, sizeof(dtap_attach_acc2));
2368
2369 dump_peers(stdout, 0, 0, &gbcfg);
2370
2371 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, random_sgsn_tlli2);
2372 OSMO_ASSERT(tlli_info);
2373 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2374 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2375 OSMO_ASSERT(!tlli_info->tlli.bss_validated);
2376 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2377 OSMO_ASSERT(tlli_info->tlli.ptmsi == bss_ptmsi2);
2378 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2379 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2380 OSMO_ASSERT(!tlli_info->sgsn_tlli.bss_validated);
2381 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2382 OSMO_ASSERT(tlli_info->sgsn_tlli.ptmsi == sgsn_ptmsi2);
2383
2384 send_llc_ul_ui(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
2385 local_bss_tlli2, &rai_bss, cell_id,
2386 GPRS_SAPI_GMM, bss_nu++,
2387 dtap_attach_complete, sizeof(dtap_attach_complete));
2388
2389 dump_peers(stdout, 0, 0, &gbcfg);
2390
2391 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2392 OSMO_ASSERT(tlli_info);
2393 OSMO_ASSERT(tlli_info->tlli.assigned == local_bss_tlli2);
2394 OSMO_ASSERT(tlli_info->tlli.current == foreign_bss_tlli2);
2395 OSMO_ASSERT(tlli_info->tlli.bss_validated);
2396 OSMO_ASSERT(!tlli_info->tlli.net_validated);
2397 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == local_sgsn_tlli2);
2398 OSMO_ASSERT(tlli_info->sgsn_tlli.current == random_sgsn_tlli2);
2399 OSMO_ASSERT(tlli_info->sgsn_tlli.bss_validated);
2400 OSMO_ASSERT(!tlli_info->sgsn_tlli.net_validated);
2401
2402 send_llc_dl_ui(nsi, "GMM INFO", &sgsn_peer[1], 0x1002,
2403 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2404 GPRS_SAPI_GMM, sgsn_nu++,
2405 dtap_gmm_information, sizeof(dtap_gmm_information));
2406
2407 dump_peers(stdout, 0, 0, &gbcfg);
2408
2409 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, local_sgsn_tlli2);
2410 OSMO_ASSERT(tlli_info);
2411 OSMO_ASSERT(tlli_info->tlli.current == local_bss_tlli2);
2412 OSMO_ASSERT(tlli_info->tlli.assigned == 0);
2413 OSMO_ASSERT(tlli_info->sgsn_tlli.current == local_sgsn_tlli2);
2414 OSMO_ASSERT(tlli_info->sgsn_tlli.assigned == 0);
2415
2416 /* Non-DTAP */
2417 send_bssgp_ul_unitdata(nsi, "XID (UL)", &bss_peer[0], 0x1002,
2418 local_bss_tlli2, &rai_bss, cell_id,
2419 llc_u_xid_ul, sizeof(llc_u_xid_ul));
2420
2421 send_bssgp_dl_unitdata(nsi, "XID (DL)", &sgsn_peer[1], 0x1002,
2422 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2423 llc_u_xid_dl, sizeof(llc_u_xid_dl));
2424
2425 send_bssgp_ul_unitdata(nsi, "LL11 DNS QUERY (UL)", &bss_peer[0], 0x1002,
2426 local_bss_tlli2, &rai_bss, cell_id,
2427 llc_ui_ll11_dns_query_ul,
2428 sizeof(llc_ui_ll11_dns_query_ul));
2429
2430 send_bssgp_dl_unitdata(nsi, "LL11 DNS RESP (DL)", &sgsn_peer[1], 0x1002,
2431 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2432 llc_ui_ll11_dns_resp_dl,
2433 sizeof(llc_ui_ll11_dns_resp_dl));
2434
2435 dump_peers(stdout, 0, 0, &gbcfg);
2436
2437 /* Other messages */
2438 send_bssgp_llc_discarded(nsi, &bss_peer[0], 0x1002,
2439 local_bss_tlli2, 1, 12);
2440
2441 dump_peers(stdout, 0, 0, &gbcfg);
2442
2443 send_bssgp_llc_discarded(nsi, &sgsn_peer[1], 0x1002,
2444 local_sgsn_tlli2, 1, 12);
2445
2446 dump_peers(stdout, 0, 0, &gbcfg);
2447
2448 send_bssgp_suspend(nsi, &bss_peer[0], local_bss_tlli2, &rai_bss);
2449
2450 dump_peers(stdout, 0, 0, &gbcfg);
2451
2452 send_bssgp_suspend_ack(nsi, &sgsn_peer[1], local_sgsn_tlli2, &rai_sgsn);
2453
2454 dump_peers(stdout, 0, 0, &gbcfg);
2455
2456 printf("--- Shutdown GPRS connection (SGSN 1) ---\n\n");
2457
2458 /* Detach */
2459 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2460 local_bss_tlli, &rai_bss, cell_id,
2461 GPRS_SAPI_GMM, bss_nu++,
2462 dtap_detach_req, sizeof(dtap_detach_req));
2463
2464 dump_peers(stdout, 0, 0, &gbcfg);
2465
2466 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[0], 0x1002,
2467 local_sgsn_tlli, 1, imsi1, sizeof(imsi1),
2468 GPRS_SAPI_GMM, sgsn_nu++,
2469 dtap_detach_acc, sizeof(dtap_detach_acc));
2470
2471 dump_peers(stdout, 0, 0, &gbcfg);
2472
2473 printf("--- Shutdown GPRS connection (SGSN 2) ---\n\n");
2474
2475 send_llc_ul_ui(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
2476 local_bss_tlli2, &rai_bss, cell_id,
2477 GPRS_SAPI_GMM, bss_nu++,
2478 dtap_detach_req, sizeof(dtap_detach_req));
2479
2480 dump_peers(stdout, 0, 0, &gbcfg);
2481
2482 send_llc_dl_ui(nsi, "DETACH ACC", &sgsn_peer[1], 0x1002,
2483 local_sgsn_tlli2, 1, imsi2, sizeof(imsi2),
2484 GPRS_SAPI_GMM, sgsn_nu++,
2485 dtap_detach_acc, sizeof(dtap_detach_acc));
2486
2487 dump_peers(stdout, 0, 0, &gbcfg);
2488
2489 dump_global(stdout, 0);
2490
2491 gbprox_reset(&gbcfg);
2492 gprs_ns_destroy(nsi);
2493 nsi = NULL;
2494}
2495
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002496/* TODO: Move tlv testing to libosmocore */
2497int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
2498int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
2499 uint8_t **value);
2500int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
2501 size_t *value_len);
2502int lv_shift(uint8_t **data, size_t *data_len,
2503 uint8_t **value, size_t *value_len);
2504
2505static void check_tlv_match(uint8_t **data, size_t *data_len,
2506 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
2507{
2508 uint8_t *value;
2509 size_t value_len;
2510 int rc;
2511
2512 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
2513 OSMO_ASSERT(rc == 0);
2514
2515 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002516 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002517 OSMO_ASSERT(value_len == exp_len);
2518 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2519}
2520
2521static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
2522 uint8_t tag, size_t len, const uint8_t *exp_val)
2523{
2524 uint8_t *value;
2525 int rc;
2526
2527 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
2528 OSMO_ASSERT(rc == 0);
2529
2530 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002531 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002532 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2533}
2534
2535static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
2536 size_t len, const uint8_t *exp_val)
2537{
2538 uint8_t *value;
2539 int rc;
2540
2541 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002542 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002543 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
2544}
2545
2546static void check_lv_shift(uint8_t **data, size_t *data_len,
2547 size_t exp_len, const uint8_t *exp_val)
2548{
2549 uint8_t *value;
2550 size_t value_len;
2551 int rc;
2552
2553 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002554 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002555 OSMO_ASSERT(value_len == exp_len);
2556 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
2557}
2558
2559static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
2560 const uint8_t *test_data)
2561{
2562 uint8_t buf[300] = {0};
2563
2564 uint8_t *unchanged_ptr = buf - 1;
2565 size_t unchanged_len = 0xdead;
2566 size_t tmp_data_len = data_len;
2567 uint8_t *value = unchanged_ptr;
2568 size_t value_len = unchanged_len;
2569 uint8_t *data = buf;
2570
2571 OSMO_ASSERT(data_len <= sizeof(buf));
2572
2573 tlv_put(data, tag, len, test_data);
2574 if (data_len < len + 2) {
2575 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
2576 tag, &value, &value_len));
2577 OSMO_ASSERT(tmp_data_len == 0);
2578 OSMO_ASSERT(data == buf + data_len);
2579 OSMO_ASSERT(value == unchanged_ptr);
2580 OSMO_ASSERT(value_len == unchanged_len);
2581 } else {
2582 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
2583 tag, &value, &value_len));
2584 OSMO_ASSERT(value != unchanged_ptr);
2585 OSMO_ASSERT(value_len != unchanged_len);
2586 }
2587}
2588
2589static void check_tv_fixed_match_data_len(size_t data_len,
2590 uint8_t tag, size_t len,
2591 const uint8_t *test_data)
2592{
2593 uint8_t buf[300] = {0};
2594
2595 uint8_t *unchanged_ptr = buf - 1;
2596 size_t tmp_data_len = data_len;
2597 uint8_t *value = unchanged_ptr;
2598 uint8_t *data = buf;
2599
2600 OSMO_ASSERT(data_len <= sizeof(buf));
2601
2602 tv_fixed_put(data, tag, len, test_data);
2603
2604 if (data_len < len + 1) {
2605 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
2606 tag, len, &value));
2607 OSMO_ASSERT(tmp_data_len == 0);
2608 OSMO_ASSERT(data == buf + data_len);
2609 OSMO_ASSERT(value == unchanged_ptr);
2610 } else {
2611 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
2612 tag, len, &value));
2613 OSMO_ASSERT(value != unchanged_ptr);
2614 }
2615}
2616
2617static void check_v_fixed_shift_data_len(size_t data_len,
2618 size_t len, const uint8_t *test_data)
2619{
2620 uint8_t buf[300] = {0};
2621
2622 uint8_t *unchanged_ptr = buf - 1;
2623 size_t tmp_data_len = data_len;
2624 uint8_t *value = unchanged_ptr;
2625 uint8_t *data = buf;
2626
2627 OSMO_ASSERT(data_len <= sizeof(buf));
2628
2629 memcpy(data, test_data, len);
2630
2631 if (data_len < len) {
2632 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
2633 len, &value));
2634 OSMO_ASSERT(tmp_data_len == 0);
2635 OSMO_ASSERT(data == buf + data_len);
2636 OSMO_ASSERT(value == unchanged_ptr);
2637 } else {
2638 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
2639 len, &value));
2640 OSMO_ASSERT(value != unchanged_ptr);
2641 }
2642}
2643
2644static void check_lv_shift_data_len(size_t data_len,
2645 size_t len, const uint8_t *test_data)
2646{
2647 uint8_t buf[300] = {0};
2648
2649 uint8_t *unchanged_ptr = buf - 1;
2650 size_t unchanged_len = 0xdead;
2651 size_t tmp_data_len = data_len;
2652 uint8_t *value = unchanged_ptr;
2653 size_t value_len = unchanged_len;
2654 uint8_t *data = buf;
2655
2656 lv_put(data, len, test_data);
2657 if (data_len < len + 1) {
2658 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
2659 &value, &value_len));
2660 OSMO_ASSERT(tmp_data_len == 0);
2661 OSMO_ASSERT(data == buf + data_len);
2662 OSMO_ASSERT(value == unchanged_ptr);
2663 OSMO_ASSERT(value_len == unchanged_len);
2664 } else {
2665 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
2666 &value, &value_len));
2667 OSMO_ASSERT(value != unchanged_ptr);
2668 OSMO_ASSERT(value_len != unchanged_len);
2669 }
2670}
2671
2672static void test_tlv_shift_functions()
2673{
2674 uint8_t test_data[1024];
2675 uint8_t buf[1024];
2676 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002677 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002678 uint8_t *data;
2679 size_t data_len;
2680 const uint8_t tag = 0x1a;
2681
2682 printf("Test shift functions\n");
2683
2684 for (i = 0; i < ARRAY_SIZE(test_data); i++)
2685 test_data[i] = (uint8_t)i;
2686
2687 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02002688 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02002689
2690 memset(buf, 0xee, sizeof(buf));
2691 data_end = data = buf;
2692
2693 for (i = 0; i < iterations; i++) {
2694 data_end = tlv_put(data_end, tag, len, test_data);
2695 data_end = tv_fixed_put(data_end, tag, len, test_data);
2696 /* v_fixed_put */
2697 memcpy(data_end, test_data, len);
2698 data_end += len;
2699 data_end = lv_put(data_end, len, test_data);
2700 }
2701
2702 data_len = data_end - data;
2703 OSMO_ASSERT(data_len <= sizeof(buf));
2704
2705 for (i = 0; i < iterations; i++) {
2706 check_tlv_match(&data, &data_len, tag, len, test_data);
2707 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
2708 check_v_fixed_shift(&data, &data_len, len, test_data);
2709 check_lv_shift(&data, &data_len, len, test_data);
2710 }
2711
2712 OSMO_ASSERT(data == data_end);
2713
2714 /* Test at end of data */
2715
2716 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
2717 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
2718 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
2719 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
2720
2721 /* Test invalid data_len */
2722 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
2723 check_tlv_match_data_len(data_len, tag, len, test_data);
2724 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
2725 check_v_fixed_shift_data_len(data_len, len, test_data);
2726 check_lv_shift_data_len(data_len, len, test_data);
2727 }
2728 }
2729}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002730
2731static void test_gbproxy_tlli_expire(void)
2732{
2733 struct gbproxy_config cfg = {0};
2734 struct gbproxy_peer *peer;
2735 const char *err_msg = NULL;
2736 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
2737 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002738 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002739 const uint32_t tlli1 = 1234 | 0xc0000000;
2740 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002741 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002742 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002743 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002744
2745 printf("Test TLLI info expiry\n\n");
2746
2747 gbproxy_init_config(&cfg);
2748
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002749 if (gbproxy_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002750 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
2751 err_msg);
2752 OSMO_ASSERT(err_msg == NULL);
2753 }
2754
2755 {
2756 struct gbproxy_tlli_info *tlli_info;
2757
2758 printf("Test TLLI replacement:\n");
2759
2760 cfg.tlli_max_len = 0;
2761 cfg.tlli_max_age = 0;
2762 peer = gbproxy_peer_alloc(&cfg, 20);
2763 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2764
2765 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002766 tlli_info = gbproxy_register_tlli(peer, tlli1,
2767 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002768 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002769 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002770 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2771
2772 /* replace the old entry */
2773 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002774 tlli_info = gbproxy_register_tlli(peer, tlli2,
2775 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002776 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002777 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002778 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2779
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002780 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002781
2782 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002783 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002784 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002785 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002786 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002787 OSMO_ASSERT(!tlli_info);
2788
2789 printf("\n");
2790
2791 gbproxy_peer_free(peer);
2792 }
2793
2794 {
2795 struct gbproxy_tlli_info *tlli_info;
2796
2797 printf("Test IMSI replacement:\n");
2798
2799 cfg.tlli_max_len = 0;
2800 cfg.tlli_max_age = 0;
2801 peer = gbproxy_peer_alloc(&cfg, 20);
2802 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2803
2804 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002805 tlli_info = gbproxy_register_tlli(peer, tlli1,
2806 imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002807 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002808 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002809 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2810
2811 /* try to replace the old entry */
2812 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002813 tlli_info = gbproxy_register_tlli(peer, tlli1,
2814 imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02002815 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002816 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002817 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2818
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002819 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002820
2821 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002822 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002823 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002824 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002825 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002826 OSMO_ASSERT(tlli_info->tlli.current == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002827
2828 printf("\n");
2829
2830 gbproxy_peer_free(peer);
2831 }
2832
2833 {
2834 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002835 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002836
2837 printf("Test TLLI expiry, max_len == 1:\n");
2838
2839 cfg.tlli_max_len = 1;
2840 cfg.tlli_max_age = 0;
2841 peer = gbproxy_peer_alloc(&cfg, 20);
2842 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2843
2844 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002845 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002846 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2847
2848 /* replace the old entry */
2849 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002850 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002851 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2852
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002853 num_removed = gbproxy_remove_stale_tllis(peer, time(NULL) + 2);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002854 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002855 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2856
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02002857 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002858
2859 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002860 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002861 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002862 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002863 OSMO_ASSERT(tlli_info);
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002864 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002865
2866 printf("\n");
2867
2868 gbproxy_peer_free(peer);
2869 }
2870
2871 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002872 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02002873 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002874
2875 printf("Test TLLI expiry, max_age == 1:\n");
2876
2877 cfg.tlli_max_len = 0;
2878 cfg.tlli_max_age = 1;
2879 peer = gbproxy_peer_alloc(&cfg, 20);
2880 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2881
2882 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002883 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002884 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2885
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002886 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002887 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002888 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002889 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2890
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002891 num_removed = gbproxy_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002892 OSMO_ASSERT(num_removed == 1);
2893 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2894
2895 dump_peers(stdout, 2, now + 2, &cfg);
2896
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002897 /* verify that 5678 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002898 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002899 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002900 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002901 OSMO_ASSERT(tlli_info);
2902 OSMO_ASSERT(tlli_info->tlli.current == tlli2);
2903
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002904 printf("\n");
2905
2906 gbproxy_peer_free(peer);
2907 }
2908
2909 {
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002910 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002911 int num_removed;
2912
2913 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
2914
2915 cfg.tlli_max_len = 0;
2916 cfg.tlli_max_age = 1;
2917 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002918 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
2919
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002920 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002921 gbproxy_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002922 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2923
2924 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002925 gbproxy_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002926 now + 1);
2927 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
2928
2929 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002930 gbproxy_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
2931 now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002932 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
2933
2934 dump_peers(stdout, 2, now + 2, &cfg);
2935
2936 printf(" Remove stale TLLIs\n");
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002937 num_removed = gbproxy_remove_stale_tllis(peer, now + 3);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02002938 OSMO_ASSERT(num_removed == 2);
2939 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
2940
2941 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002942
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002943 /* verify that tlli3 has survived */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002944 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002945 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002946 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002947 OSMO_ASSERT(!tlli_info);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002948 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi3, ARRAY_SIZE(imsi3));
Jacob Erlbeck9057bc32014-08-12 16:30:30 +02002949 OSMO_ASSERT(tlli_info);
2950 OSMO_ASSERT(tlli_info->tlli.current == tlli3);
2951
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02002952 printf("\n");
2953
2954 gbproxy_peer_free(peer);
2955 }
2956}
2957
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002958static void test_gbproxy_imsi_matching(void)
2959{
2960 struct gbproxy_config cfg = {0};
2961 struct gbproxy_peer *peer;
2962 const char *err_msg = NULL;
2963 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
2964 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2965 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
2966 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
2967 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
2968 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
2969 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
2970 const char *filter_re1 = ".*";
2971 const char *filter_re2 = "^1234";
2972 const char *filter_re3 = "^4321";
2973 const char *filter_re4_bad = "^12[";
2974
2975 printf("=== Test IMSI/TMSI matching ===\n\n");
2976
2977 gbproxy_init_config(&cfg);
2978 OSMO_ASSERT(cfg.check_imsi == 0);
2979
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002980 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002981 OSMO_ASSERT(cfg.check_imsi == 1);
2982
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002983 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002984 OSMO_ASSERT(cfg.check_imsi == 1);
2985
2986 err_msg = NULL;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002987 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002988 OSMO_ASSERT(err_msg != NULL);
2989 OSMO_ASSERT(cfg.check_imsi == 0);
2990
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002991 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002992 OSMO_ASSERT(cfg.check_imsi == 1);
2993
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002994 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, NULL, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02002995 OSMO_ASSERT(cfg.check_imsi == 0);
2996
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02002997 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02002998 OSMO_ASSERT(cfg.check_imsi == 1);
2999
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003000 gbproxy_clear_patch_filter(&cfg);
Jacob Erlbeck29805da2014-08-14 08:57:04 +02003001 OSMO_ASSERT(cfg.check_imsi == 0);
3002
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003003 peer = gbproxy_peer_alloc(&cfg, 20);
3004
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003005 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003006 OSMO_ASSERT(cfg.check_imsi == 1);
3007
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003008 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
3009 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003010 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003011 * doesn't complain, so gbproxy_check_imsi() doesn't return -1 in this
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003012 * case. */
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003013 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3014 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3015 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3016 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3017 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003018
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003019 OSMO_ASSERT(gbproxy_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003020 OSMO_ASSERT(cfg.check_imsi == 1);
3021
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02003022 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
3023 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
3024 OSMO_ASSERT(gbproxy_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
3025 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
3026 OSMO_ASSERT(gbproxy_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
3027 OSMO_ASSERT(gbproxy_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
3028 OSMO_ASSERT(gbproxy_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003029
3030 /* TODO: Check correct length but wrong type with is_mi_tmsi */
3031
3032 gbproxy_peer_free(peer);
3033}
3034
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003035static struct log_info_cat gprs_categories[] = {
3036 [DGPRS] = {
3037 .name = "DGPRS",
3038 .description = "GPRS Packet Service",
3039 .enabled = 1, .loglevel = LOGL_DEBUG,
3040 },
3041 [DNS] = {
3042 .name = "DNS",
3043 .description = "GPRS Network Service (NS)",
3044 .enabled = 1, .loglevel = LOGL_INFO,
3045 },
3046 [DBSSGP] = {
3047 .name = "DBSSGP",
3048 .description = "GPRS BSS Gateway Protocol (BSSGP)",
3049 .enabled = 1, .loglevel = LOGL_DEBUG,
3050 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003051};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003052
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003053static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003054 .cat = gprs_categories,
3055 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02003056};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003057
3058int main(int argc, char **argv)
3059{
3060 osmo_init_logging(&info);
3061 log_set_use_color(osmo_stderr_target, 0);
3062 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02003063 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003064
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003065 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02003066 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
3067 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003068
3069 rate_ctr_init(NULL);
3070
3071 setlinebuf(stdout);
3072
3073 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02003074 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02003075 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003076 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003077 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02003078 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02003079 test_gbproxy_ra_patching();
Jacob Erlbeck6bd7ded2014-08-15 17:20:06 +02003080 test_gbproxy_ptmsi_patching();
Jacob Erlbeck28fe9882014-08-26 13:33:36 +02003081 test_gbproxy_imsi_acquisition();
Jacob Erlbeckf181f9e2014-08-27 12:44:25 +02003082 test_gbproxy_secondary_sgsn();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02003083 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02003084 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02003085
3086 exit(EXIT_SUCCESS);
3087}