blob: 1b45014b5cf8b57cff0381f8714baaebb2ca542a [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 Freyther30e1ae92010-07-30 02:53:14 +080032#include <sccp/sccp.h>
33
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080034#include <stdio.h>
35
36/* test messages for ipa */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080037static uint8_t ipa_id[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080038 0x00, 0x01, 0xfe, 0x06,
39};
40
41/* SCCP messages are below */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080042static uint8_t gsm_reset[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080043 0x00, 0x12, 0xfd,
44 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
45 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
46 0x01, 0x20,
47};
48
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080049static const uint8_t gsm_reset_ack[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080050 0x00, 0x13, 0xfd,
51 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
52 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
53 0x00, 0x01, 0x31,
54};
55
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080056static const uint8_t gsm_paging[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080057 0x00, 0x20, 0xfd,
58 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
59 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10,
60 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10,
61 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06,
62};
63
64/* BSC -> MSC connection open */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080065static const uint8_t bssmap_cr[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080066 0x00, 0x2c, 0xfd,
67 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02,
68 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05,
69 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3,
70 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33,
71 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01,
72 0x31, 0x97, 0x61, 0x00
73};
74
75/* MSC -> BSC connection confirm */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080076static const uint8_t bssmap_cc[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080077 0x00, 0x0a, 0xfd,
78 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
79};
80
81/* MSC -> BSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080082static const uint8_t bssmap_released[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080083 0x00, 0x0e, 0xfd,
84 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f,
85 0x02, 0x23, 0x42, 0x00,
86};
87
88/* BSC -> MSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080089static const uint8_t bssmap_release_complete[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080090 0x00, 0x07, 0xfd,
91 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03
92};
93
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020094/* both directions IT timer */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080095static const uint8_t connnection_it[] = {
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020096 0x00, 0x0b, 0xfd,
97 0x10, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03,
98 0x00, 0x00, 0x00, 0x00,
99};
100
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800101/* error in both directions */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800102static const uint8_t proto_error[] = {
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800103 0x00, 0x05, 0xfd,
104 0x0f, 0x22, 0x33, 0x44, 0x00,
105};
106
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200107/* MGCP wrap... */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800108static const uint8_t mgcp_msg[] = {
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200109 0x00, 0x03, 0xfc,
110 0x20, 0x20, 0x20,
111};
112
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800113/* location updating request */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800114static const uint8_t bss_lu[] = {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800115 0x00, 0x2e, 0xfd,
116 0x01, 0x91, 0x45, 0x14, 0x02, 0x02, 0x04, 0x02,
117 0x42, 0xfe, 0x0f, 0x21, 0x00, 0x1f, 0x57, 0x05,
118 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x14, 0xc3,
119 0x50, 0x17, 0x12, 0x05, 0x08, 0x70, 0x72, 0xf4,
120 0x80, 0xff, 0xfe, 0x30, 0x08, 0x29, 0x44, 0x50,
121 0x12, 0x03, 0x24, 0x01, 0x95, 0x00
122};
123
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800124/* paging response */
125static const uint8_t pag_resp[] = {
126 0x00, 0x2c, 0xfd, 0x01, 0xe5, 0x68,
127 0x14, 0x02, 0x02, 0x04, 0x02, 0x42, 0xfe, 0x0f,
128 0x1f, 0x00, 0x1d, 0x57, 0x05, 0x08, 0x00, 0x72,
129 0xf4, 0x80, 0x20, 0x16, 0xc3, 0x50, 0x17, 0x10,
130 0x06, 0x27, 0x01, 0x03, 0x30, 0x18, 0x96, 0x08,
131 0x29, 0x26, 0x30, 0x32, 0x11, 0x42, 0x01, 0x19,
132 0x00
133};
134
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800135struct filter_result {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800136 const uint8_t *data;
Holger Hans Peter Freythere2c15202010-07-23 19:09:21 +0800137 const uint16_t length;
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100138 const int dir;
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800139 const int result;
140};
141
142static const struct filter_result results[] = {
143 {
144 .data = ipa_id,
145 .length = ARRAY_SIZE(ipa_id),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100146 .dir = DIR_MSC,
147 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800148 },
149 {
150 .data = gsm_reset,
151 .length = ARRAY_SIZE(gsm_reset),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100152 .dir = DIR_MSC,
153 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800154 },
155 {
156 .data = gsm_reset_ack,
157 .length = ARRAY_SIZE(gsm_reset_ack),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100158 .dir = DIR_BSC,
159 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800160 },
161 {
162 .data = gsm_paging,
163 .length = ARRAY_SIZE(gsm_paging),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100164 .dir = DIR_BSC,
165 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800166 },
167 {
168 .data = bssmap_cr,
169 .length = ARRAY_SIZE(bssmap_cr),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100170 .dir = DIR_MSC,
171 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800172 },
173 {
174 .data = bssmap_cc,
175 .length = ARRAY_SIZE(bssmap_cc),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100176 .dir = DIR_BSC,
177 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800178 },
179 {
180 .data = bssmap_released,
181 .length = ARRAY_SIZE(bssmap_released),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100182 .dir = DIR_MSC,
183 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800184 },
185 {
186 .data = bssmap_release_complete,
187 .length = ARRAY_SIZE(bssmap_release_complete),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100188 .dir = DIR_BSC,
189 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800190 },
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200191 {
192 .data = mgcp_msg,
193 .length = ARRAY_SIZE(mgcp_msg),
194 .dir = DIR_MSC,
195 .result = 0,
196 },
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +0200197 {
198 .data = connnection_it,
199 .length = ARRAY_SIZE(connnection_it),
200 .dir = DIR_BSC,
201 .result = 0,
202 },
203 {
204 .data = connnection_it,
205 .length = ARRAY_SIZE(connnection_it),
206 .dir = DIR_MSC,
207 .result = 0,
208 },
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800209 {
210 .data = proto_error,
211 .length = ARRAY_SIZE(proto_error),
212 .dir = DIR_BSC,
213 .result = 0,
214 },
215 {
216 .data = proto_error,
217 .length = ARRAY_SIZE(proto_error),
218 .dir = DIR_MSC,
219 .result = 0,
220 },
221
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800222};
223
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800224static void test_filter(void)
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800225{
226 int i;
227
228
229 /* start testinh with proper messages */
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800230 fprintf(stderr, "Testing BSS Filtering.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800231 for (i = 0; i < ARRAY_SIZE(results); ++i) {
232 int result;
233 struct bsc_nat_parsed *parsed;
234 struct msgb *msg = msgb_alloc(4096, "test-message");
235
236 fprintf(stderr, "Going to test item: %d\n", i);
237 memcpy(msg->data, results[i].data, results[i].length);
238 msg->l2h = msgb_put(msg, results[i].length);
239
240 parsed = bsc_nat_parse(msg);
241 if (!parsed) {
242 fprintf(stderr, "FAIL: Failed to parse the message\n");
243 continue;
244 }
245
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100246 result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800247 if (result != results[i].result) {
248 fprintf(stderr, "FAIL: Not the expected result got: %d wanted: %d\n",
249 result, results[i].result);
250 }
251
252 msgb_free(msg);
253 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800254}
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800255
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800256#include "bsc_data.c"
257
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800258static void copy_to_msg(struct msgb *msg, const uint8_t *data, unsigned int length)
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800259{
260 msgb_reset(msg);
261 msg->l2h = msgb_put(msg, length);
262 memcpy(msg->l2h, data, msgb_l2len(msg));
263}
264
265#define VERIFY(con_found, con, msg, ver, str) \
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800266 if (!con_found || con_found->bsc != con) { \
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800267 fprintf(stderr, "Failed to find the con: %p\n", con_found); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800268 abort(); \
269 } \
270 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
271 fprintf(stderr, "Failed to patch the %s msg.\n", str); \
272 abort(); \
273 }
274
275/* test conn tracking once */
276static void test_contrack()
277{
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800278 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800279 struct bsc_connection *con;
280 struct sccp_connections *con_found;
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800281 struct sccp_connections *rc_con;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800282 struct bsc_nat_parsed *parsed;
283 struct msgb *msg;
284
285 fprintf(stderr, "Testing connection tracking.\n");
286 nat = bsc_nat_alloc();
287 con = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc87c8b72010-04-18 02:30:57 +0800288 con->cfg = bsc_config_alloc(nat, "foo", 23);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800289 msg = msgb_alloc(4096, "test");
290
291 /* 1.) create a connection */
292 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
293 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800294 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800295 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800296 fprintf(stderr, "Con should not exist %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800297 abort();
298 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800299 rc_con = create_sccp_src_ref(con, parsed);
300 if (!rc_con) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800301 fprintf(stderr, "Failed to create a ref\n");
302 abort();
303 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800304 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800305 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800306 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800307 abort();
308 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800309 if (con_found != rc_con) {
310 fprintf(stderr, "Failed to find the right connection.\n");
311 abort();
312 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800313 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
314 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
315 abort();
316 }
317 talloc_free(parsed);
318
319 /* 2.) get the cc */
320 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
321 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800322 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
323 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
324 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800325 fprintf(stderr, "Failed to update the SCCP con.\n");
326 abort();
327 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800328
329 /* 3.) send some data */
330 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
331 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800332 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800333 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
334
335 /* 4.) receive some data */
336 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
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_dtap_patched, "MSC DTAP");
340
341 /* 5.) close the connection */
342 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
343 parsed = bsc_nat_parse(msg);
344 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
345 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
346
347 /* 6.) confirm the connection close */
348 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
349 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800350 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800351 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800352 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800353 abort();
354 }
355 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
356 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
357 abort();
358 }
359 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200360 talloc_free(parsed);
361
362 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
363 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800364 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800365
366 /* verify that it is gone */
367 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800368 fprintf(stderr, "Con should be gone. %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800369 abort();
370 }
371 talloc_free(parsed);
372
373
374 talloc_free(nat);
375 msgb_free(msg);
376}
377
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200378static void test_paging(void)
379{
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200380 int lac;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200381 struct bsc_nat *nat;
382 struct bsc_connection *con;
383 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200384 struct bsc_config cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200385 struct msgb *msg;
386
387 fprintf(stderr, "Testing paging by lac.\n");
388
389 nat = bsc_nat_alloc();
390 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200391 con->cfg = &cfg;
392 cfg.lac = 23;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200393 con->authenticated = 1;
394 llist_add(&con->list_entry, &nat->bsc_connections);
395 msg = msgb_alloc(4096, "test");
396
397 /* Test completely bad input */
398 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200399 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200400 fprintf(stderr, "Should have not found anything.\n");
401 abort();
402 }
403
404 /* Test it by not finding it */
405 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
406 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200407 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200408 fprintf(stderr, "Should have not found aynthing.\n");
409 abort();
410 }
411 talloc_free(parsed);
412
413 /* Test by finding it */
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200414 cfg.lac = 8213;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200415 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
416 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200417 if (bsc_nat_find_bsc(nat, msg, &lac) != con) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200418 fprintf(stderr, "Should have found it.\n");
419 abort();
420 }
421 talloc_free(parsed);
422}
423
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200424static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800425{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800426 struct bsc_connection *bsc;
427 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800428 struct sccp_connections con;
429 struct bsc_nat_parsed *parsed;
430 struct msgb *msg;
431
432 fprintf(stderr, "Testing MGCP.\n");
433 memset(&con, 0, sizeof(con));
434
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800435 nat = bsc_nat_alloc();
436 nat->bsc_endpoints = talloc_zero_array(nat,
437 struct bsc_endpoint,
438 33);
439 bsc = bsc_connection_alloc(nat);
440 bsc->cfg = bsc_config_alloc(nat, "foo", 2323);
441 con.bsc = bsc;
442
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800443 msg = msgb_alloc(4096, "foo");
444 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
445 parsed = bsc_nat_parse(msg);
446 if (bsc_mgcp_assign(&con, msg) != 0) {
447 fprintf(stderr, "Failed to handle assignment.\n");
448 abort();
449 }
450
451 if (con.msc_timeslot != 21) {
452 fprintf(stderr, "Timeslot should be 21.\n");
453 abort();
454 }
455
456 if (con.bsc_timeslot != 21) {
457 fprintf(stderr, "Assigned timeslot should have been 21.\n");
458 abort();
459 }
460 talloc_free(parsed);
461
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800462 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800463 if (con.bsc_timeslot != -1 || con.msc_timeslot != -1) {
464 fprintf(stderr, "Clearing should remove the mapping.\n");
465 abort();
466 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800467
468 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800469}
470
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200471/* test the code to find a given connection */
472static void test_mgcp_find(void)
473{
474 struct bsc_nat *nat;
475 struct bsc_connection *con;
476 struct sccp_connections *sccp_con;
477
478 fprintf(stderr, "Testing finding of a BSC Connection\n");
479
480 nat = bsc_nat_alloc();
481 con = bsc_connection_alloc(nat);
482 llist_add(&con->list_entry, &nat->bsc_connections);
483
484 sccp_con = talloc_zero(con, struct sccp_connections);
485 sccp_con->msc_timeslot = 12;
486 sccp_con->bsc_timeslot = 12;
487 sccp_con->bsc = con;
488 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
489
490 if (bsc_mgcp_find_con(nat, 11) != NULL) {
491 fprintf(stderr, "Found the wrong connection.\n");
492 abort();
493 }
494
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800495 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200496 fprintf(stderr, "Didn't find the connection\n");
497 abort();
498 }
499
500 sccp_con->msc_timeslot = 0;
501 sccp_con->bsc_timeslot = 0;
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800502 if (bsc_mgcp_find_con(nat, 1) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200503 fprintf(stderr, "Didn't find the connection\n");
504 abort();
505 }
506
507 /* free everything */
508 talloc_free(nat);
509}
510
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200511static void test_mgcp_rewrite(void)
512{
513 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200514 struct msgb *output;
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200515 fprintf(stderr, "Test rewriting MGCP messages.\n");
516
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200517 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
518 const char *orig = mgcp_messages[i].orig;
519 const char *patc = mgcp_messages[i].patch;
520 const char *ip = mgcp_messages[i].ip;
521 const int port = mgcp_messages[i].port;
522
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200523 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200524
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200525 output = bsc_mgcp_rewrite(input, strlen(input), ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200526 if (msgb_l2len(output) != strlen(patc)) {
527 fprintf(stderr, "Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
528 fprintf(stderr, "String '%s' vs '%s'\n", (const char *) output->l2h, patc);
529 abort();
530 }
531
532 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
533 fprintf(stderr, "Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
534 abort();
535 }
536
537 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200538 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200539 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200540}
541
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200542static void test_mgcp_parse(void)
543{
544 int code, ci;
545 char transaction[60];
546
547 fprintf(stderr, "Test MGCP response parsing.\n");
548
549 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
550 fprintf(stderr, "Failed to parse CRCX resp.\n");
551 abort();
552 }
553
554 if (code != 200) {
555 fprintf(stderr, "Failed to parse the CODE properly. Got: %d\n", code);
556 abort();
557 }
558
559 if (strcmp(transaction, "23265295") != 0) {
560 fprintf(stderr, "Failed to parse transaction id: '%s'\n", transaction);
561 abort();
562 }
563
564 ci = bsc_mgcp_extract_ci(crcx_resp);
565 if (ci != 1) {
566 fprintf(stderr, "Failed to parse the CI. Got: %d\n", ci);
567 abort();
568 }
569}
570
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800571struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800572 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800573 int length;
574 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800575 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800576
577 const char *bsc_imsi_allow;
578 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800579 const char *nat_imsi_deny;
580};
581
582static struct cr_filter cr_filter[] = {
583 {
584 .data = bssmap_cr,
585 .length = sizeof(bssmap_cr),
586 .result = 0,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800587 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800588 },
589 {
590 .data = bss_lu,
591 .length = sizeof(bss_lu),
592 .result = 0,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800593 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800594 },
595 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800596 .data = pag_resp,
597 .length = sizeof(pag_resp),
598 .result = 0,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800599 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800600 },
601 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800602 /* nat deny is before blank/null BSC */
603 .data = bss_lu,
604 .length = sizeof(bss_lu),
605 .result = -3,
606 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800607 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800608 },
609 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800610 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800611 .data = bss_lu,
612 .length = sizeof(bss_lu),
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800613 .result = 0,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800614 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800615 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800616 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800617 },
618 {
619 /* BSC allow is before NAT deny */
620 .data = bss_lu,
621 .length = sizeof(bss_lu),
622 .result = 0,
623 .bsc_imsi_allow = "[0-9]*",
624 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800625 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800626 },
627 {
628 /* filter as deny is first */
629 .data = bss_lu,
630 .length = sizeof(bss_lu),
631 .result = -2,
632 .bsc_imsi_deny = "[0-9]*",
633 .bsc_imsi_allow = "[0-9]*",
634 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800635 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800636 },
637
638};
639
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800640static void test_cr_filter()
641{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800642 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800643 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800644 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800645 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800646 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800647
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800648 struct bsc_nat *nat = bsc_nat_alloc();
649 struct bsc_connection *bsc = bsc_connection_alloc(nat);
650 bsc->cfg = bsc_config_alloc(nat, "foo", 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800651 bsc->cfg->acc_lst_name = "bsc";
652 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800653
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800654 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
655 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
656
657 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
658 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
659
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800660 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
661 msgb_reset(msg);
662 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
663
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800664 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
665 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800666
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800667 bsc_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800668 cr_filter[i].nat_imsi_deny ? 1 : 0,
669 &cr_filter[i].nat_imsi_deny);
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800670 bsc_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800671 cr_filter[i].bsc_imsi_allow ? 1 : 0,
672 &cr_filter[i].bsc_imsi_allow);
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800673 bsc_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800674 cr_filter[i].bsc_imsi_deny ? 1 : 0,
675 &cr_filter[i].bsc_imsi_deny);
676
677 parsed = bsc_nat_parse(msg);
678 if (!parsed) {
679 fprintf(stderr, "FAIL: Failed to parse the message\n");
680 abort();
681 }
682
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800683 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800684 if (res != cr_filter[i].result) {
685 fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
686 abort();
687 }
688
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800689 if (contype != cr_filter[i].contype) {
690 fprintf(stderr, "FAIL: Wrong contype %d for test %d.\n", res, contype);
691 abort();
692 }
693
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800694 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800695 }
696
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800697 msgb_free(msg);
698}
699
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800700int main(int argc, char **argv)
701{
Holger Hans Peter Freyther434a1fd2010-06-15 20:18:40 +0800702 struct log_target *stderr_target;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800703
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +0800704 sccp_set_log_area(DSCCP);
Holger Hans Peter Freytherf0945402010-07-05 13:29:42 +0800705 log_init(&log_info);
Holger Hans Peter Freyther434a1fd2010-06-15 20:18:40 +0800706 stderr_target = log_target_create_stderr();
707 log_add_target(stderr_target);
708 log_set_all_filter(stderr_target, 1);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800709
710 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200711 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200712 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200713 test_mgcp_ass_tracking();
714 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200715 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200716 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800717 test_cr_filter();
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800718 return 0;
719}
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800720
721void input_event()
722{}
723int nm_state_event()
724{
725 return -1;
726}
727