blob: e39ec0c3c5a670fedf0b35ebeec8fe7b64104c74 [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 */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080035static uint8_t ipa_id[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080036 0x00, 0x01, 0xfe, 0x06,
37};
38
39/* SCCP messages are below */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080040static uint8_t gsm_reset[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080041 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
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080047static const uint8_t gsm_reset_ack[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080048 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
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080054static const uint8_t gsm_paging[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080055 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 */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080063static const uint8_t bssmap_cr[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080064 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 */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080074static const uint8_t bssmap_cc[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080075 0x00, 0x0a, 0xfd,
76 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
77};
78
79/* MSC -> BSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080080static const uint8_t bssmap_released[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080081 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 */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080087static const uint8_t bssmap_release_complete[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080088 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 */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080093static const uint8_t connnection_it[] = {
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020094 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 */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800100static const uint8_t proto_error[] = {
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800101 0x00, 0x05, 0xfd,
102 0x0f, 0x22, 0x33, 0x44, 0x00,
103};
104
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200105/* MGCP wrap... */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800106static const uint8_t mgcp_msg[] = {
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200107 0x00, 0x03, 0xfc,
108 0x20, 0x20, 0x20,
109};
110
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800111/* location updating request */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800112static const uint8_t bss_lu[] = {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800113 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 {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800134 const uint8_t *data;
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800135 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
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800256static void copy_to_msg(struct msgb *msg, const uint8_t *data, unsigned int length)
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800257{
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{
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800276 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800277 struct bsc_connection *con;
278 struct sccp_connections *con_found;
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800279 struct sccp_connections *rc_con;
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 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800297 rc_con = create_sccp_src_ref(con, parsed);
298 if (!rc_con) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800299 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 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800307 if (con_found != rc_con) {
308 fprintf(stderr, "Failed to find the right connection.\n");
309 abort();
310 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800311 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
312 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
313 abort();
314 }
315 talloc_free(parsed);
316
317 /* 2.) get the cc */
318 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
319 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800320 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
321 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
322 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800323 fprintf(stderr, "Failed to update the SCCP con.\n");
324 abort();
325 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800326
327 /* 3.) send some data */
328 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
329 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800330 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800331 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
332
333 /* 4.) receive some data */
334 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
335 parsed = bsc_nat_parse(msg);
336 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
337 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
338
339 /* 5.) close the connection */
340 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
341 parsed = bsc_nat_parse(msg);
342 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
343 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
344
345 /* 6.) confirm the connection close */
346 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
347 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800348 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800349 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800350 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800351 abort();
352 }
353 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
354 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
355 abort();
356 }
357 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200358 talloc_free(parsed);
359
360 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
361 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800362 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800363
364 /* verify that it is gone */
365 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800366 fprintf(stderr, "Con should be gone. %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800367 abort();
368 }
369 talloc_free(parsed);
370
371
372 talloc_free(nat);
373 msgb_free(msg);
374}
375
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200376static void test_paging(void)
377{
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200378 int lac;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200379 struct bsc_nat *nat;
380 struct bsc_connection *con;
381 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200382 struct bsc_config cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200383 struct msgb *msg;
384
385 fprintf(stderr, "Testing paging by lac.\n");
386
387 nat = bsc_nat_alloc();
388 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200389 con->cfg = &cfg;
390 cfg.lac = 23;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200391 con->authenticated = 1;
392 llist_add(&con->list_entry, &nat->bsc_connections);
393 msg = msgb_alloc(4096, "test");
394
395 /* Test completely bad input */
396 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200397 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200398 fprintf(stderr, "Should have not found anything.\n");
399 abort();
400 }
401
402 /* Test it by not finding it */
403 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
404 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200405 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200406 fprintf(stderr, "Should have not found aynthing.\n");
407 abort();
408 }
409 talloc_free(parsed);
410
411 /* Test by finding it */
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200412 cfg.lac = 8213;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200413 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
414 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200415 if (bsc_nat_find_bsc(nat, msg, &lac) != con) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200416 fprintf(stderr, "Should have found it.\n");
417 abort();
418 }
419 talloc_free(parsed);
420}
421
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200422static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800423{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800424 struct bsc_connection *bsc;
425 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800426 struct sccp_connections con;
427 struct bsc_nat_parsed *parsed;
428 struct msgb *msg;
429
430 fprintf(stderr, "Testing MGCP.\n");
431 memset(&con, 0, sizeof(con));
432
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800433 nat = bsc_nat_alloc();
434 nat->bsc_endpoints = talloc_zero_array(nat,
435 struct bsc_endpoint,
436 33);
437 bsc = bsc_connection_alloc(nat);
438 bsc->cfg = bsc_config_alloc(nat, "foo", 2323);
439 con.bsc = bsc;
440
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800441 msg = msgb_alloc(4096, "foo");
442 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
443 parsed = bsc_nat_parse(msg);
444 if (bsc_mgcp_assign(&con, msg) != 0) {
445 fprintf(stderr, "Failed to handle assignment.\n");
446 abort();
447 }
448
449 if (con.msc_timeslot != 21) {
450 fprintf(stderr, "Timeslot should be 21.\n");
451 abort();
452 }
453
454 if (con.bsc_timeslot != 21) {
455 fprintf(stderr, "Assigned timeslot should have been 21.\n");
456 abort();
457 }
458 talloc_free(parsed);
459
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800460 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800461 if (con.bsc_timeslot != -1 || con.msc_timeslot != -1) {
462 fprintf(stderr, "Clearing should remove the mapping.\n");
463 abort();
464 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800465
466 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800467}
468
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200469/* test the code to find a given connection */
470static void test_mgcp_find(void)
471{
472 struct bsc_nat *nat;
473 struct bsc_connection *con;
474 struct sccp_connections *sccp_con;
475
476 fprintf(stderr, "Testing finding of a BSC Connection\n");
477
478 nat = bsc_nat_alloc();
479 con = bsc_connection_alloc(nat);
480 llist_add(&con->list_entry, &nat->bsc_connections);
481
482 sccp_con = talloc_zero(con, struct sccp_connections);
483 sccp_con->msc_timeslot = 12;
484 sccp_con->bsc_timeslot = 12;
485 sccp_con->bsc = con;
486 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
487
488 if (bsc_mgcp_find_con(nat, 11) != NULL) {
489 fprintf(stderr, "Found the wrong connection.\n");
490 abort();
491 }
492
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800493 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200494 fprintf(stderr, "Didn't find the connection\n");
495 abort();
496 }
497
498 sccp_con->msc_timeslot = 0;
499 sccp_con->bsc_timeslot = 0;
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800500 if (bsc_mgcp_find_con(nat, 1) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200501 fprintf(stderr, "Didn't find the connection\n");
502 abort();
503 }
504
505 /* free everything */
506 talloc_free(nat);
507}
508
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200509static void test_mgcp_rewrite(void)
510{
511 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200512 struct msgb *output;
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200513 fprintf(stderr, "Test rewriting MGCP messages.\n");
514
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200515 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
516 const char *orig = mgcp_messages[i].orig;
517 const char *patc = mgcp_messages[i].patch;
518 const char *ip = mgcp_messages[i].ip;
519 const int port = mgcp_messages[i].port;
520
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200521 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200522
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200523 output = bsc_mgcp_rewrite(input, strlen(input), ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200524 if (msgb_l2len(output) != strlen(patc)) {
525 fprintf(stderr, "Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
526 fprintf(stderr, "String '%s' vs '%s'\n", (const char *) output->l2h, patc);
527 abort();
528 }
529
530 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
531 fprintf(stderr, "Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
532 abort();
533 }
534
535 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200536 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200537 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200538}
539
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200540static void test_mgcp_parse(void)
541{
542 int code, ci;
543 char transaction[60];
544
545 fprintf(stderr, "Test MGCP response parsing.\n");
546
547 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
548 fprintf(stderr, "Failed to parse CRCX resp.\n");
549 abort();
550 }
551
552 if (code != 200) {
553 fprintf(stderr, "Failed to parse the CODE properly. Got: %d\n", code);
554 abort();
555 }
556
557 if (strcmp(transaction, "23265295") != 0) {
558 fprintf(stderr, "Failed to parse transaction id: '%s'\n", transaction);
559 abort();
560 }
561
562 ci = bsc_mgcp_extract_ci(crcx_resp);
563 if (ci != 1) {
564 fprintf(stderr, "Failed to parse the CI. Got: %d\n", ci);
565 abort();
566 }
567}
568
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800569struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800570 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800571 int length;
572 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800573 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800574
575 const char *bsc_imsi_allow;
576 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800577 const char *nat_imsi_deny;
578};
579
580static struct cr_filter cr_filter[] = {
581 {
582 .data = bssmap_cr,
583 .length = sizeof(bssmap_cr),
584 .result = 0,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800585 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800586 },
587 {
588 .data = bss_lu,
589 .length = sizeof(bss_lu),
590 .result = 0,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800591 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800592 },
593 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800594 .data = pag_resp,
595 .length = sizeof(pag_resp),
596 .result = 0,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800597 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800598 },
599 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800600 /* nat deny is before blank/null BSC */
601 .data = bss_lu,
602 .length = sizeof(bss_lu),
603 .result = -3,
604 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800605 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800606 },
607 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800608 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800609 .data = bss_lu,
610 .length = sizeof(bss_lu),
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800611 .result = 0,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800612 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800613 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800614 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800615 },
616 {
617 /* BSC allow is before NAT deny */
618 .data = bss_lu,
619 .length = sizeof(bss_lu),
620 .result = 0,
621 .bsc_imsi_allow = "[0-9]*",
622 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800623 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800624 },
625 {
626 /* filter as deny is first */
627 .data = bss_lu,
628 .length = sizeof(bss_lu),
629 .result = -2,
630 .bsc_imsi_deny = "[0-9]*",
631 .bsc_imsi_allow = "[0-9]*",
632 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800633 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800634 },
635
636};
637
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800638static void test_cr_filter()
639{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800640 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800641 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800642 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800643 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800644 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800645
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800646 struct bsc_nat *nat = bsc_nat_alloc();
647 struct bsc_connection *bsc = bsc_connection_alloc(nat);
648 bsc->cfg = bsc_config_alloc(nat, "foo", 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800649 bsc->cfg->acc_lst_name = "bsc";
650 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800651
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800652 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
653 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
654
655 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
656 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
657
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800658 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
659 msgb_reset(msg);
660 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
661
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800662 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
663 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800664
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800665 bsc_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800666 cr_filter[i].nat_imsi_deny ? 1 : 0,
667 &cr_filter[i].nat_imsi_deny);
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800668 bsc_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800669 cr_filter[i].bsc_imsi_allow ? 1 : 0,
670 &cr_filter[i].bsc_imsi_allow);
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800671 bsc_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800672 cr_filter[i].bsc_imsi_deny ? 1 : 0,
673 &cr_filter[i].bsc_imsi_deny);
674
675 parsed = bsc_nat_parse(msg);
676 if (!parsed) {
677 fprintf(stderr, "FAIL: Failed to parse the message\n");
678 abort();
679 }
680
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800681 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800682 if (res != cr_filter[i].result) {
683 fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
684 abort();
685 }
686
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800687 if (contype != cr_filter[i].contype) {
688 fprintf(stderr, "FAIL: Wrong contype %d for test %d.\n", res, contype);
689 abort();
690 }
691
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800692 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800693 }
694
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800695 msgb_free(msg);
696}
697
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800698int main(int argc, char **argv)
699{
Holger Hans Peter Freyther434a1fd2010-06-15 20:18:40 +0800700 struct log_target *stderr_target;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800701
Holger Hans Peter Freytherf0945402010-07-05 13:29:42 +0800702 log_init(&log_info);
Holger Hans Peter Freyther434a1fd2010-06-15 20:18:40 +0800703 stderr_target = log_target_create_stderr();
704 log_add_target(stderr_target);
705 log_set_all_filter(stderr_target, 1);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800706
707 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200708 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200709 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200710 test_mgcp_ass_tracking();
711 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200712 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200713 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800714 test_cr_filter();
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800715 return 0;
716}
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800717
718void input_event()
719{}
720int nm_state_event()
721{
722 return -1;
723}
724