blob: 0e936edfc5ae4d457fe2795243884332ffb1605e [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>
Holger Hans Peter Freytherc2b31ed2010-07-31 05:17:17 +080029#include <openbsc/bsc_nat_sccp.h>
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080030
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +080031#include <osmocore/talloc.h>
32
Harald Welted5db12c2010-08-03 15:11:51 +020033#include <osmocom/sccp/sccp.h>
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +080034
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080035#include <stdio.h>
36
37/* test messages for ipa */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080038static uint8_t ipa_id[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080039 0x00, 0x01, 0xfe, 0x06,
40};
41
42/* SCCP messages are below */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080043static uint8_t gsm_reset[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080044 0x00, 0x12, 0xfd,
45 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
46 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
47 0x01, 0x20,
48};
49
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080050static const uint8_t gsm_reset_ack[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080051 0x00, 0x13, 0xfd,
52 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
53 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
54 0x00, 0x01, 0x31,
55};
56
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080057static const uint8_t gsm_paging[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080058 0x00, 0x20, 0xfd,
59 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
60 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10,
61 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10,
62 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06,
63};
64
65/* BSC -> MSC connection open */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080066static const uint8_t bssmap_cr[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080067 0x00, 0x2c, 0xfd,
68 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02,
69 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05,
70 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3,
71 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33,
72 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01,
73 0x31, 0x97, 0x61, 0x00
74};
75
76/* MSC -> BSC connection confirm */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080077static const uint8_t bssmap_cc[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080078 0x00, 0x0a, 0xfd,
79 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
80};
81
82/* MSC -> BSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080083static const uint8_t bssmap_released[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080084 0x00, 0x0e, 0xfd,
85 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f,
86 0x02, 0x23, 0x42, 0x00,
87};
88
89/* BSC -> MSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080090static const uint8_t bssmap_release_complete[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080091 0x00, 0x07, 0xfd,
92 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03
93};
94
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020095/* both directions IT timer */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080096static const uint8_t connnection_it[] = {
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020097 0x00, 0x0b, 0xfd,
98 0x10, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03,
99 0x00, 0x00, 0x00, 0x00,
100};
101
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800102/* error in both directions */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800103static const uint8_t proto_error[] = {
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800104 0x00, 0x05, 0xfd,
105 0x0f, 0x22, 0x33, 0x44, 0x00,
106};
107
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200108/* MGCP wrap... */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800109static const uint8_t mgcp_msg[] = {
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200110 0x00, 0x03, 0xfc,
111 0x20, 0x20, 0x20,
112};
113
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800114/* location updating request */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800115static const uint8_t bss_lu[] = {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800116 0x00, 0x2e, 0xfd,
117 0x01, 0x91, 0x45, 0x14, 0x02, 0x02, 0x04, 0x02,
118 0x42, 0xfe, 0x0f, 0x21, 0x00, 0x1f, 0x57, 0x05,
119 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x14, 0xc3,
120 0x50, 0x17, 0x12, 0x05, 0x08, 0x70, 0x72, 0xf4,
121 0x80, 0xff, 0xfe, 0x30, 0x08, 0x29, 0x44, 0x50,
122 0x12, 0x03, 0x24, 0x01, 0x95, 0x00
123};
124
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800125/* paging response */
126static const uint8_t pag_resp[] = {
127 0x00, 0x2c, 0xfd, 0x01, 0xe5, 0x68,
128 0x14, 0x02, 0x02, 0x04, 0x02, 0x42, 0xfe, 0x0f,
129 0x1f, 0x00, 0x1d, 0x57, 0x05, 0x08, 0x00, 0x72,
130 0xf4, 0x80, 0x20, 0x16, 0xc3, 0x50, 0x17, 0x10,
131 0x06, 0x27, 0x01, 0x03, 0x30, 0x18, 0x96, 0x08,
132 0x29, 0x26, 0x30, 0x32, 0x11, 0x42, 0x01, 0x19,
133 0x00
134};
135
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800136struct filter_result {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800137 const uint8_t *data;
Holger Hans Peter Freythere2c15202010-07-23 19:09:21 +0800138 const uint16_t length;
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100139 const int dir;
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800140 const int result;
141};
142
143static const struct filter_result results[] = {
144 {
145 .data = ipa_id,
146 .length = ARRAY_SIZE(ipa_id),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100147 .dir = DIR_MSC,
148 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800149 },
150 {
151 .data = gsm_reset,
152 .length = ARRAY_SIZE(gsm_reset),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100153 .dir = DIR_MSC,
154 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800155 },
156 {
157 .data = gsm_reset_ack,
158 .length = ARRAY_SIZE(gsm_reset_ack),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100159 .dir = DIR_BSC,
160 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800161 },
162 {
163 .data = gsm_paging,
164 .length = ARRAY_SIZE(gsm_paging),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100165 .dir = DIR_BSC,
166 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800167 },
168 {
169 .data = bssmap_cr,
170 .length = ARRAY_SIZE(bssmap_cr),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100171 .dir = DIR_MSC,
172 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800173 },
174 {
175 .data = bssmap_cc,
176 .length = ARRAY_SIZE(bssmap_cc),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100177 .dir = DIR_BSC,
178 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800179 },
180 {
181 .data = bssmap_released,
182 .length = ARRAY_SIZE(bssmap_released),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100183 .dir = DIR_MSC,
184 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800185 },
186 {
187 .data = bssmap_release_complete,
188 .length = ARRAY_SIZE(bssmap_release_complete),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100189 .dir = DIR_BSC,
190 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800191 },
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200192 {
193 .data = mgcp_msg,
194 .length = ARRAY_SIZE(mgcp_msg),
195 .dir = DIR_MSC,
196 .result = 0,
197 },
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +0200198 {
199 .data = connnection_it,
200 .length = ARRAY_SIZE(connnection_it),
201 .dir = DIR_BSC,
202 .result = 0,
203 },
204 {
205 .data = connnection_it,
206 .length = ARRAY_SIZE(connnection_it),
207 .dir = DIR_MSC,
208 .result = 0,
209 },
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800210 {
211 .data = proto_error,
212 .length = ARRAY_SIZE(proto_error),
213 .dir = DIR_BSC,
214 .result = 0,
215 },
216 {
217 .data = proto_error,
218 .length = ARRAY_SIZE(proto_error),
219 .dir = DIR_MSC,
220 .result = 0,
221 },
222
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800223};
224
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800225static void test_filter(void)
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800226{
227 int i;
228
229
230 /* start testinh with proper messages */
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800231 fprintf(stderr, "Testing BSS Filtering.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800232 for (i = 0; i < ARRAY_SIZE(results); ++i) {
233 int result;
234 struct bsc_nat_parsed *parsed;
235 struct msgb *msg = msgb_alloc(4096, "test-message");
236
237 fprintf(stderr, "Going to test item: %d\n", i);
238 memcpy(msg->data, results[i].data, results[i].length);
239 msg->l2h = msgb_put(msg, results[i].length);
240
241 parsed = bsc_nat_parse(msg);
242 if (!parsed) {
243 fprintf(stderr, "FAIL: Failed to parse the message\n");
244 continue;
245 }
246
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100247 result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800248 if (result != results[i].result) {
249 fprintf(stderr, "FAIL: Not the expected result got: %d wanted: %d\n",
250 result, results[i].result);
251 }
252
253 msgb_free(msg);
254 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800255}
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800256
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800257#include "bsc_data.c"
258
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800259static void copy_to_msg(struct msgb *msg, const uint8_t *data, unsigned int length)
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800260{
261 msgb_reset(msg);
262 msg->l2h = msgb_put(msg, length);
263 memcpy(msg->l2h, data, msgb_l2len(msg));
264}
265
266#define VERIFY(con_found, con, msg, ver, str) \
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800267 if (!con_found || con_found->bsc != con) { \
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800268 fprintf(stderr, "Failed to find the con: %p\n", con_found); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800269 abort(); \
270 } \
271 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
272 fprintf(stderr, "Failed to patch the %s msg.\n", str); \
273 abort(); \
274 }
275
276/* test conn tracking once */
277static void test_contrack()
278{
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800279 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800280 struct bsc_connection *con;
281 struct sccp_connections *con_found;
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800282 struct sccp_connections *rc_con;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800283 struct bsc_nat_parsed *parsed;
284 struct msgb *msg;
285
286 fprintf(stderr, "Testing connection tracking.\n");
287 nat = bsc_nat_alloc();
288 con = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc87c8b72010-04-18 02:30:57 +0800289 con->cfg = bsc_config_alloc(nat, "foo", 23);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800290 msg = msgb_alloc(4096, "test");
291
292 /* 1.) create a connection */
293 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
294 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800295 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800296 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800297 fprintf(stderr, "Con should not exist %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800298 abort();
299 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800300 rc_con = create_sccp_src_ref(con, parsed);
301 if (!rc_con) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800302 fprintf(stderr, "Failed to create a ref\n");
303 abort();
304 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800305 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800306 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800307 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800308 abort();
309 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800310 if (con_found != rc_con) {
311 fprintf(stderr, "Failed to find the right connection.\n");
312 abort();
313 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800314 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
315 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
316 abort();
317 }
318 talloc_free(parsed);
319
320 /* 2.) get the cc */
321 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
322 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800323 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
324 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
325 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800326 fprintf(stderr, "Failed to update the SCCP con.\n");
327 abort();
328 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800329
330 /* 3.) send some data */
331 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
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 Freyther38f7c752010-06-15 18:48:36 +0800334 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
335
336 /* 4.) receive some data */
337 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
338 parsed = bsc_nat_parse(msg);
339 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
340 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
341
342 /* 5.) close the connection */
343 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
344 parsed = bsc_nat_parse(msg);
345 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
346 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
347
348 /* 6.) confirm the connection close */
349 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
350 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800351 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800352 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800353 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800354 abort();
355 }
356 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
357 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
358 abort();
359 }
360 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200361 talloc_free(parsed);
362
363 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
364 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800365 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800366
367 /* verify that it is gone */
368 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800369 fprintf(stderr, "Con should be gone. %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800370 abort();
371 }
372 talloc_free(parsed);
373
374
375 talloc_free(nat);
376 msgb_free(msg);
377}
378
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200379static void test_paging(void)
380{
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200381 int lac;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200382 struct bsc_nat *nat;
383 struct bsc_connection *con;
384 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200385 struct bsc_config cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200386 struct msgb *msg;
387
388 fprintf(stderr, "Testing paging by lac.\n");
389
390 nat = bsc_nat_alloc();
391 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200392 con->cfg = &cfg;
393 cfg.lac = 23;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200394 con->authenticated = 1;
395 llist_add(&con->list_entry, &nat->bsc_connections);
396 msg = msgb_alloc(4096, "test");
397
398 /* Test completely bad input */
399 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200400 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200401 fprintf(stderr, "Should have not found anything.\n");
402 abort();
403 }
404
405 /* Test it by not finding it */
406 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
407 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200408 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200409 fprintf(stderr, "Should have not found aynthing.\n");
410 abort();
411 }
412 talloc_free(parsed);
413
414 /* Test by finding it */
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200415 cfg.lac = 8213;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200416 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
417 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200418 if (bsc_nat_find_bsc(nat, msg, &lac) != con) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200419 fprintf(stderr, "Should have found it.\n");
420 abort();
421 }
422 talloc_free(parsed);
423}
424
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200425static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800426{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800427 struct bsc_connection *bsc;
428 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800429 struct sccp_connections con;
430 struct bsc_nat_parsed *parsed;
431 struct msgb *msg;
432
433 fprintf(stderr, "Testing MGCP.\n");
434 memset(&con, 0, sizeof(con));
435
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800436 nat = bsc_nat_alloc();
437 nat->bsc_endpoints = talloc_zero_array(nat,
438 struct bsc_endpoint,
439 33);
440 bsc = bsc_connection_alloc(nat);
441 bsc->cfg = bsc_config_alloc(nat, "foo", 2323);
442 con.bsc = bsc;
443
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800444 msg = msgb_alloc(4096, "foo");
445 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
446 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800447 if (bsc_mgcp_assign_patch(&con, msg) != 0) {
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800448 fprintf(stderr, "Failed to handle assignment.\n");
449 abort();
450 }
451
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800452 if (con.msc_endp != 21) {
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800453 fprintf(stderr, "Timeslot should be 21.\n");
454 abort();
455 }
456
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800457 if (con.bsc_endp != 1) {
458 fprintf(stderr, "Assigned timeslot should have been 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800459 abort();
460 }
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800461 if (con.bsc->endpoint_status[1] != 1) {
462 fprintf(stderr, "The status on the BSC is wrong.\n");
463 abort();
464 }
465
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800466 talloc_free(parsed);
467
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800468 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800469 if (con.bsc_endp != -1 || con.msc_endp != -1 || con.bsc->endpoint_status[1] != 0) {
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800470 fprintf(stderr, "Clearing should remove the mapping.\n");
471 abort();
472 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800473
474 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800475}
476
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200477/* test the code to find a given connection */
478static void test_mgcp_find(void)
479{
480 struct bsc_nat *nat;
481 struct bsc_connection *con;
482 struct sccp_connections *sccp_con;
483
484 fprintf(stderr, "Testing finding of a BSC Connection\n");
485
486 nat = bsc_nat_alloc();
487 con = bsc_connection_alloc(nat);
488 llist_add(&con->list_entry, &nat->bsc_connections);
489
490 sccp_con = talloc_zero(con, struct sccp_connections);
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800491 sccp_con->msc_endp = 12;
492 sccp_con->bsc_endp = 12;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200493 sccp_con->bsc = con;
494 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
495
496 if (bsc_mgcp_find_con(nat, 11) != NULL) {
497 fprintf(stderr, "Found the wrong connection.\n");
498 abort();
499 }
500
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800501 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200502 fprintf(stderr, "Didn't find the connection\n");
503 abort();
504 }
505
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200506 /* free everything */
507 talloc_free(nat);
508}
509
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200510static void test_mgcp_rewrite(void)
511{
512 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200513 struct msgb *output;
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200514 fprintf(stderr, "Test rewriting MGCP messages.\n");
515
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200516 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
517 const char *orig = mgcp_messages[i].orig;
518 const char *patc = mgcp_messages[i].patch;
519 const char *ip = mgcp_messages[i].ip;
520 const int port = mgcp_messages[i].port;
521
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200522 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200523
Holger Hans Peter Freytherf7c86c52010-08-30 13:44:32 +0800524 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200525 if (msgb_l2len(output) != strlen(patc)) {
526 fprintf(stderr, "Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
527 fprintf(stderr, "String '%s' vs '%s'\n", (const char *) output->l2h, patc);
528 abort();
529 }
530
531 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
532 fprintf(stderr, "Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
533 abort();
534 }
535
536 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200537 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200538 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200539}
540
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200541static void test_mgcp_parse(void)
542{
543 int code, ci;
544 char transaction[60];
545
546 fprintf(stderr, "Test MGCP response parsing.\n");
547
548 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
549 fprintf(stderr, "Failed to parse CRCX resp.\n");
550 abort();
551 }
552
553 if (code != 200) {
554 fprintf(stderr, "Failed to parse the CODE properly. Got: %d\n", code);
555 abort();
556 }
557
558 if (strcmp(transaction, "23265295") != 0) {
559 fprintf(stderr, "Failed to parse transaction id: '%s'\n", transaction);
560 abort();
561 }
562
563 ci = bsc_mgcp_extract_ci(crcx_resp);
564 if (ci != 1) {
565 fprintf(stderr, "Failed to parse the CI. Got: %d\n", ci);
566 abort();
567 }
568}
569
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800570struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800571 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800572 int length;
573 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800574 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800575
576 const char *bsc_imsi_allow;
577 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800578 const char *nat_imsi_deny;
579};
580
581static struct cr_filter cr_filter[] = {
582 {
583 .data = bssmap_cr,
584 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800585 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800586 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800587 },
588 {
589 .data = bss_lu,
590 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800591 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800592 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800593 },
594 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800595 .data = pag_resp,
596 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800597 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800598 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800599 },
600 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800601 /* nat deny is before blank/null BSC */
602 .data = bss_lu,
603 .length = sizeof(bss_lu),
604 .result = -3,
605 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800606 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800607 },
608 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800609 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800610 .data = bss_lu,
611 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800612 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800613 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800614 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800615 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800616 },
617 {
618 /* BSC allow is before NAT deny */
619 .data = bss_lu,
620 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800621 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800622 .bsc_imsi_allow = "[0-9]*",
623 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800624 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800625 },
626 {
627 /* filter as deny is first */
628 .data = bss_lu,
629 .length = sizeof(bss_lu),
630 .result = -2,
631 .bsc_imsi_deny = "[0-9]*",
632 .bsc_imsi_allow = "[0-9]*",
633 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800634 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800635 },
636
637};
638
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800639static void test_cr_filter()
640{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800641 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800642 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800643 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800644 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800645 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800646
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800647 struct bsc_nat *nat = bsc_nat_alloc();
648 struct bsc_connection *bsc = bsc_connection_alloc(nat);
649 bsc->cfg = bsc_config_alloc(nat, "foo", 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800650 bsc->cfg->acc_lst_name = "bsc";
651 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800652
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800653 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
654 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
655
656 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
657 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
658
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800659 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
660 msgb_reset(msg);
661 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
662
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800663 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
664 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800665
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800666 bsc_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800667 cr_filter[i].nat_imsi_deny ? 1 : 0,
668 &cr_filter[i].nat_imsi_deny);
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800669 bsc_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800670 cr_filter[i].bsc_imsi_allow ? 1 : 0,
671 &cr_filter[i].bsc_imsi_allow);
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800672 bsc_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800673 cr_filter[i].bsc_imsi_deny ? 1 : 0,
674 &cr_filter[i].bsc_imsi_deny);
675
676 parsed = bsc_nat_parse(msg);
677 if (!parsed) {
678 fprintf(stderr, "FAIL: Failed to parse the message\n");
679 abort();
680 }
681
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800682 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800683 if (res != cr_filter[i].result) {
684 fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
685 abort();
686 }
687
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800688 if (contype != cr_filter[i].contype) {
689 fprintf(stderr, "FAIL: Wrong contype %d for test %d.\n", res, contype);
690 abort();
691 }
692
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800693 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800694 }
695
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800696 msgb_free(msg);
697}
698
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800699int main(int argc, char **argv)
700{
Holger Hans Peter Freyther434a1fd2010-06-15 20:18:40 +0800701 struct log_target *stderr_target;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800702
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +0800703 sccp_set_log_area(DSCCP);
Holger Hans Peter Freytherf0945402010-07-05 13:29:42 +0800704 log_init(&log_info);
Holger Hans Peter Freyther434a1fd2010-06-15 20:18:40 +0800705 stderr_target = log_target_create_stderr();
706 log_add_target(stderr_target);
707 log_set_all_filter(stderr_target, 1);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800708
709 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200710 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200711 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200712 test_mgcp_ass_tracking();
713 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200714 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200715 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800716 test_cr_filter();
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800717 return 0;
718}
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800719
720void input_event()
721{}
722int nm_state_event()
723{
724 return -1;
725}
726