blob: 27454a2a9b0d9133295d390a76a63e46ea6f1494 [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 Erlbeck51a869c2013-10-15 12:00:26 +020028#include <osmocom/gprs/gprs_msgb.h>
29#include <osmocom/gprs/gprs_ns.h>
30#include <osmocom/gprs/gprs_bssgp.h>
31
32#include <openbsc/gb_proxy.h>
Holger Hans Peter Freyther7127b022014-08-04 11:52:52 +020033#include <openbsc/gprs_utils.h>
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020034#include <openbsc/debug.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020035
36#define REMOTE_BSS_ADDR 0x01020304
37#define REMOTE_SGSN_ADDR 0x05060708
38
Jacob Erlbeck2082afa2013-10-18 13:04:47 +020039#define SGSN_NSEI 0x0100
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020040
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020041struct gbproxy_config gbcfg = {0};
42
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020043static int dump_global(FILE *stream, int indent)
44{
45 unsigned int i;
46 const struct rate_ctr_group_desc *desc;
47 int rc;
48
49 rc = fprintf(stream, "%*sGbproxy global:\n", indent, "");
50 if (rc < 0)
51 return rc;
52
53 desc = gbcfg.ctrg->desc;
54
55 for (i = 0; i < desc->num_ctr; i++) {
56 struct rate_ctr *ctr = &gbcfg.ctrg->ctr[i];
57 if (ctr->current) {
58 rc = fprintf(stream, "%*s %s: %llu\n",
59 indent, "",
60 desc->ctr_desc[i].description,
61 (long long)ctr->current);
62
63 if (rc < 0)
64 return rc;
65 }
66 }
67
68 return 0;
69}
70
Jacob Erlbeck7b821d02014-08-08 08:37:37 +020071static int dump_peers(FILE *stream, int indent, time_t now,
72 struct gbproxy_config *cfg)
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020073{
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020074 struct gbproxy_peer *peer;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020075 struct gprs_ra_id raid;
76 unsigned int i;
77 const struct rate_ctr_group_desc *desc;
78 int rc;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020079
80 rc = fprintf(stream, "%*sPeers:\n", indent, "");
81 if (rc < 0)
82 return rc;
83
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +020084 llist_for_each_entry(peer, &cfg->bts_peers, list) {
Holger Hans Peter Freyther1ddd9e52014-08-04 11:35:32 +020085 struct gbproxy_tlli_info *tlli_info;
86 struct gbproxy_patch_state *state = &peer->patch_state;
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +020087 gsm48_parse_ra(&raid, peer->ra);
88
89 rc = fprintf(stream, "%*s NSEI %u, BVCI %u, %sblocked, "
90 "RAI %u-%u-%u-%u\n",
91 indent, "",
92 peer->nsei, peer->bvci,
93 peer->blocked ? "" : "not ",
94 raid.mcc, raid.mnc, raid.lac, raid.rac);
95
96 if (rc < 0)
97 return rc;
98
99 desc = peer->ctrg->desc;
100
101 for (i = 0; i < desc->num_ctr; i++) {
102 struct rate_ctr *ctr = &peer->ctrg->ctr[i];
103 if (ctr->current) {
104 rc = fprintf(stream, "%*s %s: %llu\n",
105 indent, "",
106 desc->ctr_desc[i].description,
107 (long long)ctr->current);
108
109 if (rc < 0)
110 return rc;
111 }
112 }
113
114 fprintf(stream, "%*s TLLI-Cache: %d\n",
115 indent, "", state->enabled_tllis_count);
116 llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
117 char mi_buf[200];
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200118 time_t age = now ? now - tlli_info->timestamp : 0;
Jacob Erlbeck89d3d342014-08-06 18:55:15 +0200119 if (tlli_info->mi_data_len > 0) {
120 snprintf(mi_buf, sizeof(mi_buf), "(invalid)");
121 gsm48_mi_to_string(mi_buf, sizeof(mi_buf),
122 tlli_info->mi_data,
123 tlli_info->mi_data_len);
124 } else {
125 snprintf(mi_buf, sizeof(mi_buf), "(none)");
126 }
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200127 rc = fprintf(stream,
128 "%*s TLLI %08x, IMSI %s, AGE %d\n",
129 indent, "",
130 tlli_info->tlli, mi_buf, (int)age);
131 if (rc < 0)
132 return rc;
133 }
134 }
135
136 return 0;
137}
138
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200139/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Attach Request */
140static const unsigned char bssgp_attach_req[75] = {
141 0x01, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x00, 0x04,
142 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
143 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x34, 0x01,
144 0xc0, 0x01, 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21,
145 0x08, 0x02, 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79,
146 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19, 0x18,
147 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
148 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80,
149 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
150 0x16, 0x6d, 0x01
151};
152
Jacob Erlbeck690768a2014-08-06 15:16:45 +0200153/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Identity Request */
154static const unsigned char bssgp_identity_req[] = {
155 0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
156 0x16, 0x82, 0x02, 0x58, 0x0e, 0x89, 0x41, 0xc0,
157 0x01, 0x08, 0x15, 0x01, 0xff, 0x6c, 0xba
158};
159
160/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Identity Response */
161static const unsigned char bssgp_identity_resp[] = {
162 0x01, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x00, 0x04,
163 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
164 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x11, 0x01,
165 0xc0, 0x0d, 0x08, 0x16, 0x08, 0x11, 0x12, 0x13,
166 0x14, 0x15, 0x16, 0x17, 0x18, 0xb7, 0x1b, 0x9a
167};
168
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200169/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Attach Accept */
170static const unsigned char bssgp_attach_acc[88] = {
171 0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
172 0x16, 0x82, 0x02, 0x58, 0x13, 0x99, 0x18, 0xb3,
173 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80,
174 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba,
175 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, 0x0a,
176 0x82, 0x08, 0x02, 0x0d, 0x88, 0x11, 0x12, 0x13,
177 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x81, 0x00,
178 0x0e, 0x9e, 0x41, 0xc0, 0x05, 0x08, 0x02, 0x01,
179 0x49, 0x04, 0x21, 0x63, 0x54, 0x40, 0x50, 0x60,
180 0x19, 0xcd, 0xd7, 0x08, 0x17, 0x16, 0x18, 0x05,
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +0200181 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x42, 0x67, 0x9a
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200182};
183
Jacob Erlbeck11669742014-06-06 18:47:36 +0200184/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - GMM Information */
185static const unsigned char bssgp_gmm_information[66] = {
186 0x00, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x50, 0x20,
187 0x16, 0x82, 0x02, 0x58, 0x13, 0x99, 0x18, 0xb3,
188 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80,
189 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba,
190 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, 0x0a,
191 0x82, 0x08, 0x02, 0x0d, 0x88, 0x11, 0x12, 0x13,
192 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x81, 0x00,
193 0x0e, 0x88, 0x41, 0xc0, 0x09, 0x08, 0x21, 0x04,
194 0xba, 0x3d
195};
196
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200197/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Routing Area Update Request */
198static const unsigned char bssgp_ra_upd_req[85] = {
Jacob Erlbeck11669742014-06-06 18:47:36 +0200199 0x01, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x00, 0x04,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200200 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
201 0x70, 0x80, 0x00, 0x80, 0x0e, 0x00, 0x3e, 0x01,
202 0xc0, 0x15, 0x08, 0x08, 0x10, 0x11, 0x22, 0x33,
203 0x40, 0x50, 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33,
204 0x57, 0x2b, 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48,
205 0x50, 0xc8, 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8,
206 0x48, 0x02, 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02,
207 0x00, 0x19, 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27,
208 0x07, 0x04, 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02,
209 0x20, 0x00, 0x96, 0x3e, 0x97
210};
211
212/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Routing Area Update Accept */
213static const unsigned char bssgp_ra_upd_acc[91] = {
Jacob Erlbeck11669742014-06-06 18:47:36 +0200214 0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200215 0x16, 0x82, 0x02, 0x58, 0x13, 0x9d, 0x19, 0x13,
216 0x42, 0x33, 0x57, 0x2b, 0xf7, 0xc8, 0x48, 0x02,
217 0x13, 0x48, 0x50, 0xc8, 0x48, 0x02, 0x14, 0x48,
218 0x50, 0xc8, 0x48, 0x02, 0x17, 0x49, 0x10, 0xc8,
219 0x48, 0x02, 0x00, 0x0a, 0x82, 0x07, 0x04, 0x0d,
220 0x88, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
221 0x18, 0x00, 0x81, 0x00, 0x0e, 0x9d, 0x41, 0xc0,
222 0x19, 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
223 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200224 0x05, 0xf4, 0xef, 0xe2, 0xb7, 0x00, 0x17, 0x16,
225 0xd7, 0x59, 0x65
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200226};
227
228/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Activate PDP Context Request */
229static const unsigned char bssgp_act_pdp_ctx_req[76] = {
230 0x01, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x00, 0x04,
231 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
232 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x35, 0x01,
233 0xc0, 0x0d, 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
234 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
236 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
237 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
238 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
239 0x00, 0x5a, 0xff, 0x02
240};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200241
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +0200242/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Detach Request (MO) */
243/* normal detach, power_off = 1 */
244static const unsigned char bssgp_detach_po_req[44] = {
245 0x01, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x00, 0x04,
246 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
247 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x15, 0x01,
248 0xc0, 0x19, 0x08, 0x05, 0x09, 0x18, 0x05, 0xf4,
249 0xef, 0xe2, 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97,
250 0xcb, 0x84, 0x0c, 0xeb
251};
252
253/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Detach Request (MO) */
254/* normal detach, power_off = 0 */
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200255static const unsigned char bssgp_detach_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, 0x01, 0x18, 0x05, 0xf4,
260 0xef, 0xe2, 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97,
261 0xcb, 0x7e, 0xe1, 0x41
262};
263
264/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Detach Accept */
265static const unsigned char bssgp_detach_acc[67] = {
266 0x00, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x50, 0x20,
267 0x16, 0x82, 0x02, 0x58, 0x13, 0x99, 0x18, 0xb3,
268 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80,
269 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba,
270 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, 0x0a,
271 0x82, 0x08, 0x02, 0x0d, 0x88, 0x11, 0x12, 0x13,
272 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x81, 0x00,
273 0x0e, 0x89, 0x41, 0xc0, 0x15, 0x08, 0x06, 0x00,
274 0xf7, 0x35, 0xf0
275};
276
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200277static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
278 struct sockaddr_in *peer, const unsigned char* data,
279 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200280
281static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
282 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
283{
284 /* GPRS Network Service, PDU type: NS_RESET,
285 */
286 unsigned char msg[12] = {
287 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
288 0x04, 0x82, 0x11, 0x22
289 };
290
291 msg[3] = cause;
292 msg[6] = nsvci / 256;
293 msg[7] = nsvci % 256;
294 msg[10] = nsei / 256;
295 msg[11] = nsei % 256;
296
297 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
298}
299
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200300static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
301 uint16_t nsvci, uint16_t nsei)
302{
303 /* GPRS Network Service, PDU type: NS_RESET_ACK,
304 */
305 unsigned char msg[9] = {
306 0x03, 0x01, 0x82, 0x11, 0x22,
307 0x04, 0x82, 0x11, 0x22
308 };
309
310 msg[3] = nsvci / 256;
311 msg[4] = nsvci % 256;
312 msg[7] = nsei / 256;
313 msg[8] = nsei % 256;
314
315 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
316}
317
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200318static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
319{
320 /* GPRS Network Service, PDU type: NS_ALIVE */
321 unsigned char msg[1] = {
322 0x0a
323 };
324
325 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
326}
327
328static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
329{
330 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
331 unsigned char msg[1] = {
332 0x0b
333 };
334
335 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
336}
337
338static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
339{
340 /* GPRS Network Service, PDU type: NS_UNBLOCK */
341 unsigned char msg[1] = {
342 0x06
343 };
344
345 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
346}
347
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200348static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
349{
350 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
351 unsigned char msg[1] = {
352 0x07
353 };
354
355 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
356}
357
358static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
359 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200360 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
361{
362 /* GPRS Network Service, PDU type: NS_UNITDATA */
363 unsigned char msg[4096] = {
364 0x00, 0x00, 0x00, 0x00
365 };
366
367 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
368
369 msg[2] = nsbvci / 256;
370 msg[3] = nsbvci % 256;
371 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
372
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200373 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200374}
375
376static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
377 uint16_t bvci)
378{
379 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
380 * BSSGP RESET */
Jacob Erlbeckda4b4922014-08-06 12:38:10 +0200381 unsigned char msg[18] = {
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200382 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200383 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
384 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200385 };
386
387 msg[3] = bvci / 256;
388 msg[4] = bvci % 256;
389
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200390 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
391}
392
393static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
394 struct sockaddr_in *src_addr, uint16_t bvci)
395{
396 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
397 * BSSGP RESET_ACK */
398 static unsigned char msg[5] = {
399 0x23, 0x04, 0x82, 0x00,
400 0x00
401 };
402
403 msg[3] = bvci / 256;
404 msg[4] = bvci % 256;
405
406 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200407}
408
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200409static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
410 struct sockaddr_in *src_addr,
411 struct gprs_ra_id *raid)
412{
413 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
414 unsigned char msg[15] = {
415 0x0b, 0x1f, 0x84, 0xcc, 0xd1, 0x75, 0x8b, 0x1b,
416 0x86, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60
417 };
418
419 gsm48_construct_ra(msg + 9, raid);
420
421 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
422}
423
424static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
425 struct sockaddr_in *src_addr,
426 struct gprs_ra_id *raid)
427{
428 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
429 unsigned char msg[18] = {
430 0x0c, 0x1f, 0x84, 0xcc, 0xd1, 0x75, 0x8b, 0x1b,
431 0x86, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x1d,
432 0x81, 0x01
433 };
434
435 gsm48_construct_ra(msg + 9, raid);
436
437 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
438}
439
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200440static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
441 uint16_t nsvci, uint16_t nsei)
442{
443 printf("Setup NS-VC: remote 0x%08x:%d, "
444 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
445 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
446 nsvci, nsvci, nsei, nsei);
447
448 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
449 send_ns_alive(nsi, src_addr);
450 send_ns_unblock(nsi, src_addr);
451 send_ns_alive_ack(nsi, src_addr);
452}
453
454static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
455 uint16_t bvci)
456{
457 printf("Setup BSSGP: remote 0x%08x:%d, "
458 "BVCI 0x%04x(%d)\n\n",
459 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
460 bvci, bvci);
461
462 send_bssgp_reset(nsi, src_addr, bvci);
463}
464
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200465static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer)
466{
467 gprs_ns_nsip_connect(nsi, sgsn_peer, SGSN_NSEI, SGSN_NSEI+1);
468 send_ns_reset_ack(nsi, sgsn_peer, SGSN_NSEI+1, SGSN_NSEI);
469 send_ns_alive_ack(nsi, sgsn_peer);
470 send_ns_unblock_ack(nsi, sgsn_peer);
471 send_ns_alive(nsi, sgsn_peer);
472}
473
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200474static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
475{
476 sgsn_peer->sin_family = AF_INET;
477 sgsn_peer->sin_port = htons(32000);
478 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
479}
480
481static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
482{
483 size_t i;
484
485 for (i = 0; i < size; ++i) {
486 bss_peers[i].sin_family = AF_INET;
487 bss_peers[i].sin_port = htons((i + 1) * 1111);
488 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
489 }
490}
491
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200492int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
493 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
494
495/* override */
496int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
497 struct msgb *msg, uint16_t bvci)
498{
499 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
500 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200501 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200502
503 switch (event) {
504 case GPRS_NS_EVT_UNIT_DATA:
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200505 return gbprox_rcvmsg(&gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200506 default:
507 break;
508 }
509 return 0;
510}
511
512/* override */
513ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
514 const struct sockaddr *dest_addr, socklen_t addrlen)
515{
516 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
517 const struct sockaddr *, socklen_t);
518 static sendto_t real_sendto = NULL;
519 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200520 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200521
522 if (!real_sendto)
523 real_sendto = dlsym(RTLD_NEXT, "sendto");
524
525 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200526 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
527 dest_host, dest_port,
528 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200529 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200530 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
531 dest_host, dest_port,
532 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200533 else
534 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
535
536 return len;
537}
538
539/* override */
540int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
541{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200542 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
543 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200544 uint16_t bvci = msgb_bvci(msg);
545 uint16_t nsei = msgb_nsei(msg);
546
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200547 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200548
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200549 if (!real_gprs_ns_sendmsg)
550 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
551
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200552 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200553 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
554 "msg length %d (%s)\n",
555 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200556 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200557 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
558 "msg length %d (%s)\n",
559 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200560
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200561 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200562}
563
564static void dump_rate_ctr_group(FILE *stream, const char *prefix,
565 struct rate_ctr_group *ctrg)
566{
567 unsigned int i;
568
569 for (i = 0; i < ctrg->desc->num_ctr; i++) {
570 struct rate_ctr *ctr = &ctrg->ctr[i];
571 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
572 fprintf(stream, " %s%s: %llu%s",
573 prefix, ctrg->desc->ctr_desc[i].description,
574 (long long)ctr->current,
575 "\n");
576 };
577}
578
579/* Signal handler for signals from NS layer */
580static int test_signal(unsigned int subsys, unsigned int signal,
581 void *handler_data, void *signal_data)
582{
583 struct ns_signal_data *nssd = signal_data;
584 int rc;
585
586 if (subsys != SS_L_NS)
587 return 0;
588
589 switch (signal) {
590 case S_NS_RESET:
591 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
592 nssd->nsvc->nsvci,
593 gprs_ns_ll_str(nssd->nsvc));
594 break;
595
596 case S_NS_ALIVE_EXP:
597 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
598 nssd->nsvc->nsvci,
599 gprs_ns_ll_str(nssd->nsvc));
600 break;
601
602 case S_NS_BLOCK:
603 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
604 nssd->nsvc->nsvci,
605 gprs_ns_ll_str(nssd->nsvc));
606 break;
607
608 case S_NS_UNBLOCK:
609 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
610 nssd->nsvc->nsvci,
611 gprs_ns_ll_str(nssd->nsvc));
612 break;
613
614 case S_NS_REPLACED:
615 printf("==> got signal NS_REPLACED: 0x%04x/%s",
616 nssd->nsvc->nsvci,
617 gprs_ns_ll_str(nssd->nsvc));
618 printf(" -> 0x%04x/%s\n",
619 nssd->old_nsvc->nsvci,
620 gprs_ns_ll_str(nssd->old_nsvc));
621 break;
622
623 default:
624 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
625 nssd->nsvc->nsvci,
626 gprs_ns_ll_str(nssd->nsvc));
627 break;
628 }
629 printf("\n");
630 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
631 return rc;
632}
633
634static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
635{
636 struct msgb *msg;
637 int ret;
638 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
639 fprintf(stderr, "message too long: %d\n", data_len);
640 return -1;
641 }
642
643 msg = gprs_ns_msgb_alloc();
644 memmove(msg->data, data, data_len);
645 msg->l2h = msg->data;
646 msgb_put(msg, data_len);
647
648 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
649 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
650 osmo_hexdump(data, data_len));
651
652 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
653
654 printf("result (%s) = %d\n\n", text, ret);
655
656 msgb_free(msg);
657
658 return ret;
659}
660
661static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
662{
663 struct gprs_nsvc *nsvc;
664
665 printf("Current NS-VCIs:\n");
666 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
667 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200668 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200669 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200670 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
671 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
672 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200673 );
674 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
675 }
676 printf("\n");
677}
678
679static void test_gbproxy()
680{
681 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
682 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200683 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200684
685 bssgp_nsi = nsi;
686 gbcfg.nsi = bssgp_nsi;
687 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
688
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200689 configure_sgsn_peer(&sgsn_peer);
690 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200691
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200692 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200693 printf("--- Initialise SGSN ---\n\n");
694
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200695 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200696 gprs_dump_nsi(nsi);
697
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200698 printf("--- Initialise BSS 1 ---\n\n");
699
700 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
701 setup_bssgp(nsi, &bss_peer[0], 0x1002);
702 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200703 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200704
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200705 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
706
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200707 printf("--- Initialise BSS 2 ---\n\n");
708
709 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
710 setup_bssgp(nsi, &bss_peer[1], 0x2002);
711 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200712 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200713
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200714 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
715
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200716 printf("--- Move BSS 1 to new port ---\n\n");
717
718 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
719 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200720 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200721
722 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
723
724 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
725 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200726 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200727
728 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
729
730 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
731 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200732 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200733
734 printf("--- Move BSS 2 to new port ---\n\n");
735
736 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
737 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200738 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200739
740 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
741
742 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
743 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200744 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200745
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200746 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
747
748 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
749 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200750 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200751
752 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
753
754 setup_bssgp(nsi, &bss_peer[0], 0x1012);
755 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200756 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200757
758 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
759
760 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
761
762 setup_bssgp(nsi, &bss_peer[0], 0x1002);
763 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200764 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200765
766 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
767
768 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
769
770 setup_bssgp(nsi, &bss_peer[0], 0x1002);
771 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200772 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200773
774 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
775
776 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
777
778 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
779
780 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
781
782 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
783
784 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
785
786 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
787
788 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
789
790 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
791
792 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
793
794 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
795
796 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
797
798 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
799
800 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
801
802 setup_bssgp(nsi, &bss_peer[2], 0x1002);
803 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200804 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200805
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200806 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +0200807
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200808 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
809
810 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
811
812 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
813
814 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
815
816 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
817
Jacob Erlbeckda890c72013-10-18 22:12:16 +0200818 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
819
820 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
821
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200822 dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +0200823
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200824 gbprox_reset(&gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200825 gprs_ns_destroy(nsi);
826 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200827}
828
829static void test_gbproxy_ident_changes()
830{
831 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
832 struct sockaddr_in bss_peer[1] = {{0},};
833 struct sockaddr_in sgsn_peer= {0};
834 uint16_t nsei[2] = {0x1000, 0x2000};
835 uint16_t nsvci[2] = {0x1001, 0x2001};
836 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
837
838 bssgp_nsi = nsi;
839 gbcfg.nsi = bssgp_nsi;
840 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
841
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200842 configure_sgsn_peer(&sgsn_peer);
843 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200844
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200845 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200846 printf("--- Initialise SGSN ---\n\n");
847
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200848 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200849 gprs_dump_nsi(nsi);
850
851 printf("--- Initialise BSS 1 ---\n\n");
852
853 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
854 gprs_dump_nsi(nsi);
855
856 printf("--- Setup BVCI 1 ---\n\n");
857
858 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
859 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200860 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200861
862 printf("--- Setup BVCI 2 ---\n\n");
863
864 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
865 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200866 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200867
868 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
869
870 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
871 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
872
873 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
874
875 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
876 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
877
878 printf("--- Change NSEI ---\n\n");
879
880 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
881 gprs_dump_nsi(nsi);
882
883 printf("--- Setup BVCI 1 ---\n\n");
884
885 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
886 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200887 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200888
889 printf("--- Setup BVCI 3 ---\n\n");
890
891 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
892 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200893 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200894
895 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
896
897 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
898 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
899
900 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
901 " (should fail) ---\n\n");
902
903 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200904 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200905 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200906 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200907
908 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
909
910 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
911 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
912
913 printf("--- Change NSVCI ---\n\n");
914
915 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
916 gprs_dump_nsi(nsi);
917
918 printf("--- Setup BVCI 1 ---\n\n");
919
920 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
921 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200922 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200923
924 printf("--- Setup BVCI 4 ---\n\n");
925
926 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
927 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200928 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200929
930 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
931
932 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
933 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
934
935 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
936 " (should fail) ---\n\n");
937
938 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200939 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200940 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200941 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200942
943 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
944
945 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
946 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
947
948 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
949
950 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
951 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
952
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +0200953 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +0200954 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200955
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +0200956 gbprox_reset(&gbcfg);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200957 gprs_ns_destroy(nsi);
958 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200959}
960
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200961static void test_gbproxy_ra_patching()
962{
963 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
964 struct sockaddr_in bss_peer[1] = {{0},};
965 struct sockaddr_in sgsn_peer= {0};
966 struct gprs_ra_id rai_bss =
967 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
968 struct gprs_ra_id rai_sgsn =
969 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
970 struct gprs_ra_id rai_unknown =
971 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200972 const char *err_msg = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200973
974 bssgp_nsi = nsi;
975 gbcfg.nsi = bssgp_nsi;
976 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +0200977 gbcfg.core_mcc = 123;
978 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +0200979 gbcfg.core_apn = talloc_zero_size(NULL, 100);
Holger Hans Peter Freytherce1b22e2014-08-04 14:22:13 +0200980 gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200981
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200982 configure_sgsn_peer(&sgsn_peer);
983 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200984
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200985 gbcfg.match_re = talloc_strdup(NULL, "^9898|^121314");
Holger Hans Peter Freyther3fa26442014-08-04 16:27:11 +0200986 if (gbprox_set_patch_filter(&gbcfg, gbcfg.match_re, &err_msg) != 0) {
Jacob Erlbeck7c101d92014-06-06 18:49:23 +0200987 fprintf(stderr, "Failed to compile RE '%s': %s\n",
988 gbcfg.match_re, err_msg);
989 exit(1);
990 }
991
992
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200993 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200994 printf("--- Initialise SGSN ---\n\n");
995
996 connect_sgsn(nsi, &sgsn_peer);
997 gprs_dump_nsi(nsi);
998
999 printf("--- Initialise BSS 1 ---\n\n");
1000
1001 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
1002 setup_bssgp(nsi, &bss_peer[0], 0x1002);
1003 gprs_dump_nsi(nsi);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001004 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001005
1006 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
1007
1008 send_bssgp_suspend(nsi, &bss_peer[0], &rai_bss);
1009 send_bssgp_suspend_ack(nsi, &sgsn_peer, &rai_sgsn);
1010
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001011 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001012 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001013
1014 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
1015
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001016 send_ns_unitdata(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001017 bssgp_attach_req, sizeof(bssgp_attach_req));
1018
Jacob Erlbeck690768a2014-08-06 15:16:45 +02001019 send_ns_unitdata(nsi, "IDENT REQUEST", &sgsn_peer, 0x1002,
1020 bssgp_identity_req, sizeof(bssgp_identity_req));
1021
1022 send_ns_unitdata(nsi, "IDENT RESPONSE", &bss_peer[0], 0x1002,
1023 bssgp_identity_resp, sizeof(bssgp_identity_resp));
1024
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001025 send_ns_unitdata(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001026 bssgp_attach_acc, sizeof(bssgp_attach_acc));
1027
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001028 /* Replace APN (1) */
1029 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REPLACE APN)",
1030 &bss_peer[0], 0x1002,
1031 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001032
Jacob Erlbeck11669742014-06-06 18:47:36 +02001033 send_ns_unitdata(nsi, "GMM INFO", &sgsn_peer, 0x1002,
1034 bssgp_gmm_information, sizeof(bssgp_gmm_information));
1035
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001036 /* Replace APN (2) */
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001037 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REPLACE APN)",
1038 &bss_peer[0], 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001039 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
1040
Jacob Erlbeck73685282014-05-23 20:48:07 +02001041 gbcfg.core_apn[0] = 0;
1042 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001043
1044 /* Remove APN */
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +02001045 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REMOVE APN)",
1046 &bss_peer[0], 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001047 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
1048
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001049 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001050
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001051 /* Detach */
1052 send_ns_unitdata(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
1053 bssgp_detach_req, sizeof(bssgp_detach_req));
1054
1055 send_ns_unitdata(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
1056 bssgp_detach_acc, sizeof(bssgp_detach_acc));
1057
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001058 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001059
1060 printf("--- RA update ---\n\n");
1061
1062 send_ns_unitdata(nsi, "RA UPD REQ", &bss_peer[0], 0x1002,
1063 bssgp_ra_upd_req, sizeof(bssgp_ra_upd_req));
1064
1065 send_ns_unitdata(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
1066 bssgp_ra_upd_acc, sizeof(bssgp_ra_upd_acc));
1067
1068 /* Remove APN */
1069 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REMOVE APN)",
1070 &bss_peer[0], 0x1002,
1071 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
1072
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001073 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001074
Jacob Erlbeck3e23ddf2014-08-11 15:07:37 +02001075 /* Detach (power off -> no Detach Accept) */
1076 send_ns_unitdata(nsi, "DETACH REQ (PWR OFF)", &bss_peer[0], 0x1002,
1077 bssgp_detach_po_req, sizeof(bssgp_detach_po_req));
Jacob Erlbeckaa3e3342014-06-27 11:55:04 +02001078
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001079 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001080 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001081
1082 printf("--- Bad cases ---\n\n");
1083
Jacob Erlbeck7c101d92014-06-06 18:49:23 +02001084 printf("TLLI is already detached, shouldn't patch\n");
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +02001085 send_ns_unitdata(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
1086 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
1087
Jacob Erlbeck006c0382014-05-27 13:49:04 +02001088 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001089 send_bssgp_suspend_ack(nsi, &sgsn_peer, &rai_unknown);
1090
Holger Hans Peter Freytherb9004592014-08-04 11:26:54 +02001091 dump_global(stdout, 0);
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001092 dump_peers(stdout, 0, 0, &gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001093
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001094 gbprox_reset(&gbcfg);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001095 gprs_ns_destroy(nsi);
1096 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001097}
1098
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001099/* TODO: Move tlv testing to libosmocore */
1100int v_fixed_shift(uint8_t **data, size_t *data_len, size_t len, uint8_t **value);
1101int tv_fixed_match(uint8_t **data, size_t *data_len, uint8_t tag, size_t len,
1102 uint8_t **value);
1103int tlv_match(uint8_t **data, size_t *data_len, uint8_t tag, uint8_t **value,
1104 size_t *value_len);
1105int lv_shift(uint8_t **data, size_t *data_len,
1106 uint8_t **value, size_t *value_len);
1107
1108static void check_tlv_match(uint8_t **data, size_t *data_len,
1109 uint8_t tag, size_t exp_len, const uint8_t *exp_val)
1110{
1111 uint8_t *value;
1112 size_t value_len;
1113 int rc;
1114
1115 rc = tlv_match(data, data_len, tag ^ 1, NULL, NULL);
1116 OSMO_ASSERT(rc == 0);
1117
1118 rc = tlv_match(data, data_len, tag, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001119 OSMO_ASSERT(rc == (int)value_len + 2);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001120 OSMO_ASSERT(value_len == exp_len);
1121 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
1122}
1123
1124static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
1125 uint8_t tag, size_t len, const uint8_t *exp_val)
1126{
1127 uint8_t *value;
1128 int rc;
1129
1130 rc = tv_fixed_match(data, data_len, tag ^ 1, len, NULL);
1131 OSMO_ASSERT(rc == 0);
1132
1133 rc = tv_fixed_match(data, data_len, tag, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001134 OSMO_ASSERT(rc == (int)len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001135 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
1136}
1137
1138static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
1139 size_t len, const uint8_t *exp_val)
1140{
1141 uint8_t *value;
1142 int rc;
1143
1144 rc = v_fixed_shift(data, data_len, len, &value);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001145 OSMO_ASSERT(rc == (int)len);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001146 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
1147}
1148
1149static void check_lv_shift(uint8_t **data, size_t *data_len,
1150 size_t exp_len, const uint8_t *exp_val)
1151{
1152 uint8_t *value;
1153 size_t value_len;
1154 int rc;
1155
1156 rc = lv_shift(data, data_len, &value, &value_len);
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001157 OSMO_ASSERT(rc == (int)value_len + 1);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001158 OSMO_ASSERT(value_len == exp_len);
1159 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
1160}
1161
1162static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
1163 const uint8_t *test_data)
1164{
1165 uint8_t buf[300] = {0};
1166
1167 uint8_t *unchanged_ptr = buf - 1;
1168 size_t unchanged_len = 0xdead;
1169 size_t tmp_data_len = data_len;
1170 uint8_t *value = unchanged_ptr;
1171 size_t value_len = unchanged_len;
1172 uint8_t *data = buf;
1173
1174 OSMO_ASSERT(data_len <= sizeof(buf));
1175
1176 tlv_put(data, tag, len, test_data);
1177 if (data_len < len + 2) {
1178 OSMO_ASSERT(-1 == tlv_match(&data, &tmp_data_len,
1179 tag, &value, &value_len));
1180 OSMO_ASSERT(tmp_data_len == 0);
1181 OSMO_ASSERT(data == buf + data_len);
1182 OSMO_ASSERT(value == unchanged_ptr);
1183 OSMO_ASSERT(value_len == unchanged_len);
1184 } else {
1185 OSMO_ASSERT(0 <= tlv_match(&data, &tmp_data_len,
1186 tag, &value, &value_len));
1187 OSMO_ASSERT(value != unchanged_ptr);
1188 OSMO_ASSERT(value_len != unchanged_len);
1189 }
1190}
1191
1192static void check_tv_fixed_match_data_len(size_t data_len,
1193 uint8_t tag, size_t len,
1194 const uint8_t *test_data)
1195{
1196 uint8_t buf[300] = {0};
1197
1198 uint8_t *unchanged_ptr = buf - 1;
1199 size_t tmp_data_len = data_len;
1200 uint8_t *value = unchanged_ptr;
1201 uint8_t *data = buf;
1202
1203 OSMO_ASSERT(data_len <= sizeof(buf));
1204
1205 tv_fixed_put(data, tag, len, test_data);
1206
1207 if (data_len < len + 1) {
1208 OSMO_ASSERT(-1 == tv_fixed_match(&data, &tmp_data_len,
1209 tag, len, &value));
1210 OSMO_ASSERT(tmp_data_len == 0);
1211 OSMO_ASSERT(data == buf + data_len);
1212 OSMO_ASSERT(value == unchanged_ptr);
1213 } else {
1214 OSMO_ASSERT(0 <= tv_fixed_match(&data, &tmp_data_len,
1215 tag, len, &value));
1216 OSMO_ASSERT(value != unchanged_ptr);
1217 }
1218}
1219
1220static void check_v_fixed_shift_data_len(size_t data_len,
1221 size_t len, const uint8_t *test_data)
1222{
1223 uint8_t buf[300] = {0};
1224
1225 uint8_t *unchanged_ptr = buf - 1;
1226 size_t tmp_data_len = data_len;
1227 uint8_t *value = unchanged_ptr;
1228 uint8_t *data = buf;
1229
1230 OSMO_ASSERT(data_len <= sizeof(buf));
1231
1232 memcpy(data, test_data, len);
1233
1234 if (data_len < len) {
1235 OSMO_ASSERT(-1 == v_fixed_shift(&data, &tmp_data_len,
1236 len, &value));
1237 OSMO_ASSERT(tmp_data_len == 0);
1238 OSMO_ASSERT(data == buf + data_len);
1239 OSMO_ASSERT(value == unchanged_ptr);
1240 } else {
1241 OSMO_ASSERT(0 <= v_fixed_shift(&data, &tmp_data_len,
1242 len, &value));
1243 OSMO_ASSERT(value != unchanged_ptr);
1244 }
1245}
1246
1247static void check_lv_shift_data_len(size_t data_len,
1248 size_t len, const uint8_t *test_data)
1249{
1250 uint8_t buf[300] = {0};
1251
1252 uint8_t *unchanged_ptr = buf - 1;
1253 size_t unchanged_len = 0xdead;
1254 size_t tmp_data_len = data_len;
1255 uint8_t *value = unchanged_ptr;
1256 size_t value_len = unchanged_len;
1257 uint8_t *data = buf;
1258
1259 lv_put(data, len, test_data);
1260 if (data_len < len + 1) {
1261 OSMO_ASSERT(-1 == lv_shift(&data, &tmp_data_len,
1262 &value, &value_len));
1263 OSMO_ASSERT(tmp_data_len == 0);
1264 OSMO_ASSERT(data == buf + data_len);
1265 OSMO_ASSERT(value == unchanged_ptr);
1266 OSMO_ASSERT(value_len == unchanged_len);
1267 } else {
1268 OSMO_ASSERT(0 <= lv_shift(&data, &tmp_data_len,
1269 &value, &value_len));
1270 OSMO_ASSERT(value != unchanged_ptr);
1271 OSMO_ASSERT(value_len != unchanged_len);
1272 }
1273}
1274
1275static void test_tlv_shift_functions()
1276{
1277 uint8_t test_data[1024];
1278 uint8_t buf[1024];
1279 uint8_t *data_end;
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001280 unsigned i, len;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001281 uint8_t *data;
1282 size_t data_len;
1283 const uint8_t tag = 0x1a;
1284
1285 printf("Test shift functions\n");
1286
1287 for (i = 0; i < ARRAY_SIZE(test_data); i++)
1288 test_data[i] = (uint8_t)i;
1289
1290 for (len = 0; len < 256; len++) {
Jacob Erlbeck948b7302014-08-11 10:37:35 +02001291 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001292
1293 memset(buf, 0xee, sizeof(buf));
1294 data_end = data = buf;
1295
1296 for (i = 0; i < iterations; i++) {
1297 data_end = tlv_put(data_end, tag, len, test_data);
1298 data_end = tv_fixed_put(data_end, tag, len, test_data);
1299 /* v_fixed_put */
1300 memcpy(data_end, test_data, len);
1301 data_end += len;
1302 data_end = lv_put(data_end, len, test_data);
1303 }
1304
1305 data_len = data_end - data;
1306 OSMO_ASSERT(data_len <= sizeof(buf));
1307
1308 for (i = 0; i < iterations; i++) {
1309 check_tlv_match(&data, &data_len, tag, len, test_data);
1310 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
1311 check_v_fixed_shift(&data, &data_len, len, test_data);
1312 check_lv_shift(&data, &data_len, len, test_data);
1313 }
1314
1315 OSMO_ASSERT(data == data_end);
1316
1317 /* Test at end of data */
1318
1319 OSMO_ASSERT(-1 == tlv_match(&data, &data_len, tag, NULL, NULL));
1320 OSMO_ASSERT(-1 == tv_fixed_match(&data, &data_len, tag, len, NULL));
1321 OSMO_ASSERT((len ? -1 : 0) == v_fixed_shift(&data, &data_len, len, NULL));
1322 OSMO_ASSERT(-1 == lv_shift(&data, &data_len, NULL, NULL));
1323
1324 /* Test invalid data_len */
1325 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
1326 check_tlv_match_data_len(data_len, tag, len, test_data);
1327 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
1328 check_v_fixed_shift_data_len(data_len, len, test_data);
1329 check_lv_shift_data_len(data_len, len, test_data);
1330 }
1331 }
1332}
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001333
1334static void test_gbproxy_tlli_expire(void)
1335{
1336 struct gbproxy_config cfg = {0};
1337 struct gbproxy_peer *peer;
1338 const char *err_msg = NULL;
1339 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0x26 };
1340 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0x29 };
Jacob Erlbeckf4946202014-08-08 09:33:06 +02001341 const uint8_t imsi3[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0x76, 0xf8 };
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001342 const uint32_t tlli1 = 1234 | 0xc0000000;
1343 const uint32_t tlli2 = 5678 | 0xc0000000;
Jacob Erlbeckf4946202014-08-08 09:33:06 +02001344 const uint32_t tlli3 = 3456 | 0xc0000000;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001345 const char *filter_re = ".*";
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001346 time_t now = 1407479214;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001347
1348 printf("Test TLLI info expiry\n\n");
1349
1350 gbproxy_init_config(&cfg);
1351
1352 if (gbprox_set_patch_filter(&cfg, filter_re, &err_msg) != 0) {
1353 fprintf(stderr, "gbprox_set_patch_filter: got error: %s\n",
1354 err_msg);
1355 OSMO_ASSERT(err_msg == NULL);
1356 }
1357
1358 {
1359 struct gbproxy_tlli_info *tlli_info;
1360
1361 printf("Test TLLI replacement:\n");
1362
1363 cfg.tlli_max_len = 0;
1364 cfg.tlli_max_age = 0;
1365 peer = gbproxy_peer_alloc(&cfg, 20);
1366 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1367
1368 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02001369 tlli_info = gbprox_register_tlli(peer, tlli1,
1370 imsi1, ARRAY_SIZE(imsi1), now);
1371 OSMO_ASSERT(tlli_info);
1372 OSMO_ASSERT(tlli_info->tlli == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001373 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1374
1375 /* replace the old entry */
1376 printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02001377 tlli_info = gbprox_register_tlli(peer, tlli2,
1378 imsi1, ARRAY_SIZE(imsi1), now);
1379 OSMO_ASSERT(tlli_info);
1380 OSMO_ASSERT(tlli_info->tlli == tlli2);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001381 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1382
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001383 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001384
1385 /* verify that 5678 has survived */
1386 tlli_info = gbprox_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
1387 OSMO_ASSERT(tlli_info);
1388 OSMO_ASSERT(tlli_info->tlli == tlli2);
1389 tlli_info = gbprox_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
1390 OSMO_ASSERT(!tlli_info);
1391
1392 printf("\n");
1393
1394 gbproxy_peer_free(peer);
1395 }
1396
1397 {
1398 struct gbproxy_tlli_info *tlli_info;
1399
1400 printf("Test IMSI replacement:\n");
1401
1402 cfg.tlli_max_len = 0;
1403 cfg.tlli_max_age = 0;
1404 peer = gbproxy_peer_alloc(&cfg, 20);
1405 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1406
1407 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02001408 tlli_info = gbprox_register_tlli(peer, tlli1,
1409 imsi1, ARRAY_SIZE(imsi1), now);
1410 OSMO_ASSERT(tlli_info);
1411 OSMO_ASSERT(tlli_info->tlli == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001412 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1413
1414 /* try to replace the old entry */
1415 printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck5e68ecf2014-08-07 20:18:47 +02001416 tlli_info = gbprox_register_tlli(peer, tlli1,
1417 imsi2, ARRAY_SIZE(imsi2), now);
1418 OSMO_ASSERT(tlli_info);
1419 OSMO_ASSERT(tlli_info->tlli == tlli1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001420 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1421
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001422 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001423
1424 /* verify that 5678 has survived */
1425 tlli_info = gbprox_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
1426 OSMO_ASSERT(!tlli_info);
1427 tlli_info = gbprox_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
1428 OSMO_ASSERT(tlli_info);
1429 OSMO_ASSERT(tlli_info->tlli == tlli1);
1430
1431 printf("\n");
1432
1433 gbproxy_peer_free(peer);
1434 }
1435
1436 {
1437 struct gbproxy_tlli_info *tlli_info;
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02001438 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001439
1440 printf("Test TLLI expiry, max_len == 1:\n");
1441
1442 cfg.tlli_max_len = 1;
1443 cfg.tlli_max_age = 0;
1444 peer = gbproxy_peer_alloc(&cfg, 20);
1445 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1446
1447 printf(" Add TLLI 1, IMSI 1\n");
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001448 gbprox_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001449 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1450
1451 /* replace the old entry */
1452 printf(" Add TLLI 2, IMSI 2 (should replace IMSI 1)\n");
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001453 gbprox_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2), now);
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02001454 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
1455
1456 num_removed = gbprox_remove_stale_tllis(peer, time(NULL) + 2);
1457 OSMO_ASSERT(num_removed == 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001458 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1459
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001460 dump_peers(stdout, 2, now, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001461
1462 /* verify that 5678 has survived */
1463 tlli_info = gbprox_find_tlli_by_mi(peer, imsi1, ARRAY_SIZE(imsi1));
1464 OSMO_ASSERT(!tlli_info);
1465 tlli_info = gbprox_find_tlli_by_mi(peer, imsi2, ARRAY_SIZE(imsi2));
1466 OSMO_ASSERT(tlli_info);
1467 OSMO_ASSERT(tlli_info->tlli == tlli2);
1468
1469 printf("\n");
1470
1471 gbproxy_peer_free(peer);
1472 }
1473
1474 {
Jacob Erlbeckaad32bc2014-08-07 17:23:00 +02001475 int num_removed;
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001476
1477 printf("Test TLLI expiry, max_age == 1:\n");
1478
1479 cfg.tlli_max_len = 0;
1480 cfg.tlli_max_age = 1;
1481 peer = gbproxy_peer_alloc(&cfg, 20);
1482 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1483
1484 printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001485 gbprox_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001486 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1487
Jacob Erlbeckf4946202014-08-08 09:33:06 +02001488 printf(" Add TLLI 2, IMSI 2 (should not expire after timeout)\n");
1489 gbprox_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
1490 now + 1);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001491 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
1492
Jacob Erlbeck7b821d02014-08-08 08:37:37 +02001493 num_removed = gbprox_remove_stale_tllis(peer, now + 2);
Jacob Erlbeckf4946202014-08-08 09:33:06 +02001494 OSMO_ASSERT(num_removed == 1);
1495 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1496
1497 dump_peers(stdout, 2, now + 2, &cfg);
1498
1499 printf("\n");
1500
1501 gbproxy_peer_free(peer);
1502 }
1503
1504 {
1505 int num_removed;
1506
1507 printf("Test TLLI expiry, max_len == 2, max_age == 1:\n");
1508
1509 cfg.tlli_max_len = 0;
1510 cfg.tlli_max_age = 1;
1511 peer = gbproxy_peer_alloc(&cfg, 20);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001512 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
1513
Jacob Erlbeckf4946202014-08-08 09:33:06 +02001514 printf(" Add TLLI 1, IMSI 1 (should expire)\n");
1515 gbprox_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
1516 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1517
1518 printf(" Add TLLI 2, IMSI 2 (should expire after timeout)\n");
1519 gbprox_register_tlli(peer, tlli2, imsi2, ARRAY_SIZE(imsi2),
1520 now + 1);
1521 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 2);
1522
1523 printf(" Add TLLI 3, IMSI 3 (should not expire after timeout)\n");
1524 gbprox_register_tlli(peer, tlli3, imsi3, ARRAY_SIZE(imsi3),
1525 now + 2);
1526 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 3);
1527
1528 dump_peers(stdout, 2, now + 2, &cfg);
1529
1530 printf(" Remove stale TLLIs\n");
1531 num_removed = gbprox_remove_stale_tllis(peer, now + 3);
1532 OSMO_ASSERT(num_removed == 2);
1533 OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
1534
1535 dump_peers(stdout, 2, now + 2, &cfg);
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001536
1537 printf("\n");
1538
1539 gbproxy_peer_free(peer);
1540 }
1541}
1542
Jacob Erlbeck291f0502014-08-07 10:46:29 +02001543static void test_gbproxy_imsi_matching(void)
1544{
1545 struct gbproxy_config cfg = {0};
1546 struct gbproxy_peer *peer;
1547 const char *err_msg = NULL;
1548 const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI | 0x10, 0x32, 0x54, 0xf6 };
1549 const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
1550 const uint8_t imsi3_bad[] = { GSM_MI_TYPE_IMSI | 0x10, 0xee, 0x54, 0xff };
1551 const uint8_t tmsi1[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22, 0x33, 0x44 };
1552 const uint8_t tmsi2_bad[] = { GSM_MI_TYPE_TMSI | 0xf0, 0x11, 0x22 };
1553 const uint8_t imei1[] = { GSM_MI_TYPE_IMEI | 0x10, 0x32, 0x54, 0xf6 };
1554 const uint8_t imei2[] = { GSM_MI_TYPE_IMEI | GSM_MI_ODD | 0x10, 0x32, 0x54, 0x76 };
1555 const char *filter_re1 = ".*";
1556 const char *filter_re2 = "^1234";
1557 const char *filter_re3 = "^4321";
1558 const char *filter_re4_bad = "^12[";
1559
1560 printf("=== Test IMSI/TMSI matching ===\n\n");
1561
1562 gbproxy_init_config(&cfg);
1563 OSMO_ASSERT(cfg.check_imsi == 0);
1564
1565 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re1, &err_msg) == 0);
1566 OSMO_ASSERT(cfg.check_imsi == 1);
1567
1568 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
1569 OSMO_ASSERT(cfg.check_imsi == 1);
1570
1571 err_msg = NULL;
1572 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re4_bad, &err_msg) == -1);
1573 OSMO_ASSERT(err_msg != NULL);
1574 OSMO_ASSERT(cfg.check_imsi == 0);
1575
1576 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
1577 OSMO_ASSERT(cfg.check_imsi == 1);
1578
1579 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, NULL, &err_msg) == 0);
1580 OSMO_ASSERT(cfg.check_imsi == 0);
1581
Jacob Erlbeck29805da2014-08-14 08:57:04 +02001582 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
1583 OSMO_ASSERT(cfg.check_imsi == 1);
1584
1585 gbprox_clear_patch_filter(&cfg);
1586 OSMO_ASSERT(cfg.check_imsi == 0);
1587
Jacob Erlbeck291f0502014-08-07 10:46:29 +02001588 peer = gbproxy_peer_alloc(&cfg, 20);
1589
1590 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re2, &err_msg) == 0);
1591 OSMO_ASSERT(cfg.check_imsi == 1);
1592
1593 OSMO_ASSERT(gbprox_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 1);
1594 OSMO_ASSERT(gbprox_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 1);
1595 /* imsi3_bad contains 0xE and 0xF digits, but the conversion function
1596 * doesn't complain, so gbprox_check_imsi() doesn't return -1 in this
1597 * case. */
1598 OSMO_ASSERT(gbprox_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
1599 OSMO_ASSERT(gbprox_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
1600 OSMO_ASSERT(gbprox_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
1601 OSMO_ASSERT(gbprox_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
1602 OSMO_ASSERT(gbprox_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
1603
1604 OSMO_ASSERT(gbprox_set_patch_filter(&cfg, filter_re3, &err_msg) == 0);
1605 OSMO_ASSERT(cfg.check_imsi == 1);
1606
1607 OSMO_ASSERT(gbprox_check_imsi(peer, imsi1, ARRAY_SIZE(imsi1)) == 0);
1608 OSMO_ASSERT(gbprox_check_imsi(peer, imsi2, ARRAY_SIZE(imsi2)) == 0);
1609 OSMO_ASSERT(gbprox_check_imsi(peer, imsi3_bad, ARRAY_SIZE(imsi3_bad)) == 0);
1610 OSMO_ASSERT(gbprox_check_imsi(peer, tmsi1, ARRAY_SIZE(tmsi1)) == -1);
1611 OSMO_ASSERT(gbprox_check_imsi(peer, tmsi2_bad, ARRAY_SIZE(tmsi2_bad)) == -1);
1612 OSMO_ASSERT(gbprox_check_imsi(peer, imei1, ARRAY_SIZE(imei1)) == -1);
1613 OSMO_ASSERT(gbprox_check_imsi(peer, imei2, ARRAY_SIZE(imei2)) == -1);
1614
1615 /* TODO: Check correct length but wrong type with is_mi_tmsi */
1616
1617 gbproxy_peer_free(peer);
1618}
1619
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02001620static struct log_info_cat gprs_categories[] = {
1621 [DGPRS] = {
1622 .name = "DGPRS",
1623 .description = "GPRS Packet Service",
1624 .enabled = 1, .loglevel = LOGL_DEBUG,
1625 },
1626 [DNS] = {
1627 .name = "DNS",
1628 .description = "GPRS Network Service (NS)",
1629 .enabled = 1, .loglevel = LOGL_INFO,
1630 },
1631 [DBSSGP] = {
1632 .name = "DBSSGP",
1633 .description = "GPRS BSS Gateway Protocol (BSSGP)",
1634 .enabled = 1, .loglevel = LOGL_DEBUG,
1635 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02001636};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001637
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02001638static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02001639 .cat = gprs_categories,
1640 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +02001641};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001642
1643int main(int argc, char **argv)
1644{
1645 osmo_init_logging(&info);
1646 log_set_use_color(osmo_stderr_target, 0);
1647 log_set_print_filename(osmo_stderr_target, 0);
Holger Hans Peter Freythereece6272014-08-04 15:42:36 +02001648 osmo_signal_register_handler(SS_L_NS, &test_signal, &gbcfg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001649
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001650 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +02001651 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
1652 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001653
1654 rate_ctr_init(NULL);
1655
1656 setlinebuf(stdout);
1657
1658 printf("===== GbProxy test START\n");
Holger Hans Peter Freyther18739ea2014-08-04 11:10:09 +02001659 gbproxy_init_config(&gbcfg);
Jacob Erlbeckb1381062014-07-01 12:41:13 +02001660 test_tlv_shift_functions();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001661 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001662 test_gbproxy_ident_changes();
Jacob Erlbeck291f0502014-08-07 10:46:29 +02001663 test_gbproxy_imsi_matching();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +02001664 test_gbproxy_ra_patching();
Holger Hans Peter Freyther0196c992014-08-04 17:10:08 +02001665 test_gbproxy_tlli_expire();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +02001666 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +02001667
1668 exit(EXIT_SUCCESS);
1669}