blob: 31e8cd1b33a5bdad50df541425cef07ee173f20a [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
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080012 * (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 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080021 *
22 */
23
24
25#include <openbsc/debug.h>
26#include <openbsc/gsm_data.h>
27#include <openbsc/bsc_nat.h>
Holger Hans Peter Freytherc2b31ed2010-07-31 05:17:17 +080028#include <openbsc/bsc_nat_sccp.h>
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080029
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +020030#include <osmocom/core/application.h>
Pablo Neira Ayuso928cb332011-03-26 22:08:53 +010031#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +080032
Harald Welted5db12c2010-08-03 15:11:51 +020033#include <osmocom/sccp/sccp.h>
Pablo Neira Ayuso928cb332011-03-26 22:08:53 +010034#include <osmocom/gsm/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 Freytherf5ede522012-01-06 13:56:12 +0100232 printf("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
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100238 printf("Going to test item: %d\n", i);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800239 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) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100244 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800245 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) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100250 printf("FAIL: Not the expected result got: %d wanted: %d\n",
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800251 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 Freytherf5ede522012-01-06 13:56:12 +0100268 if (!con_found) { \
269 printf("Failed to find connection.\n"); \
270 abort(); \
271 } \
272 if (con_found->bsc != con) { \
273 printf("Got connection of the wrong BSC: %d\n", \
274 con_found->bsc->cfg->nr); \
275 abort(); \
276 } \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800277 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100278 printf("Failed to patch the %s msg.\n", str); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800279 abort(); \
280 }
281
282/* test conn tracking once */
283static void test_contrack()
284{
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800285 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800286 struct bsc_connection *con;
287 struct sccp_connections *con_found;
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800288 struct sccp_connections *rc_con;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800289 struct bsc_nat_parsed *parsed;
290 struct msgb *msg;
291
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100292 printf("Testing connection tracking.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800293 nat = bsc_nat_alloc();
294 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800295 con->cfg = bsc_config_alloc(nat, "foo");
296 bsc_config_add_lac(con->cfg, 23);
297 bsc_config_add_lac(con->cfg, 49);
298 bsc_config_add_lac(con->cfg, 42);
299 bsc_config_del_lac(con->cfg, 49);
300 bsc_config_add_lac(con->cfg, 1111);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800301 msg = msgb_alloc(4096, "test");
302
303 /* 1.) create a connection */
304 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
305 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800306 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800307 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100308 printf("Con should not exist realref(%u)\n",
309 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800310 abort();
311 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800312 rc_con = create_sccp_src_ref(con, parsed);
313 if (!rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100314 printf("Failed to create a ref\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800315 abort();
316 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800317 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100318 if (!con_found) {
319 printf("Failed to find connection.\n");
320 abort();
321 }
322 if (con_found->bsc != con) {
323 printf("Got connection of the wrong BSC: %d\n",
324 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800325 abort();
326 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800327 if (con_found != rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100328 printf("Failed to find the right connection.\n");
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800329 abort();
330 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800331 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100332 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800333 abort();
334 }
335 talloc_free(parsed);
336
337 /* 2.) get the cc */
338 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
339 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800340 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
341 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
342 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100343 printf("Failed to update the SCCP con.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800344 abort();
345 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800346
347 /* 3.) send some data */
348 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
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 Freyther38f7c752010-06-15 18:48:36 +0800351 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
352
353 /* 4.) receive some data */
354 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
355 parsed = bsc_nat_parse(msg);
356 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
357 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
358
359 /* 5.) close the connection */
360 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
361 parsed = bsc_nat_parse(msg);
362 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
363 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
364
365 /* 6.) confirm the connection close */
366 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
367 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800368 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100369 if (!con_found) {
370 printf("Failed to find connection.\n");
371 abort();
372 }
373 if (con_found->bsc != con) {
374 printf("Got connection of the wrong BSC: %d\n",
375 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800376 abort();
377 }
378 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100379 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800380 abort();
381 }
382 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200383 talloc_free(parsed);
384
385 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
386 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800387 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800388
389 /* verify that it is gone */
390 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100391 printf("Con should not exist real_ref(%u)\n",
392 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800393 abort();
394 }
395 talloc_free(parsed);
396
397
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100398 bsc_config_free(con->cfg);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800399 talloc_free(nat);
400 msgb_free(msg);
401}
402
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200403static void test_paging(void)
404{
405 struct bsc_nat *nat;
406 struct bsc_connection *con;
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800407 struct bsc_config *cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200408
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100409 printf("Testing paging by lac.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200410
411 nat = bsc_nat_alloc();
412 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800413 cfg = bsc_config_alloc(nat, "unknown");
414 con->cfg = cfg;
415 bsc_config_add_lac(cfg, 23);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200416 con->authenticated = 1;
417 llist_add(&con->list_entry, &nat->bsc_connections);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200418
419 /* Test it by not finding it */
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200420 if (bsc_config_handles_lac(cfg, 8213) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100421 printf("Should not be handled.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200422 abort();
423 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200424
425 /* Test by finding it */
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800426 bsc_config_del_lac(cfg, 23);
427 bsc_config_add_lac(cfg, 8213);
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200428 if (bsc_config_handles_lac(cfg, 8213) == 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100429 printf("Should have found it.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200430 abort();
431 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200432}
433
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100434static void test_mgcp_allocations(void)
435{
436#if 0
437 struct bsc_connection *bsc;
438 struct bsc_nat *nat;
439 struct sccp_connections con;
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100440 int i, j, multiplex;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100441
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100442 printf("Testing MGCP.\n");
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100443 memset(&con, 0, sizeof(con));
444
445 nat = bsc_nat_alloc();
446 nat->bsc_endpoints = talloc_zero_array(nat,
447 struct bsc_endpoint,
448 65);
449 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100450 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100451
452 bsc = bsc_connection_alloc(nat);
453 bsc->cfg = bsc_config_alloc(nat, "foo");
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100454 bsc->cfg->max_endpoints = 60;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100455 bsc_config_add_lac(bsc->cfg, 2323);
456 bsc->last_endpoint = 0x22;
457 con.bsc = bsc;
458
459 bsc_init_endps_if_needed(bsc);
460
461 i = 1;
462 do {
463 if (bsc_assign_endpoint(bsc, &con) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100464 printf("failed to allocate... on iteration %d\n", i);
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100465 break;
466 }
467 ++i;
468 } while(1);
469
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100470 multiplex = bsc_mgcp_nr_multiplexes(bsc->cfg->max_endpoints);
471 for (i = 0; i < multiplex; ++i) {
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100472 for (j = 0; j < 32; ++j)
473 printf("%d", bsc->_endpoint_status[i*32 + j]);
474 printf(": %d of %d\n", i*32 + 32, 32 * 8);
475 }
476#endif
477}
478
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200479static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800480{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800481 struct bsc_connection *bsc;
482 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800483 struct sccp_connections con;
484 struct bsc_nat_parsed *parsed;
485 struct msgb *msg;
486
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100487 printf("Testing MGCP.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800488 memset(&con, 0, sizeof(con));
489
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800490 nat = bsc_nat_alloc();
491 nat->bsc_endpoints = talloc_zero_array(nat,
492 struct bsc_endpoint,
493 33);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100494 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100495 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100496
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800497 bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800498 bsc->cfg = bsc_config_alloc(nat, "foo");
499 bsc_config_add_lac(bsc->cfg, 2323);
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100500 bsc->last_endpoint = 0x1e;
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800501 con.bsc = bsc;
502
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800503 msg = msgb_alloc(4096, "foo");
504 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
505 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800506
507 if (msg->l2h[16] != 0 ||
508 msg->l2h[17] != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100509 printf("Input is not as expected.. %s 0x%x\n",
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200510 osmo_hexdump(msg->l2h, msgb_l2len(msg)),
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800511 msg->l2h[17]);
512 abort();
513 }
514
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800515 if (bsc_mgcp_assign_patch(&con, msg) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100516 printf("Failed to handle assignment.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800517 abort();
518 }
519
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800520 if (con.msc_endp != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100521 printf("Timeslot should be 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800522 abort();
523 }
524
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100525 if (con.bsc_endp != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100526 printf("Assigned timeslot should have been 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800527 abort();
528 }
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100529 if (con.bsc->_endpoint_status[0x1] != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100530 printf("The status on the BSC is wrong.\n");
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800531 abort();
532 }
533
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800534 int multiplex, timeslot;
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100535 mgcp_endpoint_to_timeslot(0x1, &multiplex, &timeslot);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800536
537 uint16_t cic = htons(timeslot & 0x1f);
538 if (memcmp(&cic, &msg->l2h[16], sizeof(cic)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100539 printf("Message was not patched properly\n");
540 printf("data cic: 0x%x %s\n", cic, osmo_hexdump(msg->l2h, msgb_l2len(msg)));
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800541 abort();
542 }
543
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800544 talloc_free(parsed);
545
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800546 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800547 if (con.bsc_endp != -1 || con.msc_endp != -1 ||
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100548 con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100549 printf("Clearing should remove the mapping.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800550 abort();
551 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800552
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100553 bsc_config_free(bsc->cfg);
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800554 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800555}
556
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200557/* test the code to find a given connection */
558static void test_mgcp_find(void)
559{
560 struct bsc_nat *nat;
561 struct bsc_connection *con;
562 struct sccp_connections *sccp_con;
563
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100564 printf("Testing finding of a BSC Connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200565
566 nat = bsc_nat_alloc();
567 con = bsc_connection_alloc(nat);
568 llist_add(&con->list_entry, &nat->bsc_connections);
569
570 sccp_con = talloc_zero(con, struct sccp_connections);
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800571 sccp_con->msc_endp = 12;
572 sccp_con->bsc_endp = 12;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200573 sccp_con->bsc = con;
574 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
575
576 if (bsc_mgcp_find_con(nat, 11) != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100577 printf("Found the wrong connection.\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200578 abort();
579 }
580
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800581 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100582 printf("Didn't find the connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200583 abort();
584 }
585
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200586 /* free everything */
587 talloc_free(nat);
588}
589
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200590static void test_mgcp_rewrite(void)
591{
592 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200593 struct msgb *output;
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100594 printf("Testing rewriting MGCP messages.\n");
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200595
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200596 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
597 const char *orig = mgcp_messages[i].orig;
598 const char *patc = mgcp_messages[i].patch;
599 const char *ip = mgcp_messages[i].ip;
600 const int port = mgcp_messages[i].port;
601
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200602 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200603
Holger Hans Peter Freytherf7c86c52010-08-30 13:44:32 +0800604 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200605 if (msgb_l2len(output) != strlen(patc)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100606 printf("Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
607 printf("String '%s' vs '%s'\n", (const char *) output->l2h, patc);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200608 abort();
609 }
610
611 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100612 printf("Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200613 abort();
614 }
615
616 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200617 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200618 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200619}
620
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200621static void test_mgcp_parse(void)
622{
623 int code, ci;
624 char transaction[60];
625
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100626 printf("Testing MGCP response parsing.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200627
628 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100629 printf("Failed to parse CRCX resp.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200630 abort();
631 }
632
633 if (code != 200) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100634 printf("Failed to parse the CODE properly. Got: %d\n", code);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200635 abort();
636 }
637
638 if (strcmp(transaction, "23265295") != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100639 printf("Failed to parse transaction id: '%s'\n", transaction);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200640 abort();
641 }
642
643 ci = bsc_mgcp_extract_ci(crcx_resp);
644 if (ci != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100645 printf("Failed to parse the CI. Got: %d\n", ci);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200646 abort();
647 }
648}
649
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800650struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800651 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800652 int length;
653 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800654 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800655
656 const char *bsc_imsi_allow;
657 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800658 const char *nat_imsi_deny;
659};
660
661static struct cr_filter cr_filter[] = {
662 {
663 .data = bssmap_cr,
664 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800665 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800666 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800667 },
668 {
669 .data = bss_lu,
670 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800671 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800672 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800673 },
674 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800675 .data = pag_resp,
676 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800677 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800678 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800679 },
680 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800681 /* nat deny is before blank/null BSC */
682 .data = bss_lu,
683 .length = sizeof(bss_lu),
684 .result = -3,
685 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800686 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800687 },
688 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800689 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800690 .data = bss_lu,
691 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800692 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800693 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800694 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800695 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800696 },
697 {
698 /* BSC allow is before NAT deny */
699 .data = bss_lu,
700 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800701 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800702 .bsc_imsi_allow = "[0-9]*",
703 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800704 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800705 },
706 {
707 /* filter as deny is first */
708 .data = bss_lu,
709 .length = sizeof(bss_lu),
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200710 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800711 .bsc_imsi_deny = "[0-9]*",
712 .bsc_imsi_allow = "[0-9]*",
713 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800714 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800715 },
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200716 {
717 /* deny by nat rule */
718 .data = bss_lu,
719 .length = sizeof(bss_lu),
720 .result = -3,
721 .bsc_imsi_deny = "000[0-9]*",
722 .nat_imsi_deny = "[0-9]*",
723 .contype = NAT_CON_TYPE_LU,
724 },
725 {
726 /* deny by bsc rule */
727 .data = bss_lu,
728 .length = sizeof(bss_lu),
729 .result = -2,
730 .bsc_imsi_deny = "[0-9]*",
731 .contype = NAT_CON_TYPE_LU,
732 },
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800733
734};
735
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800736static void test_cr_filter()
737{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800738 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800739 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800740 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800741 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800742 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800743
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800744 struct bsc_nat *nat = bsc_nat_alloc();
745 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800746 bsc->cfg = bsc_config_alloc(nat, "foo");
747 bsc_config_add_lac(bsc->cfg, 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800748 bsc->cfg->acc_lst_name = "bsc";
749 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800750
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800751 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
752 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
753
754 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
755 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
756
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800757 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800758 char *imsi;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800759 msgb_reset(msg);
760 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
761
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800762 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
763 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800764
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200765 if (gsm_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800766 cr_filter[i].nat_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200767 &cr_filter[i].nat_imsi_deny) != 0)
768 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200769 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800770 cr_filter[i].bsc_imsi_allow ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200771 &cr_filter[i].bsc_imsi_allow) != 0)
772 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200773 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800774 cr_filter[i].bsc_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200775 &cr_filter[i].bsc_imsi_deny) != 0)
776 abort();
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800777
778 parsed = bsc_nat_parse(msg);
779 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100780 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800781 abort();
782 }
783
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800784 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800785 if (res != cr_filter[i].result) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100786 printf("FAIL: Wrong result %d for test %d.\n", res, i);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800787 abort();
788 }
789
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800790 if (contype != cr_filter[i].contype) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100791 printf("FAIL: Wrong contype %d for test %d.\n", res, contype);
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800792 abort();
793 }
794
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800795 talloc_steal(parsed, imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800796 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800797 }
798
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800799 msgb_free(msg);
800}
801
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800802static void test_dt_filter()
803{
804 int i;
805 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
806 struct bsc_nat_parsed *parsed;
807
808 struct bsc_nat *nat = bsc_nat_alloc();
809 struct bsc_connection *bsc = bsc_connection_alloc(nat);
810 struct sccp_connections *con = talloc_zero(0, struct sccp_connections);
811
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800812 bsc->cfg = bsc_config_alloc(nat, "foo");
813 bsc_config_add_lac(bsc->cfg, 23);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800814 con->bsc = bsc;
815
816 msgb_reset(msg);
817 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
818
819 parsed = bsc_nat_parse(msg);
820 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100821 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800822 abort();
823 }
824
825 if (parsed->bssap != BSSAP_MSG_DTAP) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100826 printf("FAIL: It should be dtap\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800827 abort();
828 }
829
830 /* gsm_type is actually the size of the dtap */
831 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100832 printf("FAIL: Not enough space for the content\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800833 abort();
834 }
835
836 if (bsc_nat_filter_dt(bsc, msg, con, parsed) != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100837 printf("FAIL: Should have passed..\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800838 abort();
839 }
840
841 /* just some basic length checking... */
842 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
843 msgb_reset(msg);
844 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
845
846 parsed = bsc_nat_parse(msg);
847 if (!parsed)
848 continue;
849
850 con->imsi_checked = 0;
851 bsc_nat_filter_dt(bsc, msg, con, parsed);
852 }
853}
854
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200855static void test_setup_rewrite()
856{
857 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
858 struct msgb *out;
859 struct bsc_nat_parsed *parsed;
860 const char *imsi = "27408000001234";
861
862 struct bsc_nat *nat = bsc_nat_alloc();
863
864 /* a fake list */
Pablo Neira Ayusoab46cf32011-05-07 13:11:20 +0200865 struct osmo_config_list entries;
866 struct osmo_config_entry entry;
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200867
868 INIT_LLIST_HEAD(&entries.entry);
869 entry.mcc = "274";
870 entry.mnc = "08";
871 entry.option = "^0([1-9])";
872 entry.text = "0049";
873 llist_add_tail(&entry.list, &entries.entry);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200874 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200875
876 /* verify that nothing changed */
877 msgb_reset(msg);
878 copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
879 parsed = bsc_nat_parse(msg);
880 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100881 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200882 abort();
883 }
884
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200885 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200886 if (msg != out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100887 printf("FAIL: The message should not have been changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200888 abort();
889 }
890
891 if (out->len != ARRAY_SIZE(cc_setup_international)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100892 printf("FAIL: Length of message changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200893 abort();
894 }
895
896 if (memcmp(out->data, cc_setup_international, out->len) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100897 printf("FAIL: Content modified..\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200898 abort();
899 }
900 talloc_free(parsed);
901
902 /* verify that something in the message changes */
903 msgb_reset(msg);
904 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
905 parsed = bsc_nat_parse(msg);
906 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100907 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200908 abort();
909 }
910
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200911 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200912 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100913 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200914 abort();
915 }
916
917 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100918 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200919 abort();
920 }
921
922 if (out->len != ARRAY_SIZE(cc_setup_national_patched)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100923 printf("FAIL: Length is wrong.\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200924 abort();
925 }
926
927 if (memcmp(cc_setup_national_patched, out->data, out->len) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100928 printf("FAIL: Data is wrong.\n");
929 printf("Data was: %s\n", osmo_hexdump(out->data, out->len));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200930 abort();
931 }
932
933 msgb_free(out);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200934
935 /* Make sure that a wildcard is matching */
936 entry.mnc = "*";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200937 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200938 msg = msgb_alloc(4096, "test_dt_filter");
939 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
940 parsed = bsc_nat_parse(msg);
941 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100942 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200943 abort();
944 }
945
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200946 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200947 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100948 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200949 abort();
950 }
951
952 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100953 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200954 abort();
955 }
956
957 if (out->len != ARRAY_SIZE(cc_setup_national_patched)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100958 printf("FAIL: Length is wrong.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200959 abort();
960 }
961
962 if (memcmp(cc_setup_national_patched, out->data, out->len) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100963 printf("FAIL: Data is wrong.\n");
964 printf("Data was: %s\n", osmo_hexdump(out->data, out->len));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200965 abort();
966 }
967
968 msgb_free(out);
969
970 /* Make sure that a wildcard is matching */
971 entry.mnc = "09";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200972 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200973 msg = msgb_alloc(4096, "test_dt_filter");
974 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
975 parsed = bsc_nat_parse(msg);
976 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100977 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200978 abort();
979 }
980
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200981 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200982 if (out != msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100983 printf("FAIL: The message should be unchanged.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200984 abort();
985 }
986
987 if (out->len != ARRAY_SIZE(cc_setup_national)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100988 printf("FAIL: Foo\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200989 abort();
990 }
991
992 if (memcmp(out->data, cc_setup_national, ARRAY_SIZE(cc_setup_national)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100993 printf("FAIL: The message should really be unchanged.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200994 abort();
995 }
996
997 msgb_free(out);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200998}
999
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001000static void test_smsc_rewrite()
1001{
1002 struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
1003 struct bsc_nat_parsed *parsed;
1004 const char *imsi = "515039900406700";
1005
1006 struct bsc_nat *nat = bsc_nat_alloc();
1007
1008 /* a fake list */
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001009 struct osmo_config_list smsc_entries, dest_entries;
1010 struct osmo_config_entry smsc_entry, dest_entry;
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001011
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001012 INIT_LLIST_HEAD(&smsc_entries.entry);
1013 INIT_LLIST_HEAD(&dest_entries.entry);
1014 smsc_entry.mcc = "^515039";
1015 smsc_entry.option = "639180000105()";
1016 smsc_entry.text = "6666666666667";
1017 llist_add_tail(&smsc_entry.list, &smsc_entries.entry);
1018 dest_entry.mcc = "515";
1019 dest_entry.mnc = "03";
1020 dest_entry.option = "^0049";
1021 dest_entry.text = "";
1022 llist_add_tail(&dest_entry.list, &dest_entries.entry);
1023
1024 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
1025 bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001026
1027 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1028 parsed = bsc_nat_parse(msg);
1029 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001030 printf("FAIL: Could not parse SMS\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001031 abort();
1032 }
1033
1034 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1035 if (out == msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001036 printf("FAIL: This should have changed.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001037 abort();
1038 }
1039
1040 if (out->len != ARRAY_SIZE(smsc_rewrite_patched)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001041 printf("FAIL: The size should match.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001042 abort();
1043 }
1044
1045 if (memcmp(out->data, smsc_rewrite_patched, out->len) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001046 printf("FAIL: the data should be changed.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001047 abort();
1048 }
1049}
1050
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001051int main(int argc, char **argv)
1052{
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +08001053 sccp_set_log_area(DSCCP);
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +02001054 osmo_init_logging(&log_info);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001055
1056 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001057 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001058 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +02001059 test_mgcp_ass_tracking();
1060 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +02001061 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +02001062 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +08001063 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +08001064 test_dt_filter();
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001065 test_setup_rewrite();
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001066 test_smsc_rewrite();
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +01001067 test_mgcp_allocations();
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001068
1069 printf("Testing execution completed.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001070 return 0;
1071}