blob: 65ff4f65a4a4f3962e914ab1dcc97af37d3a3108 [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
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100267static void verify_msg(struct msgb *out, const uint8_t *ref, int ref_len)
268{
269 if (out->len != ref_len) {
270 printf("FAIL: The size should match.\n");
271 abort();
272 }
273
274 if (memcmp(out->data, ref, out->len) != 0) {
275 printf("FAIL: the data should be changed.\n");
276 printf("%s\n", osmo_hexdump(out->data, out->len));
277 printf("Wanted\n");
278 printf("%s\n", osmo_hexdump(ref, ref_len));
279 abort();
280 }
281}
282
283
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800284#define VERIFY(con_found, con, msg, ver, str) \
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100285 if (!con_found) { \
286 printf("Failed to find connection.\n"); \
287 abort(); \
288 } \
289 if (con_found->bsc != con) { \
290 printf("Got connection of the wrong BSC: %d\n", \
291 con_found->bsc->cfg->nr); \
292 abort(); \
293 } \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800294 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100295 printf("Failed to patch the %s msg.\n", str); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800296 abort(); \
297 }
298
299/* test conn tracking once */
300static void test_contrack()
301{
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800302 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800303 struct bsc_connection *con;
304 struct sccp_connections *con_found;
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800305 struct sccp_connections *rc_con;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800306 struct bsc_nat_parsed *parsed;
307 struct msgb *msg;
308
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100309 printf("Testing connection tracking.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800310 nat = bsc_nat_alloc();
311 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800312 con->cfg = bsc_config_alloc(nat, "foo");
313 bsc_config_add_lac(con->cfg, 23);
314 bsc_config_add_lac(con->cfg, 49);
315 bsc_config_add_lac(con->cfg, 42);
316 bsc_config_del_lac(con->cfg, 49);
317 bsc_config_add_lac(con->cfg, 1111);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800318 msg = msgb_alloc(4096, "test");
319
320 /* 1.) create a connection */
321 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
322 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800323 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800324 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100325 printf("Con should not exist realref(%u)\n",
326 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800327 abort();
328 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800329 rc_con = create_sccp_src_ref(con, parsed);
330 if (!rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100331 printf("Failed to create a ref\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800332 abort();
333 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800334 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100335 if (!con_found) {
336 printf("Failed to find connection.\n");
337 abort();
338 }
339 if (con_found->bsc != con) {
340 printf("Got connection of the wrong BSC: %d\n",
341 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800342 abort();
343 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800344 if (con_found != rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100345 printf("Failed to find the right connection.\n");
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800346 abort();
347 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800348 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100349 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800350 abort();
351 }
352 talloc_free(parsed);
353
354 /* 2.) get the cc */
355 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
356 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800357 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
358 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
359 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100360 printf("Failed to update the SCCP con.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800361 abort();
362 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800363
364 /* 3.) send some data */
365 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
366 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800367 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800368 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
369
370 /* 4.) receive some data */
371 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
372 parsed = bsc_nat_parse(msg);
373 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
374 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
375
376 /* 5.) close the connection */
377 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
378 parsed = bsc_nat_parse(msg);
379 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
380 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
381
382 /* 6.) confirm the connection close */
383 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
384 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800385 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100386 if (!con_found) {
387 printf("Failed to find connection.\n");
388 abort();
389 }
390 if (con_found->bsc != con) {
391 printf("Got connection of the wrong BSC: %d\n",
392 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800393 abort();
394 }
395 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100396 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800397 abort();
398 }
399 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200400 talloc_free(parsed);
401
402 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
403 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800404 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800405
406 /* verify that it is gone */
407 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100408 printf("Con should not exist real_ref(%u)\n",
409 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800410 abort();
411 }
412 talloc_free(parsed);
413
414
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100415 bsc_config_free(con->cfg);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800416 talloc_free(nat);
417 msgb_free(msg);
418}
419
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200420static void test_paging(void)
421{
422 struct bsc_nat *nat;
423 struct bsc_connection *con;
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800424 struct bsc_config *cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200425
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100426 printf("Testing paging by lac.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200427
428 nat = bsc_nat_alloc();
429 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800430 cfg = bsc_config_alloc(nat, "unknown");
431 con->cfg = cfg;
432 bsc_config_add_lac(cfg, 23);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200433 con->authenticated = 1;
434 llist_add(&con->list_entry, &nat->bsc_connections);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200435
436 /* Test it by not finding it */
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200437 if (bsc_config_handles_lac(cfg, 8213) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100438 printf("Should not be handled.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200439 abort();
440 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200441
442 /* Test by finding it */
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800443 bsc_config_del_lac(cfg, 23);
444 bsc_config_add_lac(cfg, 8213);
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200445 if (bsc_config_handles_lac(cfg, 8213) == 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100446 printf("Should have found it.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200447 abort();
448 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200449}
450
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100451static void test_mgcp_allocations(void)
452{
453#if 0
454 struct bsc_connection *bsc;
455 struct bsc_nat *nat;
456 struct sccp_connections con;
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100457 int i, j, multiplex;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100458
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100459 printf("Testing MGCP.\n");
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100460 memset(&con, 0, sizeof(con));
461
462 nat = bsc_nat_alloc();
463 nat->bsc_endpoints = talloc_zero_array(nat,
464 struct bsc_endpoint,
465 65);
466 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100467 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100468
469 bsc = bsc_connection_alloc(nat);
470 bsc->cfg = bsc_config_alloc(nat, "foo");
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100471 bsc->cfg->max_endpoints = 60;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100472 bsc_config_add_lac(bsc->cfg, 2323);
473 bsc->last_endpoint = 0x22;
474 con.bsc = bsc;
475
476 bsc_init_endps_if_needed(bsc);
477
478 i = 1;
479 do {
480 if (bsc_assign_endpoint(bsc, &con) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100481 printf("failed to allocate... on iteration %d\n", i);
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100482 break;
483 }
484 ++i;
485 } while(1);
486
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100487 multiplex = bsc_mgcp_nr_multiplexes(bsc->cfg->max_endpoints);
488 for (i = 0; i < multiplex; ++i) {
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100489 for (j = 0; j < 32; ++j)
490 printf("%d", bsc->_endpoint_status[i*32 + j]);
491 printf(": %d of %d\n", i*32 + 32, 32 * 8);
492 }
493#endif
494}
495
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200496static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800497{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800498 struct bsc_connection *bsc;
499 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800500 struct sccp_connections con;
501 struct bsc_nat_parsed *parsed;
502 struct msgb *msg;
503
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100504 printf("Testing MGCP.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800505 memset(&con, 0, sizeof(con));
506
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800507 nat = bsc_nat_alloc();
508 nat->bsc_endpoints = talloc_zero_array(nat,
509 struct bsc_endpoint,
510 33);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100511 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100512 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100513
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800514 bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800515 bsc->cfg = bsc_config_alloc(nat, "foo");
516 bsc_config_add_lac(bsc->cfg, 2323);
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100517 bsc->last_endpoint = 0x1e;
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800518 con.bsc = bsc;
519
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800520 msg = msgb_alloc(4096, "foo");
521 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
522 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800523
524 if (msg->l2h[16] != 0 ||
525 msg->l2h[17] != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100526 printf("Input is not as expected.. %s 0x%x\n",
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200527 osmo_hexdump(msg->l2h, msgb_l2len(msg)),
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800528 msg->l2h[17]);
529 abort();
530 }
531
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800532 if (bsc_mgcp_assign_patch(&con, msg) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100533 printf("Failed to handle assignment.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800534 abort();
535 }
536
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800537 if (con.msc_endp != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100538 printf("Timeslot should be 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800539 abort();
540 }
541
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100542 if (con.bsc_endp != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100543 printf("Assigned timeslot should have been 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800544 abort();
545 }
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100546 if (con.bsc->_endpoint_status[0x1] != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100547 printf("The status on the BSC is wrong.\n");
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800548 abort();
549 }
550
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800551 int multiplex, timeslot;
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100552 mgcp_endpoint_to_timeslot(0x1, &multiplex, &timeslot);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800553
554 uint16_t cic = htons(timeslot & 0x1f);
555 if (memcmp(&cic, &msg->l2h[16], sizeof(cic)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100556 printf("Message was not patched properly\n");
557 printf("data cic: 0x%x %s\n", cic, osmo_hexdump(msg->l2h, msgb_l2len(msg)));
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800558 abort();
559 }
560
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800561 talloc_free(parsed);
562
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800563 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800564 if (con.bsc_endp != -1 || con.msc_endp != -1 ||
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100565 con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100566 printf("Clearing should remove the mapping.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800567 abort();
568 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800569
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100570 bsc_config_free(bsc->cfg);
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800571 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800572}
573
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200574/* test the code to find a given connection */
575static void test_mgcp_find(void)
576{
577 struct bsc_nat *nat;
578 struct bsc_connection *con;
579 struct sccp_connections *sccp_con;
580
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100581 printf("Testing finding of a BSC Connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200582
583 nat = bsc_nat_alloc();
584 con = bsc_connection_alloc(nat);
585 llist_add(&con->list_entry, &nat->bsc_connections);
586
587 sccp_con = talloc_zero(con, struct sccp_connections);
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800588 sccp_con->msc_endp = 12;
589 sccp_con->bsc_endp = 12;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200590 sccp_con->bsc = con;
591 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
592
593 if (bsc_mgcp_find_con(nat, 11) != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100594 printf("Found the wrong connection.\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200595 abort();
596 }
597
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800598 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100599 printf("Didn't find the connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200600 abort();
601 }
602
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200603 /* free everything */
604 talloc_free(nat);
605}
606
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200607static void test_mgcp_rewrite(void)
608{
609 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200610 struct msgb *output;
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100611 printf("Testing rewriting MGCP messages.\n");
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200612
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200613 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
614 const char *orig = mgcp_messages[i].orig;
615 const char *patc = mgcp_messages[i].patch;
616 const char *ip = mgcp_messages[i].ip;
617 const int port = mgcp_messages[i].port;
618
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200619 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200620
Holger Hans Peter Freytherf7c86c52010-08-30 13:44:32 +0800621 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200622 if (msgb_l2len(output) != strlen(patc)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100623 printf("Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
624 printf("String '%s' vs '%s'\n", (const char *) output->l2h, patc);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200625 abort();
626 }
627
628 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100629 printf("Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200630 abort();
631 }
632
633 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200634 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200635 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200636}
637
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200638static void test_mgcp_parse(void)
639{
640 int code, ci;
641 char transaction[60];
642
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100643 printf("Testing MGCP response parsing.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200644
645 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100646 printf("Failed to parse CRCX resp.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200647 abort();
648 }
649
650 if (code != 200) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100651 printf("Failed to parse the CODE properly. Got: %d\n", code);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200652 abort();
653 }
654
655 if (strcmp(transaction, "23265295") != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100656 printf("Failed to parse transaction id: '%s'\n", transaction);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200657 abort();
658 }
659
660 ci = bsc_mgcp_extract_ci(crcx_resp);
661 if (ci != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100662 printf("Failed to parse the CI. Got: %d\n", ci);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200663 abort();
664 }
665}
666
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800667struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800668 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800669 int length;
670 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800671 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800672
673 const char *bsc_imsi_allow;
674 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800675 const char *nat_imsi_deny;
676};
677
678static struct cr_filter cr_filter[] = {
679 {
680 .data = bssmap_cr,
681 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800682 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800683 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800684 },
685 {
686 .data = bss_lu,
687 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800688 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800689 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800690 },
691 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800692 .data = pag_resp,
693 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800694 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800695 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800696 },
697 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800698 /* nat deny is before blank/null BSC */
699 .data = bss_lu,
700 .length = sizeof(bss_lu),
701 .result = -3,
702 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800703 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800704 },
705 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800706 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800707 .data = bss_lu,
708 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800709 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800710 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800711 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800712 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800713 },
714 {
715 /* BSC allow is before NAT deny */
716 .data = bss_lu,
717 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800718 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800719 .bsc_imsi_allow = "[0-9]*",
720 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800721 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800722 },
723 {
724 /* filter as deny is first */
725 .data = bss_lu,
726 .length = sizeof(bss_lu),
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200727 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800728 .bsc_imsi_deny = "[0-9]*",
729 .bsc_imsi_allow = "[0-9]*",
730 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800731 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800732 },
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200733 {
734 /* deny by nat rule */
735 .data = bss_lu,
736 .length = sizeof(bss_lu),
737 .result = -3,
738 .bsc_imsi_deny = "000[0-9]*",
739 .nat_imsi_deny = "[0-9]*",
740 .contype = NAT_CON_TYPE_LU,
741 },
742 {
743 /* deny by bsc rule */
744 .data = bss_lu,
745 .length = sizeof(bss_lu),
746 .result = -2,
747 .bsc_imsi_deny = "[0-9]*",
748 .contype = NAT_CON_TYPE_LU,
749 },
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800750
751};
752
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800753static void test_cr_filter()
754{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800755 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800756 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800757 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800758 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800759 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800760
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800761 struct bsc_nat *nat = bsc_nat_alloc();
762 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800763 bsc->cfg = bsc_config_alloc(nat, "foo");
764 bsc_config_add_lac(bsc->cfg, 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800765 bsc->cfg->acc_lst_name = "bsc";
766 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800767
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800768 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
769 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
770
771 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
772 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
773
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800774 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800775 char *imsi;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800776 msgb_reset(msg);
777 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
778
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800779 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
780 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800781
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200782 if (gsm_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800783 cr_filter[i].nat_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200784 &cr_filter[i].nat_imsi_deny) != 0)
785 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200786 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800787 cr_filter[i].bsc_imsi_allow ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200788 &cr_filter[i].bsc_imsi_allow) != 0)
789 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200790 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800791 cr_filter[i].bsc_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200792 &cr_filter[i].bsc_imsi_deny) != 0)
793 abort();
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800794
795 parsed = bsc_nat_parse(msg);
796 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100797 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800798 abort();
799 }
800
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800801 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800802 if (res != cr_filter[i].result) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100803 printf("FAIL: Wrong result %d for test %d.\n", res, i);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800804 abort();
805 }
806
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800807 if (contype != cr_filter[i].contype) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100808 printf("FAIL: Wrong contype %d for test %d.\n", res, contype);
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800809 abort();
810 }
811
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800812 talloc_steal(parsed, imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800813 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800814 }
815
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800816 msgb_free(msg);
817}
818
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800819static void test_dt_filter()
820{
821 int i;
822 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
823 struct bsc_nat_parsed *parsed;
824
825 struct bsc_nat *nat = bsc_nat_alloc();
826 struct bsc_connection *bsc = bsc_connection_alloc(nat);
827 struct sccp_connections *con = talloc_zero(0, struct sccp_connections);
828
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800829 bsc->cfg = bsc_config_alloc(nat, "foo");
830 bsc_config_add_lac(bsc->cfg, 23);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800831 con->bsc = bsc;
832
833 msgb_reset(msg);
834 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
835
836 parsed = bsc_nat_parse(msg);
837 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100838 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800839 abort();
840 }
841
842 if (parsed->bssap != BSSAP_MSG_DTAP) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100843 printf("FAIL: It should be dtap\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800844 abort();
845 }
846
847 /* gsm_type is actually the size of the dtap */
848 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100849 printf("FAIL: Not enough space for the content\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800850 abort();
851 }
852
853 if (bsc_nat_filter_dt(bsc, msg, con, parsed) != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100854 printf("FAIL: Should have passed..\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800855 abort();
856 }
857
858 /* just some basic length checking... */
859 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
860 msgb_reset(msg);
861 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
862
863 parsed = bsc_nat_parse(msg);
864 if (!parsed)
865 continue;
866
867 con->imsi_checked = 0;
868 bsc_nat_filter_dt(bsc, msg, con, parsed);
869 }
870}
871
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200872static void test_setup_rewrite()
873{
874 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
875 struct msgb *out;
876 struct bsc_nat_parsed *parsed;
877 const char *imsi = "27408000001234";
878
879 struct bsc_nat *nat = bsc_nat_alloc();
880
881 /* a fake list */
Pablo Neira Ayusoab46cf32011-05-07 13:11:20 +0200882 struct osmo_config_list entries;
883 struct osmo_config_entry entry;
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200884
885 INIT_LLIST_HEAD(&entries.entry);
886 entry.mcc = "274";
887 entry.mnc = "08";
888 entry.option = "^0([1-9])";
889 entry.text = "0049";
890 llist_add_tail(&entry.list, &entries.entry);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200891 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200892
893 /* verify that nothing changed */
894 msgb_reset(msg);
895 copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
896 parsed = bsc_nat_parse(msg);
897 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100898 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200899 abort();
900 }
901
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200902 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200903 if (msg != out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100904 printf("FAIL: The message should not have been changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200905 abort();
906 }
907
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100908 verify_msg(out, cc_setup_international, ARRAY_SIZE(cc_setup_international));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200909 talloc_free(parsed);
910
911 /* verify that something in the message changes */
912 msgb_reset(msg);
913 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
914 parsed = bsc_nat_parse(msg);
915 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100916 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200917 abort();
918 }
919
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200920 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200921 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100922 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200923 abort();
924 }
925
926 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100927 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200928 abort();
929 }
930
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100931 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200932 msgb_free(out);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200933
934 /* Make sure that a wildcard is matching */
935 entry.mnc = "*";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200936 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200937 msg = msgb_alloc(4096, "test_dt_filter");
938 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
939 parsed = bsc_nat_parse(msg);
940 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100941 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200942 abort();
943 }
944
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200945 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200946 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100947 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200948 abort();
949 }
950
951 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100952 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200953 abort();
954 }
955
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100956 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200957 msgb_free(out);
958
959 /* Make sure that a wildcard is matching */
960 entry.mnc = "09";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200961 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200962 msg = msgb_alloc(4096, "test_dt_filter");
963 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
964 parsed = bsc_nat_parse(msg);
965 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100966 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200967 abort();
968 }
969
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200970 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200971 if (out != msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100972 printf("FAIL: The message should be unchanged.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200973 abort();
974 }
975
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100976 verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200977 msgb_free(out);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200978}
979
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200980static void test_smsc_rewrite()
981{
982 struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
983 struct bsc_nat_parsed *parsed;
984 const char *imsi = "515039900406700";
985
986 struct bsc_nat *nat = bsc_nat_alloc();
987
988 /* a fake list */
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +0100989 struct osmo_config_list smsc_entries, dest_entries, clear_entries;
990 struct osmo_config_entry smsc_entry, dest_entry, clear_entry;
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200991
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +0200992 INIT_LLIST_HEAD(&smsc_entries.entry);
993 INIT_LLIST_HEAD(&dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +0100994 INIT_LLIST_HEAD(&clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +0200995 smsc_entry.mcc = "^515039";
996 smsc_entry.option = "639180000105()";
997 smsc_entry.text = "6666666666667";
998 llist_add_tail(&smsc_entry.list, &smsc_entries.entry);
999 dest_entry.mcc = "515";
1000 dest_entry.mnc = "03";
1001 dest_entry.option = "^0049";
1002 dest_entry.text = "";
1003 llist_add_tail(&dest_entry.list, &dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001004 clear_entry.mcc = "^515039";
1005 clear_entry.option = "^0049";
1006 clear_entry.text = "";
1007 llist_add_tail(&clear_entry.list, &clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001008
1009 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
1010 bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001011 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001012
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001013 printf("Testing SMSC rewriting.\n");
1014
1015 /*
1016 * Check if the SMSC address is changed
1017 */
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001018 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1019 parsed = bsc_nat_parse(msg);
1020 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001021 printf("FAIL: Could not parse SMS\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001022 abort();
1023 }
1024
1025 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1026 if (out == msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001027 printf("FAIL: This should have changed.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001028 abort();
1029 }
1030
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +01001031 verify_msg(out, smsc_rewrite_patched, ARRAY_SIZE(smsc_rewrite_patched));
1032 msgb_free(out);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001033
1034 /* clear out the filter for SMSC */
1035 printf("Attempting to only rewrite the HDR\n");
1036 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL);
1037 msg = msgb_alloc(4096, "SMSC rewrite");
1038 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1039 parsed = bsc_nat_parse(msg);
1040 if (!parsed) {
1041 printf("FAIL: Could not parse SMS\n");
1042 abort();
1043 }
1044
1045 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1046 if (out == msg) {
1047 printf("FAIL: This should have changed.\n");
1048 abort();
1049 }
1050
1051 verify_msg(out, smsc_rewrite_patched_hdr, ARRAY_SIZE(smsc_rewrite_patched_hdr));
1052 msgb_free(out);
1053
1054 /* clear out the next filter */
1055 printf("Attempting to change nothing.\n");
1056 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL);
1057 msg = msgb_alloc(4096, "SMSC rewrite");
1058 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1059 parsed = bsc_nat_parse(msg);
1060 if (!parsed) {
1061 printf("FAIL: Could not parse SMS\n");
1062 abort();
1063 }
1064
1065 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1066 if (out != msg) {
1067 printf("FAIL: This should not have changed.\n");
1068 abort();
1069 }
1070
1071 verify_msg(out, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1072 msgb_free(out);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001073}
1074
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001075int main(int argc, char **argv)
1076{
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +08001077 sccp_set_log_area(DSCCP);
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +02001078 osmo_init_logging(&log_info);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001079
1080 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001081 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001082 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +02001083 test_mgcp_ass_tracking();
1084 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +02001085 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +02001086 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +08001087 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +08001088 test_dt_filter();
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001089 test_setup_rewrite();
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001090 test_smsc_rewrite();
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +01001091 test_mgcp_allocations();
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001092
1093 printf("Testing execution completed.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001094 return 0;
1095}