blob: d6105adb8fcc35451d0c9d4cc2bda612319c5ce1 [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 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 Freyther0bd60f32010-10-08 22:08:29 +0800290 con->cfg = bsc_config_alloc(nat, "foo");
291 bsc_config_add_lac(con->cfg, 23);
292 bsc_config_add_lac(con->cfg, 49);
293 bsc_config_add_lac(con->cfg, 42);
294 bsc_config_del_lac(con->cfg, 49);
295 bsc_config_add_lac(con->cfg, 1111);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800296 msg = msgb_alloc(4096, "test");
297
298 /* 1.) create a connection */
299 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
300 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800301 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800302 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800303 fprintf(stderr, "Con should not exist %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800304 abort();
305 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800306 rc_con = create_sccp_src_ref(con, parsed);
307 if (!rc_con) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800308 fprintf(stderr, "Failed to create a ref\n");
309 abort();
310 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800311 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800312 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800313 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800314 abort();
315 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800316 if (con_found != rc_con) {
317 fprintf(stderr, "Failed to find the right connection.\n");
318 abort();
319 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800320 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
321 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
322 abort();
323 }
324 talloc_free(parsed);
325
326 /* 2.) get the cc */
327 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
328 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800329 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
330 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
331 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800332 fprintf(stderr, "Failed to update the SCCP con.\n");
333 abort();
334 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800335
336 /* 3.) send some data */
337 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
338 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800339 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800340 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
341
342 /* 4.) receive some data */
343 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
344 parsed = bsc_nat_parse(msg);
345 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
346 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
347
348 /* 5.) close the connection */
349 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
350 parsed = bsc_nat_parse(msg);
351 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
352 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
353
354 /* 6.) confirm the connection close */
355 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
356 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800357 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800358 if (!con_found || con_found->bsc != con) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800359 fprintf(stderr, "Failed to find the con: %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800360 abort();
361 }
362 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
363 fprintf(stderr, "Failed to patch the BSC CR msg.\n");
364 abort();
365 }
366 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200367 talloc_free(parsed);
368
369 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
370 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800371 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800372
373 /* verify that it is gone */
374 if (con_found != NULL) {
Holger Hans Peter Freyther72ba1622010-06-15 18:48:44 +0800375 fprintf(stderr, "Con should be gone. %p\n", con_found);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800376 abort();
377 }
378 talloc_free(parsed);
379
380
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100381 bsc_config_free(con->cfg);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800382 talloc_free(nat);
383 msgb_free(msg);
384}
385
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200386static void test_paging(void)
387{
388 struct bsc_nat *nat;
389 struct bsc_connection *con;
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800390 struct bsc_config *cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200391
392 fprintf(stderr, "Testing paging by lac.\n");
393
394 nat = bsc_nat_alloc();
395 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800396 cfg = bsc_config_alloc(nat, "unknown");
397 con->cfg = cfg;
398 bsc_config_add_lac(cfg, 23);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200399 con->authenticated = 1;
400 llist_add(&con->list_entry, &nat->bsc_connections);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200401
402 /* Test it by not finding it */
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200403 if (bsc_config_handles_lac(cfg, 8213) != 0) {
404 fprintf(stderr, "Should not be handled.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200405 abort();
406 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200407
408 /* Test by finding it */
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800409 bsc_config_del_lac(cfg, 23);
410 bsc_config_add_lac(cfg, 8213);
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200411 if (bsc_config_handles_lac(cfg, 8213) == 0) {
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200412 fprintf(stderr, "Should have found it.\n");
413 abort();
414 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200415}
416
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100417static void test_mgcp_allocations(void)
418{
419#if 0
420 struct bsc_connection *bsc;
421 struct bsc_nat *nat;
422 struct sccp_connections con;
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100423 int i, j, multiplex;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100424
425 fprintf(stderr, "Testing MGCP.\n");
426 memset(&con, 0, sizeof(con));
427
428 nat = bsc_nat_alloc();
429 nat->bsc_endpoints = talloc_zero_array(nat,
430 struct bsc_endpoint,
431 65);
432 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100433 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100434
435 bsc = bsc_connection_alloc(nat);
436 bsc->cfg = bsc_config_alloc(nat, "foo");
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100437 bsc->cfg->max_endpoints = 60;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100438 bsc_config_add_lac(bsc->cfg, 2323);
439 bsc->last_endpoint = 0x22;
440 con.bsc = bsc;
441
442 bsc_init_endps_if_needed(bsc);
443
444 i = 1;
445 do {
446 if (bsc_assign_endpoint(bsc, &con) != 0) {
447 fprintf(stderr, "failed to allocate... on iteration %d\n", i);
448 break;
449 }
450 ++i;
451 } while(1);
452
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100453 multiplex = bsc_mgcp_nr_multiplexes(bsc->cfg->max_endpoints);
454 for (i = 0; i < multiplex; ++i) {
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100455 for (j = 0; j < 32; ++j)
456 printf("%d", bsc->_endpoint_status[i*32 + j]);
457 printf(": %d of %d\n", i*32 + 32, 32 * 8);
458 }
459#endif
460}
461
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200462static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800463{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800464 struct bsc_connection *bsc;
465 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800466 struct sccp_connections con;
467 struct bsc_nat_parsed *parsed;
468 struct msgb *msg;
469
470 fprintf(stderr, "Testing MGCP.\n");
471 memset(&con, 0, sizeof(con));
472
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800473 nat = bsc_nat_alloc();
474 nat->bsc_endpoints = talloc_zero_array(nat,
475 struct bsc_endpoint,
476 33);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100477 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100478 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100479
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800480 bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800481 bsc->cfg = bsc_config_alloc(nat, "foo");
482 bsc_config_add_lac(bsc->cfg, 2323);
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100483 bsc->last_endpoint = 0x1e;
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800484 con.bsc = bsc;
485
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800486 msg = msgb_alloc(4096, "foo");
487 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
488 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800489
490 if (msg->l2h[16] != 0 ||
491 msg->l2h[17] != 0x1) {
492 fprintf(stderr, "Input is not as expected.. %s 0x%x\n",
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200493 osmo_hexdump(msg->l2h, msgb_l2len(msg)),
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800494 msg->l2h[17]);
495 abort();
496 }
497
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800498 if (bsc_mgcp_assign_patch(&con, msg) != 0) {
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800499 fprintf(stderr, "Failed to handle assignment.\n");
500 abort();
501 }
502
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800503 if (con.msc_endp != 1) {
504 fprintf(stderr, "Timeslot should be 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800505 abort();
506 }
507
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100508 if (con.bsc_endp != 0x1) {
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800509 fprintf(stderr, "Assigned timeslot should have been 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800510 abort();
511 }
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100512 if (con.bsc->_endpoint_status[0x1] != 1) {
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800513 fprintf(stderr, "The status on the BSC is wrong.\n");
514 abort();
515 }
516
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800517 int multiplex, timeslot;
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100518 mgcp_endpoint_to_timeslot(0x1, &multiplex, &timeslot);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800519
520 uint16_t cic = htons(timeslot & 0x1f);
521 if (memcmp(&cic, &msg->l2h[16], sizeof(cic)) != 0) {
522 fprintf(stderr, "Message was not patched properly\n");
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200523 fprintf(stderr, "data cic: 0x%x %s\n", cic, osmo_hexdump(msg->l2h, msgb_l2len(msg)));
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800524 abort();
525 }
526
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800527 talloc_free(parsed);
528
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800529 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800530 if (con.bsc_endp != -1 || con.msc_endp != -1 ||
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100531 con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1) {
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800532 fprintf(stderr, "Clearing should remove the mapping.\n");
533 abort();
534 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800535
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100536 bsc_config_free(bsc->cfg);
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800537 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800538}
539
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200540/* test the code to find a given connection */
541static void test_mgcp_find(void)
542{
543 struct bsc_nat *nat;
544 struct bsc_connection *con;
545 struct sccp_connections *sccp_con;
546
547 fprintf(stderr, "Testing finding of a BSC Connection\n");
548
549 nat = bsc_nat_alloc();
550 con = bsc_connection_alloc(nat);
551 llist_add(&con->list_entry, &nat->bsc_connections);
552
553 sccp_con = talloc_zero(con, struct sccp_connections);
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800554 sccp_con->msc_endp = 12;
555 sccp_con->bsc_endp = 12;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200556 sccp_con->bsc = con;
557 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
558
559 if (bsc_mgcp_find_con(nat, 11) != NULL) {
560 fprintf(stderr, "Found the wrong connection.\n");
561 abort();
562 }
563
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800564 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200565 fprintf(stderr, "Didn't find the connection\n");
566 abort();
567 }
568
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200569 /* free everything */
570 talloc_free(nat);
571}
572
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200573static void test_mgcp_rewrite(void)
574{
575 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200576 struct msgb *output;
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200577 fprintf(stderr, "Test rewriting MGCP messages.\n");
578
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200579 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
580 const char *orig = mgcp_messages[i].orig;
581 const char *patc = mgcp_messages[i].patch;
582 const char *ip = mgcp_messages[i].ip;
583 const int port = mgcp_messages[i].port;
584
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200585 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200586
Holger Hans Peter Freytherf7c86c52010-08-30 13:44:32 +0800587 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200588 if (msgb_l2len(output) != strlen(patc)) {
589 fprintf(stderr, "Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
590 fprintf(stderr, "String '%s' vs '%s'\n", (const char *) output->l2h, patc);
591 abort();
592 }
593
594 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
595 fprintf(stderr, "Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
596 abort();
597 }
598
599 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200600 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200601 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200602}
603
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200604static void test_mgcp_parse(void)
605{
606 int code, ci;
607 char transaction[60];
608
609 fprintf(stderr, "Test MGCP response parsing.\n");
610
611 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
612 fprintf(stderr, "Failed to parse CRCX resp.\n");
613 abort();
614 }
615
616 if (code != 200) {
617 fprintf(stderr, "Failed to parse the CODE properly. Got: %d\n", code);
618 abort();
619 }
620
621 if (strcmp(transaction, "23265295") != 0) {
622 fprintf(stderr, "Failed to parse transaction id: '%s'\n", transaction);
623 abort();
624 }
625
626 ci = bsc_mgcp_extract_ci(crcx_resp);
627 if (ci != 1) {
628 fprintf(stderr, "Failed to parse the CI. Got: %d\n", ci);
629 abort();
630 }
631}
632
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800633struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800634 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800635 int length;
636 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800637 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800638
639 const char *bsc_imsi_allow;
640 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800641 const char *nat_imsi_deny;
642};
643
644static struct cr_filter cr_filter[] = {
645 {
646 .data = bssmap_cr,
647 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800648 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800649 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800650 },
651 {
652 .data = bss_lu,
653 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800654 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800655 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800656 },
657 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800658 .data = pag_resp,
659 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800660 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800661 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800662 },
663 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800664 /* nat deny is before blank/null BSC */
665 .data = bss_lu,
666 .length = sizeof(bss_lu),
667 .result = -3,
668 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800669 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800670 },
671 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800672 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800673 .data = bss_lu,
674 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800675 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800676 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800677 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800678 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800679 },
680 {
681 /* BSC allow is before NAT deny */
682 .data = bss_lu,
683 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800684 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800685 .bsc_imsi_allow = "[0-9]*",
686 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800687 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800688 },
689 {
690 /* filter as deny is first */
691 .data = bss_lu,
692 .length = sizeof(bss_lu),
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200693 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800694 .bsc_imsi_deny = "[0-9]*",
695 .bsc_imsi_allow = "[0-9]*",
696 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800697 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800698 },
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200699 {
700 /* deny by nat rule */
701 .data = bss_lu,
702 .length = sizeof(bss_lu),
703 .result = -3,
704 .bsc_imsi_deny = "000[0-9]*",
705 .nat_imsi_deny = "[0-9]*",
706 .contype = NAT_CON_TYPE_LU,
707 },
708 {
709 /* deny by bsc rule */
710 .data = bss_lu,
711 .length = sizeof(bss_lu),
712 .result = -2,
713 .bsc_imsi_deny = "[0-9]*",
714 .contype = NAT_CON_TYPE_LU,
715 },
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800716
717};
718
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800719static void test_cr_filter()
720{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800721 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800722 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800723 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800724 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800725 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800726
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800727 struct bsc_nat *nat = bsc_nat_alloc();
728 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800729 bsc->cfg = bsc_config_alloc(nat, "foo");
730 bsc_config_add_lac(bsc->cfg, 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800731 bsc->cfg->acc_lst_name = "bsc";
732 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800733
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800734 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
735 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
736
737 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
738 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
739
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800740 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800741 char *imsi;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800742 msgb_reset(msg);
743 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
744
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800745 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
746 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800747
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200748 if (gsm_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800749 cr_filter[i].nat_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200750 &cr_filter[i].nat_imsi_deny) != 0)
751 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200752 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800753 cr_filter[i].bsc_imsi_allow ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200754 &cr_filter[i].bsc_imsi_allow) != 0)
755 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200756 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800757 cr_filter[i].bsc_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200758 &cr_filter[i].bsc_imsi_deny) != 0)
759 abort();
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800760
761 parsed = bsc_nat_parse(msg);
762 if (!parsed) {
763 fprintf(stderr, "FAIL: Failed to parse the message\n");
764 abort();
765 }
766
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800767 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800768 if (res != cr_filter[i].result) {
769 fprintf(stderr, "FAIL: Wrong result %d for test %d.\n", res, i);
770 abort();
771 }
772
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800773 if (contype != cr_filter[i].contype) {
774 fprintf(stderr, "FAIL: Wrong contype %d for test %d.\n", res, contype);
775 abort();
776 }
777
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800778 talloc_steal(parsed, imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800779 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800780 }
781
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800782 msgb_free(msg);
783}
784
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800785static void test_dt_filter()
786{
787 int i;
788 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
789 struct bsc_nat_parsed *parsed;
790
791 struct bsc_nat *nat = bsc_nat_alloc();
792 struct bsc_connection *bsc = bsc_connection_alloc(nat);
793 struct sccp_connections *con = talloc_zero(0, struct sccp_connections);
794
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800795 bsc->cfg = bsc_config_alloc(nat, "foo");
796 bsc_config_add_lac(bsc->cfg, 23);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800797 con->bsc = bsc;
798
799 msgb_reset(msg);
800 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
801
802 parsed = bsc_nat_parse(msg);
803 if (!parsed) {
804 fprintf(stderr, "FAIL: Could not parse ID resp\n");
805 abort();
806 }
807
808 if (parsed->bssap != BSSAP_MSG_DTAP) {
809 fprintf(stderr, "FAIL: It should be dtap\n");
810 abort();
811 }
812
813 /* gsm_type is actually the size of the dtap */
814 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
815 fprintf(stderr, "FAIL: Not enough space for the content\n");
816 abort();
817 }
818
819 if (bsc_nat_filter_dt(bsc, msg, con, parsed) != 1) {
820 fprintf(stderr, "FAIL: Should have passed..\n");
821 abort();
822 }
823
824 /* just some basic length checking... */
825 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
826 msgb_reset(msg);
827 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
828
829 parsed = bsc_nat_parse(msg);
830 if (!parsed)
831 continue;
832
833 con->imsi_checked = 0;
834 bsc_nat_filter_dt(bsc, msg, con, parsed);
835 }
836}
837
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200838static void test_setup_rewrite()
839{
840 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
841 struct msgb *out;
842 struct bsc_nat_parsed *parsed;
843 const char *imsi = "27408000001234";
844
845 struct bsc_nat *nat = bsc_nat_alloc();
846
847 /* a fake list */
Pablo Neira Ayusoab46cf32011-05-07 13:11:20 +0200848 struct osmo_config_list entries;
849 struct osmo_config_entry entry;
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200850
851 INIT_LLIST_HEAD(&entries.entry);
852 entry.mcc = "274";
853 entry.mnc = "08";
854 entry.option = "^0([1-9])";
855 entry.text = "0049";
856 llist_add_tail(&entry.list, &entries.entry);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200857 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200858
859 /* verify that nothing changed */
860 msgb_reset(msg);
861 copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
862 parsed = bsc_nat_parse(msg);
863 if (!parsed) {
864 fprintf(stderr, "FAIL: Could not parse ID resp\n");
865 abort();
866 }
867
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200868 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200869 if (msg != out) {
870 fprintf(stderr, "FAIL: The message should not have been changed\n");
871 abort();
872 }
873
874 if (out->len != ARRAY_SIZE(cc_setup_international)) {
875 fprintf(stderr, "FAIL: Length of message changed\n");
876 abort();
877 }
878
879 if (memcmp(out->data, cc_setup_international, out->len) != 0) {
880 fprintf(stderr, "FAIL: Content modified..\n");
881 abort();
882 }
883 talloc_free(parsed);
884
885 /* verify that something in the message changes */
886 msgb_reset(msg);
887 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
888 parsed = bsc_nat_parse(msg);
889 if (!parsed) {
890 fprintf(stderr, "FAIL: Could not parse ID resp\n");
891 abort();
892 }
893
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200894 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200895 if (!out) {
896 fprintf(stderr, "FAIL: A new message should be created.\n");
897 abort();
898 }
899
900 if (msg == out) {
901 fprintf(stderr, "FAIL: The message should have changed\n");
902 abort();
903 }
904
905 if (out->len != ARRAY_SIZE(cc_setup_national_patched)) {
906 fprintf(stderr, "FAIL: Length is wrong.\n");
907 abort();
908 }
909
910 if (memcmp(cc_setup_national_patched, out->data, out->len) != 0) {
911 fprintf(stderr, "FAIL: Data is wrong.\n");
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200912 fprintf(stderr, "Data was: %s\n", osmo_hexdump(out->data, out->len));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200913 abort();
914 }
915
916 msgb_free(out);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200917
918 /* Make sure that a wildcard is matching */
919 entry.mnc = "*";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200920 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200921 msg = msgb_alloc(4096, "test_dt_filter");
922 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
923 parsed = bsc_nat_parse(msg);
924 if (!parsed) {
925 fprintf(stderr, "FAIL: Could not parse ID resp\n");
926 abort();
927 }
928
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200929 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200930 if (!out) {
931 fprintf(stderr, "FAIL: A new message should be created.\n");
932 abort();
933 }
934
935 if (msg == out) {
936 fprintf(stderr, "FAIL: The message should have changed\n");
937 abort();
938 }
939
940 if (out->len != ARRAY_SIZE(cc_setup_national_patched)) {
941 fprintf(stderr, "FAIL: Length is wrong.\n");
942 abort();
943 }
944
945 if (memcmp(cc_setup_national_patched, out->data, out->len) != 0) {
946 fprintf(stderr, "FAIL: Data is wrong.\n");
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200947 fprintf(stderr, "Data was: %s\n", osmo_hexdump(out->data, out->len));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200948 abort();
949 }
950
951 msgb_free(out);
952
953 /* Make sure that a wildcard is matching */
954 entry.mnc = "09";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200955 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200956 msg = msgb_alloc(4096, "test_dt_filter");
957 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
958 parsed = bsc_nat_parse(msg);
959 if (!parsed) {
960 fprintf(stderr, "FAIL: Could not parse ID resp\n");
961 abort();
962 }
963
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200964 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200965 if (out != msg) {
966 fprintf(stderr, "FAIL: The message should be unchanged.\n");
967 abort();
968 }
969
970 if (out->len != ARRAY_SIZE(cc_setup_national)) {
971 fprintf(stderr, "FAIL: Foo\n");
972 abort();
973 }
974
975 if (memcmp(out->data, cc_setup_national, ARRAY_SIZE(cc_setup_national)) != 0) {
976 fprintf(stderr, "FAIL: The message should really be unchanged.\n");
977 abort();
978 }
979
980 msgb_free(out);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200981}
982
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200983static void test_smsc_rewrite()
984{
985 struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
986 struct bsc_nat_parsed *parsed;
987 const char *imsi = "515039900406700";
988
989 struct bsc_nat *nat = bsc_nat_alloc();
990
991 /* a fake list */
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +0200992 struct osmo_config_list smsc_entries, dest_entries;
993 struct osmo_config_entry smsc_entry, dest_entry;
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200994
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +0200995 INIT_LLIST_HEAD(&smsc_entries.entry);
996 INIT_LLIST_HEAD(&dest_entries.entry);
997 smsc_entry.mcc = "^515039";
998 smsc_entry.option = "639180000105()";
999 smsc_entry.text = "6666666666667";
1000 llist_add_tail(&smsc_entry.list, &smsc_entries.entry);
1001 dest_entry.mcc = "515";
1002 dest_entry.mnc = "03";
1003 dest_entry.option = "^0049";
1004 dest_entry.text = "";
1005 llist_add_tail(&dest_entry.list, &dest_entries.entry);
1006
1007 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
1008 bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001009
1010 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1011 parsed = bsc_nat_parse(msg);
1012 if (!parsed) {
1013 fprintf(stderr, "FAIL: Could not parse SMS\n");
1014 abort();
1015 }
1016
1017 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1018 if (out == msg) {
1019 fprintf(stderr, "FAIL: This should have changed.\n");
1020 abort();
1021 }
1022
1023 if (out->len != ARRAY_SIZE(smsc_rewrite_patched)) {
1024 fprintf(stderr, "FAIL: The size should match.\n");
1025 abort();
1026 }
1027
1028 if (memcmp(out->data, smsc_rewrite_patched, out->len) != 0) {
1029 fprintf(stderr, "FAIL: the data should be changed.\n");
1030 abort();
1031 }
1032}
1033
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001034int main(int argc, char **argv)
1035{
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +08001036 sccp_set_log_area(DSCCP);
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +02001037 osmo_init_logging(&log_info);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001038
1039 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001040 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001041 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +02001042 test_mgcp_ass_tracking();
1043 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +02001044 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +02001045 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +08001046 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +08001047 test_dt_filter();
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001048 test_setup_rewrite();
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001049 test_smsc_rewrite();
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +01001050 test_mgcp_allocations();
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001051 return 0;
1052}