blob: fa7e0bb12757e766e21f53013ffc3102d92d0a8a [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>
16#include <sys/types.h>
17#include <sys/socket.h>
18
19#include <osmocom/core/msgb.h>
20#include <osmocom/core/application.h>
21#include <osmocom/core/utils.h>
22#include <osmocom/core/logging.h>
23#include <osmocom/core/talloc.h>
24#include <osmocom/core/signal.h>
25#include <osmocom/core/rate_ctr.h>
26#include <osmocom/gprs/gprs_msgb.h>
27#include <osmocom/gprs/gprs_ns.h>
28#include <osmocom/gprs/gprs_bssgp.h>
29
30#include <openbsc/gb_proxy.h>
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020031#include <openbsc/debug.h>
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020032
33#define REMOTE_BSS_ADDR 0x01020304
34#define REMOTE_SGSN_ADDR 0x05060708
35
Jacob Erlbeck2082afa2013-10-18 13:04:47 +020036#define SGSN_NSEI 0x0100
Jacob Erlbeck51a869c2013-10-15 12:00:26 +020037
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020038struct gbproxy_config gbcfg = {0};
39
40/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Attach Request */
41static const unsigned char bssgp_attach_req[75] = {
42 0x01, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x00, 0x04,
43 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
44 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x34, 0x01,
45 0xc0, 0x01, 0x08, 0x01, 0x02, 0xf5, 0xe0, 0x21,
46 0x08, 0x02, 0x05, 0xf4, 0xfb, 0xc5, 0x46, 0x79,
47 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x19, 0x18,
48 0xb3, 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60,
49 0x80, 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80,
50 0xba, 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00,
51 0x16, 0x6d, 0x01
52};
53
54/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Attach Accept */
55static const unsigned char bssgp_attach_acc[88] = {
56 0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
57 0x16, 0x82, 0x02, 0x58, 0x13, 0x99, 0x18, 0xb3,
58 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80,
59 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba,
60 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, 0x0a,
61 0x82, 0x08, 0x02, 0x0d, 0x88, 0x11, 0x12, 0x13,
62 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x81, 0x00,
63 0x0e, 0x9e, 0x41, 0xc0, 0x05, 0x08, 0x02, 0x01,
64 0x49, 0x04, 0x21, 0x63, 0x54, 0x40, 0x50, 0x60,
65 0x19, 0xcd, 0xd7, 0x08, 0x17, 0x16, 0x18, 0x05,
66 0xf4, 0xfb, 0xc5, 0x47, 0x22, 0x42, 0x67, 0x9a
67};
68
Jacob Erlbeck11669742014-06-06 18:47:36 +020069/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - GMM Information */
70static const unsigned char bssgp_gmm_information[66] = {
71 0x00, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x50, 0x20,
72 0x16, 0x82, 0x02, 0x58, 0x13, 0x99, 0x18, 0xb3,
73 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80,
74 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba,
75 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, 0x0a,
76 0x82, 0x08, 0x02, 0x0d, 0x88, 0x11, 0x12, 0x13,
77 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x81, 0x00,
78 0x0e, 0x88, 0x41, 0xc0, 0x09, 0x08, 0x21, 0x04,
79 0xba, 0x3d
80};
81
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020082/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Routing Area Update Request */
83static const unsigned char bssgp_ra_upd_req[85] = {
Jacob Erlbeck11669742014-06-06 18:47:36 +020084 0x01, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x00, 0x04,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +020085 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
86 0x70, 0x80, 0x00, 0x80, 0x0e, 0x00, 0x3e, 0x01,
87 0xc0, 0x15, 0x08, 0x08, 0x10, 0x11, 0x22, 0x33,
88 0x40, 0x50, 0x60, 0x1d, 0x19, 0x13, 0x42, 0x33,
89 0x57, 0x2b, 0xf7, 0xc8, 0x48, 0x02, 0x13, 0x48,
90 0x50, 0xc8, 0x48, 0x02, 0x14, 0x48, 0x50, 0xc8,
91 0x48, 0x02, 0x17, 0x49, 0x10, 0xc8, 0x48, 0x02,
92 0x00, 0x19, 0x8b, 0xb2, 0x92, 0x17, 0x16, 0x27,
93 0x07, 0x04, 0x31, 0x02, 0xe5, 0xe0, 0x32, 0x02,
94 0x20, 0x00, 0x96, 0x3e, 0x97
95};
96
97/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Routing Area Update Accept */
98static const unsigned char bssgp_ra_upd_acc[91] = {
Jacob Erlbeck11669742014-06-06 18:47:36 +020099 0x00, 0xbb, 0xc5, 0x46, 0x79, 0x00, 0x50, 0x20,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200100 0x16, 0x82, 0x02, 0x58, 0x13, 0x9d, 0x19, 0x13,
101 0x42, 0x33, 0x57, 0x2b, 0xf7, 0xc8, 0x48, 0x02,
102 0x13, 0x48, 0x50, 0xc8, 0x48, 0x02, 0x14, 0x48,
103 0x50, 0xc8, 0x48, 0x02, 0x17, 0x49, 0x10, 0xc8,
104 0x48, 0x02, 0x00, 0x0a, 0x82, 0x07, 0x04, 0x0d,
105 0x88, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
106 0x18, 0x00, 0x81, 0x00, 0x0e, 0x9d, 0x41, 0xc0,
107 0x19, 0x08, 0x09, 0x00, 0x49, 0x21, 0x63, 0x54,
108 0x40, 0x50, 0x60, 0x19, 0x54, 0xab, 0xb3, 0x18,
109 0x05, 0xf4, 0xef, 0xe2, 0x81, 0x17, 0x17, 0x16,
110 0xc3, 0xbf, 0xcc
111};
112
113/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Activate PDP Context Request */
114static const unsigned char bssgp_act_pdp_ctx_req[76] = {
115 0x01, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x00, 0x04,
116 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
117 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x35, 0x01,
118 0xc0, 0x0d, 0x0a, 0x41, 0x05, 0x03, 0x0c, 0x00,
119 0x00, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x28, 0x03,
121 0x02, 0x61, 0x62, 0x27, 0x14, 0x80, 0x80, 0x21,
122 0x10, 0x01, 0x00, 0x00, 0x10, 0x81, 0x06, 0x00,
123 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00,
124 0x00, 0x5a, 0xff, 0x02
125};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200126
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200127/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Detach Request */
128static const unsigned char bssgp_detach_req[44] = {
129 0x01, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x00, 0x04,
130 0x08, 0x88, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60,
131 0x75, 0x30, 0x00, 0x80, 0x0e, 0x00, 0x15, 0x01,
132 0xc0, 0x19, 0x08, 0x05, 0x01, 0x18, 0x05, 0xf4,
133 0xef, 0xe2, 0xb7, 0x00, 0x19, 0x03, 0xb9, 0x97,
134 0xcb, 0x7e, 0xe1, 0x41
135};
136
137/* Base Station Subsystem GPRS Protocol: GSM A-I/F DTAP - Detach Accept */
138static const unsigned char bssgp_detach_acc[67] = {
139 0x00, 0xef, 0xe2, 0xb7, 0x00, 0x00, 0x50, 0x20,
140 0x16, 0x82, 0x02, 0x58, 0x13, 0x99, 0x18, 0xb3,
141 0x43, 0x2b, 0x25, 0x96, 0x62, 0x00, 0x60, 0x80,
142 0x9a, 0xc2, 0xc6, 0x62, 0x00, 0x60, 0x80, 0xba,
143 0xc8, 0xc6, 0x62, 0x00, 0x60, 0x80, 0x00, 0x0a,
144 0x82, 0x08, 0x02, 0x0d, 0x88, 0x11, 0x12, 0x13,
145 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x81, 0x00,
146 0x0e, 0x89, 0x41, 0xc0, 0x15, 0x08, 0x06, 0x00,
147 0xf7, 0x35, 0xf0
148};
149
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200150static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text,
151 struct sockaddr_in *peer, const unsigned char* data,
152 size_t data_len);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200153
154static void send_ns_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
155 enum ns_cause cause, uint16_t nsvci, uint16_t nsei)
156{
157 /* GPRS Network Service, PDU type: NS_RESET,
158 */
159 unsigned char msg[12] = {
160 0x02, 0x00, 0x81, 0x01, 0x01, 0x82, 0x11, 0x22,
161 0x04, 0x82, 0x11, 0x22
162 };
163
164 msg[3] = cause;
165 msg[6] = nsvci / 256;
166 msg[7] = nsvci % 256;
167 msg[10] = nsei / 256;
168 msg[11] = nsei % 256;
169
170 gprs_process_message(nsi, "RESET", src_addr, msg, sizeof(msg));
171}
172
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200173static void send_ns_reset_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
174 uint16_t nsvci, uint16_t nsei)
175{
176 /* GPRS Network Service, PDU type: NS_RESET_ACK,
177 */
178 unsigned char msg[9] = {
179 0x03, 0x01, 0x82, 0x11, 0x22,
180 0x04, 0x82, 0x11, 0x22
181 };
182
183 msg[3] = nsvci / 256;
184 msg[4] = nsvci % 256;
185 msg[7] = nsei / 256;
186 msg[8] = nsei % 256;
187
188 gprs_process_message(nsi, "RESET_ACK", src_addr, msg, sizeof(msg));
189}
190
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200191static void send_ns_alive(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
192{
193 /* GPRS Network Service, PDU type: NS_ALIVE */
194 unsigned char msg[1] = {
195 0x0a
196 };
197
198 gprs_process_message(nsi, "ALIVE", src_addr, msg, sizeof(msg));
199}
200
201static void send_ns_alive_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
202{
203 /* GPRS Network Service, PDU type: NS_ALIVE_ACK */
204 unsigned char msg[1] = {
205 0x0b
206 };
207
208 gprs_process_message(nsi, "ALIVE_ACK", src_addr, msg, sizeof(msg));
209}
210
211static void send_ns_unblock(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
212{
213 /* GPRS Network Service, PDU type: NS_UNBLOCK */
214 unsigned char msg[1] = {
215 0x06
216 };
217
218 gprs_process_message(nsi, "UNBLOCK", src_addr, msg, sizeof(msg));
219}
220
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200221static void send_ns_unblock_ack(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr)
222{
223 /* GPRS Network Service, PDU type: NS_UNBLOCK_ACK */
224 unsigned char msg[1] = {
225 0x07
226 };
227
228 gprs_process_message(nsi, "UNBLOCK_ACK", src_addr, msg, sizeof(msg));
229}
230
231static void send_ns_unitdata(struct gprs_ns_inst *nsi, const char *text,
232 struct sockaddr_in *src_addr, uint16_t nsbvci,
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200233 const unsigned char *bssgp_msg, size_t bssgp_msg_size)
234{
235 /* GPRS Network Service, PDU type: NS_UNITDATA */
236 unsigned char msg[4096] = {
237 0x00, 0x00, 0x00, 0x00
238 };
239
240 OSMO_ASSERT(bssgp_msg_size <= sizeof(msg) - 4);
241
242 msg[2] = nsbvci / 256;
243 msg[3] = nsbvci % 256;
244 memcpy(msg + 4, bssgp_msg, bssgp_msg_size);
245
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200246 gprs_process_message(nsi, text ? text : "UNITDATA", src_addr, msg, bssgp_msg_size + 4);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200247}
248
249static void send_bssgp_reset(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
250 uint16_t bvci)
251{
252 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
253 * BSSGP RESET */
254 unsigned char msg[22] = {
255 0x22, 0x04, 0x82, 0x4a,
Jacob Erlbeckdef03912014-06-02 10:48:59 +0200256 0x2e, 0x07, 0x81, 0x08, 0x08, 0x88, 0x11, 0x22,
257 0x33, 0x40, 0x50, 0x60, 0x10, 0x00
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200258 };
259
260 msg[3] = bvci / 256;
261 msg[4] = bvci % 256;
262
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200263 send_ns_unitdata(nsi, "BVC_RESET", src_addr, 0, msg, sizeof(msg));
264}
265
266static void send_bssgp_reset_ack(struct gprs_ns_inst *nsi,
267 struct sockaddr_in *src_addr, uint16_t bvci)
268{
269 /* GPRS Network Service, PDU type: NS_UNITDATA, BVCI 0
270 * BSSGP RESET_ACK */
271 static unsigned char msg[5] = {
272 0x23, 0x04, 0x82, 0x00,
273 0x00
274 };
275
276 msg[3] = bvci / 256;
277 msg[4] = bvci % 256;
278
279 send_ns_unitdata(nsi, "BVC_RESET_ACK", src_addr, 0, msg, sizeof(msg));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200280}
281
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200282static void send_bssgp_suspend(struct gprs_ns_inst *nsi,
283 struct sockaddr_in *src_addr,
284 struct gprs_ra_id *raid)
285{
286 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND */
287 unsigned char msg[15] = {
288 0x0b, 0x1f, 0x84, 0xcc, 0xd1, 0x75, 0x8b, 0x1b,
289 0x86, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60
290 };
291
292 gsm48_construct_ra(msg + 9, raid);
293
294 send_ns_unitdata(nsi, "BVC_SUSPEND", src_addr, 0, msg, sizeof(msg));
295}
296
297static void send_bssgp_suspend_ack(struct gprs_ns_inst *nsi,
298 struct sockaddr_in *src_addr,
299 struct gprs_ra_id *raid)
300{
301 /* Base Station Subsystem GPRS Protocol, BSSGP SUSPEND ACK */
302 unsigned char msg[18] = {
303 0x0c, 0x1f, 0x84, 0xcc, 0xd1, 0x75, 0x8b, 0x1b,
304 0x86, 0x11, 0x22, 0x33, 0x40, 0x50, 0x60, 0x1d,
305 0x81, 0x01
306 };
307
308 gsm48_construct_ra(msg + 9, raid);
309
310 send_ns_unitdata(nsi, "BVC_SUSPEND_ACK", src_addr, 0, msg, sizeof(msg));
311}
312
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200313static void setup_ns(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
314 uint16_t nsvci, uint16_t nsei)
315{
316 printf("Setup NS-VC: remote 0x%08x:%d, "
317 "NSVCI 0x%04x(%d), NSEI 0x%04x(%d)\n\n",
318 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
319 nsvci, nsvci, nsei, nsei);
320
321 send_ns_reset(nsi, src_addr, NS_CAUSE_OM_INTERVENTION, nsvci, nsei);
322 send_ns_alive(nsi, src_addr);
323 send_ns_unblock(nsi, src_addr);
324 send_ns_alive_ack(nsi, src_addr);
325}
326
327static void setup_bssgp(struct gprs_ns_inst *nsi, struct sockaddr_in *src_addr,
328 uint16_t bvci)
329{
330 printf("Setup BSSGP: remote 0x%08x:%d, "
331 "BVCI 0x%04x(%d)\n\n",
332 ntohl(src_addr->sin_addr.s_addr), ntohs(src_addr->sin_port),
333 bvci, bvci);
334
335 send_bssgp_reset(nsi, src_addr, bvci);
336}
337
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200338static void connect_sgsn(struct gprs_ns_inst *nsi, struct sockaddr_in *sgsn_peer)
339{
340 gprs_ns_nsip_connect(nsi, sgsn_peer, SGSN_NSEI, SGSN_NSEI+1);
341 send_ns_reset_ack(nsi, sgsn_peer, SGSN_NSEI+1, SGSN_NSEI);
342 send_ns_alive_ack(nsi, sgsn_peer);
343 send_ns_unblock_ack(nsi, sgsn_peer);
344 send_ns_alive(nsi, sgsn_peer);
345}
346
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200347static void configure_sgsn_peer(struct sockaddr_in *sgsn_peer)
348{
349 sgsn_peer->sin_family = AF_INET;
350 sgsn_peer->sin_port = htons(32000);
351 sgsn_peer->sin_addr.s_addr = htonl(REMOTE_SGSN_ADDR);
352}
353
354static void configure_bss_peers(struct sockaddr_in *bss_peers, size_t size)
355{
356 size_t i;
357
358 for (i = 0; i < size; ++i) {
359 bss_peers[i].sin_family = AF_INET;
360 bss_peers[i].sin_port = htons((i + 1) * 1111);
361 bss_peers[i].sin_addr.s_addr = htonl(REMOTE_BSS_ADDR);
362 }
363}
364
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200365int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
366 struct sockaddr_in *saddr, enum gprs_ns_ll ll);
367
368/* override */
369int gprs_ns_callback(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
370 struct msgb *msg, uint16_t bvci)
371{
372 printf("CALLBACK, event %d, msg length %d, bvci 0x%04x\n%s\n\n",
373 event, msgb_bssgp_len(msg), bvci,
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200374 osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200375
376 switch (event) {
377 case GPRS_NS_EVT_UNIT_DATA:
Jacob Erlbecke75fec62013-10-15 12:00:27 +0200378 return gbprox_rcvmsg(msg, nsvc->nsei, bvci, nsvc->nsvci);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200379 default:
380 break;
381 }
382 return 0;
383}
384
385/* override */
386ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
387 const struct sockaddr *dest_addr, socklen_t addrlen)
388{
389 typedef ssize_t (*sendto_t)(int, const void *, size_t, int,
390 const struct sockaddr *, socklen_t);
391 static sendto_t real_sendto = NULL;
392 uint32_t dest_host = htonl(((struct sockaddr_in *)dest_addr)->sin_addr.s_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200393 int dest_port = htons(((struct sockaddr_in *)dest_addr)->sin_port);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200394
395 if (!real_sendto)
396 real_sendto = dlsym(RTLD_NEXT, "sendto");
397
398 if (dest_host == REMOTE_BSS_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200399 printf("MESSAGE to BSS at 0x%08x:%d, msg length %d\n%s\n\n",
400 dest_host, dest_port,
401 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200402 else if (dest_host == REMOTE_SGSN_ADDR)
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200403 printf("MESSAGE to SGSN at 0x%08x:%d, msg length %d\n%s\n\n",
404 dest_host, dest_port,
405 len, osmo_hexdump(buf, len));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200406 else
407 return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
408
409 return len;
410}
411
412/* override */
413int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
414{
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200415 typedef int (*gprs_ns_sendmsg_t)(struct gprs_ns_inst *nsi, struct msgb *msg);
416 static gprs_ns_sendmsg_t real_gprs_ns_sendmsg = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200417 uint16_t bvci = msgb_bvci(msg);
418 uint16_t nsei = msgb_nsei(msg);
419
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200420 size_t len = msgb_length(msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200421
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200422 if (!real_gprs_ns_sendmsg)
423 real_gprs_ns_sendmsg = dlsym(RTLD_NEXT, "gprs_ns_sendmsg");
424
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200425 if (nsei == SGSN_NSEI)
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200426 printf("NS UNITDATA MESSAGE to SGSN, BVCI 0x%04x, "
427 "msg length %d (%s)\n",
428 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200429 else
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200430 printf("NS UNITDATA MESSAGE to BSS, BVCI 0x%04x, "
431 "msg length %d (%s)\n",
432 bvci, len, __func__);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200433
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200434 return real_gprs_ns_sendmsg(nsi, msg);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200435}
436
437static void dump_rate_ctr_group(FILE *stream, const char *prefix,
438 struct rate_ctr_group *ctrg)
439{
440 unsigned int i;
441
442 for (i = 0; i < ctrg->desc->num_ctr; i++) {
443 struct rate_ctr *ctr = &ctrg->ctr[i];
444 if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.'))
445 fprintf(stream, " %s%s: %llu%s",
446 prefix, ctrg->desc->ctr_desc[i].description,
447 (long long)ctr->current,
448 "\n");
449 };
450}
451
452/* Signal handler for signals from NS layer */
453static int test_signal(unsigned int subsys, unsigned int signal,
454 void *handler_data, void *signal_data)
455{
456 struct ns_signal_data *nssd = signal_data;
457 int rc;
458
459 if (subsys != SS_L_NS)
460 return 0;
461
462 switch (signal) {
463 case S_NS_RESET:
464 printf("==> got signal NS_RESET, NS-VC 0x%04x/%s\n",
465 nssd->nsvc->nsvci,
466 gprs_ns_ll_str(nssd->nsvc));
467 break;
468
469 case S_NS_ALIVE_EXP:
470 printf("==> got signal NS_ALIVE_EXP, NS-VC 0x%04x/%s\n",
471 nssd->nsvc->nsvci,
472 gprs_ns_ll_str(nssd->nsvc));
473 break;
474
475 case S_NS_BLOCK:
476 printf("==> got signal NS_BLOCK, NS-VC 0x%04x/%s\n",
477 nssd->nsvc->nsvci,
478 gprs_ns_ll_str(nssd->nsvc));
479 break;
480
481 case S_NS_UNBLOCK:
482 printf("==> got signal NS_UNBLOCK, NS-VC 0x%04x/%s\n",
483 nssd->nsvc->nsvci,
484 gprs_ns_ll_str(nssd->nsvc));
485 break;
486
487 case S_NS_REPLACED:
488 printf("==> got signal NS_REPLACED: 0x%04x/%s",
489 nssd->nsvc->nsvci,
490 gprs_ns_ll_str(nssd->nsvc));
491 printf(" -> 0x%04x/%s\n",
492 nssd->old_nsvc->nsvci,
493 gprs_ns_ll_str(nssd->old_nsvc));
494 break;
495
496 default:
497 printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal,
498 nssd->nsvc->nsvci,
499 gprs_ns_ll_str(nssd->nsvc));
500 break;
501 }
502 printf("\n");
503 rc = gbprox_signal(subsys, signal, handler_data, signal_data);
504 return rc;
505}
506
507static int gprs_process_message(struct gprs_ns_inst *nsi, const char *text, struct sockaddr_in *peer, const unsigned char* data, size_t data_len)
508{
509 struct msgb *msg;
510 int ret;
511 if (data_len > NS_ALLOC_SIZE - NS_ALLOC_HEADROOM) {
512 fprintf(stderr, "message too long: %d\n", data_len);
513 return -1;
514 }
515
516 msg = gprs_ns_msgb_alloc();
517 memmove(msg->data, data, data_len);
518 msg->l2h = msg->data;
519 msgb_put(msg, data_len);
520
521 printf("PROCESSING %s from 0x%08x:%d\n%s\n\n",
522 text, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
523 osmo_hexdump(data, data_len));
524
525 ret = gprs_ns_rcvmsg(nsi, msg, peer, GPRS_NS_LL_UDP);
526
527 printf("result (%s) = %d\n\n", text, ret);
528
529 msgb_free(msg);
530
531 return ret;
532}
533
534static void gprs_dump_nsi(struct gprs_ns_inst *nsi)
535{
536 struct gprs_nsvc *nsvc;
537
538 printf("Current NS-VCIs:\n");
539 llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
540 struct sockaddr_in *peer = &(nsvc->ip.bts_addr);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200541 printf(" VCI 0x%04x, NSEI 0x%04x, peer 0x%08x:%d%s%s\n",
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200542 nsvc->nsvci, nsvc->nsei,
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200543 ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port),
544 nsvc->state & NSE_S_BLOCKED ? ", blocked" : "",
545 nsvc->state & NSE_S_ALIVE ? "" : ", dead"
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200546 );
547 dump_rate_ctr_group(stdout, " ", nsvc->ctrg);
548 }
549 printf("\n");
550}
551
552static void test_gbproxy()
553{
554 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
555 struct sockaddr_in bss_peer[4] = {{0},};
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200556 struct sockaddr_in sgsn_peer= {0};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200557
558 bssgp_nsi = nsi;
559 gbcfg.nsi = bssgp_nsi;
560 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
561
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200562 configure_sgsn_peer(&sgsn_peer);
563 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200564
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200565 printf("=== %s ===\n", __func__);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200566 printf("--- Initialise SGSN ---\n\n");
567
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200568 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200569 gprs_dump_nsi(nsi);
570
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200571 printf("--- Initialise BSS 1 ---\n\n");
572
573 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
574 setup_bssgp(nsi, &bss_peer[0], 0x1002);
575 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200576 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200577
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200578 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
579
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200580 printf("--- Initialise BSS 2 ---\n\n");
581
582 setup_ns(nsi, &bss_peer[1], 0x2001, 0x2000);
583 setup_bssgp(nsi, &bss_peer[1], 0x2002);
584 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200585 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200586
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200587 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x2002);
588
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200589 printf("--- Move BSS 1 to new port ---\n\n");
590
591 setup_ns(nsi, &bss_peer[2], 0x1001, 0x1000);
592 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200593 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200594
595 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
596
597 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
598 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200599 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200600
601 printf("--- Move BSS 1 to current BSS 2 port ---\n\n");
602
603 setup_ns(nsi, &bss_peer[0], 0x2001, 0x2000);
604 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200605 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200606
607 printf("--- Move BSS 2 to new port ---\n\n");
608
609 setup_ns(nsi, &bss_peer[3], 0x2001, 0x2000);
610 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200611 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200612
613 printf("--- Move BSS 2 to former BSS 1 port ---\n\n");
614
615 setup_ns(nsi, &bss_peer[2], 0x2001, 0x2000);
616 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200617 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200618
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200619 printf("--- Move BSS 1 to original BSS 1 port ---\n\n");
620
621 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
622 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200623 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200624
625 printf("--- Reset BSS 1 with a new BVCI ---\n\n");
626
627 setup_bssgp(nsi, &bss_peer[0], 0x1012);
628 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200629 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200630
631 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1012);
632
633 printf("--- Reset BSS 1 with the old BVCI ---\n\n");
634
635 setup_bssgp(nsi, &bss_peer[0], 0x1002);
636 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200637 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200638
639 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
640
641 printf("--- Reset BSS 1 with the old BVCI again ---\n\n");
642
643 setup_bssgp(nsi, &bss_peer[0], 0x1002);
644 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200645 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200646
647 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
648
649 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1012 ---\n\n");
650
651 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
652
653 printf("--- Send message from SGSN to BSS 1, BVCI 0x1012 ---\n\n");
654
655 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
656
657 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
658
659 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
660
661 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
662
663 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
664
665 printf("--- Send message from BSS 2 to SGSN, BVCI 0x2002 ---\n\n");
666
667 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x2002, (uint8_t *)"", 0);
668
669 printf("--- Send message from SGSN to BSS 2, BVCI 0x2002 ---\n\n");
670
671 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x2002, (uint8_t *)"", 0);
672
673 printf("--- Reset BSS 1 with the old BVCI on BSS2's link ---\n\n");
674
675 setup_bssgp(nsi, &bss_peer[2], 0x1002);
676 gprs_dump_nsi(nsi);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200677 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200678
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200679 gbprox_dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +0200680
Jacob Erlbeck2082afa2013-10-18 13:04:47 +0200681 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
682
683 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
684
685 send_ns_unitdata(nsi, NULL, &bss_peer[0], 0x1012, (uint8_t *)"", 0);
686
687 printf("--- Send message from SGSN to BSS 1, BVCI 0x1002 ---\n\n");
688
689 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x1012, (uint8_t *)"", 0);
690
Jacob Erlbeckda890c72013-10-18 22:12:16 +0200691 printf("--- Send message from SGSN to BSS 1, BVCI 0x10ff (invalid) ---\n\n");
692
693 send_ns_unitdata(nsi, NULL, &sgsn_peer, 0x10ff, (uint8_t *)"", 0);
694
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200695 gbprox_dump_global(stdout, 0);
Jacob Erlbeckda890c72013-10-18 22:12:16 +0200696
Holger Hans Peter Freyther84db98f2014-07-07 19:22:02 +0200697 gbprox_reset();
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200698 gprs_ns_destroy(nsi);
699 nsi = NULL;
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200700}
701
702static void test_gbproxy_ident_changes()
703{
704 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
705 struct sockaddr_in bss_peer[1] = {{0},};
706 struct sockaddr_in sgsn_peer= {0};
707 uint16_t nsei[2] = {0x1000, 0x2000};
708 uint16_t nsvci[2] = {0x1001, 0x2001};
709 uint16_t bvci[4] = {0x1002, 0x2002, 0x3002, 0x4002};
710
711 bssgp_nsi = nsi;
712 gbcfg.nsi = bssgp_nsi;
713 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
714
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200715 configure_sgsn_peer(&sgsn_peer);
716 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200717
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200718 printf("=== %s ===\n", __func__);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200719 printf("--- Initialise SGSN ---\n\n");
720
Jacob Erlbeck2e038f72014-07-07 10:46:00 +0200721 connect_sgsn(nsi, &sgsn_peer);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200722 gprs_dump_nsi(nsi);
723
724 printf("--- Initialise BSS 1 ---\n\n");
725
726 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[0]);
727 gprs_dump_nsi(nsi);
728
729 printf("--- Setup BVCI 1 ---\n\n");
730
731 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
732 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200733 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200734
735 printf("--- Setup BVCI 2 ---\n\n");
736
737 setup_bssgp(nsi, &bss_peer[0], bvci[1]);
738 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[1]);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200739 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200740
741 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
742
743 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
744 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
745
746 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 ---\n\n");
747
748 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
749 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
750
751 printf("--- Change NSEI ---\n\n");
752
753 setup_ns(nsi, &bss_peer[0], nsvci[0], nsei[1]);
754 gprs_dump_nsi(nsi);
755
756 printf("--- Setup BVCI 1 ---\n\n");
757
758 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
759 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200760 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200761
762 printf("--- Setup BVCI 3 ---\n\n");
763
764 setup_bssgp(nsi, &bss_peer[0], bvci[2]);
765 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[2]);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200766 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200767
768 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
769
770 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
771 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
772
773 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
774 " (should fail) ---\n\n");
775
776 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200777 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200778 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200779 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200780
781 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
782
783 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
784 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
785
786 printf("--- Change NSVCI ---\n\n");
787
788 setup_ns(nsi, &bss_peer[0], nsvci[1], nsei[1]);
789 gprs_dump_nsi(nsi);
790
791 printf("--- Setup BVCI 1 ---\n\n");
792
793 setup_bssgp(nsi, &bss_peer[0], bvci[0]);
794 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[0]);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200795 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200796
797 printf("--- Setup BVCI 4 ---\n\n");
798
799 setup_bssgp(nsi, &bss_peer[0], bvci[3]);
800 send_bssgp_reset_ack(nsi, &sgsn_peer, bvci[3]);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200801 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200802
803 printf("--- Send message from BSS 1 to SGSN and back, BVCI 1 ---\n\n");
804
805 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[0], (uint8_t *)"", 0);
806 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[0], (uint8_t *)"", 0);
807
808 printf("--- Send message from BSS 1 to SGSN and back, BVCI 2 "
809 " (should fail) ---\n\n");
810
811 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200812 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200813 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[1], (uint8_t *)"", 0);
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200814 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200815
816 printf("--- Send message from BSS 1 to SGSN and back, BVCI 3 ---\n\n");
817
818 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[2], (uint8_t *)"", 0);
819 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[2], (uint8_t *)"", 0);
820
821 printf("--- Send message from BSS 1 to SGSN and back, BVCI 4 ---\n\n");
822
823 send_ns_unitdata(nsi, NULL, &bss_peer[0], bvci[3], (uint8_t *)"", 0);
824 send_ns_unitdata(nsi, NULL, &sgsn_peer, bvci[3], (uint8_t *)"", 0);
825
Jacob Erlbeckb32d3c02014-07-07 10:45:59 +0200826 gbprox_dump_global(stdout, 0);
827 gbprox_dump_peers(stdout, 0);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200828
Holger Hans Peter Freyther84db98f2014-07-07 19:22:02 +0200829 gbprox_reset();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200830 gprs_ns_destroy(nsi);
831 nsi = NULL;
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200832}
833
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200834static void test_gbproxy_ra_patching()
835{
836 struct gprs_ns_inst *nsi = gprs_ns_instantiate(gprs_ns_callback, NULL);
837 struct sockaddr_in bss_peer[1] = {{0},};
838 struct sockaddr_in sgsn_peer= {0};
839 struct gprs_ra_id rai_bss =
840 {.mcc = 112, .mnc = 332, .lac = 16464, .rac = 96};
841 struct gprs_ra_id rai_sgsn =
842 {.mcc = 123, .mnc = 456, .lac = 16464, .rac = 96};
843 struct gprs_ra_id rai_unknown =
844 {.mcc = 1, .mnc = 99, .lac = 99, .rac = 96};
845
846 bssgp_nsi = nsi;
847 gbcfg.nsi = bssgp_nsi;
848 gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
Jacob Erlbeck67a44452014-05-19 10:14:58 +0200849 gbcfg.core_mcc = 123;
850 gbcfg.core_mnc = 456;
Jacob Erlbeck73685282014-05-23 20:48:07 +0200851 gbcfg.core_apn = talloc_zero_size(NULL, 100);
852 gbcfg.core_apn_size = gbprox_str_to_apn(gbcfg.core_apn, "foo.bar", 100);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200853
Holger Hans Peter Freyther99a20d62014-07-07 14:19:10 +0200854 configure_sgsn_peer(&sgsn_peer);
855 configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200856
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200857 printf("=== %s ===\n", __func__);
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200858 printf("--- Initialise SGSN ---\n\n");
859
860 connect_sgsn(nsi, &sgsn_peer);
861 gprs_dump_nsi(nsi);
862
863 printf("--- Initialise BSS 1 ---\n\n");
864
865 setup_ns(nsi, &bss_peer[0], 0x1001, 0x1000);
866 setup_bssgp(nsi, &bss_peer[0], 0x1002);
867 gprs_dump_nsi(nsi);
868 gbprox_dump_peers(stdout, 0);
869
870 send_bssgp_reset_ack(nsi, &sgsn_peer, 0x1002);
871
872 send_bssgp_suspend(nsi, &bss_peer[0], &rai_bss);
873 send_bssgp_suspend_ack(nsi, &sgsn_peer, &rai_sgsn);
874
875 gbprox_dump_global(stdout, 0);
876 gbprox_dump_peers(stdout, 0);
877
878 printf("--- Send message from BSS 1 to SGSN, BVCI 0x1002 ---\n\n");
879
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200880 send_ns_unitdata(nsi, "ATTACH REQUEST", &bss_peer[0], 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200881 bssgp_attach_req, sizeof(bssgp_attach_req));
882
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200883 send_ns_unitdata(nsi, "ATTACH ACCEPT", &sgsn_peer, 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200884 bssgp_attach_acc, sizeof(bssgp_attach_acc));
885
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200886 send_ns_unitdata(nsi, "UPDATE REQ", &bss_peer[0], 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200887 bssgp_ra_upd_req, sizeof(bssgp_ra_upd_req));
888
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200889 send_ns_unitdata(nsi, "RA UPD ACC", &sgsn_peer, 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200890 bssgp_ra_upd_acc, sizeof(bssgp_ra_upd_acc));
891
Jacob Erlbeck11669742014-06-06 18:47:36 +0200892 send_ns_unitdata(nsi, "GMM INFO", &sgsn_peer, 0x1002,
893 bssgp_gmm_information, sizeof(bssgp_gmm_information));
894
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200895 /* Replace APN */
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200896 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REPLACE APN)",
897 &bss_peer[0], 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200898 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
899
Jacob Erlbeck73685282014-05-23 20:48:07 +0200900 gbcfg.core_apn[0] = 0;
901 gbcfg.core_apn_size = 0;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200902
903 /* Remove APN */
Jacob Erlbeckff0d65a2014-07-09 23:19:11 +0200904 send_ns_unitdata(nsi, "ACT PDP CTX REQ (REMOVE APN)",
905 &bss_peer[0], 0x1002,
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200906 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
907
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200908 /* Detach */
909 send_ns_unitdata(nsi, "DETACH REQ", &bss_peer[0], 0x1002,
910 bssgp_detach_req, sizeof(bssgp_detach_req));
911
912 send_ns_unitdata(nsi, "DETACH ACC", &sgsn_peer, 0x1002,
913 bssgp_detach_acc, sizeof(bssgp_detach_acc));
914
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200915 gbprox_dump_global(stdout, 0);
916 gbprox_dump_peers(stdout, 0);
917
918 printf("--- Bad cases ---\n\n");
919
Jacob Erlbeck006c0382014-05-27 13:49:04 +0200920 printf("Invalid BVCI, shouldn't patch\n");
Jacob Erlbeckcf02eb12014-06-19 10:23:50 +0200921 send_ns_unitdata(nsi, "ACT PDP CTX REQ", &bss_peer[0], 0x1002,
922 bssgp_act_pdp_ctx_req, sizeof(bssgp_act_pdp_ctx_req));
923
Jacob Erlbeck006c0382014-05-27 13:49:04 +0200924 printf("Invalid RAI, shouldn't patch\n");
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200925 send_bssgp_suspend_ack(nsi, &sgsn_peer, &rai_unknown);
926
927 gbprox_dump_global(stdout, 0);
928 gbprox_dump_peers(stdout, 0);
929
Holger Hans Peter Freyther84db98f2014-07-07 19:22:02 +0200930 gbprox_reset();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200931 gprs_ns_destroy(nsi);
932 nsi = NULL;
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200933}
934
Jacob Erlbeck627e7d92014-07-03 13:28:13 +0200935static struct log_info_cat gprs_categories[] = {
936 [DGPRS] = {
937 .name = "DGPRS",
938 .description = "GPRS Packet Service",
939 .enabled = 1, .loglevel = LOGL_DEBUG,
940 },
941 [DNS] = {
942 .name = "DNS",
943 .description = "GPRS Network Service (NS)",
944 .enabled = 1, .loglevel = LOGL_INFO,
945 },
946 [DBSSGP] = {
947 .name = "DBSSGP",
948 .description = "GPRS BSS Gateway Protocol (BSSGP)",
949 .enabled = 1, .loglevel = LOGL_DEBUG,
950 },
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +0200951};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200952
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +0200953static struct log_info info = {
Jacob Erlbeck627e7d92014-07-03 13:28:13 +0200954 .cat = gprs_categories,
955 .num_cat = ARRAY_SIZE(gprs_categories),
Holger Hans Peter Freyther2840b3f2014-07-07 19:48:14 +0200956};
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200957
958int main(int argc, char **argv)
959{
960 osmo_init_logging(&info);
961 log_set_use_color(osmo_stderr_target, 0);
962 log_set_print_filename(osmo_stderr_target, 0);
963 osmo_signal_register_handler(SS_L_NS, &test_signal, NULL);
964
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200965 log_set_print_filename(osmo_stderr_target, 0);
Jacob Erlbeck627e7d92014-07-03 13:28:13 +0200966 log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
967 log_set_all_filter(osmo_stderr_target, 1);
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200968
969 rate_ctr_init(NULL);
970
971 setlinebuf(stdout);
972
973 printf("===== GbProxy test START\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200974 test_gbproxy();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200975 test_gbproxy_ident_changes();
Jacob Erlbeck7fb42db2014-07-07 10:46:01 +0200976 test_gbproxy_ra_patching();
Jacob Erlbeck72b401f2013-10-24 12:48:55 +0200977 printf("===== GbProxy test END\n\n");
Jacob Erlbeck51a869c2013-10-15 12:00:26 +0200978
979 exit(EXIT_SUCCESS);
980}