blob: 0ccd23f6638c8c7aa5cc7990f89f6d00b0168672 [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 Freytherf1924982010-05-15 23:54:04 +0800122/* paging response */
123static const uint8_t pag_resp[] = {
124 0x00, 0x2c, 0xfd, 0x01, 0xe5, 0x68,
125 0x14, 0x02, 0x02, 0x04, 0x02, 0x42, 0xfe, 0x0f,
126 0x1f, 0x00, 0x1d, 0x57, 0x05, 0x08, 0x00, 0x72,
127 0xf4, 0x80, 0x20, 0x16, 0xc3, 0x50, 0x17, 0x10,
128 0x06, 0x27, 0x01, 0x03, 0x30, 0x18, 0x96, 0x08,
129 0x29, 0x26, 0x30, 0x32, 0x11, 0x42, 0x01, 0x19,
130 0x00
131};
132
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800133struct filter_result {
134 const u_int8_t *data;
135 const u_int16_t length;
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100136 const int dir;
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800137 const int result;
138};
139
140static const struct filter_result results[] = {
141 {
142 .data = ipa_id,
143 .length = ARRAY_SIZE(ipa_id),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100144 .dir = DIR_MSC,
145 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800146 },
147 {
148 .data = gsm_reset,
149 .length = ARRAY_SIZE(gsm_reset),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100150 .dir = DIR_MSC,
151 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800152 },
153 {
154 .data = gsm_reset_ack,
155 .length = ARRAY_SIZE(gsm_reset_ack),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100156 .dir = DIR_BSC,
157 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800158 },
159 {
160 .data = gsm_paging,
161 .length = ARRAY_SIZE(gsm_paging),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100162 .dir = DIR_BSC,
163 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800164 },
165 {
166 .data = bssmap_cr,
167 .length = ARRAY_SIZE(bssmap_cr),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100168 .dir = DIR_MSC,
169 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800170 },
171 {
172 .data = bssmap_cc,
173 .length = ARRAY_SIZE(bssmap_cc),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100174 .dir = DIR_BSC,
175 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800176 },
177 {
178 .data = bssmap_released,
179 .length = ARRAY_SIZE(bssmap_released),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100180 .dir = DIR_MSC,
181 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800182 },
183 {
184 .data = bssmap_release_complete,
185 .length = ARRAY_SIZE(bssmap_release_complete),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100186 .dir = DIR_BSC,
187 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800188 },
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200189 {
190 .data = mgcp_msg,
191 .length = ARRAY_SIZE(mgcp_msg),
192 .dir = DIR_MSC,
193 .result = 0,
194 },
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +0200195 {
196 .data = connnection_it,
197 .length = ARRAY_SIZE(connnection_it),
198 .dir = DIR_BSC,
199 .result = 0,
200 },
201 {
202 .data = connnection_it,
203 .length = ARRAY_SIZE(connnection_it),
204 .dir = DIR_MSC,
205 .result = 0,
206 },
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800207 {
208 .data = proto_error,
209 .length = ARRAY_SIZE(proto_error),
210 .dir = DIR_BSC,
211 .result = 0,
212 },
213 {
214 .data = proto_error,
215 .length = ARRAY_SIZE(proto_error),
216 .dir = DIR_MSC,
217 .result = 0,
218 },
219
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800220};
221
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800222static void test_filter(void)
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800223{
224 int i;
225
226
227 /* start testinh with proper messages */
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800228 fprintf(stderr, "Testing BSS Filtering.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800229 for (i = 0; i < ARRAY_SIZE(results); ++i) {
230 int result;
231 struct bsc_nat_parsed *parsed;
232 struct msgb *msg = msgb_alloc(4096, "test-message");
233
234 fprintf(stderr, "Going to test item: %d\n", i);
235 memcpy(msg->data, results[i].data, results[i].length);
236 msg->l2h = msgb_put(msg, results[i].length);
237
238 parsed = bsc_nat_parse(msg);
239 if (!parsed) {
240 fprintf(stderr, "FAIL: Failed to parse the message\n");
241 continue;
242 }
243
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100244 result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800245 if (result != results[i].result) {
246 fprintf(stderr, "FAIL: Not the expected result got: %d wanted: %d\n",
247 result, results[i].result);
248 }
249
250 msgb_free(msg);
251 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800252}
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800253
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800254#include "bsc_data.c"
255
256static void copy_to_msg(struct msgb *msg, const u_int8_t *data, unsigned int length)
257{
258 msgb_reset(msg);
259 msg->l2h = msgb_put(msg, length);
260 memcpy(msg->l2h, data, msgb_l2len(msg));
261}
262
263#define VERIFY(con_found, con, msg, ver, str) \
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800264 if (!con_found || con_found->bsc != con) { \
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800265 fprintf(stderr, "Failed to find the con: %p\n", con_found); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800266 abort(); \
267 } \
268 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
269 fprintf(stderr, "Failed to patch the %s msg.\n", str); \
270 abort(); \
271 }
272
273/* test conn tracking once */
274static void test_contrack()
275{
276 int rc;
277 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800278 struct bsc_connection *con;
279 struct sccp_connections *con_found;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800280 struct bsc_nat_parsed *parsed;
281 struct msgb *msg;
282
283 fprintf(stderr, "Testing connection tracking.\n");
284 nat = bsc_nat_alloc();
285 con = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc87c8b72010-04-18 02:30:57 +0800286 con->cfg = bsc_config_alloc(nat, "foo", 23);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800287 msg = msgb_alloc(4096, "test");
288
289 /* 1.) create a connection */
290 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
291 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800292 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800293 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800294 fprintf(stderr, "Con should not exist %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800295 abort();
296 }
297 rc = create_sccp_src_ref(con, msg, parsed);
298 if (rc != 0) {
299 fprintf(stderr, "Failed to create a ref\n");
300 abort();
301 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800302 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800303 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800304 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800305 abort();
306 }
307 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
308 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
309 abort();
310 }
311 talloc_free(parsed);
312
313 /* 2.) get the cc */
314 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
315 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800316 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
317 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
318 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800319 fprintf(stderr, "Failed to update the SCCP con.\n");
320 abort();
321 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800322
323 /* 3.) send some data */
324 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
325 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800326 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800327 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
328
329 /* 4.) receive some data */
330 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
331 parsed = bsc_nat_parse(msg);
332 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
333 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
334
335 /* 5.) close the connection */
336 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
337 parsed = bsc_nat_parse(msg);
338 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
339 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
340
341 /* 6.) confirm the connection close */
342 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
343 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800344 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800345 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800346 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800347 abort();
348 }
349 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
350 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
351 abort();
352 }
353 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200354 talloc_free(parsed);
355
356 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
357 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800358 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800359
360 /* verify that it is gone */
361 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800362 fprintf(stderr, "Con should be gone. %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800363 abort();
364 }
365 talloc_free(parsed);
366
367
368 talloc_free(nat);
369 msgb_free(msg);
370}
371
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200372static void test_paging(void)
373{
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200374 int lac;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200375 struct bsc_nat *nat;
376 struct bsc_connection *con;
377 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200378 struct bsc_config cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200379 struct msgb *msg;
380
381 fprintf(stderr, "Testing paging by lac.\n");
382
383 nat = bsc_nat_alloc();
384 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200385 con->cfg = &cfg;
386 cfg.lac = 23;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200387 con->authenticated = 1;
388 llist_add(&con->list_entry, &nat->bsc_connections);
389 msg = msgb_alloc(4096, "test");
390
391 /* Test completely bad input */
392 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200393 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200394 fprintf(stderr, "Should have not found anything.\n");
395 abort();
396 }
397
398 /* Test it by not finding it */
399 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
400 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200401 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200402 fprintf(stderr, "Should have not found aynthing.\n");
403 abort();
404 }
405 talloc_free(parsed);
406
407 /* Test by finding it */
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200408 cfg.lac = 8213;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200409 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
410 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200411 if (bsc_nat_find_bsc(nat, msg, &lac) != con) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200412 fprintf(stderr, "Should have found it.\n");
413 abort();
414 }
415 talloc_free(parsed);
416}
417
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200418static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800419{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800420 struct bsc_connection *bsc;
421 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800422 struct sccp_connections con;
423 struct bsc_nat_parsed *parsed;
424 struct msgb *msg;
425
426 fprintf(stderr, "Testing MGCP.\n");
427 memset(&con, 0, sizeof(con));
428
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800429 nat = bsc_nat_alloc();
430 nat->bsc_endpoints = talloc_zero_array(nat,
431 struct bsc_endpoint,
432 33);
433 bsc = bsc_connection_alloc(nat);
434 bsc->cfg = bsc_config_alloc(nat, "foo", 2323);
435 con.bsc = bsc;
436
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800437 msg = msgb_alloc(4096, "foo");
438 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
439 parsed = bsc_nat_parse(msg);
440 if (bsc_mgcp_assign(&con, msg) != 0) {
441 fprintf(stderr, "Failed to handle assignment.\n");
442 abort();
443 }
444
445 if (con.msc_timeslot != 21) {
446 fprintf(stderr, "Timeslot should be 21.\n");
447 abort();
448 }
449
450 if (con.bsc_timeslot != 21) {
451 fprintf(stderr, "Assigned timeslot should have been 21.\n");
452 abort();
453 }
454 talloc_free(parsed);
455
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800456 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800457 if (con.bsc_timeslot != -1 || con.msc_timeslot != -1) {
458 fprintf(stderr, "Clearing should remove the mapping.\n");
459 abort();
460 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800461
462 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800463}
464
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200465/* test the code to find a given connection */
466static void test_mgcp_find(void)
467{
468 struct bsc_nat *nat;
469 struct bsc_connection *con;
470 struct sccp_connections *sccp_con;
471
472 fprintf(stderr, "Testing finding of a BSC Connection\n");
473
474 nat = bsc_nat_alloc();
475 con = bsc_connection_alloc(nat);
476 llist_add(&con->list_entry, &nat->bsc_connections);
477
478 sccp_con = talloc_zero(con, struct sccp_connections);
479 sccp_con->msc_timeslot = 12;
480 sccp_con->bsc_timeslot = 12;
481 sccp_con->bsc = con;
482 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
483
484 if (bsc_mgcp_find_con(nat, 11) != NULL) {
485 fprintf(stderr, "Found the wrong connection.\n");
486 abort();
487 }
488
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800489 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200490 fprintf(stderr, "Didn't find the connection\n");
491 abort();
492 }
493
494 sccp_con->msc_timeslot = 0;
495 sccp_con->bsc_timeslot = 0;
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800496 if (bsc_mgcp_find_con(nat, 1) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200497 fprintf(stderr, "Didn't find the connection\n");
498 abort();
499 }
500
501 /* free everything */
502 talloc_free(nat);
503}
504
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200505static void test_mgcp_rewrite(void)
506{
507 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200508 struct msgb *output;
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200509 fprintf(stderr, "Test rewriting MGCP messages.\n");
510
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200511 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
512 const char *orig = mgcp_messages[i].orig;
513 const char *patc = mgcp_messages[i].patch;
514 const char *ip = mgcp_messages[i].ip;
515 const int port = mgcp_messages[i].port;
516
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200517 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200518
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200519 output = bsc_mgcp_rewrite(input, strlen(input), ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200520 if (msgb_l2len(output) != strlen(patc)) {
521 fprintf(stderr, "Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
522 fprintf(stderr, "String '%s' vs '%s'\n", (const char *) output->l2h, patc);
523 abort();
524 }
525
526 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
527 fprintf(stderr, "Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
528 abort();
529 }
530
531 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200532 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200533 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200534}
535
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200536static void test_mgcp_parse(void)
537{
538 int code, ci;
539 char transaction[60];
540
541 fprintf(stderr, "Test MGCP response parsing.\n");
542
543 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
544 fprintf(stderr, "Failed to parse CRCX resp.\n");
545 abort();
546 }
547
548 if (code != 200) {
549 fprintf(stderr, "Failed to parse the CODE properly. Got: %d\n", code);
550 abort();
551 }
552
553 if (strcmp(transaction, "23265295") != 0) {
554 fprintf(stderr, "Failed to parse transaction id: '%s'\n", transaction);
555 abort();
556 }
557
558 ci = bsc_mgcp_extract_ci(crcx_resp);
559 if (ci != 1) {
560 fprintf(stderr, "Failed to parse the CI. Got: %d\n", ci);
561 abort();
562 }
563}
564
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800565struct cr_filter {
566 const u_int8_t *data;
567 int length;
568 int result;
569
570 const char *bsc_imsi_allow;
571 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800572 const char *nat_imsi_deny;
573};
574
575static struct cr_filter cr_filter[] = {
576 {
577 .data = bssmap_cr,
578 .length = sizeof(bssmap_cr),
579 .result = 0,
580 },
581 {
582 .data = bss_lu,
583 .length = sizeof(bss_lu),
584 .result = 0,
585 },
586 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800587 .data = pag_resp,
588 .length = sizeof(pag_resp),
589 .result = 0,
590 },
591 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800592 /* nat deny is before blank/null BSC */
593 .data = bss_lu,
594 .length = sizeof(bss_lu),
595 .result = -3,
596 .nat_imsi_deny = "[0-9]*",
597 },
598 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800599 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800600 .data = bss_lu,
601 .length = sizeof(bss_lu),
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800602 .result = 0,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800603 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800604 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800605 },
606 {
607 /* BSC allow is before NAT deny */
608 .data = bss_lu,
609 .length = sizeof(bss_lu),
610 .result = 0,
611 .bsc_imsi_allow = "[0-9]*",
612 .nat_imsi_deny = "[0-9]*",
613 },
614 {
615 /* filter as deny is first */
616 .data = bss_lu,
617 .length = sizeof(bss_lu),
618 .result = -2,
619 .bsc_imsi_deny = "[0-9]*",
620 .bsc_imsi_allow = "[0-9]*",
621 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800622 },
623
624};
625
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800626static void test_cr_filter()
627{
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800628 int i, res;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800629 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800630 struct bsc_nat_parsed *parsed;
631
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800632 struct bsc_nat *nat = bsc_nat_alloc();
633 struct bsc_connection *bsc = bsc_connection_alloc(nat);
634 bsc->cfg = bsc_config_alloc(nat, "foo", 1234);
635
636 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
637 msgb_reset(msg);
638 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
639
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800640 bsc_parse_reg(nat, &nat->imsi_deny_re, &nat->imsi_deny,
641 cr_filter[i].nat_imsi_deny ? 1 : 0,
642 &cr_filter[i].nat_imsi_deny);
643 bsc_parse_reg(bsc->cfg, &bsc->cfg->imsi_allow_re, &bsc->cfg->imsi_allow,
644 cr_filter[i].bsc_imsi_allow ? 1 : 0,
645 &cr_filter[i].bsc_imsi_allow);
646 bsc_parse_reg(bsc->cfg, &bsc->cfg->imsi_deny_re, &bsc->cfg->imsi_deny,
647 cr_filter[i].bsc_imsi_deny ? 1 : 0,
648 &cr_filter[i].bsc_imsi_deny);
649
650 parsed = bsc_nat_parse(msg);
651 if (!parsed) {
652 fprintf(stderr, "FAIL: Failed to parse the message\n");
653 abort();
654 }
655
656 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed);
657 if (res != cr_filter[i].result) {
658 fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
659 abort();
660 }
661
662 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800663 }
664
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800665 msgb_free(msg);
666}
667
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800668int main(int argc, char **argv)
669{
670 struct debug_target *stderr_target;
671
672 stderr_target = debug_target_create_stderr();
673 debug_add_target(stderr_target);
674 debug_set_all_filter(stderr_target, 1);
675
676 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200677 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200678 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200679 test_mgcp_ass_tracking();
680 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200681 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200682 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800683 test_cr_filter();
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800684 return 0;
685}
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800686
687void input_event()
688{}
689int nm_state_event()
690{
691 return -1;
692}
693
694int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
695{
696 return -1;
697}