blob: 9751dc9dd0c440c2977896387bebb75576f33afe [file] [log] [blame]
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001/*
2 * BSC NAT Message filtering
3 *
4 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
Holger Hans Peter Freytherdf6143a2010-06-15 18:46:56 +08005 * (C) 2010 by On-Waves
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08006 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 */
24
25
26#include <openbsc/debug.h>
27#include <openbsc/gsm_data.h>
28#include <openbsc/bsc_nat.h>
29
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +080030#include <osmocore/talloc.h>
31
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080032#include <stdio.h>
33
34/* test messages for ipa */
35static u_int8_t ipa_id[] = {
36 0x00, 0x01, 0xfe, 0x06,
37};
38
39/* SCCP messages are below */
40static u_int8_t gsm_reset[] = {
41 0x00, 0x12, 0xfd,
42 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
43 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
44 0x01, 0x20,
45};
46
47static const u_int8_t gsm_reset_ack[] = {
48 0x00, 0x13, 0xfd,
49 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
50 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
51 0x00, 0x01, 0x31,
52};
53
54static const u_int8_t gsm_paging[] = {
55 0x00, 0x20, 0xfd,
56 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
57 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10,
58 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10,
59 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06,
60};
61
62/* BSC -> MSC connection open */
63static const u_int8_t bssmap_cr[] = {
64 0x00, 0x2c, 0xfd,
65 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02,
66 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05,
67 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3,
68 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33,
69 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01,
70 0x31, 0x97, 0x61, 0x00
71};
72
73/* MSC -> BSC connection confirm */
74static const u_int8_t bssmap_cc[] = {
75 0x00, 0x0a, 0xfd,
76 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
77};
78
79/* MSC -> BSC released */
80static const u_int8_t bssmap_released[] = {
81 0x00, 0x0e, 0xfd,
82 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f,
83 0x02, 0x23, 0x42, 0x00,
84};
85
86/* BSC -> MSC released */
87static const u_int8_t bssmap_release_complete[] = {
88 0x00, 0x07, 0xfd,
89 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03
90};
91
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020092/* both directions IT timer */
93static const u_int8_t connnection_it[] = {
94 0x00, 0x0b, 0xfd,
95 0x10, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03,
96 0x00, 0x00, 0x00, 0x00,
97};
98
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +080099/* error in both directions */
100static const u_int8_t proto_error[] = {
101 0x00, 0x05, 0xfd,
102 0x0f, 0x22, 0x33, 0x44, 0x00,
103};
104
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200105/* MGCP wrap... */
106static const u_int8_t mgcp_msg[] = {
107 0x00, 0x03, 0xfc,
108 0x20, 0x20, 0x20,
109};
110
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800111/* location updating request */
112static const u_int8_t bss_lu[] = {
113 0x00, 0x2e, 0xfd,
114 0x01, 0x91, 0x45, 0x14, 0x02, 0x02, 0x04, 0x02,
115 0x42, 0xfe, 0x0f, 0x21, 0x00, 0x1f, 0x57, 0x05,
116 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x14, 0xc3,
117 0x50, 0x17, 0x12, 0x05, 0x08, 0x70, 0x72, 0xf4,
118 0x80, 0xff, 0xfe, 0x30, 0x08, 0x29, 0x44, 0x50,
119 0x12, 0x03, 0x24, 0x01, 0x95, 0x00
120};
121
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800122struct filter_result {
123 const u_int8_t *data;
124 const u_int16_t length;
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100125 const int dir;
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800126 const int result;
127};
128
129static const struct filter_result results[] = {
130 {
131 .data = ipa_id,
132 .length = ARRAY_SIZE(ipa_id),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100133 .dir = DIR_MSC,
134 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800135 },
136 {
137 .data = gsm_reset,
138 .length = ARRAY_SIZE(gsm_reset),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100139 .dir = DIR_MSC,
140 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800141 },
142 {
143 .data = gsm_reset_ack,
144 .length = ARRAY_SIZE(gsm_reset_ack),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100145 .dir = DIR_BSC,
146 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800147 },
148 {
149 .data = gsm_paging,
150 .length = ARRAY_SIZE(gsm_paging),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100151 .dir = DIR_BSC,
152 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800153 },
154 {
155 .data = bssmap_cr,
156 .length = ARRAY_SIZE(bssmap_cr),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100157 .dir = DIR_MSC,
158 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800159 },
160 {
161 .data = bssmap_cc,
162 .length = ARRAY_SIZE(bssmap_cc),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100163 .dir = DIR_BSC,
164 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800165 },
166 {
167 .data = bssmap_released,
168 .length = ARRAY_SIZE(bssmap_released),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100169 .dir = DIR_MSC,
170 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800171 },
172 {
173 .data = bssmap_release_complete,
174 .length = ARRAY_SIZE(bssmap_release_complete),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100175 .dir = DIR_BSC,
176 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800177 },
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200178 {
179 .data = mgcp_msg,
180 .length = ARRAY_SIZE(mgcp_msg),
181 .dir = DIR_MSC,
182 .result = 0,
183 },
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +0200184 {
185 .data = connnection_it,
186 .length = ARRAY_SIZE(connnection_it),
187 .dir = DIR_BSC,
188 .result = 0,
189 },
190 {
191 .data = connnection_it,
192 .length = ARRAY_SIZE(connnection_it),
193 .dir = DIR_MSC,
194 .result = 0,
195 },
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800196 {
197 .data = proto_error,
198 .length = ARRAY_SIZE(proto_error),
199 .dir = DIR_BSC,
200 .result = 0,
201 },
202 {
203 .data = proto_error,
204 .length = ARRAY_SIZE(proto_error),
205 .dir = DIR_MSC,
206 .result = 0,
207 },
208
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800209};
210
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800211static void test_filter(void)
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800212{
213 int i;
214
215
216 /* start testinh with proper messages */
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800217 fprintf(stderr, "Testing BSS Filtering.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800218 for (i = 0; i < ARRAY_SIZE(results); ++i) {
219 int result;
220 struct bsc_nat_parsed *parsed;
221 struct msgb *msg = msgb_alloc(4096, "test-message");
222
223 fprintf(stderr, "Going to test item: %d\n", i);
224 memcpy(msg->data, results[i].data, results[i].length);
225 msg->l2h = msgb_put(msg, results[i].length);
226
227 parsed = bsc_nat_parse(msg);
228 if (!parsed) {
229 fprintf(stderr, "FAIL: Failed to parse the message\n");
230 continue;
231 }
232
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100233 result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800234 if (result != results[i].result) {
235 fprintf(stderr, "FAIL: Not the expected result got: %d wanted: %d\n",
236 result, results[i].result);
237 }
238
239 msgb_free(msg);
240 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800241}
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800242
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800243#include "bsc_data.c"
244
245static void copy_to_msg(struct msgb *msg, const u_int8_t *data, unsigned int length)
246{
247 msgb_reset(msg);
248 msg->l2h = msgb_put(msg, length);
249 memcpy(msg->l2h, data, msgb_l2len(msg));
250}
251
252#define VERIFY(con_found, con, msg, ver, str) \
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800253 if (!con_found || con_found->bsc != con) { \
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800254 fprintf(stderr, "Failed to find the con: %p\n", con_found); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800255 abort(); \
256 } \
257 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
258 fprintf(stderr, "Failed to patch the %s msg.\n", str); \
259 abort(); \
260 }
261
262/* test conn tracking once */
263static void test_contrack()
264{
265 int rc;
266 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800267 struct bsc_connection *con;
268 struct sccp_connections *con_found;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800269 struct bsc_nat_parsed *parsed;
270 struct msgb *msg;
271
272 fprintf(stderr, "Testing connection tracking.\n");
273 nat = bsc_nat_alloc();
274 con = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc87c8b72010-04-18 02:30:57 +0800275 con->cfg = bsc_config_alloc(nat, "foo", 23);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800276 msg = msgb_alloc(4096, "test");
277
278 /* 1.) create a connection */
279 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
280 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800281 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800282 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800283 fprintf(stderr, "Con should not exist %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800284 abort();
285 }
286 rc = create_sccp_src_ref(con, msg, parsed);
287 if (rc != 0) {
288 fprintf(stderr, "Failed to create a ref\n");
289 abort();
290 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800291 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800292 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800293 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800294 abort();
295 }
296 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
297 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
298 abort();
299 }
300 talloc_free(parsed);
301
302 /* 2.) get the cc */
303 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
304 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800305 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
306 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
307 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800308 fprintf(stderr, "Failed to update the SCCP con.\n");
309 abort();
310 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800311
312 /* 3.) send some data */
313 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
314 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800315 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800316 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
317
318 /* 4.) receive some data */
319 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
320 parsed = bsc_nat_parse(msg);
321 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
322 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
323
324 /* 5.) close the connection */
325 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
326 parsed = bsc_nat_parse(msg);
327 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
328 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
329
330 /* 6.) confirm the connection close */
331 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
332 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800333 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800334 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800335 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800336 abort();
337 }
338 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
339 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
340 abort();
341 }
342 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200343 talloc_free(parsed);
344
345 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
346 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800347 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800348
349 /* verify that it is gone */
350 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800351 fprintf(stderr, "Con should be gone. %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800352 abort();
353 }
354 talloc_free(parsed);
355
356
357 talloc_free(nat);
358 msgb_free(msg);
359}
360
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200361static void test_paging(void)
362{
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200363 int lac;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200364 struct bsc_nat *nat;
365 struct bsc_connection *con;
366 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200367 struct bsc_config cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200368 struct msgb *msg;
369
370 fprintf(stderr, "Testing paging by lac.\n");
371
372 nat = bsc_nat_alloc();
373 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200374 con->cfg = &cfg;
375 cfg.lac = 23;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200376 con->authenticated = 1;
377 llist_add(&con->list_entry, &nat->bsc_connections);
378 msg = msgb_alloc(4096, "test");
379
380 /* Test completely bad input */
381 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200382 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200383 fprintf(stderr, "Should have not found anything.\n");
384 abort();
385 }
386
387 /* Test it by not finding it */
388 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
389 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200390 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200391 fprintf(stderr, "Should have not found aynthing.\n");
392 abort();
393 }
394 talloc_free(parsed);
395
396 /* Test by finding it */
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200397 cfg.lac = 8213;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200398 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
399 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200400 if (bsc_nat_find_bsc(nat, msg, &lac) != con) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200401 fprintf(stderr, "Should have found it.\n");
402 abort();
403 }
404 talloc_free(parsed);
405}
406
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200407static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800408{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800409 struct bsc_connection *bsc;
410 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800411 struct sccp_connections con;
412 struct bsc_nat_parsed *parsed;
413 struct msgb *msg;
414
415 fprintf(stderr, "Testing MGCP.\n");
416 memset(&con, 0, sizeof(con));
417
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800418 nat = bsc_nat_alloc();
419 nat->bsc_endpoints = talloc_zero_array(nat,
420 struct bsc_endpoint,
421 33);
422 bsc = bsc_connection_alloc(nat);
423 bsc->cfg = bsc_config_alloc(nat, "foo", 2323);
424 con.bsc = bsc;
425
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800426 msg = msgb_alloc(4096, "foo");
427 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
428 parsed = bsc_nat_parse(msg);
429 if (bsc_mgcp_assign(&con, msg) != 0) {
430 fprintf(stderr, "Failed to handle assignment.\n");
431 abort();
432 }
433
434 if (con.msc_timeslot != 21) {
435 fprintf(stderr, "Timeslot should be 21.\n");
436 abort();
437 }
438
439 if (con.bsc_timeslot != 21) {
440 fprintf(stderr, "Assigned timeslot should have been 21.\n");
441 abort();
442 }
443 talloc_free(parsed);
444
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800445 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800446 if (con.bsc_timeslot != -1 || con.msc_timeslot != -1) {
447 fprintf(stderr, "Clearing should remove the mapping.\n");
448 abort();
449 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800450
451 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800452}
453
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200454/* test the code to find a given connection */
455static void test_mgcp_find(void)
456{
457 struct bsc_nat *nat;
458 struct bsc_connection *con;
459 struct sccp_connections *sccp_con;
460
461 fprintf(stderr, "Testing finding of a BSC Connection\n");
462
463 nat = bsc_nat_alloc();
464 con = bsc_connection_alloc(nat);
465 llist_add(&con->list_entry, &nat->bsc_connections);
466
467 sccp_con = talloc_zero(con, struct sccp_connections);
468 sccp_con->msc_timeslot = 12;
469 sccp_con->bsc_timeslot = 12;
470 sccp_con->bsc = con;
471 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
472
473 if (bsc_mgcp_find_con(nat, 11) != NULL) {
474 fprintf(stderr, "Found the wrong connection.\n");
475 abort();
476 }
477
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800478 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200479 fprintf(stderr, "Didn't find the connection\n");
480 abort();
481 }
482
483 sccp_con->msc_timeslot = 0;
484 sccp_con->bsc_timeslot = 0;
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800485 if (bsc_mgcp_find_con(nat, 1) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200486 fprintf(stderr, "Didn't find the connection\n");
487 abort();
488 }
489
490 /* free everything */
491 talloc_free(nat);
492}
493
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200494static void test_mgcp_rewrite(void)
495{
496 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200497 struct msgb *output;
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200498 fprintf(stderr, "Test rewriting MGCP messages.\n");
499
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200500 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
501 const char *orig = mgcp_messages[i].orig;
502 const char *patc = mgcp_messages[i].patch;
503 const char *ip = mgcp_messages[i].ip;
504 const int port = mgcp_messages[i].port;
505
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200506 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200507
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200508 output = bsc_mgcp_rewrite(input, strlen(input), ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200509 if (msgb_l2len(output) != strlen(patc)) {
510 fprintf(stderr, "Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
511 fprintf(stderr, "String '%s' vs '%s'\n", (const char *) output->l2h, patc);
512 abort();
513 }
514
515 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
516 fprintf(stderr, "Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
517 abort();
518 }
519
520 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200521 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200522 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200523}
524
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200525static void test_mgcp_parse(void)
526{
527 int code, ci;
528 char transaction[60];
529
530 fprintf(stderr, "Test MGCP response parsing.\n");
531
532 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
533 fprintf(stderr, "Failed to parse CRCX resp.\n");
534 abort();
535 }
536
537 if (code != 200) {
538 fprintf(stderr, "Failed to parse the CODE properly. Got: %d\n", code);
539 abort();
540 }
541
542 if (strcmp(transaction, "23265295") != 0) {
543 fprintf(stderr, "Failed to parse transaction id: '%s'\n", transaction);
544 abort();
545 }
546
547 ci = bsc_mgcp_extract_ci(crcx_resp);
548 if (ci != 1) {
549 fprintf(stderr, "Failed to parse the CI. Got: %d\n", ci);
550 abort();
551 }
552}
553
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800554struct cr_filter {
555 const u_int8_t *data;
556 int length;
557 int result;
558
559 const char *bsc_imsi_allow;
560 const char *bsc_imsi_deny;
561 const char *nat_imsi_allow;
562 const char *nat_imsi_deny;
563};
564
565static struct cr_filter cr_filter[] = {
566 {
567 .data = bssmap_cr,
568 .length = sizeof(bssmap_cr),
569 .result = 0,
570 },
571 {
572 .data = bss_lu,
573 .length = sizeof(bss_lu),
574 .result = 0,
575 },
576 {
577 /* nat deny is before blank/null BSC */
578 .data = bss_lu,
579 .length = sizeof(bss_lu),
580 .result = -3,
581 .nat_imsi_deny = "[0-9]*",
582 },
583 {
584 /* nat deny is before blank/null BSC */
585 .data = bss_lu,
586 .length = sizeof(bss_lu),
587 .result = -3,
588 .nat_imsi_deny = "[0-9]*",
589 .bsc_imsi_allow = "(2440(*",
590 },
591 {
592 /* BSC allow is before NAT deny */
593 .data = bss_lu,
594 .length = sizeof(bss_lu),
595 .result = 0,
596 .bsc_imsi_allow = "[0-9]*",
597 .nat_imsi_deny = "[0-9]*",
598 },
599 {
600 /* filter as deny is first */
601 .data = bss_lu,
602 .length = sizeof(bss_lu),
603 .result = -2,
604 .bsc_imsi_deny = "[0-9]*",
605 .bsc_imsi_allow = "[0-9]*",
606 .nat_imsi_deny = "[0-9]*",
607 .nat_imsi_allow = "[0-9]*",
608 },
609
610};
611
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800612static void test_cr_filter()
613{
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800614 int i, res;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800615 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800616 struct bsc_nat_parsed *parsed;
617
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800618 struct bsc_nat *nat = bsc_nat_alloc();
619 struct bsc_connection *bsc = bsc_connection_alloc(nat);
620 bsc->cfg = bsc_config_alloc(nat, "foo", 1234);
621
622 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
623 msgb_reset(msg);
624 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
625
626 bsc_parse_reg(nat, &nat->imsi_allow_re, &nat->imsi_allow,
627 cr_filter[i].nat_imsi_allow ? 1 : 0,
628 &cr_filter[i].nat_imsi_allow);
629 bsc_parse_reg(nat, &nat->imsi_deny_re, &nat->imsi_deny,
630 cr_filter[i].nat_imsi_deny ? 1 : 0,
631 &cr_filter[i].nat_imsi_deny);
632 bsc_parse_reg(bsc->cfg, &bsc->cfg->imsi_allow_re, &bsc->cfg->imsi_allow,
633 cr_filter[i].bsc_imsi_allow ? 1 : 0,
634 &cr_filter[i].bsc_imsi_allow);
635 bsc_parse_reg(bsc->cfg, &bsc->cfg->imsi_deny_re, &bsc->cfg->imsi_deny,
636 cr_filter[i].bsc_imsi_deny ? 1 : 0,
637 &cr_filter[i].bsc_imsi_deny);
638
639 parsed = bsc_nat_parse(msg);
640 if (!parsed) {
641 fprintf(stderr, "FAIL: Failed to parse the message\n");
642 abort();
643 }
644
645 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed);
646 if (res != cr_filter[i].result) {
647 fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
648 abort();
649 }
650
651 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800652 }
653
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800654 msgb_free(msg);
655}
656
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800657int main(int argc, char **argv)
658{
659 struct debug_target *stderr_target;
660
661 stderr_target = debug_target_create_stderr();
662 debug_add_target(stderr_target);
663 debug_set_all_filter(stderr_target, 1);
664
665 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200666 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200667 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200668 test_mgcp_ass_tracking();
669 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200670 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200671 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800672 test_cr_filter();
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800673 return 0;
674}
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800675
676void input_event()
677{}
678int nm_state_event()
679{
680 return -1;
681}
682
683int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
684{
685 return -1;
686}