blob: 0d55fb3db252305ee5b7b572b0155dba612b7bab [file] [log] [blame]
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001/* test routines for gbproxy
2 * send NS messages to the gbproxy and dumps what happens
3 * (C) 2013 by sysmocom s.f.m.c. GmbH
4 * Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
5 */
6
7#undef _GNU_SOURCE
8#define _GNU_SOURCE
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <stdint.h>
13#include <string.h>
14#include <getopt.h>
15#include <dlfcn.h>
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020016#include <time.h>
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020017#include <sys/types.h>
18#include <sys/socket.h>
19
20#include <osmocom/core/msgb.h>
21#include <osmocom/core/application.h>
22#include <osmocom/core/utils.h>
23#include <osmocom/core/logging.h>
24#include <osmocom/core/talloc.h>
25#include <osmocom/core/signal.h>
26#include <osmocom/core/rate_ctr.h>
Jacob Erlbeck077abce2014-07-01 12:41:13 +020027#include <osmocom/gsm/tlv.h>
Jacob Erlbeck31132872014-08-11 17:26:21 +020028#include <osmocom/gsm/gsm_utils.h>
Jacob Erlbeck76fa57a2013-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 Freyther8ac3a722014-08-04 11:52:52 +020034#include <openbsc/gprs_utils.h>
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +020035#include <openbsc/debug.h>
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020036
37#define REMOTE_BSS_ADDR 0x01020304
38#define REMOTE_SGSN_ADDR 0x05060708
39
Jacob Erlbeck45017722013-10-18 13:04:47 +020040#define SGSN_NSEI 0x0100
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +020041
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +020042struct gbproxy_config gbcfg = {0};
43
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020044static int dump_global(FILE *stream, int indent)
45{
46 unsigned int i;
47 const struct rate_ctr_group_desc *desc;
48 int rc;
49
50 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
51 if (rc < 0)
52 return rc;
53
54 desc = gbcfg.ctrg->desc;
55
56 for (i = 0; i < desc->num_ctr; i++) {
57 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
58 if (ctr->current) {
59 rc = fprintf(stream, "%*s %s: %llu\n",
60 indent, "",
61 desc->ctr_desc[i].description,
62 (long long)ctr->current);
63
64 if (rc < 0)
65 return rc;
66 }
67 }
68
69 return 0;
70}
71
Jacob Erlbeckc404c082014-08-08 08:37:37 +020072static int dump_peers(FILE *stream, int indent, time_t now,
73 struct gbproxy_config *cfg)
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020074{
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +020075 struct gbproxy_peer *peer;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020076 struct gprs_ra_id raid;
77 unsigned int i;
78 const struct rate_ctr_group_desc *desc;
79 int rc;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020080
81 rc = fprintf(stream, "%*sPeers:\n", indent, "");
82 if (rc < 0)
83 return rc;
84
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +020085 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Holger Hans Peter Freytherd64bf222014-08-04 11:35:32 +020086 struct gbproxy_tlli_info *tlli_info;
87 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +020088 gsm48_parse_ra(&raid, peer->ra);
89
90 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
91 "RAI %u-%u-%u-%u\n",
92 indent, "",
93 peer->nsei, peer->bvci,
94 peer->blocked ? "" : "not ",
95 raid.mcc, raid.mnc, raid.lac, raid.rac);
96
97 if (rc < 0)
98 return rc;
99
100 desc = peer->ctrg->desc;
101
102 for (i = 0; i < desc->num_ctr; i++) {
103 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
104 if (ctr->current) {
105 rc = fprintf(stream, "%*s %s: %llu\n",
106 indent, "",
107 desc->ctr_desc[i].description,
108 (long long)ctr->current);
109
110 if (rc < 0)
111 return rc;
112 }
113 }
114
115 fprintf(stream, "%*s TLLI-Cache: %d\n",
116 indent, "", state->enabled_tllis_count);
117 llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
118 char mi_buf[200];
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200119 time_t age = now ? now - tlli_info->timestamp : 0;
Jacob Erlbeck9ac42ba2014-08-06 18:55:15 +0200120 if (tlli_info->mi_data_len > 0) {
121 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
122 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
123 tlli_info->mi_data,
124 tlli_info->mi_data_len);
125 } else {
126 snprintf(mi_buf, sizeof(mi_buf), "(none)");
127 }
Jacob Erlbeck31132872014-08-11 17:26:21 +0200128 fprintf(stream, "%*s TLLI %08x",
129 indent, "", tlli_info->tlli);
130 if (tlli_info->assigned_tlli)
131 fprintf(stream, "/%08x", tlli_info->assigned_tlli);
132 rc = fprintf(stream, ", IMSI %s, AGE %d\n",
133 mi_buf, (int)age);
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200134 if (rc < 0)
135 return rc;
136 }
137 }
138
139 return 0;
140}
141
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200142/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Attach Request */
143static const unsigned char bssgp_attach_req[75] = {
144 0x01, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x00, 0x04,
145 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
146 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x34, 0x01,
147 0xc0, 0x01, 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21,
148 0x08, 0x02, 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79,
149 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19, 0x18,
150 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
151 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80,
152 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
153 0x16, 0x6d, 0x01
154};
155
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +0200156/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Identity Request */
157static const unsigned char bssgp_identity_req[] = {
158 0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
159 0x16, 0x82, 0x02, 0x58, 0x0e, 0x89, 0x41, 0xc0,
160 0x01, 0x08, 0x15, 0x01, 0xff, 0x6c, 0xba
161};
162
163/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Identity Response */
164static const unsigned char bssgp_identity_resp[] = {
165 0x01, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x00, 0x04,
166 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
167 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x11, 0x01,
168 0xc0, 0x0d, 0x08, 0x16, 0x08, 0x11, 0x12, 0x13,
169 0x14, 0x15, 0x16, 0x17, 0x18, 0xb7, 0x1b, 0x9a
170};
171
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200172/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Attach Accept */
173static const unsigned char bssgp_attach_acc[88] = {
174 0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
175 0x16, 0x82, 0x02, 0x58, 0x13, 0x99, 0x18, 0xb3,
176 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80,
177 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba,
178 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, 0x0a,
179 0x82, 0x08, 0x02, 0x0d, 0x88, 0x11, 0x12, 0x13,
180 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x81, 0x00,
181 0x0e, 0x9e, 0x41, 0xc0, 0x05, 0x08, 0x02, 0x01,
182 0x49, 0x04, 0x21, 0x63, 0x54, 0x40, 0x50, 0x60,
183 0x19, 0xcd, 0xd7, 0x08, 0x17, 0x16, 0x18, 0x05,
Jacob Erlbeck386621c2014-06-27 11:55:04 +0200184 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x42, 0x67, 0x9a
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200185};
186
Jacob Erlbeck31132872014-08-11 17:26:21 +0200187/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Attach Complete */
188static const unsigned char bssgp_attach_complete[] = {
189 0x01, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x00, 0x04,
190 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
191 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x08, 0x01,
192 0xc0, 0x11, 0x08, 0x03, 0xff, 0xff, 0xff
193};
194
Jacob Erlbeckab7366f2014-06-06 18:47:36 +0200195/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - GMM Information */
196static const unsigned char bssgp_gmm_information[66] = {
197 0x00, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x50, 0x20,
198 0x16, 0x82, 0x02, 0x58, 0x13, 0x99, 0x18, 0xb3,
199 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80,
200 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba,
201 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, 0x0a,
202 0x82, 0x08, 0x02, 0x0d, 0x88, 0x11, 0x12, 0x13,
203 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x81, 0x00,
204 0x0e, 0x88, 0x41, 0xc0, 0x09, 0x08, 0x21, 0x04,
205 0xba, 0x3d
206};
207
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200208/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Routing Area Update Request */
209static const unsigned char bssgp_ra_upd_req[85] = {
Jacob Erlbeckab7366f2014-06-06 18:47:36 +0200210 0x01, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x00, 0x04,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200211 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
212 0x70, 0x80, 0x00, 0x80, 0x0e, 0x00, 0x3e, 0x01,
213 0xc0, 0x15, 0x08, 0x08, 0x10, 0x11, 0x22, 0x33,
214 0x40, 0x50, 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33,
215 0x57, 0x2b, 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48,
216 0x50, 0xc8, 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8,
217 0x48, 0x02, 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02,
218 0x00, 0x19, 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27,
219 0x07, 0x04, 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02,
220 0x20, 0x00, 0x96, 0x3e, 0x97
221};
222
223/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Routing Area Update Accept */
224static const unsigned char bssgp_ra_upd_acc[91] = {
Jacob Erlbeckab7366f2014-06-06 18:47:36 +0200225 0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200226 0x16, 0x82, 0x02, 0x58, 0x13, 0x9d, 0x19, 0x13,
227 0x42, 0x33, 0x57, 0x2b, 0xf7, 0xc8, 0x48, 0x02,
228 0x13, 0x48, 0x50, 0xc8, 0x48, 0x02, 0x14, 0x48,
229 0x50, 0xc8, 0x48, 0x02, 0x17, 0x49, 0x10, 0xc8,
230 0x48, 0x02, 0x00, 0x0a, 0x82, 0x07, 0x04, 0x0d,
231 0x88, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
232 0x18, 0x00, 0x81, 0x00, 0x0e, 0x9d, 0x41, 0xc0,
233 0x19, 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
234 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200235 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
236 0xd7, 0x59, 0x65
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200237};
238
239/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Activate PDP Context Request */
240static const unsigned char bssgp_act_pdp_ctx_req[76] = {
241 0x01, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x00, 0x04,
242 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
243 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x35, 0x01,
244 0xc0, 0x0d, 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
245 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
247 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
248 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
249 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
250 0x00, 0x5a, 0xff, 0x02
251};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200252
Jacob Erlbeckf95340d2014-08-11 15:07:37 +0200253/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Detach Request (MO) */
254/* normal detach, power_off = 1 */
255static const unsigned char bssgp_detach_po_req[44] = {
256 0x01, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x00, 0x04,
257 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
258 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x15, 0x01,
259 0xc0, 0x19, 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4,
260 0xef, 0xe2, 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97,
261 0xcb, 0x84, 0x0c, 0xeb
262};
263
264/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Detach Request (MO) */
265/* normal detach, power_off = 0 */
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +0200266static const unsigned char bssgp_detach_req[44] = {
267 0x01, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x00, 0x04,
268 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
269 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x15, 0x01,
270 0xc0, 0x19, 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4,
271 0xef, 0xe2, 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97,
272 0xcb, 0x7e, 0xe1, 0x41
273};
274
275/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Detach Accept */
276static const unsigned char bssgp_detach_acc[67] = {
277 0x00, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x50, 0x20,
278 0x16, 0x82, 0x02, 0x58, 0x13, 0x99, 0x18, 0xb3,
279 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80,
280 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba,
281 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, 0x0a,
282 0x82, 0x08, 0x02, 0x0d, 0x88, 0x11, 0x12, 0x13,
283 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x81, 0x00,
284 0x0e, 0x89, 0x41, 0xc0, 0x15, 0x08, 0x06, 0x00,
285 0xf7, 0x35, 0xf0
286};
287
Jacob Erlbeck45017722013-10-18 13:04:47 +0200288static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
289 struct sockaddr_in *peer, const unsigned char* data,
290 size_t data_len);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200291
292static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
293 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
294{
295 /* GPRS Network Service, PDU type: NS_RESET,
296 */
297 unsigned char msg[12] = {
298 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
299 0x04, 0x82, 0x11, 0x22
300 };
301
302 msg[3] = cause;
303 msg[6] = nsvci / 256;
304 msg[7] = nsvci % 256;
305 msg[10] = nsei / 256;
306 msg[11] = nsei % 256;
307
308 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
309}
310
Jacob Erlbeck45017722013-10-18 13:04:47 +0200311static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
312 uint16_t nsvci, uint16_t nsei)
313{
314 /* GPRS Network Service, PDU type: NS_RESET_ACK,
315 */
316 unsigned char msg[9] = {
317 0x03, 0x01, 0x82, 0x11, 0x22,
318 0x04, 0x82, 0x11, 0x22
319 };
320
321 msg[3] = nsvci / 256;
322 msg[4] = nsvci % 256;
323 msg[7] = nsei / 256;
324 msg[8] = nsei % 256;
325
326 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
327}
328
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200329static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
330{
331 /* GPRS Network Service, PDU type: NS_ALIVE */
332 unsigned char msg[1] = {
333 0x0a
334 };
335
336 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
337}
338
339static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
340{
341 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
342 unsigned char msg[1] = {
343 0x0b
344 };
345
346 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
347}
348
349static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
350{
351 /* GPRS Network Service, PDU type: NS_UNBLOCK */
352 unsigned char msg[1] = {
353 0x06
354 };
355
356 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
357}
358
Jacob Erlbeck45017722013-10-18 13:04:47 +0200359static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
360{
361 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
362 unsigned char msg[1] = {
363 0x07
364 };
365
366 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
367}
368
369static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
370 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200371 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
372{
373 /* GPRS Network Service, PDU type: NS_UNITDATA */
374 unsigned char msg[4096] = {
375 0x00, 0x00, 0x00, 0x00
376 };
377
378 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
379
380 msg[2] = nsbvci / 256;
381 msg[3] = nsbvci % 256;
382 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
383
Jacob Erlbeck45017722013-10-18 13:04:47 +0200384 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200385}
386
387static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
388 uint16_t bvci)
389{
390 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
391 * BSSGP RESET */
Jacob Erlbeck8a600ae2014-08-06 12:38:10 +0200392 unsigned char msg[18] = {
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200393 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeck3f086322014-06-02 10:48:59 +0200394 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
395 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200396 };
397
398 msg[3] = bvci / 256;
399 msg[4] = bvci % 256;
400
Jacob Erlbeck45017722013-10-18 13:04:47 +0200401 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
402}
403
404static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
405 struct sockaddr_in *src_addr, uint16_t bvci)
406{
407 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
408 * BSSGP RESET_ACK */
409 static unsigned char msg[5] = {
410 0x23, 0x04, 0x82, 0x00,
411 0x00
412 };
413
414 msg[3] = bvci / 256;
415 msg[4] = bvci % 256;
416
417 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200418}
419
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200420static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
421 struct sockaddr_in *src_addr,
422 struct gprs_ra_id *raid)
423{
424 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
425 unsigned char msg[15] = {
426 0x0b, 0x1f, 0x84, 0xcc, 0xd1, 0x75, 0x8b, 0x1b,
427 0x86, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60
428 };
429
430 gsm48_construct_ra(msg + 9, raid);
431
432 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
433}
434
435static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
436 struct sockaddr_in *src_addr,
437 struct gprs_ra_id *raid)
438{
439 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
440 unsigned char msg[18] = {
441 0x0c, 0x1f, 0x84, 0xcc, 0xd1, 0x75, 0x8b, 0x1b,
442 0x86, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x1d,
443 0x81, 0x01
444 };
445
446 gsm48_construct_ra(msg + 9, raid);
447
448 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
449}
450
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200451static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
452 uint16_t nsvci, uint16_t nsei)
453{
454 printf("Setup NS-VC: remote 0x%08x:%d, "
455 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
456 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
457 nsvci, nsvci, nsei, nsei);
458
459 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
460 send_ns_alive(nsi, src_addr);
461 send_ns_unblock(nsi, src_addr);
462 send_ns_alive_ack(nsi, src_addr);
463}
464
465static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
466 uint16_t bvci)
467{
468 printf("Setup BSSGP: remote 0x%08x:%d, "
469 "BVCI 0x%04x(%d)\n\n",
470 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
471 bvci, bvci);
472
473 send_bssgp_reset(nsi, src_addr, bvci);
474}
475
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200476static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer)
477{
478 gprs_ns_nsip_connect(nsi, sgsn_peer, SGSN_NSEI, SGSN_NSEI+1);
479 send_ns_reset_ack(nsi, sgsn_peer, SGSN_NSEI+1, SGSN_NSEI);
480 send_ns_alive_ack(nsi, sgsn_peer);
481 send_ns_unblock_ack(nsi, sgsn_peer);
482 send_ns_alive(nsi, sgsn_peer);
483}
484
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200485static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
486{
487 sgsn_peer->sin_family = AF_INET;
488 sgsn_peer->sin_port = htons(32000);
489 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
490}
491
492static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
493{
494 size_t i;
495
496 for (i = 0; i < size; ++i) {
497 bss_peers[i].sin_family = AF_INET;
498 bss_peers[i].sin_port = htons((i + 1) * 1111);
499 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
500 }
501}
502
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200503int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
504 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
505
506/* override */
507int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
508 struct msgb *msg, uint16_t bvci)
509{
510 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
511 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200512 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200513
514 switch (event) {
515 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +0200516 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200517 default:
518 break;
519 }
520 return 0;
521}
522
523/* override */
524ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
525 const struct sockaddr *dest_addr, socklen_t addrlen)
526{
527 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
528 const struct sockaddr *, socklen_t);
529 static sendto_t real_sendto = NULL;
530 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200531 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200532
533 if (!real_sendto)
534 real_sendto = dlsym(RTLD_NEXT, "sendto");
535
536 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck45017722013-10-18 13:04:47 +0200537 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
538 dest_host, dest_port,
539 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200540 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck45017722013-10-18 13:04:47 +0200541 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
542 dest_host, dest_port,
543 len, osmo_hexdump(buf, len));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200544 else
545 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
546
547 return len;
548}
549
550/* override */
551int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
552{
Jacob Erlbeck45017722013-10-18 13:04:47 +0200553 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
554 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200555 uint16_t bvci = msgb_bvci(msg);
556 uint16_t nsei = msgb_nsei(msg);
557
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200558 size_t len = msgb_length(msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200559
Jacob Erlbeck45017722013-10-18 13:04:47 +0200560 if (!real_gprs_ns_sendmsg)
561 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
562
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200563 if (nsei == SGSN_NSEI)
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200564 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
565 "msg length %d (%s)\n",
566 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200567 else
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200568 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
569 "msg length %d (%s)\n",
570 bvci, len, __func__);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200571
Jacob Erlbeck45017722013-10-18 13:04:47 +0200572 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200573}
574
575static void dump_rate_ctr_group(FILE *stream, const char *prefix,
576 struct rate_ctr_group *ctrg)
577{
578 unsigned int i;
579
580 for (i = 0; i < ctrg->desc->num_ctr; i++) {
581 struct rate_ctr *ctr = &ctrg->ctr[i];
582 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
583 fprintf(stream, " %s%s: %llu%s",
584 prefix, ctrg->desc->ctr_desc[i].description,
585 (long long)ctr->current,
586 "\n");
587 };
588}
589
590/* Signal handler for signals from NS layer */
591static int test_signal(unsigned int subsys, unsigned int signal,
592 void *handler_data, void *signal_data)
593{
594 struct ns_signal_data *nssd = signal_data;
595 int rc;
596
597 if (subsys != SS_L_NS)
598 return 0;
599
600 switch (signal) {
601 case S_NS_RESET:
602 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
603 nssd->nsvc->nsvci,
604 gprs_ns_ll_str(nssd->nsvc));
605 break;
606
607 case S_NS_ALIVE_EXP:
608 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
609 nssd->nsvc->nsvci,
610 gprs_ns_ll_str(nssd->nsvc));
611 break;
612
613 case S_NS_BLOCK:
614 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
615 nssd->nsvc->nsvci,
616 gprs_ns_ll_str(nssd->nsvc));
617 break;
618
619 case S_NS_UNBLOCK:
620 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
621 nssd->nsvc->nsvci,
622 gprs_ns_ll_str(nssd->nsvc));
623 break;
624
625 case S_NS_REPLACED:
626 printf("==> got signal NS_REPLACED: 0x%04x/%s",
627 nssd->nsvc->nsvci,
628 gprs_ns_ll_str(nssd->nsvc));
629 printf(" -> 0x%04x/%s\n",
630 nssd->old_nsvc->nsvci,
631 gprs_ns_ll_str(nssd->old_nsvc));
632 break;
633
634 default:
635 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
636 nssd->nsvc->nsvci,
637 gprs_ns_ll_str(nssd->nsvc));
638 break;
639 }
640 printf("\n");
641 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
642 return rc;
643}
644
645static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
646{
647 struct msgb *msg;
648 int ret;
649 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
650 fprintf(stderr, "message too long: %d\n", data_len);
651 return -1;
652 }
653
654 msg = gprs_ns_msgb_alloc();
655 memmove(msg->data, data, data_len);
656 msg->l2h = msg->data;
657 msgb_put(msg, data_len);
658
659 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
660 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
661 osmo_hexdump(data, data_len));
662
663 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
664
665 printf("result (%s) = %d\n\n", text, ret);
666
667 msgb_free(msg);
668
669 return ret;
670}
671
672static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
673{
674 struct gprs_nsvc *nsvc;
675
676 printf("Current NS-VCIs:\n");
677 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
678 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200679 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200680 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck45017722013-10-18 13:04:47 +0200681 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
682 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
683 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200684 );
685 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
686 }
687 printf("\n");
688}
689
690static void test_gbproxy()
691{
692 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
693 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck45017722013-10-18 13:04:47 +0200694 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200695
696 bssgp_nsi = nsi;
697 gbcfg.nsi = bssgp_nsi;
698 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
699
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200700 configure_sgsn_peer(&sgsn_peer);
701 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200702
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200703 printf("=== %s ===\n", __func__);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200704 printf("--- Initialise SGSN ---\n\n");
705
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200706 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200707 gprs_dump_nsi(nsi);
708
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200709 printf("--- Initialise BSS 1 ---\n\n");
710
711 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
712 setup_bssgp(nsi, &bss_peer[0], 0x1002);
713 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200714 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200715
Jacob Erlbeck45017722013-10-18 13:04:47 +0200716 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
717
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200718 printf("--- Initialise BSS 2 ---\n\n");
719
720 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
721 setup_bssgp(nsi, &bss_peer[1], 0x2002);
722 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200723 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200724
Jacob Erlbeck45017722013-10-18 13:04:47 +0200725 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
726
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200727 printf("--- Move BSS 1 to new port ---\n\n");
728
729 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
730 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200731 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200732
733 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
734
735 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
736 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200737 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200738
739 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
740
741 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
742 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200743 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200744
745 printf("--- Move BSS 2 to new port ---\n\n");
746
747 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
748 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200749 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200750
751 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
752
753 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
754 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200755 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200756
Jacob Erlbeck45017722013-10-18 13:04:47 +0200757 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
758
759 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
760 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200761 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200762
763 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
764
765 setup_bssgp(nsi, &bss_peer[0], 0x1012);
766 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200767 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200768
769 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
770
771 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
772
773 setup_bssgp(nsi, &bss_peer[0], 0x1002);
774 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200775 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200776
777 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
778
779 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
780
781 setup_bssgp(nsi, &bss_peer[0], 0x1002);
782 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200783 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200784
785 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
786
787 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
788
789 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
790
791 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
792
793 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
794
795 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
796
797 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
798
799 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
800
801 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
802
803 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
804
805 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
806
807 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
808
809 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
810
811 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
812
813 setup_bssgp(nsi, &bss_peer[2], 0x1002);
814 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200815 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck45017722013-10-18 13:04:47 +0200816
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200817 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +0200818
Jacob Erlbeck45017722013-10-18 13:04:47 +0200819 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
820
821 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
822
823 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
824
825 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
826
827 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
828
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +0200829 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
830
831 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
832
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200833 dump_global(stdout, 0);
Jacob Erlbeckcc4a2aa2013-10-18 22:12:16 +0200834
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +0200835 gbprox_reset(&gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200836 gprs_ns_destroy(nsi);
837 nsi = NULL;
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200838}
839
840static void test_gbproxy_ident_changes()
841{
842 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
843 struct sockaddr_in bss_peer[1] = {{0},};
844 struct sockaddr_in sgsn_peer= {0};
845 uint16_t nsei[2] = {0x1000, 0x2000};
846 uint16_t nsvci[2] = {0x1001, 0x2001};
847 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
848
849 bssgp_nsi = nsi;
850 gbcfg.nsi = bssgp_nsi;
851 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
852
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200853 configure_sgsn_peer(&sgsn_peer);
854 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200855
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +0200856 printf("=== %s ===\n", __func__);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200857 printf("--- Initialise SGSN ---\n\n");
858
Jacob Erlbeck738b1c82014-07-07 10:46:00 +0200859 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200860 gprs_dump_nsi(nsi);
861
862 printf("--- Initialise BSS 1 ---\n\n");
863
864 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
865 gprs_dump_nsi(nsi);
866
867 printf("--- Setup BVCI 1 ---\n\n");
868
869 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
870 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200871 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200872
873 printf("--- Setup BVCI 2 ---\n\n");
874
875 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
876 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200877 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200878
879 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
880
881 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
882 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
883
884 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
885
886 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
887 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
888
889 printf("--- Change NSEI ---\n\n");
890
891 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
892 gprs_dump_nsi(nsi);
893
894 printf("--- Setup BVCI 1 ---\n\n");
895
896 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
897 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200898 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200899
900 printf("--- Setup BVCI 3 ---\n\n");
901
902 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
903 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200904 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200905
906 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
907
908 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
909 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
910
911 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
912 " (should fail) ---\n\n");
913
914 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200915 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200916 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200917 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200918
919 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
920
921 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
922 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
923
924 printf("--- Change NSVCI ---\n\n");
925
926 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
927 gprs_dump_nsi(nsi);
928
929 printf("--- Setup BVCI 1 ---\n\n");
930
931 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
932 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200933 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200934
935 printf("--- Setup BVCI 4 ---\n\n");
936
937 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
938 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200939 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200940
941 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
942
943 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
944 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
945
946 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
947 " (should fail) ---\n\n");
948
949 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200950 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200951 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200952 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200953
954 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
955
956 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
957 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
958
959 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
960
961 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
962 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
963
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +0200964 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +0200965 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200966
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +0200967 gbprox_reset(&gbcfg);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +0200968 gprs_ns_destroy(nsi);
969 nsi = NULL;
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +0200970}
971
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200972static void test_gbproxy_ra_patching()
973{
974 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
975 struct sockaddr_in bss_peer[1] = {{0},};
976 struct sockaddr_in sgsn_peer= {0};
977 struct gprs_ra_id rai_bss =
978 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
979 struct gprs_ra_id rai_sgsn =
980 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
981 struct gprs_ra_id rai_unknown =
982 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeck43037632014-06-06 18:49:23 +0200983 const char *err_msg = NULL;
Jacob Erlbeck31132872014-08-11 17:26:21 +0200984 const uint32_t ptmsi = 0xefe2b700;
985 const uint32_t local_tlli = 0xefe2b700;
986 struct gbproxy_tlli_info *tlli_info;
987 struct gbproxy_peer *peer;
988
989 OSMO_ASSERT(local_tlli == gprs_tmsi2tlli(ptmsi, TLLI_LOCAL));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200990
991 bssgp_nsi = nsi;
992 gbcfg.nsi = bssgp_nsi;
993 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck2504bc42014-05-19 10:14:58 +0200994 gbcfg.core_mcc = 123;
995 gbcfg.core_mnc = 456;
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +0200996 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freyther2d10ad12014-08-04 14:22:13 +0200997 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +0200998
Holger Hans Peter Freyther731097d2014-07-07 14:19:10 +0200999 configure_sgsn_peer(&sgsn_peer);
1000 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001001
Jacob Erlbeck43037632014-06-06 18:49:23 +02001002 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Holger Hans Peter Freyther5e94f7f2014-08-04 16:27:11 +02001003 if (gbprox_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck43037632014-06-06 18:49:23 +02001004 fprintf(stderr, "Failed to compile RE '%s': %s\n",
1005 gbcfg.match_re, err_msg);
1006 exit(1);
1007 }
1008
1009
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001010 printf("=== %s ===\n", __func__);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001011 printf("--- Initialise SGSN ---\n\n");
1012
1013 connect_sgsn(nsi, &sgsn_peer);
1014 gprs_dump_nsi(nsi);
1015
1016 printf("--- Initialise BSS 1 ---\n\n");
1017
1018 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1019 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1020 gprs_dump_nsi(nsi);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001021 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001022
Jacob Erlbeck31132872014-08-11 17:26:21 +02001023 peer = gbprox_peer_by_nsei(&gbcfg, 0x1000);
1024 OSMO_ASSERT(peer != NULL);
1025
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001026 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1027
1028 send_bssgp_suspend(nsi, &bss_peer[0], &rai_bss);
1029 send_bssgp_suspend_ack(nsi, &sgsn_peer, &rai_sgsn);
1030
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001031 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001032 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001033
1034 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1035
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001036 send_ns_unitdata(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001037 bssgp_attach_req, sizeof(bssgp_attach_req));
1038
Jacob Erlbeckdc6dcdf2014-08-06 15:16:45 +02001039 send_ns_unitdata(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1040 bssgp_identity_req, sizeof(bssgp_identity_req));
1041
1042 send_ns_unitdata(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1043 bssgp_identity_resp, sizeof(bssgp_identity_resp));
1044
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001045 send_ns_unitdata(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001046 bssgp_attach_acc, sizeof(bssgp_attach_acc));
1047
Jacob Erlbeck31132872014-08-11 17:26:21 +02001048 tlli_info = gbprox_find_tlli(peer, local_tlli);
1049 OSMO_ASSERT(tlli_info);
1050 OSMO_ASSERT(tlli_info->assigned_tlli == local_tlli);
1051 OSMO_ASSERT(tlli_info->tlli != local_tlli);
1052 OSMO_ASSERT(!tlli_info->bss_validated);
1053 OSMO_ASSERT(!tlli_info->net_validated);
1054
1055 send_ns_unitdata(nsi, "ATTACH COMPLETE", &bss_peer[0], 0x1002,
1056 bssgp_attach_complete, sizeof(bssgp_attach_complete));
1057
1058 tlli_info = gbprox_find_tlli(peer, local_tlli);
1059 OSMO_ASSERT(tlli_info);
1060 OSMO_ASSERT(tlli_info->assigned_tlli == local_tlli);
1061 OSMO_ASSERT(tlli_info->tlli != local_tlli);
1062 OSMO_ASSERT(tlli_info->bss_validated);
1063 OSMO_ASSERT(!tlli_info->net_validated);
1064
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001065 /* Replace APN (1) */
1066 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REPLACE APN)",
1067 &bss_peer[0], 0x1002,
1068 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001069
Jacob Erlbeck31132872014-08-11 17:26:21 +02001070 tlli_info = gbprox_find_tlli(peer, local_tlli);
1071 OSMO_ASSERT(tlli_info);
1072 OSMO_ASSERT(tlli_info->assigned_tlli == local_tlli);
1073 OSMO_ASSERT(tlli_info->tlli != local_tlli);
1074 OSMO_ASSERT(tlli_info->bss_validated);
1075 OSMO_ASSERT(!tlli_info->net_validated);
1076
Jacob Erlbeckab7366f2014-06-06 18:47:36 +02001077 send_ns_unitdata(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1078 bssgp_gmm_information, sizeof(bssgp_gmm_information));
1079
Jacob Erlbeck31132872014-08-11 17:26:21 +02001080 tlli_info = gbprox_find_tlli(peer, local_tlli);
1081 OSMO_ASSERT(tlli_info);
1082 OSMO_ASSERT(tlli_info->assigned_tlli == 0);
1083 OSMO_ASSERT(tlli_info->tlli == local_tlli);
1084
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001085 /* Replace APN (2) */
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001086 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REPLACE APN)",
1087 &bss_peer[0], 0x1002,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001088 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
1089
Jacob Erlbeck5620c6d2014-05-23 20:48:07 +02001090 gbcfg.core_apn[0] = 0;
1091 gbcfg.core_apn_size = 0;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001092
1093 /* Remove APN */
Jacob Erlbeck03a2ee22014-07-09 23:19:11 +02001094 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REMOVE APN)",
1095 &bss_peer[0], 0x1002,
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001096 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
1097
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001098 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001099
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001100 /* Detach */
1101 send_ns_unitdata(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1102 bssgp_detach_req, sizeof(bssgp_detach_req));
1103
1104 send_ns_unitdata(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1105 bssgp_detach_acc, sizeof(bssgp_detach_acc));
1106
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001107 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001108
1109 printf("--- RA update ---\n\n");
1110
1111 send_ns_unitdata(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1112 bssgp_ra_upd_req, sizeof(bssgp_ra_upd_req));
1113
1114 send_ns_unitdata(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1115 bssgp_ra_upd_acc, sizeof(bssgp_ra_upd_acc));
1116
1117 /* Remove APN */
1118 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REMOVE APN)",
1119 &bss_peer[0], 0x1002,
1120 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
1121
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001122 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001123
Jacob Erlbeckf95340d2014-08-11 15:07:37 +02001124 /* Detach (power off -> no Detach Accept) */
1125 send_ns_unitdata(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1126 bssgp_detach_po_req, sizeof(bssgp_detach_po_req));
Jacob Erlbeck386621c2014-06-27 11:55:04 +02001127
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001128 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001129 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001130
1131 printf("--- Bad cases ---\n\n");
1132
Jacob Erlbeck43037632014-06-06 18:49:23 +02001133 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckbf6020f2014-06-19 10:23:50 +02001134 send_ns_unitdata(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1135 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
1136
Jacob Erlbeck90a1fd12014-05-27 13:49:04 +02001137 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001138 send_bssgp_suspend_ack(nsi, &sgsn_peer, &rai_unknown);
1139
Holger Hans Peter Freytherf28f8f52014-08-04 11:26:54 +02001140 dump_global(stdout, 0);
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001141 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001142
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001143 gbprox_reset(&gbcfg);
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001144 gprs_ns_destroy(nsi);
1145 nsi = NULL;
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001146}
1147
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001148/* TODO: Move tlv testing to libosmocore */
1149int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
1150int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
1151 uint8_t **value);
1152int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
1153 size_t *value_len);
1154int lv_shift(uint8_t **data, size_t *data_len,
1155 uint8_t **value, size_t *value_len);
1156
1157static void check_tlv_match(uint8_t **data, size_t *data_len,
1158 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
1159{
1160 uint8_t *value;
1161 size_t value_len;
1162 int rc;
1163
1164 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
1165 OSMO_ASSERT(rc == 0);
1166
1167 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001168 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001169 OSMO_ASSERT(value_len == exp_len);
1170 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
1171}
1172
1173static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
1174 uint8_t tag, size_t len, const uint8_t *exp_val)
1175{
1176 uint8_t *value;
1177 int rc;
1178
1179 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
1180 OSMO_ASSERT(rc == 0);
1181
1182 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001183 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001184 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
1185}
1186
1187static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
1188 size_t len, const uint8_t *exp_val)
1189{
1190 uint8_t *value;
1191 int rc;
1192
1193 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001194 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001195 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
1196}
1197
1198static void check_lv_shift(uint8_t **data, size_t *data_len,
1199 size_t exp_len, const uint8_t *exp_val)
1200{
1201 uint8_t *value;
1202 size_t value_len;
1203 int rc;
1204
1205 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001206 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001207 OSMO_ASSERT(value_len == exp_len);
1208 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
1209}
1210
1211static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
1212 const uint8_t *test_data)
1213{
1214 uint8_t buf[300] = {0};
1215
1216 uint8_t *unchanged_ptr = buf - 1;
1217 size_t unchanged_len = 0xdead;
1218 size_t tmp_data_len = data_len;
1219 uint8_t *value = unchanged_ptr;
1220 size_t value_len = unchanged_len;
1221 uint8_t *data = buf;
1222
1223 OSMO_ASSERT(data_len <= sizeof(buf));
1224
1225 tlv_put(data, tag, len, test_data);
1226 if (data_len < len + 2) {
1227 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
1228 tag, &value, &value_len));
1229 OSMO_ASSERT(tmp_data_len == 0);
1230 OSMO_ASSERT(data == buf + data_len);
1231 OSMO_ASSERT(value == unchanged_ptr);
1232 OSMO_ASSERT(value_len == unchanged_len);
1233 } else {
1234 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
1235 tag, &value, &value_len));
1236 OSMO_ASSERT(value != unchanged_ptr);
1237 OSMO_ASSERT(value_len != unchanged_len);
1238 }
1239}
1240
1241static void check_tv_fixed_match_data_len(size_t data_len,
1242 uint8_t tag, size_t len,
1243 const uint8_t *test_data)
1244{
1245 uint8_t buf[300] = {0};
1246
1247 uint8_t *unchanged_ptr = buf - 1;
1248 size_t tmp_data_len = data_len;
1249 uint8_t *value = unchanged_ptr;
1250 uint8_t *data = buf;
1251
1252 OSMO_ASSERT(data_len <= sizeof(buf));
1253
1254 tv_fixed_put(data, tag, len, test_data);
1255
1256 if (data_len < len + 1) {
1257 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
1258 tag, len, &value));
1259 OSMO_ASSERT(tmp_data_len == 0);
1260 OSMO_ASSERT(data == buf + data_len);
1261 OSMO_ASSERT(value == unchanged_ptr);
1262 } else {
1263 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
1264 tag, len, &value));
1265 OSMO_ASSERT(value != unchanged_ptr);
1266 }
1267}
1268
1269static void check_v_fixed_shift_data_len(size_t data_len,
1270 size_t len, const uint8_t *test_data)
1271{
1272 uint8_t buf[300] = {0};
1273
1274 uint8_t *unchanged_ptr = buf - 1;
1275 size_t tmp_data_len = data_len;
1276 uint8_t *value = unchanged_ptr;
1277 uint8_t *data = buf;
1278
1279 OSMO_ASSERT(data_len <= sizeof(buf));
1280
1281 memcpy(data, test_data, len);
1282
1283 if (data_len < len) {
1284 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
1285 len, &value));
1286 OSMO_ASSERT(tmp_data_len == 0);
1287 OSMO_ASSERT(data == buf + data_len);
1288 OSMO_ASSERT(value == unchanged_ptr);
1289 } else {
1290 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
1291 len, &value));
1292 OSMO_ASSERT(value != unchanged_ptr);
1293 }
1294}
1295
1296static void check_lv_shift_data_len(size_t data_len,
1297 size_t len, const uint8_t *test_data)
1298{
1299 uint8_t buf[300] = {0};
1300
1301 uint8_t *unchanged_ptr = buf - 1;
1302 size_t unchanged_len = 0xdead;
1303 size_t tmp_data_len = data_len;
1304 uint8_t *value = unchanged_ptr;
1305 size_t value_len = unchanged_len;
1306 uint8_t *data = buf;
1307
1308 lv_put(data, len, test_data);
1309 if (data_len < len + 1) {
1310 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
1311 &value, &value_len));
1312 OSMO_ASSERT(tmp_data_len == 0);
1313 OSMO_ASSERT(data == buf + data_len);
1314 OSMO_ASSERT(value == unchanged_ptr);
1315 OSMO_ASSERT(value_len == unchanged_len);
1316 } else {
1317 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
1318 &value, &value_len));
1319 OSMO_ASSERT(value != unchanged_ptr);
1320 OSMO_ASSERT(value_len != unchanged_len);
1321 }
1322}
1323
1324static void test_tlv_shift_functions()
1325{
1326 uint8_t test_data[1024];
1327 uint8_t buf[1024];
1328 uint8_t *data_end;
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001329 unsigned i, len;
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001330 uint8_t *data;
1331 size_t data_len;
1332 const uint8_t tag = 0x1a;
1333
1334 printf("Test shift functions\n");
1335
1336 for (i = 0; i < ARRAY_SIZE(test_data); i++)
1337 test_data[i] = (uint8_t)i;
1338
1339 for (len = 0; len < 256; len++) {
Jacob Erlbeckb5eff5d2014-08-11 10:37:35 +02001340 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001341
1342 memset(buf, 0xee, sizeof(buf));
1343 data_end = data = buf;
1344
1345 for (i = 0; i < iterations; i++) {
1346 data_end = tlv_put(data_end, tag, len, test_data);
1347 data_end = tv_fixed_put(data_end, tag, len, test_data);
1348 /* v_fixed_put */
1349 memcpy(data_end, test_data, len);
1350 data_end += len;
1351 data_end = lv_put(data_end, len, test_data);
1352 }
1353
1354 data_len = data_end - data;
1355 OSMO_ASSERT(data_len <= sizeof(buf));
1356
1357 for (i = 0; i < iterations; i++) {
1358 check_tlv_match(&data, &data_len, tag, len, test_data);
1359 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
1360 check_v_fixed_shift(&data, &data_len, len, test_data);
1361 check_lv_shift(&data, &data_len, len, test_data);
1362 }
1363
1364 OSMO_ASSERT(data == data_end);
1365
1366 /* Test at end of data */
1367
1368 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
1369 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
1370 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
1371 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
1372
1373 /* Test invalid data_len */
1374 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
1375 check_tlv_match_data_len(data_len, tag, len, test_data);
1376 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
1377 check_v_fixed_shift_data_len(data_len, len, test_data);
1378 check_lv_shift_data_len(data_len, len, test_data);
1379 }
1380 }
1381}
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001382
1383static void test_gbproxy_tlli_expire(void)
1384{
1385 struct gbproxy_config cfg = {0};
1386 struct gbproxy_peer *peer;
1387 const char *err_msg = NULL;
1388 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
1389 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02001390 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001391 const uint32_t tlli1 = 1234 | 0xc0000000;
1392 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02001393 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001394 const char *filter_re = ".*";
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001395 time_t now = 1407479214;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001396
1397 printf("Test TLLI info expiry\n\n");
1398
1399 gbproxy_init_config(&cfg);
1400
1401 if (gbprox_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
1402 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
1403 err_msg);
1404 OSMO_ASSERT(err_msg == NULL);
1405 }
1406
1407 {
1408 struct gbproxy_tlli_info *tlli_info;
1409
1410 printf("Test TLLI replacement:\n");
1411
1412 cfg.tlli_max_len = 0;
1413 cfg.tlli_max_age = 0;
1414 peer = gbproxy_peer_alloc(&cfg, 20);
1415 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1416
1417 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckccc59702014-08-07 20:18:47 +02001418 tlli_info = gbprox_register_tlli(peer, tlli1,
1419 imsi1, ARRAY_SIZE(imsi1), now);
1420 OSMO_ASSERT(tlli_info);
1421 OSMO_ASSERT(tlli_info->tlli == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001422 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1423
1424 /* replace the old entry */
1425 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeckccc59702014-08-07 20:18:47 +02001426 tlli_info = gbprox_register_tlli(peer, tlli2,
1427 imsi1, ARRAY_SIZE(imsi1), now);
1428 OSMO_ASSERT(tlli_info);
1429 OSMO_ASSERT(tlli_info->tlli == tlli2);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001430 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1431
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001432 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001433
1434 /* verify that 5678 has survived */
1435 tlli_info = gbprox_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
1436 OSMO_ASSERT(tlli_info);
1437 OSMO_ASSERT(tlli_info->tlli == tlli2);
1438 tlli_info = gbprox_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
1439 OSMO_ASSERT(!tlli_info);
1440
1441 printf("\n");
1442
1443 gbproxy_peer_free(peer);
1444 }
1445
1446 {
1447 struct gbproxy_tlli_info *tlli_info;
1448
1449 printf("Test IMSI replacement:\n");
1450
1451 cfg.tlli_max_len = 0;
1452 cfg.tlli_max_age = 0;
1453 peer = gbproxy_peer_alloc(&cfg, 20);
1454 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1455
1456 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckccc59702014-08-07 20:18:47 +02001457 tlli_info = gbprox_register_tlli(peer, tlli1,
1458 imsi1, ARRAY_SIZE(imsi1), now);
1459 OSMO_ASSERT(tlli_info);
1460 OSMO_ASSERT(tlli_info->tlli == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001461 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1462
1463 /* try to replace the old entry */
1464 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeckccc59702014-08-07 20:18:47 +02001465 tlli_info = gbprox_register_tlli(peer, tlli1,
1466 imsi2, ARRAY_SIZE(imsi2), now);
1467 OSMO_ASSERT(tlli_info);
1468 OSMO_ASSERT(tlli_info->tlli == tlli1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001469 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1470
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001471 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001472
1473 /* verify that 5678 has survived */
1474 tlli_info = gbprox_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
1475 OSMO_ASSERT(!tlli_info);
1476 tlli_info = gbprox_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
1477 OSMO_ASSERT(tlli_info);
1478 OSMO_ASSERT(tlli_info->tlli == tlli1);
1479
1480 printf("\n");
1481
1482 gbproxy_peer_free(peer);
1483 }
1484
1485 {
1486 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02001487 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001488
1489 printf("Test TLLI expiry, max_len == 1:\n");
1490
1491 cfg.tlli_max_len = 1;
1492 cfg.tlli_max_age = 0;
1493 peer = gbproxy_peer_alloc(&cfg, 20);
1494 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1495
1496 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001497 gbprox_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001498 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1499
1500 /* replace the old entry */
1501 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001502 gbprox_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02001503 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
1504
1505 num_removed = gbprox_remove_stale_tllis(peer, time(NULL) + 2);
1506 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001507 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1508
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001509 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001510
1511 /* verify that 5678 has survived */
1512 tlli_info = gbprox_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
1513 OSMO_ASSERT(!tlli_info);
1514 tlli_info = gbprox_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
1515 OSMO_ASSERT(tlli_info);
1516 OSMO_ASSERT(tlli_info->tlli == tlli2);
1517
1518 printf("\n");
1519
1520 gbproxy_peer_free(peer);
1521 }
1522
1523 {
Jacob Erlbeck985b46e2014-08-07 17:23:00 +02001524 int num_removed;
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001525
1526 printf("Test TLLI expiry, max_age == 1:\n");
1527
1528 cfg.tlli_max_len = 0;
1529 cfg.tlli_max_age = 1;
1530 peer = gbproxy_peer_alloc(&cfg, 20);
1531 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1532
1533 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001534 gbprox_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001535 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1536
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02001537 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
1538 gbprox_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
1539 now + 1);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001540 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
1541
Jacob Erlbeckc404c082014-08-08 08:37:37 +02001542 num_removed = gbprox_remove_stale_tllis(peer, now + 2);
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02001543 OSMO_ASSERT(num_removed == 1);
1544 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1545
1546 dump_peers(stdout, 2, now + 2, &cfg);
1547
1548 printf("\n");
1549
1550 gbproxy_peer_free(peer);
1551 }
1552
1553 {
1554 int num_removed;
1555
1556 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
1557
1558 cfg.tlli_max_len = 0;
1559 cfg.tlli_max_age = 1;
1560 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001561 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1562
Jacob Erlbeck3e2045e2014-08-08 09:33:06 +02001563 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
1564 gbprox_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
1565 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1566
1567 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
1568 gbprox_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
1569 now + 1);
1570 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
1571
1572 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
1573 gbprox_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
1574 now + 2);
1575 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
1576
1577 dump_peers(stdout, 2, now + 2, &cfg);
1578
1579 printf(" Remove stale TLLIs\n");
1580 num_removed = gbprox_remove_stale_tllis(peer, now + 3);
1581 OSMO_ASSERT(num_removed == 2);
1582 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1583
1584 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001585
1586 printf("\n");
1587
1588 gbproxy_peer_free(peer);
1589 }
1590}
1591
Jacob Erlbeckb6799772014-08-07 10:46:29 +02001592static void test_gbproxy_imsi_matching(void)
1593{
1594 struct gbproxy_config cfg = {0};
1595 struct gbproxy_peer *peer;
1596 const char *err_msg = NULL;
1597 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
1598 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
1599 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
1600 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
1601 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
1602 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
1603 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
1604 const char *filter_re1 = ".*";
1605 const char *filter_re2 = "^1234";
1606 const char *filter_re3 = "^4321";
1607 const char *filter_re4_bad = "^12[";
1608
1609 printf("=== Test IMSI/TMSI matching ===\n\n");
1610
1611 gbproxy_init_config(&cfg);
1612 OSMO_ASSERT(cfg.check_imsi == 0);
1613
1614 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
1615 OSMO_ASSERT(cfg.check_imsi == 1);
1616
1617 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
1618 OSMO_ASSERT(cfg.check_imsi == 1);
1619
1620 err_msg = NULL;
1621 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
1622 OSMO_ASSERT(err_msg != NULL);
1623 OSMO_ASSERT(cfg.check_imsi == 0);
1624
1625 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
1626 OSMO_ASSERT(cfg.check_imsi == 1);
1627
1628 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, NULL, &err_msg) == 0);
1629 OSMO_ASSERT(cfg.check_imsi == 0);
1630
Jacob Erlbeck581728f2014-08-14 08:57:04 +02001631 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
1632 OSMO_ASSERT(cfg.check_imsi == 1);
1633
1634 gbprox_clear_patch_filter(&cfg);
1635 OSMO_ASSERT(cfg.check_imsi == 0);
1636
Jacob Erlbeckb6799772014-08-07 10:46:29 +02001637 peer = gbproxy_peer_alloc(&cfg, 20);
1638
1639 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
1640 OSMO_ASSERT(cfg.check_imsi == 1);
1641
1642 OSMO_ASSERT(gbprox_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
1643 OSMO_ASSERT(gbprox_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
1644 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
1645 * doesn't complain, so gbprox_check_imsi() doesn't return -1 in this
1646 * case. */
1647 OSMO_ASSERT(gbprox_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
1648 OSMO_ASSERT(gbprox_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
1649 OSMO_ASSERT(gbprox_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
1650 OSMO_ASSERT(gbprox_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
1651 OSMO_ASSERT(gbprox_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
1652
1653 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
1654 OSMO_ASSERT(cfg.check_imsi == 1);
1655
1656 OSMO_ASSERT(gbprox_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
1657 OSMO_ASSERT(gbprox_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
1658 OSMO_ASSERT(gbprox_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
1659 OSMO_ASSERT(gbprox_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
1660 OSMO_ASSERT(gbprox_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
1661 OSMO_ASSERT(gbprox_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
1662 OSMO_ASSERT(gbprox_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
1663
1664 /* TODO: Check correct length but wrong type with is_mi_tmsi */
1665
1666 gbproxy_peer_free(peer);
1667}
1668
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02001669static struct log_info_cat gprs_categories[] = {
1670 [DGPRS] = {
1671 .name = "DGPRS",
1672 .description = "GPRS Packet Service",
1673 .enabled = 1, .loglevel = LOGL_DEBUG,
1674 },
1675 [DNS] = {
1676 .name = "DNS",
1677 .description = "GPRS Network Service (NS)",
1678 .enabled = 1, .loglevel = LOGL_INFO,
1679 },
1680 [DBSSGP] = {
1681 .name = "DBSSGP",
1682 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1683 .enabled = 1, .loglevel = LOGL_DEBUG,
1684 },
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02001685};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001686
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02001687static struct log_info info = {
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02001688 .cat = gprs_categories,
1689 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther89276422014-07-07 19:48:14 +02001690};
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001691
1692int main(int argc, char **argv)
1693{
1694 osmo_init_logging(&info);
1695 log_set_use_color(osmo_stderr_target, 0);
1696 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freyther7d9c1df2014-08-04 15:42:36 +02001697 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001698
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001699 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeckb440bf82014-07-03 13:28:13 +02001700 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
1701 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001702
1703 rate_ctr_init(NULL);
1704
1705 setlinebuf(stdout);
1706
1707 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther5eaf1a22014-08-04 11:10:09 +02001708 gbproxy_init_config(&gbcfg);
Jacob Erlbeck077abce2014-07-01 12:41:13 +02001709 test_tlv_shift_functions();
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001710 test_gbproxy();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001711 test_gbproxy_ident_changes();
Jacob Erlbeckb6799772014-08-07 10:46:29 +02001712 test_gbproxy_imsi_matching();
Jacob Erlbeckeb3102e2014-07-07 10:46:01 +02001713 test_gbproxy_ra_patching();
Holger Hans Peter Freyther60fa5b92014-08-04 17:10:08 +02001714 test_gbproxy_tlli_expire();
Jacob Erlbeck67f03bd2013-10-24 12:48:55 +02001715 printf("===== GbProxy test END\n\n");
Jacob Erlbeck76fa57a2013-10-15 12:00:26 +02001716
1717 exit(EXIT_SUCCESS);
1718}