blob: e1a17acc978782b6e6f69fb024e839d0450eccb7 [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 Freyther32685402010-09-15 05:20:40 +080034#include <osmocore/protocol/gsm_08_08.h>
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +080035
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080036#include <stdio.h>
37
38/* test messages for ipa */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080039static uint8_t ipa_id[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080040 0x00, 0x01, 0xfe, 0x06,
41};
42
43/* SCCP messages are below */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080044static uint8_t gsm_reset[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080045 0x00, 0x12, 0xfd,
46 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
47 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
48 0x01, 0x20,
49};
50
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080051static const uint8_t gsm_reset_ack[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080052 0x00, 0x13, 0xfd,
53 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
54 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
55 0x00, 0x01, 0x31,
56};
57
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080058static const uint8_t gsm_paging[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080059 0x00, 0x20, 0xfd,
60 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
61 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10,
62 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10,
63 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06,
64};
65
66/* BSC -> MSC connection open */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080067static const uint8_t bssmap_cr[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080068 0x00, 0x2c, 0xfd,
69 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02,
70 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05,
71 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3,
72 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33,
73 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01,
74 0x31, 0x97, 0x61, 0x00
75};
76
77/* MSC -> BSC connection confirm */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080078static const uint8_t bssmap_cc[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080079 0x00, 0x0a, 0xfd,
80 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
81};
82
83/* MSC -> BSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080084static const uint8_t bssmap_released[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080085 0x00, 0x0e, 0xfd,
86 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f,
87 0x02, 0x23, 0x42, 0x00,
88};
89
90/* BSC -> MSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080091static const uint8_t bssmap_release_complete[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080092 0x00, 0x07, 0xfd,
93 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03
94};
95
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020096/* both directions IT timer */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080097static const uint8_t connnection_it[] = {
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020098 0x00, 0x0b, 0xfd,
99 0x10, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03,
100 0x00, 0x00, 0x00, 0x00,
101};
102
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800103/* error in both directions */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800104static const uint8_t proto_error[] = {
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800105 0x00, 0x05, 0xfd,
106 0x0f, 0x22, 0x33, 0x44, 0x00,
107};
108
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200109/* MGCP wrap... */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800110static const uint8_t mgcp_msg[] = {
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200111 0x00, 0x03, 0xfc,
112 0x20, 0x20, 0x20,
113};
114
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800115/* location updating request */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800116static const uint8_t bss_lu[] = {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800117 0x00, 0x2e, 0xfd,
118 0x01, 0x91, 0x45, 0x14, 0x02, 0x02, 0x04, 0x02,
119 0x42, 0xfe, 0x0f, 0x21, 0x00, 0x1f, 0x57, 0x05,
120 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x14, 0xc3,
121 0x50, 0x17, 0x12, 0x05, 0x08, 0x70, 0x72, 0xf4,
122 0x80, 0xff, 0xfe, 0x30, 0x08, 0x29, 0x44, 0x50,
123 0x12, 0x03, 0x24, 0x01, 0x95, 0x00
124};
125
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800126/* paging response */
127static const uint8_t pag_resp[] = {
128 0x00, 0x2c, 0xfd, 0x01, 0xe5, 0x68,
129 0x14, 0x02, 0x02, 0x04, 0x02, 0x42, 0xfe, 0x0f,
130 0x1f, 0x00, 0x1d, 0x57, 0x05, 0x08, 0x00, 0x72,
131 0xf4, 0x80, 0x20, 0x16, 0xc3, 0x50, 0x17, 0x10,
132 0x06, 0x27, 0x01, 0x03, 0x30, 0x18, 0x96, 0x08,
133 0x29, 0x26, 0x30, 0x32, 0x11, 0x42, 0x01, 0x19,
134 0x00
135};
136
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800137struct filter_result {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800138 const uint8_t *data;
Holger Hans Peter Freythere2c15202010-07-23 19:09:21 +0800139 const uint16_t length;
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100140 const int dir;
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800141 const int result;
142};
143
144static const struct filter_result results[] = {
145 {
146 .data = ipa_id,
147 .length = ARRAY_SIZE(ipa_id),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100148 .dir = DIR_MSC,
149 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800150 },
151 {
152 .data = gsm_reset,
153 .length = ARRAY_SIZE(gsm_reset),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100154 .dir = DIR_MSC,
155 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800156 },
157 {
158 .data = gsm_reset_ack,
159 .length = ARRAY_SIZE(gsm_reset_ack),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100160 .dir = DIR_BSC,
161 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800162 },
163 {
164 .data = gsm_paging,
165 .length = ARRAY_SIZE(gsm_paging),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100166 .dir = DIR_BSC,
167 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800168 },
169 {
170 .data = bssmap_cr,
171 .length = ARRAY_SIZE(bssmap_cr),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100172 .dir = DIR_MSC,
173 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800174 },
175 {
176 .data = bssmap_cc,
177 .length = ARRAY_SIZE(bssmap_cc),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100178 .dir = DIR_BSC,
179 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800180 },
181 {
182 .data = bssmap_released,
183 .length = ARRAY_SIZE(bssmap_released),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100184 .dir = DIR_MSC,
185 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800186 },
187 {
188 .data = bssmap_release_complete,
189 .length = ARRAY_SIZE(bssmap_release_complete),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100190 .dir = DIR_BSC,
191 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800192 },
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200193 {
194 .data = mgcp_msg,
195 .length = ARRAY_SIZE(mgcp_msg),
196 .dir = DIR_MSC,
197 .result = 0,
198 },
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +0200199 {
200 .data = connnection_it,
201 .length = ARRAY_SIZE(connnection_it),
202 .dir = DIR_BSC,
203 .result = 0,
204 },
205 {
206 .data = connnection_it,
207 .length = ARRAY_SIZE(connnection_it),
208 .dir = DIR_MSC,
209 .result = 0,
210 },
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800211 {
212 .data = proto_error,
213 .length = ARRAY_SIZE(proto_error),
214 .dir = DIR_BSC,
215 .result = 0,
216 },
217 {
218 .data = proto_error,
219 .length = ARRAY_SIZE(proto_error),
220 .dir = DIR_MSC,
221 .result = 0,
222 },
223
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800224};
225
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800226static void test_filter(void)
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800227{
228 int i;
229
230
231 /* start testinh with proper messages */
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800232 fprintf(stderr, "Testing BSS Filtering.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800233 for (i = 0; i < ARRAY_SIZE(results); ++i) {
234 int result;
235 struct bsc_nat_parsed *parsed;
236 struct msgb *msg = msgb_alloc(4096, "test-message");
237
238 fprintf(stderr, "Going to test item: %d\n", i);
239 memcpy(msg->data, results[i].data, results[i].length);
240 msg->l2h = msgb_put(msg, results[i].length);
241
242 parsed = bsc_nat_parse(msg);
243 if (!parsed) {
244 fprintf(stderr, "FAIL: Failed to parse the message\n");
245 continue;
246 }
247
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100248 result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800249 if (result != results[i].result) {
250 fprintf(stderr, "FAIL: Not the expected result got: %d wanted: %d\n",
251 result, results[i].result);
252 }
253
254 msgb_free(msg);
255 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800256}
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800257
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800258#include "bsc_data.c"
259
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800260static void copy_to_msg(struct msgb *msg, const uint8_t *data, unsigned int length)
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800261{
262 msgb_reset(msg);
263 msg->l2h = msgb_put(msg, length);
264 memcpy(msg->l2h, data, msgb_l2len(msg));
265}
266
267#define VERIFY(con_found, con, msg, ver, str) \
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800268 if (!con_found || con_found->bsc != con) { \
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800269 fprintf(stderr, "Failed to find the con: %p\n", con_found); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800270 abort(); \
271 } \
272 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
273 fprintf(stderr, "Failed to patch the %s msg.\n", str); \
274 abort(); \
275 }
276
277/* test conn tracking once */
278static void test_contrack()
279{
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800280 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800281 struct bsc_connection *con;
282 struct sccp_connections *con_found;
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800283 struct sccp_connections *rc_con;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800284 struct bsc_nat_parsed *parsed;
285 struct msgb *msg;
286
287 fprintf(stderr, "Testing connection tracking.\n");
288 nat = bsc_nat_alloc();
289 con = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc87c8b72010-04-18 02:30:57 +0800290 con->cfg = bsc_config_alloc(nat, "foo", 23);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800291 msg = msgb_alloc(4096, "test");
292
293 /* 1.) create a connection */
294 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
295 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800296 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800297 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800298 fprintf(stderr, "Con should not exist %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800299 abort();
300 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800301 rc_con = create_sccp_src_ref(con, parsed);
302 if (!rc_con) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800303 fprintf(stderr, "Failed to create a ref\n");
304 abort();
305 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800306 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800307 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800308 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800309 abort();
310 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800311 if (con_found != rc_con) {
312 fprintf(stderr, "Failed to find the right connection.\n");
313 abort();
314 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800315 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
316 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
317 abort();
318 }
319 talloc_free(parsed);
320
321 /* 2.) get the cc */
322 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
323 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800324 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
325 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
326 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800327 fprintf(stderr, "Failed to update the SCCP con.\n");
328 abort();
329 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800330
331 /* 3.) send some data */
332 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
333 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800334 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800335 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
336
337 /* 4.) receive some data */
338 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
339 parsed = bsc_nat_parse(msg);
340 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
341 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
342
343 /* 5.) close the connection */
344 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
345 parsed = bsc_nat_parse(msg);
346 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
347 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
348
349 /* 6.) confirm the connection close */
350 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
351 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800352 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800353 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800354 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800355 abort();
356 }
357 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
358 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
359 abort();
360 }
361 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200362 talloc_free(parsed);
363
364 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
365 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800366 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800367
368 /* verify that it is gone */
369 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800370 fprintf(stderr, "Con should be gone. %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800371 abort();
372 }
373 talloc_free(parsed);
374
375
376 talloc_free(nat);
377 msgb_free(msg);
378}
379
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200380static void test_paging(void)
381{
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200382 int lac;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200383 struct bsc_nat *nat;
384 struct bsc_connection *con;
385 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200386 struct bsc_config cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200387 struct msgb *msg;
388
389 fprintf(stderr, "Testing paging by lac.\n");
390
391 nat = bsc_nat_alloc();
392 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200393 con->cfg = &cfg;
394 cfg.lac = 23;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200395 con->authenticated = 1;
396 llist_add(&con->list_entry, &nat->bsc_connections);
397 msg = msgb_alloc(4096, "test");
398
399 /* Test completely bad input */
400 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200401 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200402 fprintf(stderr, "Should have not found anything.\n");
403 abort();
404 }
405
406 /* Test it by not finding it */
407 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
408 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200409 if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200410 fprintf(stderr, "Should have not found aynthing.\n");
411 abort();
412 }
413 talloc_free(parsed);
414
415 /* Test by finding it */
Holger Hans Peter Freyther47dd4942010-04-06 15:11:34 +0200416 cfg.lac = 8213;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200417 copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
418 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther979a3092010-04-17 08:07:19 +0200419 if (bsc_nat_find_bsc(nat, msg, &lac) != con) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200420 fprintf(stderr, "Should have found it.\n");
421 abort();
422 }
423 talloc_free(parsed);
424}
425
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200426static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800427{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800428 struct bsc_connection *bsc;
429 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800430 struct sccp_connections con;
431 struct bsc_nat_parsed *parsed;
432 struct msgb *msg;
433
434 fprintf(stderr, "Testing MGCP.\n");
435 memset(&con, 0, sizeof(con));
436
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800437 nat = bsc_nat_alloc();
438 nat->bsc_endpoints = talloc_zero_array(nat,
439 struct bsc_endpoint,
440 33);
441 bsc = bsc_connection_alloc(nat);
442 bsc->cfg = bsc_config_alloc(nat, "foo", 2323);
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800443 bsc->last_endpoint = 0x1a;
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800444 con.bsc = bsc;
445
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800446 msg = msgb_alloc(4096, "foo");
447 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
448 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800449 if (bsc_mgcp_assign_patch(&con, msg) != 0) {
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800450 fprintf(stderr, "Failed to handle assignment.\n");
451 abort();
452 }
453
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800454 if (con.msc_endp != 21) {
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800455 fprintf(stderr, "Timeslot should be 21.\n");
456 abort();
457 }
458
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800459 if (con.bsc_endp != 0x1b) {
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800460 fprintf(stderr, "Assigned timeslot should have been 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800461 abort();
462 }
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800463 if (con.bsc->endpoint_status[0x1b] != 1) {
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800464 fprintf(stderr, "The status on the BSC is wrong.\n");
465 abort();
466 }
467
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800468 talloc_free(parsed);
469
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800470 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800471 if (con.bsc_endp != -1 || con.msc_endp != -1 ||
472 con.bsc->endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1b) {
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800473 fprintf(stderr, "Clearing should remove the mapping.\n");
474 abort();
475 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800476
477 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800478}
479
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200480/* test the code to find a given connection */
481static void test_mgcp_find(void)
482{
483 struct bsc_nat *nat;
484 struct bsc_connection *con;
485 struct sccp_connections *sccp_con;
486
487 fprintf(stderr, "Testing finding of a BSC Connection\n");
488
489 nat = bsc_nat_alloc();
490 con = bsc_connection_alloc(nat);
491 llist_add(&con->list_entry, &nat->bsc_connections);
492
493 sccp_con = talloc_zero(con, struct sccp_connections);
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800494 sccp_con->msc_endp = 12;
495 sccp_con->bsc_endp = 12;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200496 sccp_con->bsc = con;
497 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
498
499 if (bsc_mgcp_find_con(nat, 11) != NULL) {
500 fprintf(stderr, "Found the wrong connection.\n");
501 abort();
502 }
503
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800504 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200505 fprintf(stderr, "Didn't find the connection\n");
506 abort();
507 }
508
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200509 /* free everything */
510 talloc_free(nat);
511}
512
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200513static void test_mgcp_rewrite(void)
514{
515 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200516 struct msgb *output;
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200517 fprintf(stderr, "Test rewriting MGCP messages.\n");
518
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200519 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
520 const char *orig = mgcp_messages[i].orig;
521 const char *patc = mgcp_messages[i].patch;
522 const char *ip = mgcp_messages[i].ip;
523 const int port = mgcp_messages[i].port;
524
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200525 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200526
Holger Hans Peter Freytherf7c86c52010-08-30 13:44:32 +0800527 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200528 if (msgb_l2len(output) != strlen(patc)) {
529 fprintf(stderr, "Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
530 fprintf(stderr, "String '%s' vs '%s'\n", (const char *) output->l2h, patc);
531 abort();
532 }
533
534 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
535 fprintf(stderr, "Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
536 abort();
537 }
538
539 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200540 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200541 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200542}
543
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200544static void test_mgcp_parse(void)
545{
546 int code, ci;
547 char transaction[60];
548
549 fprintf(stderr, "Test MGCP response parsing.\n");
550
551 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
552 fprintf(stderr, "Failed to parse CRCX resp.\n");
553 abort();
554 }
555
556 if (code != 200) {
557 fprintf(stderr, "Failed to parse the CODE properly. Got: %d\n", code);
558 abort();
559 }
560
561 if (strcmp(transaction, "23265295") != 0) {
562 fprintf(stderr, "Failed to parse transaction id: '%s'\n", transaction);
563 abort();
564 }
565
566 ci = bsc_mgcp_extract_ci(crcx_resp);
567 if (ci != 1) {
568 fprintf(stderr, "Failed to parse the CI. Got: %d\n", ci);
569 abort();
570 }
571}
572
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800573struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800574 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800575 int length;
576 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800577 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800578
579 const char *bsc_imsi_allow;
580 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800581 const char *nat_imsi_deny;
582};
583
584static struct cr_filter cr_filter[] = {
585 {
586 .data = bssmap_cr,
587 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800588 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800589 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800590 },
591 {
592 .data = bss_lu,
593 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800594 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800595 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800596 },
597 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800598 .data = pag_resp,
599 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800600 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800601 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800602 },
603 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800604 /* nat deny is before blank/null BSC */
605 .data = bss_lu,
606 .length = sizeof(bss_lu),
607 .result = -3,
608 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800609 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800610 },
611 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800612 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800613 .data = bss_lu,
614 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800615 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800616 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800617 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800618 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800619 },
620 {
621 /* BSC allow is before NAT deny */
622 .data = bss_lu,
623 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800624 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800625 .bsc_imsi_allow = "[0-9]*",
626 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800627 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800628 },
629 {
630 /* filter as deny is first */
631 .data = bss_lu,
632 .length = sizeof(bss_lu),
633 .result = -2,
634 .bsc_imsi_deny = "[0-9]*",
635 .bsc_imsi_allow = "[0-9]*",
636 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800637 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800638 },
639
640};
641
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800642static void test_cr_filter()
643{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800644 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800645 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800646 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800647 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800648 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800649
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800650 struct bsc_nat *nat = bsc_nat_alloc();
651 struct bsc_connection *bsc = bsc_connection_alloc(nat);
652 bsc->cfg = bsc_config_alloc(nat, "foo", 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800653 bsc->cfg->acc_lst_name = "bsc";
654 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800655
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800656 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
657 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
658
659 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
660 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
661
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800662 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
663 msgb_reset(msg);
664 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
665
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800666 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
667 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800668
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800669 bsc_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800670 cr_filter[i].nat_imsi_deny ? 1 : 0,
671 &cr_filter[i].nat_imsi_deny);
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800672 bsc_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800673 cr_filter[i].bsc_imsi_allow ? 1 : 0,
674 &cr_filter[i].bsc_imsi_allow);
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800675 bsc_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800676 cr_filter[i].bsc_imsi_deny ? 1 : 0,
677 &cr_filter[i].bsc_imsi_deny);
678
679 parsed = bsc_nat_parse(msg);
680 if (!parsed) {
681 fprintf(stderr, "FAIL: Failed to parse the message\n");
682 abort();
683 }
684
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800685 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800686 if (res != cr_filter[i].result) {
687 fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
688 abort();
689 }
690
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800691 if (contype != cr_filter[i].contype) {
692 fprintf(stderr, "FAIL: Wrong contype %d for test %d.\n", res, contype);
693 abort();
694 }
695
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800696 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800697 }
698
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800699 msgb_free(msg);
700}
701
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800702static void test_dt_filter()
703{
704 int i;
705 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
706 struct bsc_nat_parsed *parsed;
707
708 struct bsc_nat *nat = bsc_nat_alloc();
709 struct bsc_connection *bsc = bsc_connection_alloc(nat);
710 struct sccp_connections *con = talloc_zero(0, struct sccp_connections);
711
712 bsc->cfg = bsc_config_alloc(nat, "foo", 23);
713 con->bsc = bsc;
714
715 msgb_reset(msg);
716 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
717
718 parsed = bsc_nat_parse(msg);
719 if (!parsed) {
720 fprintf(stderr, "FAIL: Could not parse ID resp\n");
721 abort();
722 }
723
724 if (parsed->bssap != BSSAP_MSG_DTAP) {
725 fprintf(stderr, "FAIL: It should be dtap\n");
726 abort();
727 }
728
729 /* gsm_type is actually the size of the dtap */
730 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
731 fprintf(stderr, "FAIL: Not enough space for the content\n");
732 abort();
733 }
734
735 if (bsc_nat_filter_dt(bsc, msg, con, parsed) != 1) {
736 fprintf(stderr, "FAIL: Should have passed..\n");
737 abort();
738 }
739
740 /* just some basic length checking... */
741 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
742 msgb_reset(msg);
743 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
744
745 parsed = bsc_nat_parse(msg);
746 if (!parsed)
747 continue;
748
749 con->imsi_checked = 0;
750 bsc_nat_filter_dt(bsc, msg, con, parsed);
751 }
752}
753
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800754int main(int argc, char **argv)
755{
Holger Hans Peter Freyther434a1fd2010-06-15 20:18:40 +0800756 struct log_target *stderr_target;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800757
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +0800758 sccp_set_log_area(DSCCP);
Holger Hans Peter Freytherf0945402010-07-05 13:29:42 +0800759 log_init(&log_info);
Holger Hans Peter Freyther434a1fd2010-06-15 20:18:40 +0800760 stderr_target = log_target_create_stderr();
761 log_add_target(stderr_target);
762 log_set_all_filter(stderr_target, 1);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800763
764 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200765 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200766 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200767 test_mgcp_ass_tracking();
768 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200769 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200770 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800771 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800772 test_dt_filter();
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800773 return 0;
774}
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800775
776void input_event()
777{}
778int nm_state_event()
779{
780 return -1;
781}
782