blob: 6148a375d094e880761be565ec747536dd7a6bc0 [file] [log] [blame]
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001/*
2 * BSC NAT Message filtering
3 *
Holger Hans Peter Freytherdbd94492013-04-02 12:34:11 +02004 * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
5 * (C) 2010-2013 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) {
Holger Hans Peter Freytherbe530122012-01-18 17:20:23 +0100270 printf("FAIL: The size should match: %d vs. %d\n",
271 out->len, ref_len);
272 printf("%s\n", osmo_hexdump(out->data, out->len));
273 printf("Wanted\n");
274 printf("%s\n", osmo_hexdump(ref, ref_len));
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100275 abort();
276 }
277
278 if (memcmp(out->data, ref, out->len) != 0) {
279 printf("FAIL: the data should be changed.\n");
280 printf("%s\n", osmo_hexdump(out->data, out->len));
281 printf("Wanted\n");
282 printf("%s\n", osmo_hexdump(ref, ref_len));
283 abort();
284 }
285}
286
287
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800288#define VERIFY(con_found, con, msg, ver, str) \
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100289 if (!con_found) { \
290 printf("Failed to find connection.\n"); \
291 abort(); \
292 } \
293 if (con_found->bsc != con) { \
294 printf("Got connection of the wrong BSC: %d\n", \
295 con_found->bsc->cfg->nr); \
296 abort(); \
297 } \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800298 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100299 printf("Failed to patch the %s msg.\n", str); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800300 abort(); \
301 }
302
303/* test conn tracking once */
304static void test_contrack()
305{
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800306 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800307 struct bsc_connection *con;
308 struct sccp_connections *con_found;
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800309 struct sccp_connections *rc_con;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800310 struct bsc_nat_parsed *parsed;
311 struct msgb *msg;
312
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100313 printf("Testing connection tracking.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800314 nat = bsc_nat_alloc();
315 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800316 con->cfg = bsc_config_alloc(nat, "foo");
317 bsc_config_add_lac(con->cfg, 23);
318 bsc_config_add_lac(con->cfg, 49);
319 bsc_config_add_lac(con->cfg, 42);
320 bsc_config_del_lac(con->cfg, 49);
321 bsc_config_add_lac(con->cfg, 1111);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800322 msg = msgb_alloc(4096, "test");
323
324 /* 1.) create a connection */
325 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
326 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800327 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800328 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100329 printf("Con should not exist realref(%u)\n",
330 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800331 abort();
332 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800333 rc_con = create_sccp_src_ref(con, parsed);
334 if (!rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100335 printf("Failed to create a ref\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800336 abort();
337 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800338 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100339 if (!con_found) {
340 printf("Failed to find connection.\n");
341 abort();
342 }
343 if (con_found->bsc != con) {
344 printf("Got connection of the wrong BSC: %d\n",
345 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800346 abort();
347 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800348 if (con_found != rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100349 printf("Failed to find the right connection.\n");
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800350 abort();
351 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800352 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100353 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800354 abort();
355 }
356 talloc_free(parsed);
357
358 /* 2.) get the cc */
359 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
360 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800361 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
362 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
363 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100364 printf("Failed to update the SCCP con.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800365 abort();
366 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800367
368 /* 3.) send some data */
369 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
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 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
373
374 /* 4.) receive some data */
375 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
376 parsed = bsc_nat_parse(msg);
377 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
378 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
379
380 /* 5.) close the connection */
381 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
382 parsed = bsc_nat_parse(msg);
383 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
384 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
385
386 /* 6.) confirm the connection close */
387 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
388 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800389 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100390 if (!con_found) {
391 printf("Failed to find connection.\n");
392 abort();
393 }
394 if (con_found->bsc != con) {
395 printf("Got connection of the wrong BSC: %d\n",
396 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800397 abort();
398 }
399 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100400 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800401 abort();
402 }
403 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200404 talloc_free(parsed);
405
406 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
407 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800408 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800409
410 /* verify that it is gone */
411 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100412 printf("Con should not exist real_ref(%u)\n",
413 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800414 abort();
415 }
416 talloc_free(parsed);
417
418
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100419 bsc_config_free(con->cfg);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800420 talloc_free(nat);
421 msgb_free(msg);
422}
423
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200424static void test_paging(void)
425{
426 struct bsc_nat *nat;
427 struct bsc_connection *con;
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800428 struct bsc_config *cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200429
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100430 printf("Testing paging by lac.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200431
432 nat = bsc_nat_alloc();
433 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800434 cfg = bsc_config_alloc(nat, "unknown");
435 con->cfg = cfg;
436 bsc_config_add_lac(cfg, 23);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200437 con->authenticated = 1;
438 llist_add(&con->list_entry, &nat->bsc_connections);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200439
440 /* Test it by not finding it */
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200441 if (bsc_config_handles_lac(cfg, 8213) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100442 printf("Should not be handled.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200443 abort();
444 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200445
446 /* Test by finding it */
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800447 bsc_config_del_lac(cfg, 23);
448 bsc_config_add_lac(cfg, 8213);
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200449 if (bsc_config_handles_lac(cfg, 8213) == 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100450 printf("Should have found it.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200451 abort();
452 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200453}
454
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100455static void test_mgcp_allocations(void)
456{
457#if 0
458 struct bsc_connection *bsc;
459 struct bsc_nat *nat;
460 struct sccp_connections con;
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100461 int i, j, multiplex;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100462
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100463 printf("Testing MGCP.\n");
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100464 memset(&con, 0, sizeof(con));
465
466 nat = bsc_nat_alloc();
467 nat->bsc_endpoints = talloc_zero_array(nat,
468 struct bsc_endpoint,
469 65);
470 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100471 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100472
473 bsc = bsc_connection_alloc(nat);
474 bsc->cfg = bsc_config_alloc(nat, "foo");
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100475 bsc->cfg->max_endpoints = 60;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100476 bsc_config_add_lac(bsc->cfg, 2323);
477 bsc->last_endpoint = 0x22;
478 con.bsc = bsc;
479
480 bsc_init_endps_if_needed(bsc);
481
482 i = 1;
483 do {
484 if (bsc_assign_endpoint(bsc, &con) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100485 printf("failed to allocate... on iteration %d\n", i);
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100486 break;
487 }
488 ++i;
489 } while(1);
490
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100491 multiplex = bsc_mgcp_nr_multiplexes(bsc->cfg->max_endpoints);
492 for (i = 0; i < multiplex; ++i) {
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100493 for (j = 0; j < 32; ++j)
494 printf("%d", bsc->_endpoint_status[i*32 + j]);
495 printf(": %d of %d\n", i*32 + 32, 32 * 8);
496 }
497#endif
498}
499
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200500static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800501{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800502 struct bsc_connection *bsc;
503 struct bsc_nat *nat;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800504 struct sccp_connections con;
505 struct bsc_nat_parsed *parsed;
506 struct msgb *msg;
507
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100508 printf("Testing MGCP.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800509 memset(&con, 0, sizeof(con));
510
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800511 nat = bsc_nat_alloc();
512 nat->bsc_endpoints = talloc_zero_array(nat,
513 struct bsc_endpoint,
514 33);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100515 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100516 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freyther462b7d72012-10-24 21:53:40 +0200517 mgcp_endpoints_allocate(&nat->mgcp_cfg->trunk);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100518
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800519 bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800520 bsc->cfg = bsc_config_alloc(nat, "foo");
521 bsc_config_add_lac(bsc->cfg, 2323);
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100522 bsc->last_endpoint = 0x1e;
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800523 con.bsc = bsc;
524
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800525 msg = msgb_alloc(4096, "foo");
526 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
527 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800528
529 if (msg->l2h[16] != 0 ||
530 msg->l2h[17] != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100531 printf("Input is not as expected.. %s 0x%x\n",
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200532 osmo_hexdump(msg->l2h, msgb_l2len(msg)),
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800533 msg->l2h[17]);
534 abort();
535 }
536
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800537 if (bsc_mgcp_assign_patch(&con, msg) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100538 printf("Failed to handle assignment.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800539 abort();
540 }
541
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800542 if (con.msc_endp != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100543 printf("Timeslot should be 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800544 abort();
545 }
546
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100547 if (con.bsc_endp != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100548 printf("Assigned timeslot should have been 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800549 abort();
550 }
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100551 if (con.bsc->_endpoint_status[0x1] != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100552 printf("The status on the BSC is wrong.\n");
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800553 abort();
554 }
555
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800556 int multiplex, timeslot;
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100557 mgcp_endpoint_to_timeslot(0x1, &multiplex, &timeslot);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800558
559 uint16_t cic = htons(timeslot & 0x1f);
560 if (memcmp(&cic, &msg->l2h[16], sizeof(cic)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100561 printf("Message was not patched properly\n");
562 printf("data cic: 0x%x %s\n", cic, osmo_hexdump(msg->l2h, msgb_l2len(msg)));
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800563 abort();
564 }
565
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800566 talloc_free(parsed);
567
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800568 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800569 if (con.bsc_endp != -1 || con.msc_endp != -1 ||
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100570 con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100571 printf("Clearing should remove the mapping.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800572 abort();
573 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800574
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100575 bsc_config_free(bsc->cfg);
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800576 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800577}
578
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200579/* test the code to find a given connection */
580static void test_mgcp_find(void)
581{
582 struct bsc_nat *nat;
583 struct bsc_connection *con;
584 struct sccp_connections *sccp_con;
585
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100586 printf("Testing finding of a BSC Connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200587
588 nat = bsc_nat_alloc();
589 con = bsc_connection_alloc(nat);
590 llist_add(&con->list_entry, &nat->bsc_connections);
591
592 sccp_con = talloc_zero(con, struct sccp_connections);
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800593 sccp_con->msc_endp = 12;
594 sccp_con->bsc_endp = 12;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200595 sccp_con->bsc = con;
596 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
597
598 if (bsc_mgcp_find_con(nat, 11) != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100599 printf("Found the wrong connection.\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200600 abort();
601 }
602
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800603 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100604 printf("Didn't find the connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200605 abort();
606 }
607
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200608 /* free everything */
609 talloc_free(nat);
610}
611
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200612static void test_mgcp_rewrite(void)
613{
614 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200615 struct msgb *output;
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100616 printf("Testing rewriting MGCP messages.\n");
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200617
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200618 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
619 const char *orig = mgcp_messages[i].orig;
620 const char *patc = mgcp_messages[i].patch;
621 const char *ip = mgcp_messages[i].ip;
622 const int port = mgcp_messages[i].port;
623
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200624 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200625
Holger Hans Peter Freytherf7c86c52010-08-30 13:44:32 +0800626 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200627 if (msgb_l2len(output) != strlen(patc)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100628 printf("Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
629 printf("String '%s' vs '%s'\n", (const char *) output->l2h, patc);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200630 abort();
631 }
632
633 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100634 printf("Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200635 abort();
636 }
637
638 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200639 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200640 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200641}
642
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200643static void test_mgcp_parse(void)
644{
645 int code, ci;
646 char transaction[60];
647
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100648 printf("Testing MGCP response parsing.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200649
650 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100651 printf("Failed to parse CRCX resp.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200652 abort();
653 }
654
655 if (code != 200) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100656 printf("Failed to parse the CODE properly. Got: %d\n", code);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200657 abort();
658 }
659
660 if (strcmp(transaction, "23265295") != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100661 printf("Failed to parse transaction id: '%s'\n", transaction);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200662 abort();
663 }
664
665 ci = bsc_mgcp_extract_ci(crcx_resp);
666 if (ci != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100667 printf("Failed to parse the CI. Got: %d\n", ci);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200668 abort();
669 }
670}
671
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800672struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800673 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800674 int length;
675 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800676 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800677
678 const char *bsc_imsi_allow;
679 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800680 const char *nat_imsi_deny;
681};
682
683static struct cr_filter cr_filter[] = {
684 {
685 .data = bssmap_cr,
686 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800687 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800688 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800689 },
690 {
691 .data = bss_lu,
692 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800693 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800694 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800695 },
696 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800697 .data = pag_resp,
698 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800699 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800700 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800701 },
702 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800703 /* nat deny is before blank/null BSC */
704 .data = bss_lu,
705 .length = sizeof(bss_lu),
706 .result = -3,
707 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800708 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800709 },
710 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800711 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800712 .data = bss_lu,
713 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800714 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800715 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800716 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800717 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800718 },
719 {
720 /* BSC allow is before NAT deny */
721 .data = bss_lu,
722 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800723 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800724 .bsc_imsi_allow = "[0-9]*",
725 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800726 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800727 },
728 {
729 /* filter as deny is first */
730 .data = bss_lu,
731 .length = sizeof(bss_lu),
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200732 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800733 .bsc_imsi_deny = "[0-9]*",
734 .bsc_imsi_allow = "[0-9]*",
735 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800736 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800737 },
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200738 {
739 /* deny by nat rule */
740 .data = bss_lu,
741 .length = sizeof(bss_lu),
742 .result = -3,
743 .bsc_imsi_deny = "000[0-9]*",
744 .nat_imsi_deny = "[0-9]*",
745 .contype = NAT_CON_TYPE_LU,
746 },
747 {
748 /* deny by bsc rule */
749 .data = bss_lu,
750 .length = sizeof(bss_lu),
751 .result = -2,
752 .bsc_imsi_deny = "[0-9]*",
753 .contype = NAT_CON_TYPE_LU,
754 },
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800755
756};
757
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800758static void test_cr_filter()
759{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800760 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800761 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800762 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800763 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800764 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100765 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800766
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800767 struct bsc_nat *nat = bsc_nat_alloc();
768 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800769 bsc->cfg = bsc_config_alloc(nat, "foo");
770 bsc_config_add_lac(bsc->cfg, 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800771 bsc->cfg->acc_lst_name = "bsc";
772 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800773
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800774 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
775 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
776
777 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
778 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
779
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800780 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800781 char *imsi;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800782 msgb_reset(msg);
783 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
784
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800785 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
786 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800787
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200788 if (gsm_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800789 cr_filter[i].nat_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200790 &cr_filter[i].nat_imsi_deny) != 0)
791 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200792 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800793 cr_filter[i].bsc_imsi_allow ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200794 &cr_filter[i].bsc_imsi_allow) != 0)
795 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200796 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800797 cr_filter[i].bsc_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200798 &cr_filter[i].bsc_imsi_deny) != 0)
799 abort();
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800800
801 parsed = bsc_nat_parse(msg);
802 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100803 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800804 abort();
805 }
806
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100807 memset(&cause, 0, sizeof(cause));
808 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi, &cause);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800809 if (res != cr_filter[i].result) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100810 printf("FAIL: Wrong result %d for test %d.\n", res, i);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800811 abort();
812 }
813
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800814 if (contype != cr_filter[i].contype) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100815 printf("FAIL: Wrong contype %d for test %d.\n", res, contype);
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800816 abort();
817 }
818
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800819 talloc_steal(parsed, imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800820 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800821 }
822
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800823 msgb_free(msg);
824}
825
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800826static void test_dt_filter()
827{
828 int i;
829 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
830 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100831 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800832
833 struct bsc_nat *nat = bsc_nat_alloc();
834 struct bsc_connection *bsc = bsc_connection_alloc(nat);
835 struct sccp_connections *con = talloc_zero(0, struct sccp_connections);
836
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800837 bsc->cfg = bsc_config_alloc(nat, "foo");
838 bsc_config_add_lac(bsc->cfg, 23);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800839 con->bsc = bsc;
840
841 msgb_reset(msg);
842 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
843
844 parsed = bsc_nat_parse(msg);
845 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100846 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800847 abort();
848 }
849
850 if (parsed->bssap != BSSAP_MSG_DTAP) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100851 printf("FAIL: It should be dtap\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800852 abort();
853 }
854
855 /* gsm_type is actually the size of the dtap */
856 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100857 printf("FAIL: Not enough space for the content\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800858 abort();
859 }
860
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100861 memset(&cause, 0, sizeof(cause));
862 if (bsc_nat_filter_dt(bsc, msg, con, parsed, &cause) != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100863 printf("FAIL: Should have passed..\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800864 abort();
865 }
866
867 /* just some basic length checking... */
868 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
869 msgb_reset(msg);
870 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
871
872 parsed = bsc_nat_parse(msg);
873 if (!parsed)
874 continue;
875
876 con->imsi_checked = 0;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100877 memset(&cause, 0, sizeof(cause));
878 bsc_nat_filter_dt(bsc, msg, con, parsed, &cause);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800879 }
880}
881
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200882static void test_setup_rewrite()
883{
884 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
885 struct msgb *out;
886 struct bsc_nat_parsed *parsed;
887 const char *imsi = "27408000001234";
888
889 struct bsc_nat *nat = bsc_nat_alloc();
890
891 /* a fake list */
Pablo Neira Ayusoab46cf32011-05-07 13:11:20 +0200892 struct osmo_config_list entries;
893 struct osmo_config_entry entry;
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200894
895 INIT_LLIST_HEAD(&entries.entry);
896 entry.mcc = "274";
897 entry.mnc = "08";
898 entry.option = "^0([1-9])";
899 entry.text = "0049";
900 llist_add_tail(&entry.list, &entries.entry);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200901 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200902
903 /* verify that nothing changed */
904 msgb_reset(msg);
905 copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
906 parsed = bsc_nat_parse(msg);
907 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100908 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200909 abort();
910 }
911
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200912 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200913 if (msg != out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100914 printf("FAIL: The message should not have been changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200915 abort();
916 }
917
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100918 verify_msg(out, cc_setup_international, ARRAY_SIZE(cc_setup_international));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200919 talloc_free(parsed);
920
921 /* verify that something in the message changes */
922 msgb_reset(msg);
923 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
924 parsed = bsc_nat_parse(msg);
925 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100926 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200927 abort();
928 }
929
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200930 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200931 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100932 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200933 abort();
934 }
935
936 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100937 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200938 abort();
939 }
940
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100941 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200942 msgb_free(out);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200943
944 /* Make sure that a wildcard is matching */
945 entry.mnc = "*";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200946 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200947 msg = msgb_alloc(4096, "test_dt_filter");
948 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
949 parsed = bsc_nat_parse(msg);
950 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100951 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200952 abort();
953 }
954
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200955 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200956 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100957 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200958 abort();
959 }
960
961 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100962 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200963 abort();
964 }
965
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100966 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200967 msgb_free(out);
968
969 /* Make sure that a wildcard is matching */
970 entry.mnc = "09";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200971 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200972 msg = msgb_alloc(4096, "test_dt_filter");
973 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
974 parsed = bsc_nat_parse(msg);
975 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100976 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200977 abort();
978 }
979
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200980 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200981 if (out != msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100982 printf("FAIL: The message should be unchanged.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200983 abort();
984 }
985
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100986 verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200987 msgb_free(out);
Holger Hans Peter Freytherdbd94492013-04-02 12:34:11 +0200988
989 /* Now see what happens to an international number */
990 entry.mnc = "*";
991 entry.option = "^\\+[0-9][0-9]([1-9])";
992 entry.text = "0036";
993 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
994 msg = msgb_alloc(4096, "test_dt_filter");
995 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
996 parsed = bsc_nat_parse(msg);
997 if (!parsed) {
998 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
999 abort();
1000 }
1001
1002 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1003 if (!out) {
1004 printf("FAIL: A new message should be created %d.\n", __LINE__);
1005 abort();
1006 }
1007
1008 if (msg == out) {
1009 printf("FAIL: The message should have changed %d\n", __LINE__);
1010 abort();
1011 }
1012
1013 verify_msg(out, cc_setup_national_patched_patched,
1014 ARRAY_SIZE(cc_setup_national_patched_patched));
1015 msgb_free(out);
1016
1017 /* go from international back to national */
1018 entry.mnc = "*";
1019 entry.option = "^\\+([0-9])";
1020 entry.text = "36";
1021 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1022 msg = msgb_alloc(4096, "test_dt_filter");
1023 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1024 parsed = bsc_nat_parse(msg);
1025 if (!parsed) {
1026 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
1027 abort();
1028 }
1029
1030 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1031 if (!out) {
1032 printf("FAIL: A new message should be created %d.\n", __LINE__);
1033 abort();
1034 }
1035
1036 if (msg == out) {
1037 printf("FAIL: The message should have changed %d\n", __LINE__);
1038 abort();
1039 }
1040
1041 verify_msg(out, cc_setup_national_again,
1042 ARRAY_SIZE(cc_setup_national_again));
1043 msgb_free(out);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001044}
1045
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001046static void test_sms_smsc_rewrite()
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001047{
1048 struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
1049 struct bsc_nat_parsed *parsed;
1050 const char *imsi = "515039900406700";
1051
1052 struct bsc_nat *nat = bsc_nat_alloc();
1053
1054 /* a fake list */
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001055 struct osmo_config_list smsc_entries, dest_entries, clear_entries;
1056 struct osmo_config_entry smsc_entry, dest_entry, clear_entry;
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001057
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001058 INIT_LLIST_HEAD(&smsc_entries.entry);
1059 INIT_LLIST_HEAD(&dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001060 INIT_LLIST_HEAD(&clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001061 smsc_entry.mcc = "^515039";
1062 smsc_entry.option = "639180000105()";
1063 smsc_entry.text = "6666666666667";
1064 llist_add_tail(&smsc_entry.list, &smsc_entries.entry);
1065 dest_entry.mcc = "515";
1066 dest_entry.mnc = "03";
1067 dest_entry.option = "^0049";
1068 dest_entry.text = "";
1069 llist_add_tail(&dest_entry.list, &dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001070 clear_entry.mcc = "^515039";
1071 clear_entry.option = "^0049";
1072 clear_entry.text = "";
1073 llist_add_tail(&clear_entry.list, &clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001074
1075 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
1076 bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001077 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001078
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001079 printf("Testing SMSC rewriting.\n");
1080
1081 /*
1082 * Check if the SMSC address is changed
1083 */
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001084 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1085 parsed = bsc_nat_parse(msg);
1086 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001087 printf("FAIL: Could not parse SMS\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001088 abort();
1089 }
1090
1091 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1092 if (out == msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001093 printf("FAIL: This should have changed.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001094 abort();
1095 }
1096
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +01001097 verify_msg(out, smsc_rewrite_patched, ARRAY_SIZE(smsc_rewrite_patched));
1098 msgb_free(out);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001099
1100 /* clear out the filter for SMSC */
1101 printf("Attempting to only rewrite the HDR\n");
1102 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL);
1103 msg = msgb_alloc(4096, "SMSC rewrite");
1104 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1105 parsed = bsc_nat_parse(msg);
1106 if (!parsed) {
1107 printf("FAIL: Could not parse SMS\n");
1108 abort();
1109 }
1110
1111 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1112 if (out == msg) {
1113 printf("FAIL: This should have changed.\n");
1114 abort();
1115 }
1116
1117 verify_msg(out, smsc_rewrite_patched_hdr, ARRAY_SIZE(smsc_rewrite_patched_hdr));
1118 msgb_free(out);
1119
1120 /* clear out the next filter */
1121 printf("Attempting to change nothing.\n");
1122 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL);
1123 msg = msgb_alloc(4096, "SMSC rewrite");
1124 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1125 parsed = bsc_nat_parse(msg);
1126 if (!parsed) {
1127 printf("FAIL: Could not parse SMS\n");
1128 abort();
1129 }
1130
1131 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1132 if (out != msg) {
1133 printf("FAIL: This should not have changed.\n");
1134 abort();
1135 }
1136
1137 verify_msg(out, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1138 msgb_free(out);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001139}
1140
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001141static void test_sms_number_rewrite(void)
1142{
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001143 struct msgb *msg, *out;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001144 struct bsc_nat_parsed *parsed;
1145 const char *imsi = "515039900406700";
1146
1147 struct bsc_nat *nat = bsc_nat_alloc();
1148
1149 /* a fake list */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001150 struct osmo_config_list num_entries, clear_entries;
1151 struct osmo_config_entry num_entry, clear_entry;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001152
1153 INIT_LLIST_HEAD(&num_entries.entry);
1154 num_entry.mcc = "^515039";
1155 num_entry.option = "^0049()";
1156 num_entry.text = "0032";
1157 llist_add_tail(&num_entry.list, &num_entries.entry);
1158
1159 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_num_rewr, &num_entries);
1160
1161 printf("Testing SMS TP-DA rewriting.\n");
1162
1163 /*
1164 * Check if the SMSC address is changed
1165 */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001166 msg = msgb_alloc(4096, "SMSC rewrite");
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001167 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1168 parsed = bsc_nat_parse(msg);
1169 if (!parsed) {
1170 printf("FAIL: Could not parse SMS\n");
1171 abort();
1172 }
1173
1174 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1175 if (out == msg) {
1176 printf("FAIL: This should have changed.\n");
1177 abort();
1178 }
1179
1180 verify_msg(out, smsc_rewrite_num_patched,
1181 ARRAY_SIZE(smsc_rewrite_num_patched));
1182 msgb_free(out);
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001183
1184 /*
1185 * Now with TP-SRR rewriting enabled
1186 */
1187 INIT_LLIST_HEAD(&clear_entries.entry);
1188 clear_entry.mcc = "^515039";
1189 clear_entry.option = "";
1190 clear_entry.text = "";
1191 llist_add_tail(&clear_entry.list, &clear_entries.entry);
1192 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
1193
1194 msg = msgb_alloc(4096, "SMSC rewrite");
1195 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1196 parsed = bsc_nat_parse(msg);
1197 if (!parsed) {
1198 printf("FAIL: Could not parse SMS\n");
1199 abort();
1200 }
1201
1202 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1203 if (out == msg) {
1204 printf("FAIL: This should have changed.\n");
1205 abort();
1206 }
1207
1208 verify_msg(out, smsc_rewrite_num_patched_tp_srr,
1209 ARRAY_SIZE(smsc_rewrite_num_patched_tp_srr));
1210 msgb_free(out);
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001211}
1212
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001213static void test_barr_list_parsing(void)
1214{
1215 int rc;
1216 int cm, lu;
1217 struct rb_node *node;
1218 struct rb_root root = RB_ROOT;
1219 struct osmo_config_list *lst = osmo_config_list_parse(NULL, "barr.cfg");
1220 if (lst == NULL)
1221 abort();
1222
1223 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1224 if (rc != 0)
1225 abort();
1226 talloc_free(lst);
1227
1228
1229 for (node = rb_first(&root); node; node = rb_next(node)) {
1230 struct bsc_nat_barr_entry *entry;
1231 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1232 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1233 entry->cm_reject_cause, entry->lu_reject_cause);
1234 }
1235
1236 /* do the look up now.. */
1237 rc = bsc_nat_barr_find(&root, "12123119", &cm, &lu);
1238 if (!rc) {
1239 printf("Failed to find the IMSI.\n");
1240 abort();
1241 }
1242
1243 if (cm != 3 || lu != 4) {
1244 printf("Found CM(%d) and LU(%d)\n", cm, lu);
1245 abort();
1246 }
1247
1248 /* empty and check that it is empty */
1249 bsc_nat_barr_adapt(NULL, &root, NULL);
1250 if (!RB_EMPTY_ROOT(&root)) {
1251 printf("Failed to empty the list.\n");
1252 abort();
1253 }
1254
1255 /* check that dup results in an error */
1256 lst = osmo_config_list_parse(NULL, "barr_dup.cfg");
1257 if (lst == NULL) {
1258 printf("Failed to parse list with dups\n");
1259 abort();
1260 }
1261
1262 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1263 if (rc != -1) {
1264 printf("It should have failed due dup\n");
1265 abort();
1266 }
1267 talloc_free(lst);
1268
1269 /* dump for reference */
1270 for (node = rb_first(&root); node; node = rb_next(node)) {
1271 struct bsc_nat_barr_entry *entry;
1272 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1273 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1274 entry->cm_reject_cause, entry->lu_reject_cause);
1275
1276 }
1277}
1278
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001279int main(int argc, char **argv)
1280{
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +08001281 sccp_set_log_area(DSCCP);
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +02001282 osmo_init_logging(&log_info);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001283
1284 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001285 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001286 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +02001287 test_mgcp_ass_tracking();
1288 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +02001289 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +02001290 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +08001291 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +08001292 test_dt_filter();
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001293 test_setup_rewrite();
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001294 test_sms_smsc_rewrite();
1295 test_sms_number_rewrite();
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +01001296 test_mgcp_allocations();
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001297 test_barr_list_parsing();
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001298
1299 printf("Testing execution completed.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001300 return 0;
1301}
Holger Hans Peter Freytherc3271872012-11-05 14:54:56 +01001302
1303/* stub */
1304void bsc_nat_send_mgcp_to_msc(struct bsc_nat *nat, struct msgb *msg)
1305{
1306 abort();
1307}