blob: 0d65487658044ef23c59d152fc19a299a539efd1 [file] [log] [blame]
Holger Hans Peter Freytherf75a6802010-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 Freyther98e49d42010-06-15 18:46:56 +08005 * (C) 2010 by On-Waves
Holger Hans Peter Freytherf75a6802010-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 Freytherb63a9f82010-06-15 18:48:36 +080030#include <osmocore/talloc.h>
31
Holger Hans Peter Freytherf75a6802010-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 Freyther55e8f552010-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 Freytherdd6c51b2010-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 Freyther6b998282010-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 Freyther13abb822010-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 Freytherf75a6802010-06-15 18:45:38 +0800122struct filter_result {
123 const u_int8_t *data;
124 const u_int16_t length;
Holger Hans Peter Freytherbbf6b652010-01-30 11:53:30 +0100125 const int dir;
Holger Hans Peter Freytherf75a6802010-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 Freytherbbf6b652010-01-30 11:53:30 +0100133 .dir = DIR_MSC,
134 .result = 1,
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800135 },
136 {
137 .data = gsm_reset,
138 .length = ARRAY_SIZE(gsm_reset),
Holger Hans Peter Freytherbbf6b652010-01-30 11:53:30 +0100139 .dir = DIR_MSC,
140 .result = 1,
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800141 },
142 {
143 .data = gsm_reset_ack,
144 .length = ARRAY_SIZE(gsm_reset_ack),
Holger Hans Peter Freytherbbf6b652010-01-30 11:53:30 +0100145 .dir = DIR_BSC,
146 .result = 1,
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800147 },
148 {
149 .data = gsm_paging,
150 .length = ARRAY_SIZE(gsm_paging),
Holger Hans Peter Freytherbbf6b652010-01-30 11:53:30 +0100151 .dir = DIR_BSC,
152 .result = 0,
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800153 },
154 {
155 .data = bssmap_cr,
156 .length = ARRAY_SIZE(bssmap_cr),
Holger Hans Peter Freytherbbf6b652010-01-30 11:53:30 +0100157 .dir = DIR_MSC,
158 .result = 0,
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800159 },
160 {
161 .data = bssmap_cc,
162 .length = ARRAY_SIZE(bssmap_cc),
Holger Hans Peter Freytherbbf6b652010-01-30 11:53:30 +0100163 .dir = DIR_BSC,
164 .result = 0,
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800165 },
166 {
167 .data = bssmap_released,
168 .length = ARRAY_SIZE(bssmap_released),
Holger Hans Peter Freytherbbf6b652010-01-30 11:53:30 +0100169 .dir = DIR_MSC,
170 .result = 0,
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800171 },
172 {
173 .data = bssmap_release_complete,
174 .length = ARRAY_SIZE(bssmap_release_complete),
Holger Hans Peter Freytherbbf6b652010-01-30 11:53:30 +0100175 .dir = DIR_BSC,
176 .result = 0,
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800177 },
Holger Hans Peter Freyther6b998282010-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 Freyther55e8f552010-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 Freytherdd6c51b2010-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 Freytherf75a6802010-06-15 18:45:38 +0800209};
210
Holger Hans Peter Freytherb63a9f82010-06-15 18:48:36 +0800211static void test_filter(void)
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800212{
213 int i;
214
215
216 /* start testinh with proper messages */
Holger Hans Peter Freytherb63a9f82010-06-15 18:48:36 +0800217 fprintf(stderr, "Testing BSS Filtering.\n");
Holger Hans Peter Freytherf75a6802010-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 Freytherbbf6b652010-01-30 11:53:30 +0100233 result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
Holger Hans Peter Freytherf75a6802010-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 Freytherb63a9f82010-06-15 18:48:36 +0800241}
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800242
Holger Hans Peter Freytherb63a9f82010-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 Freyther75ee8412010-06-15 18:48:55 +0800253 if (!con_found || con_found->bsc != con) { \
Holger Hans Peter Freytherd062c522010-06-15 18:48:44 +0800254 fprintf(stderr, "Failed to find the con: %p\n", con_found); \
Holger Hans Peter Freytherb63a9f82010-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 Freyther75ee8412010-06-15 18:48:55 +0800267 struct bsc_connection *con;
268 struct sccp_connections *con_found;
Holger Hans Peter Freytherb63a9f82010-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 Freyther7d841e62010-04-18 02:30:57 +0800275 con->cfg = bsc_config_alloc(nat, "foo", 23);
Holger Hans Peter Freytherb63a9f82010-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 Freytherda30c4b2010-04-21 18:56:12 +0800281 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherb63a9f82010-06-15 18:48:36 +0800282 if (con_found != NULL) {
Holger Hans Peter Freytherd062c522010-06-15 18:48:44 +0800283 fprintf(stderr, "Con should not exist %p\n", con_found);
Holger Hans Peter Freytherb63a9f82010-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 Freytherda30c4b2010-04-21 18:56:12 +0800291 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther75ee8412010-06-15 18:48:55 +0800292 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freytherd062c522010-06-15 18:48:44 +0800293 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freytherb63a9f82010-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 Freyther75ee8412010-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 Freytherb63a9f82010-06-15 18:48:36 +0800308 fprintf(stderr, "Failed to update the SCCP con.\n");
309 abort();
310 }
Holger Hans Peter Freytherb63a9f82010-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 Freytherda30c4b2010-04-21 18:56:12 +0800315 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherb63a9f82010-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 Freytherda30c4b2010-04-21 18:56:12 +0800333 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther75ee8412010-06-15 18:48:55 +0800334 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freytherd062c522010-06-15 18:48:44 +0800335 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freytherb63a9f82010-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 Freytherbedecf32010-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 Freytherda30c4b2010-04-21 18:56:12 +0800347 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherb63a9f82010-06-15 18:48:36 +0800348
349 /* verify that it is gone */
350 if (con_found != NULL) {
Holger Hans Peter Freytherd062c522010-06-15 18:48:44 +0800351 fprintf(stderr, "Con should be gone. %p\n", con_found);
Holger Hans Peter Freytherb63a9f82010-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 Freytherd5deb332010-03-30 06:51:53 +0200361static void test_paging(void)
362{
Holger Hans Peter Freyther935b2df2010-04-17 08:07:19 +0200363 int lac;
Holger Hans Peter Freytherd5deb332010-03-30 06:51:53 +0200364 struct bsc_nat *nat;
365 struct bsc_connection *con;
366 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freytherbfcf5192010-04-06 15:11:34 +0200367 struct bsc_config cfg;
Holger Hans Peter Freytherd5deb332010-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 Freytherbfcf5192010-04-06 15:11:34 +0200374 con->cfg = &cfg;
375 cfg.lac = 23;
Holger Hans Peter Freytherd5deb332010-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 Freyther935b2df2010-04-17 08:07:19 +0200382 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freytherd5deb332010-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 Freyther935b2df2010-04-17 08:07:19 +0200390 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freytherd5deb332010-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 Freytherbfcf5192010-04-06 15:11:34 +0200397 cfg.lac = 8213;
Holger Hans Peter Freytherd5deb332010-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 Freyther935b2df2010-04-17 08:07:19 +0200400 if (bsc_nat_find_bsc(nat, msg, &lac) != con) {
Holger Hans Peter Freytherd5deb332010-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 Freyther89179982010-04-01 03:55:27 +0200407static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freytherdccb9152010-06-15 18:49:53 +0800408{
Holger Hans Peter Freyther36330952010-04-22 12:08:17 +0800409 struct bsc_connection *bsc;
410 struct bsc_nat *nat;
Holger Hans Peter Freytherdccb9152010-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 Freyther36330952010-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 Freytherdccb9152010-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 Freyther36330952010-04-22 12:08:17 +0800445 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freytherdccb9152010-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 Freyther36330952010-04-22 12:08:17 +0800450
451 talloc_free(nat);
Holger Hans Peter Freytherdccb9152010-06-15 18:49:53 +0800452}
453
Holger Hans Peter Freyther89179982010-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 Freyther98d15ef2010-04-18 02:26:16 +0800478 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freyther89179982010-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 Freyther98d15ef2010-04-18 02:26:16 +0800485 if (bsc_mgcp_find_con(nat, 1) != sccp_con) {
Holger Hans Peter Freyther89179982010-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 Freytheracd64202010-04-01 06:48:52 +0200494static void test_mgcp_rewrite(void)
495{
496 int i;
Holger Hans Peter Freyther0d0aaa62010-04-04 18:09:10 +0200497 struct msgb *output;
Holger Hans Peter Freytheracd64202010-04-01 06:48:52 +0200498 fprintf(stderr, "Test rewriting MGCP messages.\n");
499
Holger Hans Peter Freytheracd64202010-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 Freyther0d0aaa62010-04-04 18:09:10 +0200506 char *input = strdup(orig);
Holger Hans Peter Freytheracd64202010-04-01 06:48:52 +0200507
Holger Hans Peter Freyther0d0aaa62010-04-04 18:09:10 +0200508 output = bsc_mgcp_rewrite(input, strlen(input), ip, port);
Holger Hans Peter Freytheracd64202010-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 Freyther0d0aaa62010-04-04 18:09:10 +0200521 free(input);
Holger Hans Peter Freytheracd64202010-04-01 06:48:52 +0200522 }
Holger Hans Peter Freytheracd64202010-04-01 06:48:52 +0200523}
524
Holger Hans Peter Freyther9fec0102010-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 Freyther13abb822010-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;
Holger Hans Peter Freyther13abb822010-05-14 19:49:35 +0800561 const char *nat_imsi_deny;
562};
563
564static struct cr_filter cr_filter[] = {
565 {
566 .data = bssmap_cr,
567 .length = sizeof(bssmap_cr),
568 .result = 0,
569 },
570 {
571 .data = bss_lu,
572 .length = sizeof(bss_lu),
573 .result = 0,
574 },
575 {
576 /* nat deny is before blank/null BSC */
577 .data = bss_lu,
578 .length = sizeof(bss_lu),
579 .result = -3,
580 .nat_imsi_deny = "[0-9]*",
581 },
582 {
Holger Hans Peter Freyther58bce3f2010-05-14 23:07:58 +0800583 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther13abb822010-05-14 19:49:35 +0800584 .data = bss_lu,
585 .length = sizeof(bss_lu),
Holger Hans Peter Freyther58bce3f2010-05-14 23:07:58 +0800586 .result = 0,
Holger Hans Peter Freyther13abb822010-05-14 19:49:35 +0800587 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther58bce3f2010-05-14 23:07:58 +0800588 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther13abb822010-05-14 19:49:35 +0800589 },
590 {
591 /* BSC allow is before NAT deny */
592 .data = bss_lu,
593 .length = sizeof(bss_lu),
594 .result = 0,
595 .bsc_imsi_allow = "[0-9]*",
596 .nat_imsi_deny = "[0-9]*",
597 },
598 {
599 /* filter as deny is first */
600 .data = bss_lu,
601 .length = sizeof(bss_lu),
602 .result = -2,
603 .bsc_imsi_deny = "[0-9]*",
604 .bsc_imsi_allow = "[0-9]*",
605 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther13abb822010-05-14 19:49:35 +0800606 },
607
608};
609
Holger Hans Peter Freyther28b08d62010-05-14 08:12:57 +0800610static void test_cr_filter()
611{
Holger Hans Peter Freyther13abb822010-05-14 19:49:35 +0800612 int i, res;
Holger Hans Peter Freyther28b08d62010-05-14 08:12:57 +0800613 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther28b08d62010-05-14 08:12:57 +0800614 struct bsc_nat_parsed *parsed;
615
Holger Hans Peter Freyther13abb822010-05-14 19:49:35 +0800616 struct bsc_nat *nat = bsc_nat_alloc();
617 struct bsc_connection *bsc = bsc_connection_alloc(nat);
618 bsc->cfg = bsc_config_alloc(nat, "foo", 1234);
619
620 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
621 msgb_reset(msg);
622 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
623
Holger Hans Peter Freyther13abb822010-05-14 19:49:35 +0800624 bsc_parse_reg(nat, &nat->imsi_deny_re, &nat->imsi_deny,
625 cr_filter[i].nat_imsi_deny ? 1 : 0,
626 &cr_filter[i].nat_imsi_deny);
627 bsc_parse_reg(bsc->cfg, &bsc->cfg->imsi_allow_re, &bsc->cfg->imsi_allow,
628 cr_filter[i].bsc_imsi_allow ? 1 : 0,
629 &cr_filter[i].bsc_imsi_allow);
630 bsc_parse_reg(bsc->cfg, &bsc->cfg->imsi_deny_re, &bsc->cfg->imsi_deny,
631 cr_filter[i].bsc_imsi_deny ? 1 : 0,
632 &cr_filter[i].bsc_imsi_deny);
633
634 parsed = bsc_nat_parse(msg);
635 if (!parsed) {
636 fprintf(stderr, "FAIL: Failed to parse the message\n");
637 abort();
638 }
639
640 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed);
641 if (res != cr_filter[i].result) {
642 fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
643 abort();
644 }
645
646 talloc_free(parsed);
Holger Hans Peter Freyther28b08d62010-05-14 08:12:57 +0800647 }
648
Holger Hans Peter Freyther28b08d62010-05-14 08:12:57 +0800649 msgb_free(msg);
650}
651
Holger Hans Peter Freytherb63a9f82010-06-15 18:48:36 +0800652int main(int argc, char **argv)
653{
654 struct debug_target *stderr_target;
655
656 stderr_target = debug_target_create_stderr();
657 debug_add_target(stderr_target);
658 debug_set_all_filter(stderr_target, 1);
659
660 test_filter();
Holger Hans Peter Freytherd5deb332010-03-30 06:51:53 +0200661 test_contrack();
Holger Hans Peter Freytherd5deb332010-03-30 06:51:53 +0200662 test_paging();
Holger Hans Peter Freyther89179982010-04-01 03:55:27 +0200663 test_mgcp_ass_tracking();
664 test_mgcp_find();
Holger Hans Peter Freytheracd64202010-04-01 06:48:52 +0200665 test_mgcp_rewrite();
Holger Hans Peter Freyther9fec0102010-04-01 10:16:28 +0200666 test_mgcp_parse();
Holger Hans Peter Freyther28b08d62010-05-14 08:12:57 +0800667 test_cr_filter();
Holger Hans Peter Freytherf75a6802010-06-15 18:45:38 +0800668 return 0;
669}
Holger Hans Peter Freytherb63a9f82010-06-15 18:48:36 +0800670
671void input_event()
672{}
673int nm_state_event()
674{
675 return -1;
676}
677
678int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
679{
680 return -1;
681}