blob: 5158f46cf55d9ba4fbb2045fe245aa8532b4be5e [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 Freytherddf191e2013-06-25 11:44:01 +020029#include <openbsc/nat_rewrite_trie.h>
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080030
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +020031#include <osmocom/core/application.h>
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +020032#include <osmocom/core/backtrace.h>
Pablo Neira Ayuso928cb332011-03-26 22:08:53 +010033#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +080034
Harald Welted5db12c2010-08-03 15:11:51 +020035#include <osmocom/sccp/sccp.h>
Pablo Neira Ayuso928cb332011-03-26 22:08:53 +010036#include <osmocom/gsm/protocol/gsm_08_08.h>
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +080037
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080038#include <stdio.h>
39
40/* test messages for ipa */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080041static uint8_t ipa_id[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080042 0x00, 0x01, 0xfe, 0x06,
43};
44
45/* SCCP messages are below */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080046static uint8_t gsm_reset[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080047 0x00, 0x12, 0xfd,
48 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
49 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
50 0x01, 0x20,
51};
52
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080053static const uint8_t gsm_reset_ack[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080054 0x00, 0x13, 0xfd,
55 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
56 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
57 0x00, 0x01, 0x31,
58};
59
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080060static const uint8_t gsm_paging[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080061 0x00, 0x20, 0xfd,
62 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
63 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10,
64 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10,
65 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06,
66};
67
68/* BSC -> MSC connection open */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080069static const uint8_t bssmap_cr[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080070 0x00, 0x2c, 0xfd,
71 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02,
72 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05,
73 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3,
74 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33,
75 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01,
76 0x31, 0x97, 0x61, 0x00
77};
78
79/* MSC -> BSC connection confirm */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080080static const uint8_t bssmap_cc[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080081 0x00, 0x0a, 0xfd,
82 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
83};
84
85/* MSC -> BSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080086static const uint8_t bssmap_released[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080087 0x00, 0x0e, 0xfd,
88 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f,
89 0x02, 0x23, 0x42, 0x00,
90};
91
92/* BSC -> MSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080093static const uint8_t bssmap_release_complete[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080094 0x00, 0x07, 0xfd,
95 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03
96};
97
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020098/* both directions IT timer */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080099static const uint8_t connnection_it[] = {
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +0200100 0x00, 0x0b, 0xfd,
101 0x10, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03,
102 0x00, 0x00, 0x00, 0x00,
103};
104
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800105/* error in both directions */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800106static const uint8_t proto_error[] = {
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800107 0x00, 0x05, 0xfd,
108 0x0f, 0x22, 0x33, 0x44, 0x00,
109};
110
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200111/* MGCP wrap... */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800112static const uint8_t mgcp_msg[] = {
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200113 0x00, 0x03, 0xfc,
114 0x20, 0x20, 0x20,
115};
116
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800117/* location updating request */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800118static const uint8_t bss_lu[] = {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800119 0x00, 0x2e, 0xfd,
120 0x01, 0x91, 0x45, 0x14, 0x02, 0x02, 0x04, 0x02,
121 0x42, 0xfe, 0x0f, 0x21, 0x00, 0x1f, 0x57, 0x05,
122 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x14, 0xc3,
123 0x50, 0x17, 0x12, 0x05, 0x08, 0x70, 0x72, 0xf4,
124 0x80, 0xff, 0xfe, 0x30, 0x08, 0x29, 0x44, 0x50,
125 0x12, 0x03, 0x24, 0x01, 0x95, 0x00
126};
127
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800128/* paging response */
129static const uint8_t pag_resp[] = {
130 0x00, 0x2c, 0xfd, 0x01, 0xe5, 0x68,
131 0x14, 0x02, 0x02, 0x04, 0x02, 0x42, 0xfe, 0x0f,
132 0x1f, 0x00, 0x1d, 0x57, 0x05, 0x08, 0x00, 0x72,
133 0xf4, 0x80, 0x20, 0x16, 0xc3, 0x50, 0x17, 0x10,
134 0x06, 0x27, 0x01, 0x03, 0x30, 0x18, 0x96, 0x08,
135 0x29, 0x26, 0x30, 0x32, 0x11, 0x42, 0x01, 0x19,
136 0x00
137};
138
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800139struct filter_result {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800140 const uint8_t *data;
Holger Hans Peter Freythere2c15202010-07-23 19:09:21 +0800141 const uint16_t length;
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100142 const int dir;
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800143 const int result;
144};
145
146static const struct filter_result results[] = {
147 {
148 .data = ipa_id,
149 .length = ARRAY_SIZE(ipa_id),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100150 .dir = DIR_MSC,
151 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800152 },
153 {
154 .data = gsm_reset,
155 .length = ARRAY_SIZE(gsm_reset),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100156 .dir = DIR_MSC,
157 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800158 },
159 {
160 .data = gsm_reset_ack,
161 .length = ARRAY_SIZE(gsm_reset_ack),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100162 .dir = DIR_BSC,
163 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800164 },
165 {
166 .data = gsm_paging,
167 .length = ARRAY_SIZE(gsm_paging),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100168 .dir = DIR_BSC,
169 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800170 },
171 {
172 .data = bssmap_cr,
173 .length = ARRAY_SIZE(bssmap_cr),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100174 .dir = DIR_MSC,
175 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800176 },
177 {
178 .data = bssmap_cc,
179 .length = ARRAY_SIZE(bssmap_cc),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100180 .dir = DIR_BSC,
181 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800182 },
183 {
184 .data = bssmap_released,
185 .length = ARRAY_SIZE(bssmap_released),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100186 .dir = DIR_MSC,
187 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800188 },
189 {
190 .data = bssmap_release_complete,
191 .length = ARRAY_SIZE(bssmap_release_complete),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100192 .dir = DIR_BSC,
193 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800194 },
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200195 {
196 .data = mgcp_msg,
197 .length = ARRAY_SIZE(mgcp_msg),
198 .dir = DIR_MSC,
199 .result = 0,
200 },
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +0200201 {
202 .data = connnection_it,
203 .length = ARRAY_SIZE(connnection_it),
204 .dir = DIR_BSC,
205 .result = 0,
206 },
207 {
208 .data = connnection_it,
209 .length = ARRAY_SIZE(connnection_it),
210 .dir = DIR_MSC,
211 .result = 0,
212 },
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800213 {
214 .data = proto_error,
215 .length = ARRAY_SIZE(proto_error),
216 .dir = DIR_BSC,
217 .result = 0,
218 },
219 {
220 .data = proto_error,
221 .length = ARRAY_SIZE(proto_error),
222 .dir = DIR_MSC,
223 .result = 0,
224 },
225
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800226};
227
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800228static void test_filter(void)
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800229{
230 int i;
231
232
233 /* start testinh with proper messages */
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100234 printf("Testing BSS Filtering.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800235 for (i = 0; i < ARRAY_SIZE(results); ++i) {
236 int result;
237 struct bsc_nat_parsed *parsed;
238 struct msgb *msg = msgb_alloc(4096, "test-message");
239
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100240 printf("Going to test item: %d\n", i);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800241 memcpy(msg->data, results[i].data, results[i].length);
242 msg->l2h = msgb_put(msg, results[i].length);
243
244 parsed = bsc_nat_parse(msg);
245 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100246 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800247 continue;
248 }
249
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100250 result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800251 if (result != results[i].result) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100252 printf("FAIL: Not the expected result got: %d wanted: %d\n",
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800253 result, results[i].result);
254 }
255
256 msgb_free(msg);
257 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800258}
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800259
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800260#include "bsc_data.c"
261
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800262static void copy_to_msg(struct msgb *msg, const uint8_t *data, unsigned int length)
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800263{
264 msgb_reset(msg);
265 msg->l2h = msgb_put(msg, length);
266 memcpy(msg->l2h, data, msgb_l2len(msg));
267}
268
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100269static void verify_msg(struct msgb *out, const uint8_t *ref, int ref_len)
270{
271 if (out->len != ref_len) {
Holger Hans Peter Freytherbe530122012-01-18 17:20:23 +0100272 printf("FAIL: The size should match: %d vs. %d\n",
273 out->len, ref_len);
274 printf("%s\n", osmo_hexdump(out->data, out->len));
275 printf("Wanted\n");
276 printf("%s\n", osmo_hexdump(ref, ref_len));
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100277 abort();
278 }
279
280 if (memcmp(out->data, ref, out->len) != 0) {
281 printf("FAIL: the data should be changed.\n");
282 printf("%s\n", osmo_hexdump(out->data, out->len));
283 printf("Wanted\n");
284 printf("%s\n", osmo_hexdump(ref, ref_len));
285 abort();
286 }
287}
288
289
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800290#define VERIFY(con_found, con, msg, ver, str) \
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100291 if (!con_found) { \
292 printf("Failed to find connection.\n"); \
293 abort(); \
294 } \
295 if (con_found->bsc != con) { \
296 printf("Got connection of the wrong BSC: %d\n", \
297 con_found->bsc->cfg->nr); \
298 abort(); \
299 } \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800300 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100301 printf("Failed to patch the %s msg.\n", str); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800302 abort(); \
303 }
304
305/* test conn tracking once */
306static void test_contrack()
307{
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800308 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800309 struct bsc_connection *con;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200310 struct nat_sccp_connection *con_found;
311 struct nat_sccp_connection *rc_con;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800312 struct bsc_nat_parsed *parsed;
313 struct msgb *msg;
314
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100315 printf("Testing connection tracking.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800316 nat = bsc_nat_alloc();
317 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800318 con->cfg = bsc_config_alloc(nat, "foo");
319 bsc_config_add_lac(con->cfg, 23);
320 bsc_config_add_lac(con->cfg, 49);
321 bsc_config_add_lac(con->cfg, 42);
322 bsc_config_del_lac(con->cfg, 49);
323 bsc_config_add_lac(con->cfg, 1111);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800324 msg = msgb_alloc(4096, "test");
325
326 /* 1.) create a connection */
327 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
328 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800329 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800330 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100331 printf("Con should not exist realref(%u)\n",
332 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800333 abort();
334 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800335 rc_con = create_sccp_src_ref(con, parsed);
336 if (!rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100337 printf("Failed to create a ref\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800338 abort();
339 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800340 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100341 if (!con_found) {
342 printf("Failed to find connection.\n");
343 abort();
344 }
345 if (con_found->bsc != con) {
346 printf("Got connection of the wrong BSC: %d\n",
347 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800348 abort();
349 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800350 if (con_found != rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100351 printf("Failed to find the right connection.\n");
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800352 abort();
353 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800354 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100355 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800356 abort();
357 }
358 talloc_free(parsed);
359
360 /* 2.) get the cc */
361 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
362 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800363 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
364 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
365 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100366 printf("Failed to update the SCCP con.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800367 abort();
368 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800369
370 /* 3.) send some data */
371 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
372 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800373 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800374 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
375
376 /* 4.) receive some data */
377 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
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_dtap_patched, "MSC DTAP");
381
382 /* 5.) close the connection */
383 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
384 parsed = bsc_nat_parse(msg);
385 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
386 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
387
388 /* 6.) confirm the connection close */
389 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
390 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800391 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100392 if (!con_found) {
393 printf("Failed to find connection.\n");
394 abort();
395 }
396 if (con_found->bsc != con) {
397 printf("Got connection of the wrong BSC: %d\n",
398 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800399 abort();
400 }
401 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100402 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800403 abort();
404 }
405 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200406 talloc_free(parsed);
407
408 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
409 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800410 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800411
412 /* verify that it is gone */
413 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100414 printf("Con should not exist real_ref(%u)\n",
415 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800416 abort();
417 }
418 talloc_free(parsed);
419
420
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100421 bsc_config_free(con->cfg);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800422 talloc_free(nat);
423 msgb_free(msg);
424}
425
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200426static void test_paging(void)
427{
428 struct bsc_nat *nat;
429 struct bsc_connection *con;
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800430 struct bsc_config *cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200431
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100432 printf("Testing paging by lac.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200433
434 nat = bsc_nat_alloc();
435 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800436 cfg = bsc_config_alloc(nat, "unknown");
437 con->cfg = cfg;
438 bsc_config_add_lac(cfg, 23);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200439 con->authenticated = 1;
440 llist_add(&con->list_entry, &nat->bsc_connections);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200441
442 /* Test it by not finding it */
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200443 if (bsc_config_handles_lac(cfg, 8213) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100444 printf("Should not be handled.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200445 abort();
446 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200447
448 /* Test by finding it */
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800449 bsc_config_del_lac(cfg, 23);
450 bsc_config_add_lac(cfg, 8213);
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200451 if (bsc_config_handles_lac(cfg, 8213) == 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100452 printf("Should have found it.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200453 abort();
454 }
Holger Hans Peter Freyther3615a302013-06-25 12:03:36 +0200455
456 talloc_free(nat);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200457}
458
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100459static void test_mgcp_allocations(void)
460{
461#if 0
462 struct bsc_connection *bsc;
463 struct bsc_nat *nat;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200464 struct nat_sccp_connection con;
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100465 int i, j, multiplex;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100466
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100467 printf("Testing MGCP.\n");
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100468 memset(&con, 0, sizeof(con));
469
470 nat = bsc_nat_alloc();
471 nat->bsc_endpoints = talloc_zero_array(nat,
472 struct bsc_endpoint,
473 65);
474 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100475 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100476
477 bsc = bsc_connection_alloc(nat);
478 bsc->cfg = bsc_config_alloc(nat, "foo");
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100479 bsc->cfg->max_endpoints = 60;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100480 bsc_config_add_lac(bsc->cfg, 2323);
481 bsc->last_endpoint = 0x22;
482 con.bsc = bsc;
483
484 bsc_init_endps_if_needed(bsc);
485
486 i = 1;
487 do {
488 if (bsc_assign_endpoint(bsc, &con) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100489 printf("failed to allocate... on iteration %d\n", i);
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100490 break;
491 }
492 ++i;
493 } while(1);
494
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100495 multiplex = bsc_mgcp_nr_multiplexes(bsc->cfg->max_endpoints);
496 for (i = 0; i < multiplex; ++i) {
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100497 for (j = 0; j < 32; ++j)
498 printf("%d", bsc->_endpoint_status[i*32 + j]);
499 printf(": %d of %d\n", i*32 + 32, 32 * 8);
500 }
501#endif
502}
503
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200504static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800505{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800506 struct bsc_connection *bsc;
507 struct bsc_nat *nat;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200508 struct nat_sccp_connection con;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800509 struct bsc_nat_parsed *parsed;
510 struct msgb *msg;
511
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100512 printf("Testing MGCP.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800513 memset(&con, 0, sizeof(con));
514
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800515 nat = bsc_nat_alloc();
516 nat->bsc_endpoints = talloc_zero_array(nat,
517 struct bsc_endpoint,
518 33);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100519 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100520 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freyther462b7d72012-10-24 21:53:40 +0200521 mgcp_endpoints_allocate(&nat->mgcp_cfg->trunk);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100522
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800523 bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800524 bsc->cfg = bsc_config_alloc(nat, "foo");
525 bsc_config_add_lac(bsc->cfg, 2323);
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100526 bsc->last_endpoint = 0x1e;
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800527 con.bsc = bsc;
528
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800529 msg = msgb_alloc(4096, "foo");
530 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
531 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800532
533 if (msg->l2h[16] != 0 ||
534 msg->l2h[17] != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100535 printf("Input is not as expected.. %s 0x%x\n",
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200536 osmo_hexdump(msg->l2h, msgb_l2len(msg)),
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800537 msg->l2h[17]);
538 abort();
539 }
540
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800541 if (bsc_mgcp_assign_patch(&con, msg) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100542 printf("Failed to handle assignment.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800543 abort();
544 }
545
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800546 if (con.msc_endp != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100547 printf("Timeslot should be 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800548 abort();
549 }
550
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100551 if (con.bsc_endp != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100552 printf("Assigned timeslot should have been 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800553 abort();
554 }
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100555 if (con.bsc->_endpoint_status[0x1] != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100556 printf("The status on the BSC is wrong.\n");
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800557 abort();
558 }
559
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800560 int multiplex, timeslot;
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100561 mgcp_endpoint_to_timeslot(0x1, &multiplex, &timeslot);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800562
563 uint16_t cic = htons(timeslot & 0x1f);
564 if (memcmp(&cic, &msg->l2h[16], sizeof(cic)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100565 printf("Message was not patched properly\n");
566 printf("data cic: 0x%x %s\n", cic, osmo_hexdump(msg->l2h, msgb_l2len(msg)));
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800567 abort();
568 }
569
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800570 talloc_free(parsed);
571
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800572 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800573 if (con.bsc_endp != -1 || con.msc_endp != -1 ||
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100574 con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100575 printf("Clearing should remove the mapping.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800576 abort();
577 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800578
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100579 bsc_config_free(bsc->cfg);
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800580 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800581}
582
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200583/* test the code to find a given connection */
584static void test_mgcp_find(void)
585{
586 struct bsc_nat *nat;
587 struct bsc_connection *con;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200588 struct nat_sccp_connection *sccp_con;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200589
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100590 printf("Testing finding of a BSC Connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200591
592 nat = bsc_nat_alloc();
593 con = bsc_connection_alloc(nat);
594 llist_add(&con->list_entry, &nat->bsc_connections);
595
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200596 sccp_con = talloc_zero(con, struct nat_sccp_connection);
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800597 sccp_con->msc_endp = 12;
598 sccp_con->bsc_endp = 12;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200599 sccp_con->bsc = con;
600 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
601
602 if (bsc_mgcp_find_con(nat, 11) != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100603 printf("Found the wrong connection.\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200604 abort();
605 }
606
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800607 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100608 printf("Didn't find the connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200609 abort();
610 }
611
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200612 /* free everything */
613 talloc_free(nat);
614}
615
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200616static void test_mgcp_rewrite(void)
617{
618 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200619 struct msgb *output;
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100620 printf("Testing rewriting MGCP messages.\n");
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200621
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200622 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
623 const char *orig = mgcp_messages[i].orig;
624 const char *patc = mgcp_messages[i].patch;
625 const char *ip = mgcp_messages[i].ip;
626 const int port = mgcp_messages[i].port;
627
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200628 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200629
Holger Hans Peter Freytherf7c86c52010-08-30 13:44:32 +0800630 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200631 if (msgb_l2len(output) != strlen(patc)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100632 printf("Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
633 printf("String '%s' vs '%s'\n", (const char *) output->l2h, patc);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200634 abort();
635 }
636
637 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100638 printf("Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200639 abort();
640 }
641
642 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200643 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200644 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200645}
646
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200647static void test_mgcp_parse(void)
648{
649 int code, ci;
650 char transaction[60];
651
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100652 printf("Testing MGCP response parsing.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200653
654 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100655 printf("Failed to parse CRCX resp.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200656 abort();
657 }
658
659 if (code != 200) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100660 printf("Failed to parse the CODE properly. Got: %d\n", code);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200661 abort();
662 }
663
664 if (strcmp(transaction, "23265295") != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100665 printf("Failed to parse transaction id: '%s'\n", transaction);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200666 abort();
667 }
668
669 ci = bsc_mgcp_extract_ci(crcx_resp);
670 if (ci != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100671 printf("Failed to parse the CI. Got: %d\n", ci);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200672 abort();
673 }
674}
675
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800676struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800677 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800678 int length;
679 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800680 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800681
682 const char *bsc_imsi_allow;
683 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800684 const char *nat_imsi_deny;
685};
686
687static struct cr_filter cr_filter[] = {
688 {
689 .data = bssmap_cr,
690 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800691 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800692 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800693 },
694 {
695 .data = bss_lu,
696 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800697 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800698 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800699 },
700 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800701 .data = pag_resp,
702 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800703 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800704 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800705 },
706 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800707 /* nat deny is before blank/null BSC */
708 .data = bss_lu,
709 .length = sizeof(bss_lu),
710 .result = -3,
711 .nat_imsi_deny = "[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 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800715 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800716 .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 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800720 .bsc_imsi_allow = "2440[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 /* BSC allow is before NAT deny */
725 .data = bss_lu,
726 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800727 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800728 .bsc_imsi_allow = "[0-9]*",
729 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800730 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800731 },
732 {
733 /* filter as deny is first */
734 .data = bss_lu,
735 .length = sizeof(bss_lu),
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200736 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800737 .bsc_imsi_deny = "[0-9]*",
738 .bsc_imsi_allow = "[0-9]*",
739 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800740 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800741 },
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200742 {
743 /* deny by nat rule */
744 .data = bss_lu,
745 .length = sizeof(bss_lu),
746 .result = -3,
747 .bsc_imsi_deny = "000[0-9]*",
748 .nat_imsi_deny = "[0-9]*",
749 .contype = NAT_CON_TYPE_LU,
750 },
751 {
752 /* deny by bsc rule */
753 .data = bss_lu,
754 .length = sizeof(bss_lu),
755 .result = -2,
756 .bsc_imsi_deny = "[0-9]*",
757 .contype = NAT_CON_TYPE_LU,
758 },
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800759
760};
761
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800762static void test_cr_filter()
763{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800764 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800765 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800766 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800767 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800768 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100769 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800770
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800771 struct bsc_nat *nat = bsc_nat_alloc();
772 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800773 bsc->cfg = bsc_config_alloc(nat, "foo");
774 bsc_config_add_lac(bsc->cfg, 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800775 bsc->cfg->acc_lst_name = "bsc";
776 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800777
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800778 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
779 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
780
781 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
782 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
783
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800784 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800785 char *imsi;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800786 msgb_reset(msg);
787 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
788
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200789 if (gsm_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800790 cr_filter[i].nat_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200791 &cr_filter[i].nat_imsi_deny) != 0)
792 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200793 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800794 cr_filter[i].bsc_imsi_allow ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200795 &cr_filter[i].bsc_imsi_allow) != 0)
796 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200797 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800798 cr_filter[i].bsc_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200799 &cr_filter[i].bsc_imsi_deny) != 0)
800 abort();
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800801
802 parsed = bsc_nat_parse(msg);
803 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100804 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800805 abort();
806 }
807
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100808 memset(&cause, 0, sizeof(cause));
809 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi, &cause);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800810 if (res != cr_filter[i].result) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100811 printf("FAIL: Wrong result %d for test %d.\n", res, i);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800812 abort();
813 }
814
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800815 if (contype != cr_filter[i].contype) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100816 printf("FAIL: Wrong contype %d for test %d.\n", res, contype);
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800817 abort();
818 }
819
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800820 talloc_steal(parsed, imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800821 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800822 }
823
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800824 msgb_free(msg);
Holger Hans Peter Freyther3615a302013-06-25 12:03:36 +0200825 talloc_free(nat);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800826}
827
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800828static void test_dt_filter()
829{
830 int i;
831 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
832 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100833 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800834
835 struct bsc_nat *nat = bsc_nat_alloc();
836 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200837 struct nat_sccp_connection *con = talloc_zero(0, struct nat_sccp_connection);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800838
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800839 bsc->cfg = bsc_config_alloc(nat, "foo");
840 bsc_config_add_lac(bsc->cfg, 23);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800841 con->bsc = bsc;
842
843 msgb_reset(msg);
844 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
845
846 parsed = bsc_nat_parse(msg);
847 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100848 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800849 abort();
850 }
851
852 if (parsed->bssap != BSSAP_MSG_DTAP) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100853 printf("FAIL: It should be dtap\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800854 abort();
855 }
856
857 /* gsm_type is actually the size of the dtap */
858 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100859 printf("FAIL: Not enough space for the content\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800860 abort();
861 }
862
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100863 memset(&cause, 0, sizeof(cause));
864 if (bsc_nat_filter_dt(bsc, msg, con, parsed, &cause) != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100865 printf("FAIL: Should have passed..\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800866 abort();
867 }
868
869 /* just some basic length checking... */
870 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
871 msgb_reset(msg);
872 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
873
874 parsed = bsc_nat_parse(msg);
875 if (!parsed)
876 continue;
877
878 con->imsi_checked = 0;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100879 memset(&cause, 0, sizeof(cause));
880 bsc_nat_filter_dt(bsc, msg, con, parsed, &cause);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800881 }
882}
883
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200884static void test_setup_rewrite()
885{
886 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
887 struct msgb *out;
888 struct bsc_nat_parsed *parsed;
889 const char *imsi = "27408000001234";
890
891 struct bsc_nat *nat = bsc_nat_alloc();
892
893 /* a fake list */
Pablo Neira Ayusoab46cf32011-05-07 13:11:20 +0200894 struct osmo_config_list entries;
895 struct osmo_config_entry entry;
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200896
897 INIT_LLIST_HEAD(&entries.entry);
898 entry.mcc = "274";
899 entry.mnc = "08";
900 entry.option = "^0([1-9])";
901 entry.text = "0049";
902 llist_add_tail(&entry.list, &entries.entry);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200903 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200904
905 /* verify that nothing changed */
906 msgb_reset(msg);
907 copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
908 parsed = bsc_nat_parse(msg);
909 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100910 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200911 abort();
912 }
913
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200914 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200915 if (msg != out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100916 printf("FAIL: The message should not have been changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200917 abort();
918 }
919
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100920 verify_msg(out, cc_setup_international, ARRAY_SIZE(cc_setup_international));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200921 talloc_free(parsed);
922
923 /* verify that something in the message changes */
924 msgb_reset(msg);
925 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
926 parsed = bsc_nat_parse(msg);
927 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100928 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200929 abort();
930 }
931
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200932 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200933 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100934 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200935 abort();
936 }
937
938 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100939 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200940 abort();
941 }
942
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100943 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200944 msgb_free(out);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200945
946 /* Make sure that a wildcard is matching */
947 entry.mnc = "*";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200948 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200949 msg = msgb_alloc(4096, "test_dt_filter");
950 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
951 parsed = bsc_nat_parse(msg);
952 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100953 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200954 abort();
955 }
956
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200957 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200958 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100959 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200960 abort();
961 }
962
963 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100964 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200965 abort();
966 }
967
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100968 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200969 msgb_free(out);
970
971 /* Make sure that a wildcard is matching */
972 entry.mnc = "09";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200973 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200974 msg = msgb_alloc(4096, "test_dt_filter");
975 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
976 parsed = bsc_nat_parse(msg);
977 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100978 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200979 abort();
980 }
981
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200982 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200983 if (out != msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100984 printf("FAIL: The message should be unchanged.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200985 abort();
986 }
987
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100988 verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200989 msgb_free(out);
Holger Hans Peter Freytherdbd94492013-04-02 12:34:11 +0200990
991 /* Now see what happens to an international number */
992 entry.mnc = "*";
993 entry.option = "^\\+[0-9][0-9]([1-9])";
994 entry.text = "0036";
995 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
996 msg = msgb_alloc(4096, "test_dt_filter");
997 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
998 parsed = bsc_nat_parse(msg);
999 if (!parsed) {
1000 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
1001 abort();
1002 }
1003
1004 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1005 if (!out) {
1006 printf("FAIL: A new message should be created %d.\n", __LINE__);
1007 abort();
1008 }
1009
1010 if (msg == out) {
1011 printf("FAIL: The message should have changed %d\n", __LINE__);
1012 abort();
1013 }
1014
1015 verify_msg(out, cc_setup_national_patched_patched,
1016 ARRAY_SIZE(cc_setup_national_patched_patched));
1017 msgb_free(out);
1018
1019 /* go from international back to national */
1020 entry.mnc = "*";
1021 entry.option = "^\\+([0-9])";
1022 entry.text = "36";
1023 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1024 msg = msgb_alloc(4096, "test_dt_filter");
1025 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1026 parsed = bsc_nat_parse(msg);
1027 if (!parsed) {
1028 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
1029 abort();
1030 }
1031
1032 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1033 if (!out) {
1034 printf("FAIL: A new message should be created %d.\n", __LINE__);
1035 abort();
1036 }
1037
1038 if (msg == out) {
1039 printf("FAIL: The message should have changed %d\n", __LINE__);
1040 abort();
1041 }
1042
1043 verify_msg(out, cc_setup_national_again,
1044 ARRAY_SIZE(cc_setup_national_again));
1045 msgb_free(out);
Holger Hans Peter Freyther3615a302013-06-25 12:03:36 +02001046 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, NULL);
1047 talloc_free(nat);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001048}
1049
Holger Hans Peter Freytherddf191e2013-06-25 11:44:01 +02001050static void test_setup_rewrite_prefix(void)
1051{
1052 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
1053 struct msgb *out;
1054 struct bsc_nat_parsed *parsed;
1055 const char *imsi = "27408000001234";
1056
1057 struct bsc_nat *nat = bsc_nat_alloc();
1058
1059 /* a fake list */
1060 struct osmo_config_list entries;
1061 struct osmo_config_entry entry;
1062
1063 INIT_LLIST_HEAD(&entries.entry);
1064 entry.mcc = "274";
1065 entry.mnc = "08";
1066 entry.option = "^0([1-9])";
1067 entry.text = "prefix_lookup";
1068 llist_add_tail(&entry.list, &entries.entry);
1069 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1070
1071 nat->num_rewr_trie = nat_rewrite_parse(nat, "prefixes.csv");
1072
1073 msgb_reset(msg);
1074 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
1075 parsed = bsc_nat_parse(msg);
1076 if (!parsed) {
1077 printf("FAIL: Could not parse ID resp\n");
1078 abort();
1079 }
1080
1081 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1082 if (!out) {
1083 printf("FAIL: A new message should be created.\n");
1084 abort();
1085 }
1086
1087 if (msg == out) {
1088 printf("FAIL: The message should have changed\n");
1089 abort();
1090 }
1091
1092 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1093 msgb_free(out);
1094
1095 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, NULL);
1096 talloc_free(nat);
1097}
1098
Holger Hans Peter Freyther67e423c2013-06-25 15:38:31 +02001099static void test_setup_rewrite_post(void)
1100{
1101 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
1102 struct msgb *out;
1103 struct bsc_nat_parsed *parsed;
1104 const char *imsi = "27408000001234";
1105
1106 struct bsc_nat *nat = bsc_nat_alloc();
1107
1108 /* a fake list */
1109 struct osmo_config_list entries;
1110 struct osmo_config_entry entry;
1111 struct osmo_config_list entries_post;
1112 struct osmo_config_entry entry_post;
1113
1114 INIT_LLIST_HEAD(&entries.entry);
1115 entry.mcc = "274";
1116 entry.mnc = "08";
1117 entry.option = "^0([1-9])";
1118 entry.text = "0049";
1119 llist_add_tail(&entry.list, &entries.entry);
1120 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1121
1122 /* attempt to undo the previous one */
1123 INIT_LLIST_HEAD(&entries_post.entry);
1124 entry_post.mcc = "274";
1125 entry_post.mnc = "08";
1126 entry_post.option = "^\\+49([1-9])";
1127 entry_post.text = "prefix_lookup";
1128 llist_add_tail(&entry_post.list, &entries_post.entry);
1129 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr_post, &entries_post);
1130
1131 nat->num_rewr_trie = nat_rewrite_parse(nat, "prefixes.csv");
1132
1133 msgb_reset(msg);
1134 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
1135 parsed = bsc_nat_parse(msg);
1136 if (!parsed) {
1137 printf("FAIL: Could not parse ID resp\n");
1138 abort();
1139 }
1140
1141 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1142 if (!out) {
1143 printf("FAIL: A new message should be created.\n");
1144 abort();
1145 }
1146
1147 if (msg == out) {
1148 printf("FAIL: The message should have changed\n");
1149 abort();
1150 }
1151
1152 verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national));
1153 msgb_free(out);
1154
1155 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, NULL);
1156 talloc_free(nat);
1157}
1158
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001159static void test_sms_smsc_rewrite()
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001160{
1161 struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
1162 struct bsc_nat_parsed *parsed;
1163 const char *imsi = "515039900406700";
1164
1165 struct bsc_nat *nat = bsc_nat_alloc();
1166
1167 /* a fake list */
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001168 struct osmo_config_list smsc_entries, dest_entries, clear_entries;
1169 struct osmo_config_entry smsc_entry, dest_entry, clear_entry;
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001170
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001171 INIT_LLIST_HEAD(&smsc_entries.entry);
1172 INIT_LLIST_HEAD(&dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001173 INIT_LLIST_HEAD(&clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001174 smsc_entry.mcc = "^515039";
1175 smsc_entry.option = "639180000105()";
1176 smsc_entry.text = "6666666666667";
1177 llist_add_tail(&smsc_entry.list, &smsc_entries.entry);
1178 dest_entry.mcc = "515";
1179 dest_entry.mnc = "03";
1180 dest_entry.option = "^0049";
1181 dest_entry.text = "";
1182 llist_add_tail(&dest_entry.list, &dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001183 clear_entry.mcc = "^515039";
1184 clear_entry.option = "^0049";
1185 clear_entry.text = "";
1186 llist_add_tail(&clear_entry.list, &clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001187
1188 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
1189 bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001190 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001191
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001192 printf("Testing SMSC rewriting.\n");
1193
1194 /*
1195 * Check if the SMSC address is changed
1196 */
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001197 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1198 parsed = bsc_nat_parse(msg);
1199 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001200 printf("FAIL: Could not parse SMS\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001201 abort();
1202 }
1203
1204 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1205 if (out == msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001206 printf("FAIL: This should have changed.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001207 abort();
1208 }
1209
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +01001210 verify_msg(out, smsc_rewrite_patched, ARRAY_SIZE(smsc_rewrite_patched));
1211 msgb_free(out);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001212
1213 /* clear out the filter for SMSC */
1214 printf("Attempting to only rewrite the HDR\n");
1215 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL);
1216 msg = msgb_alloc(4096, "SMSC rewrite");
1217 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1218 parsed = bsc_nat_parse(msg);
1219 if (!parsed) {
1220 printf("FAIL: Could not parse SMS\n");
1221 abort();
1222 }
1223
1224 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1225 if (out == msg) {
1226 printf("FAIL: This should have changed.\n");
1227 abort();
1228 }
1229
1230 verify_msg(out, smsc_rewrite_patched_hdr, ARRAY_SIZE(smsc_rewrite_patched_hdr));
1231 msgb_free(out);
1232
1233 /* clear out the next filter */
1234 printf("Attempting to change nothing.\n");
1235 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL);
1236 msg = msgb_alloc(4096, "SMSC rewrite");
1237 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1238 parsed = bsc_nat_parse(msg);
1239 if (!parsed) {
1240 printf("FAIL: Could not parse SMS\n");
1241 abort();
1242 }
1243
1244 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1245 if (out != msg) {
1246 printf("FAIL: This should not have changed.\n");
1247 abort();
1248 }
1249
1250 verify_msg(out, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1251 msgb_free(out);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001252}
1253
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001254static void test_sms_number_rewrite(void)
1255{
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001256 struct msgb *msg, *out;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001257 struct bsc_nat_parsed *parsed;
1258 const char *imsi = "515039900406700";
1259
1260 struct bsc_nat *nat = bsc_nat_alloc();
1261
1262 /* a fake list */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001263 struct osmo_config_list num_entries, clear_entries;
1264 struct osmo_config_entry num_entry, clear_entry;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001265
1266 INIT_LLIST_HEAD(&num_entries.entry);
1267 num_entry.mcc = "^515039";
1268 num_entry.option = "^0049()";
1269 num_entry.text = "0032";
1270 llist_add_tail(&num_entry.list, &num_entries.entry);
1271
1272 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_num_rewr, &num_entries);
1273
1274 printf("Testing SMS TP-DA rewriting.\n");
1275
1276 /*
1277 * Check if the SMSC address is changed
1278 */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001279 msg = msgb_alloc(4096, "SMSC rewrite");
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001280 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1281 parsed = bsc_nat_parse(msg);
1282 if (!parsed) {
1283 printf("FAIL: Could not parse SMS\n");
1284 abort();
1285 }
1286
1287 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1288 if (out == msg) {
1289 printf("FAIL: This should have changed.\n");
1290 abort();
1291 }
1292
1293 verify_msg(out, smsc_rewrite_num_patched,
1294 ARRAY_SIZE(smsc_rewrite_num_patched));
1295 msgb_free(out);
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001296
1297 /*
1298 * Now with TP-SRR rewriting enabled
1299 */
1300 INIT_LLIST_HEAD(&clear_entries.entry);
1301 clear_entry.mcc = "^515039";
1302 clear_entry.option = "";
1303 clear_entry.text = "";
1304 llist_add_tail(&clear_entry.list, &clear_entries.entry);
1305 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
1306
1307 msg = msgb_alloc(4096, "SMSC rewrite");
1308 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1309 parsed = bsc_nat_parse(msg);
1310 if (!parsed) {
1311 printf("FAIL: Could not parse SMS\n");
1312 abort();
1313 }
1314
1315 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1316 if (out == msg) {
1317 printf("FAIL: This should have changed.\n");
1318 abort();
1319 }
1320
1321 verify_msg(out, smsc_rewrite_num_patched_tp_srr,
1322 ARRAY_SIZE(smsc_rewrite_num_patched_tp_srr));
1323 msgb_free(out);
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001324}
1325
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001326static void test_barr_list_parsing(void)
1327{
1328 int rc;
1329 int cm, lu;
1330 struct rb_node *node;
1331 struct rb_root root = RB_ROOT;
1332 struct osmo_config_list *lst = osmo_config_list_parse(NULL, "barr.cfg");
1333 if (lst == NULL)
1334 abort();
1335
1336 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1337 if (rc != 0)
1338 abort();
1339 talloc_free(lst);
1340
1341
1342 for (node = rb_first(&root); node; node = rb_next(node)) {
1343 struct bsc_nat_barr_entry *entry;
1344 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1345 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1346 entry->cm_reject_cause, entry->lu_reject_cause);
1347 }
1348
1349 /* do the look up now.. */
1350 rc = bsc_nat_barr_find(&root, "12123119", &cm, &lu);
1351 if (!rc) {
1352 printf("Failed to find the IMSI.\n");
1353 abort();
1354 }
1355
1356 if (cm != 3 || lu != 4) {
1357 printf("Found CM(%d) and LU(%d)\n", cm, lu);
1358 abort();
1359 }
1360
1361 /* empty and check that it is empty */
1362 bsc_nat_barr_adapt(NULL, &root, NULL);
1363 if (!RB_EMPTY_ROOT(&root)) {
1364 printf("Failed to empty the list.\n");
1365 abort();
1366 }
1367
1368 /* check that dup results in an error */
1369 lst = osmo_config_list_parse(NULL, "barr_dup.cfg");
1370 if (lst == NULL) {
1371 printf("Failed to parse list with dups\n");
1372 abort();
1373 }
1374
1375 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1376 if (rc != -1) {
1377 printf("It should have failed due dup\n");
1378 abort();
1379 }
1380 talloc_free(lst);
1381
1382 /* dump for reference */
1383 for (node = rb_first(&root); node; node = rb_next(node)) {
1384 struct bsc_nat_barr_entry *entry;
1385 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1386 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1387 entry->cm_reject_cause, entry->lu_reject_cause);
1388
1389 }
1390}
1391
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001392static void test_nat_extract_lac()
1393{
1394 int res;
1395 struct bsc_connection *bsc;
1396 struct bsc_nat *nat;
1397 struct nat_sccp_connection con;
1398 struct bsc_nat_parsed *parsed;
1399 struct msgb *msg = msgb_alloc(4096, "test-message");
1400
1401 printf("Testing LAC extraction from SCCP CR\n");
1402
1403 /* initialize the testcase */
1404 nat = bsc_nat_alloc();
1405 bsc = bsc_connection_alloc(nat);
1406 bsc->cfg = bsc_config_alloc(nat, "foo");
1407
1408 memset(&con, 0, sizeof(con));
1409 con.bsc = bsc;
1410
1411 /* create the SCCP CR */
1412 msg->l2h = msgb_put(msg, ARRAY_SIZE(bssmap_cr));
1413 memcpy(msg->l2h, bssmap_cr, ARRAY_SIZE(bssmap_cr));
1414
1415 /* parse it and pass it on */
1416 parsed = bsc_nat_parse(msg);
1417 res = bsc_nat_extract_lac(bsc, &con, parsed, msg);
1418 OSMO_ASSERT(res == 0);
1419
1420 /* verify the LAC */
1421 OSMO_ASSERT(con.lac == 8210);
1422 OSMO_ASSERT(con.ci == 50000);
1423}
1424
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001425int main(int argc, char **argv)
1426{
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +08001427 sccp_set_log_area(DSCCP);
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +02001428 osmo_init_logging(&log_info);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001429
1430 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001431 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001432 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +02001433 test_mgcp_ass_tracking();
1434 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +02001435 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +02001436 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +08001437 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +08001438 test_dt_filter();
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001439 test_setup_rewrite();
Holger Hans Peter Freytherddf191e2013-06-25 11:44:01 +02001440 test_setup_rewrite_prefix();
Holger Hans Peter Freyther67e423c2013-06-25 15:38:31 +02001441 test_setup_rewrite_post();
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001442 test_sms_smsc_rewrite();
1443 test_sms_number_rewrite();
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +01001444 test_mgcp_allocations();
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001445 test_barr_list_parsing();
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001446 test_nat_extract_lac();
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001447
1448 printf("Testing execution completed.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001449 return 0;
1450}
Holger Hans Peter Freytherc3271872012-11-05 14:54:56 +01001451
1452/* stub */
1453void bsc_nat_send_mgcp_to_msc(struct bsc_nat *nat, struct msgb *msg)
1454{
1455 abort();
1456}