blob: b0350044ea1eeb5a3fc9549979944c4c80f6f7b6 [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 Freyther04fd9922010-03-30 06:51:53 +0200455}
456
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100457static void test_mgcp_allocations(void)
458{
459#if 0
460 struct bsc_connection *bsc;
461 struct bsc_nat *nat;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200462 struct nat_sccp_connection con;
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100463 int i, j, multiplex;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100464
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100465 printf("Testing MGCP.\n");
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100466 memset(&con, 0, sizeof(con));
467
468 nat = bsc_nat_alloc();
469 nat->bsc_endpoints = talloc_zero_array(nat,
470 struct bsc_endpoint,
471 65);
472 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100473 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100474
475 bsc = bsc_connection_alloc(nat);
476 bsc->cfg = bsc_config_alloc(nat, "foo");
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100477 bsc->cfg->max_endpoints = 60;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100478 bsc_config_add_lac(bsc->cfg, 2323);
479 bsc->last_endpoint = 0x22;
480 con.bsc = bsc;
481
482 bsc_init_endps_if_needed(bsc);
483
484 i = 1;
485 do {
486 if (bsc_assign_endpoint(bsc, &con) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100487 printf("failed to allocate... on iteration %d\n", i);
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100488 break;
489 }
490 ++i;
491 } while(1);
492
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100493 multiplex = bsc_mgcp_nr_multiplexes(bsc->cfg->max_endpoints);
494 for (i = 0; i < multiplex; ++i) {
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100495 for (j = 0; j < 32; ++j)
496 printf("%d", bsc->_endpoint_status[i*32 + j]);
497 printf(": %d of %d\n", i*32 + 32, 32 * 8);
498 }
499#endif
500}
501
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200502static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800503{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800504 struct bsc_connection *bsc;
505 struct bsc_nat *nat;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200506 struct nat_sccp_connection con;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800507 struct bsc_nat_parsed *parsed;
508 struct msgb *msg;
509
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100510 printf("Testing MGCP.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800511 memset(&con, 0, sizeof(con));
512
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800513 nat = bsc_nat_alloc();
514 nat->bsc_endpoints = talloc_zero_array(nat,
515 struct bsc_endpoint,
516 33);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100517 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100518 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freyther462b7d72012-10-24 21:53:40 +0200519 mgcp_endpoints_allocate(&nat->mgcp_cfg->trunk);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100520
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800521 bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800522 bsc->cfg = bsc_config_alloc(nat, "foo");
523 bsc_config_add_lac(bsc->cfg, 2323);
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100524 bsc->last_endpoint = 0x1e;
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800525 con.bsc = bsc;
526
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800527 msg = msgb_alloc(4096, "foo");
528 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
529 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800530
531 if (msg->l2h[16] != 0 ||
532 msg->l2h[17] != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100533 printf("Input is not as expected.. %s 0x%x\n",
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200534 osmo_hexdump(msg->l2h, msgb_l2len(msg)),
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800535 msg->l2h[17]);
536 abort();
537 }
538
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800539 if (bsc_mgcp_assign_patch(&con, msg) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100540 printf("Failed to handle assignment.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800541 abort();
542 }
543
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800544 if (con.msc_endp != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100545 printf("Timeslot should be 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800546 abort();
547 }
548
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100549 if (con.bsc_endp != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100550 printf("Assigned timeslot should have been 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800551 abort();
552 }
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100553 if (con.bsc->_endpoint_status[0x1] != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100554 printf("The status on the BSC is wrong.\n");
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800555 abort();
556 }
557
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800558 int multiplex, timeslot;
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100559 mgcp_endpoint_to_timeslot(0x1, &multiplex, &timeslot);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800560
561 uint16_t cic = htons(timeslot & 0x1f);
562 if (memcmp(&cic, &msg->l2h[16], sizeof(cic)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100563 printf("Message was not patched properly\n");
564 printf("data cic: 0x%x %s\n", cic, osmo_hexdump(msg->l2h, msgb_l2len(msg)));
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800565 abort();
566 }
567
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800568 talloc_free(parsed);
569
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800570 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800571 if (con.bsc_endp != -1 || con.msc_endp != -1 ||
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100572 con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100573 printf("Clearing should remove the mapping.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800574 abort();
575 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800576
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100577 bsc_config_free(bsc->cfg);
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800578 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800579}
580
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200581/* test the code to find a given connection */
582static void test_mgcp_find(void)
583{
584 struct bsc_nat *nat;
585 struct bsc_connection *con;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200586 struct nat_sccp_connection *sccp_con;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200587
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100588 printf("Testing finding of a BSC Connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200589
590 nat = bsc_nat_alloc();
591 con = bsc_connection_alloc(nat);
592 llist_add(&con->list_entry, &nat->bsc_connections);
593
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200594 sccp_con = talloc_zero(con, struct nat_sccp_connection);
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800595 sccp_con->msc_endp = 12;
596 sccp_con->bsc_endp = 12;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200597 sccp_con->bsc = con;
598 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
599
600 if (bsc_mgcp_find_con(nat, 11) != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100601 printf("Found the wrong connection.\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200602 abort();
603 }
604
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800605 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100606 printf("Didn't find the connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200607 abort();
608 }
609
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200610 /* free everything */
611 talloc_free(nat);
612}
613
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200614static void test_mgcp_rewrite(void)
615{
616 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200617 struct msgb *output;
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100618 printf("Testing rewriting MGCP messages.\n");
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200619
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200620 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
621 const char *orig = mgcp_messages[i].orig;
622 const char *patc = mgcp_messages[i].patch;
623 const char *ip = mgcp_messages[i].ip;
624 const int port = mgcp_messages[i].port;
625
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200626 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200627
Holger Hans Peter Freytherf7c86c52010-08-30 13:44:32 +0800628 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200629 if (msgb_l2len(output) != strlen(patc)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100630 printf("Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
631 printf("String '%s' vs '%s'\n", (const char *) output->l2h, patc);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200632 abort();
633 }
634
635 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100636 printf("Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200637 abort();
638 }
639
640 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200641 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200642 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200643}
644
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200645static void test_mgcp_parse(void)
646{
647 int code, ci;
648 char transaction[60];
649
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100650 printf("Testing MGCP response parsing.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200651
652 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100653 printf("Failed to parse CRCX resp.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200654 abort();
655 }
656
657 if (code != 200) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100658 printf("Failed to parse the CODE properly. Got: %d\n", code);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200659 abort();
660 }
661
662 if (strcmp(transaction, "23265295") != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100663 printf("Failed to parse transaction id: '%s'\n", transaction);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200664 abort();
665 }
666
667 ci = bsc_mgcp_extract_ci(crcx_resp);
668 if (ci != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100669 printf("Failed to parse the CI. Got: %d\n", ci);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200670 abort();
671 }
672}
673
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800674struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800675 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800676 int length;
677 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800678 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800679
680 const char *bsc_imsi_allow;
681 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800682 const char *nat_imsi_deny;
683};
684
685static struct cr_filter cr_filter[] = {
686 {
687 .data = bssmap_cr,
688 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800689 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800690 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800691 },
692 {
693 .data = bss_lu,
694 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800695 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800696 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800697 },
698 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800699 .data = pag_resp,
700 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800701 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800702 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800703 },
704 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800705 /* nat deny is before blank/null BSC */
706 .data = bss_lu,
707 .length = sizeof(bss_lu),
708 .result = -3,
709 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800710 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800711 },
712 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800713 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800714 .data = bss_lu,
715 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800716 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800717 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800718 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800719 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800720 },
721 {
722 /* BSC allow is before NAT deny */
723 .data = bss_lu,
724 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800725 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800726 .bsc_imsi_allow = "[0-9]*",
727 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800728 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800729 },
730 {
731 /* filter as deny is first */
732 .data = bss_lu,
733 .length = sizeof(bss_lu),
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200734 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800735 .bsc_imsi_deny = "[0-9]*",
736 .bsc_imsi_allow = "[0-9]*",
737 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800738 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800739 },
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200740 {
741 /* deny by nat rule */
742 .data = bss_lu,
743 .length = sizeof(bss_lu),
744 .result = -3,
745 .bsc_imsi_deny = "000[0-9]*",
746 .nat_imsi_deny = "[0-9]*",
747 .contype = NAT_CON_TYPE_LU,
748 },
749 {
750 /* deny by bsc rule */
751 .data = bss_lu,
752 .length = sizeof(bss_lu),
753 .result = -2,
754 .bsc_imsi_deny = "[0-9]*",
755 .contype = NAT_CON_TYPE_LU,
756 },
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800757
758};
759
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800760static void test_cr_filter()
761{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800762 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800763 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800764 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800765 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800766 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100767 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800768
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800769 struct bsc_nat *nat = bsc_nat_alloc();
770 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800771 bsc->cfg = bsc_config_alloc(nat, "foo");
772 bsc_config_add_lac(bsc->cfg, 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800773 bsc->cfg->acc_lst_name = "bsc";
774 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800775
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800776 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
777 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
778
779 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
780 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
781
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800782 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800783 char *imsi;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800784 msgb_reset(msg);
785 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
786
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200787 if (gsm_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800788 cr_filter[i].nat_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200789 &cr_filter[i].nat_imsi_deny) != 0)
790 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200791 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800792 cr_filter[i].bsc_imsi_allow ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200793 &cr_filter[i].bsc_imsi_allow) != 0)
794 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200795 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800796 cr_filter[i].bsc_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200797 &cr_filter[i].bsc_imsi_deny) != 0)
798 abort();
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800799
800 parsed = bsc_nat_parse(msg);
801 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100802 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800803 abort();
804 }
805
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100806 memset(&cause, 0, sizeof(cause));
807 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi, &cause);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800808 if (res != cr_filter[i].result) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100809 printf("FAIL: Wrong result %d for test %d.\n", res, i);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800810 abort();
811 }
812
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800813 if (contype != cr_filter[i].contype) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100814 printf("FAIL: Wrong contype %d for test %d.\n", res, contype);
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800815 abort();
816 }
817
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800818 talloc_steal(parsed, imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800819 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800820 }
821
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800822 msgb_free(msg);
823}
824
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800825static void test_dt_filter()
826{
827 int i;
828 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
829 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100830 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800831
832 struct bsc_nat *nat = bsc_nat_alloc();
833 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200834 struct nat_sccp_connection *con = talloc_zero(0, struct nat_sccp_connection);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800835
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800836 bsc->cfg = bsc_config_alloc(nat, "foo");
837 bsc_config_add_lac(bsc->cfg, 23);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800838 con->bsc = bsc;
839
840 msgb_reset(msg);
841 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
842
843 parsed = bsc_nat_parse(msg);
844 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100845 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800846 abort();
847 }
848
849 if (parsed->bssap != BSSAP_MSG_DTAP) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100850 printf("FAIL: It should be dtap\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800851 abort();
852 }
853
854 /* gsm_type is actually the size of the dtap */
855 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100856 printf("FAIL: Not enough space for the content\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800857 abort();
858 }
859
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100860 memset(&cause, 0, sizeof(cause));
861 if (bsc_nat_filter_dt(bsc, msg, con, parsed, &cause) != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100862 printf("FAIL: Should have passed..\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800863 abort();
864 }
865
866 /* just some basic length checking... */
867 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
868 msgb_reset(msg);
869 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
870
871 parsed = bsc_nat_parse(msg);
872 if (!parsed)
873 continue;
874
875 con->imsi_checked = 0;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100876 memset(&cause, 0, sizeof(cause));
877 bsc_nat_filter_dt(bsc, msg, con, parsed, &cause);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800878 }
879}
880
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200881static void test_setup_rewrite()
882{
883 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
884 struct msgb *out;
885 struct bsc_nat_parsed *parsed;
886 const char *imsi = "27408000001234";
887
888 struct bsc_nat *nat = bsc_nat_alloc();
889
890 /* a fake list */
Pablo Neira Ayusoab46cf32011-05-07 13:11:20 +0200891 struct osmo_config_list entries;
892 struct osmo_config_entry entry;
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200893
894 INIT_LLIST_HEAD(&entries.entry);
895 entry.mcc = "274";
896 entry.mnc = "08";
897 entry.option = "^0([1-9])";
898 entry.text = "0049";
899 llist_add_tail(&entry.list, &entries.entry);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200900 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200901
902 /* verify that nothing changed */
903 msgb_reset(msg);
904 copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
905 parsed = bsc_nat_parse(msg);
906 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100907 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200908 abort();
909 }
910
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200911 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200912 if (msg != out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100913 printf("FAIL: The message should not have been changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200914 abort();
915 }
916
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100917 verify_msg(out, cc_setup_international, ARRAY_SIZE(cc_setup_international));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200918 talloc_free(parsed);
919
920 /* verify that something in the message changes */
921 msgb_reset(msg);
922 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
923 parsed = bsc_nat_parse(msg);
924 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100925 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200926 abort();
927 }
928
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200929 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200930 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100931 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200932 abort();
933 }
934
935 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100936 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200937 abort();
938 }
939
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100940 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200941 msgb_free(out);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200942
943 /* Make sure that a wildcard is matching */
944 entry.mnc = "*";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200945 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200946 msg = msgb_alloc(4096, "test_dt_filter");
947 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
948 parsed = bsc_nat_parse(msg);
949 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100950 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200951 abort();
952 }
953
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200954 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200955 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100956 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200957 abort();
958 }
959
960 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100961 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200962 abort();
963 }
964
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100965 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200966 msgb_free(out);
967
968 /* Make sure that a wildcard is matching */
969 entry.mnc = "09";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200970 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200971 msg = msgb_alloc(4096, "test_dt_filter");
972 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
973 parsed = bsc_nat_parse(msg);
974 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100975 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200976 abort();
977 }
978
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200979 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200980 if (out != msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100981 printf("FAIL: The message should be unchanged.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200982 abort();
983 }
984
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100985 verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200986 msgb_free(out);
Holger Hans Peter Freytherdbd94492013-04-02 12:34:11 +0200987
988 /* Now see what happens to an international number */
989 entry.mnc = "*";
990 entry.option = "^\\+[0-9][0-9]([1-9])";
991 entry.text = "0036";
992 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
993 msg = msgb_alloc(4096, "test_dt_filter");
994 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
995 parsed = bsc_nat_parse(msg);
996 if (!parsed) {
997 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
998 abort();
999 }
1000
1001 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1002 if (!out) {
1003 printf("FAIL: A new message should be created %d.\n", __LINE__);
1004 abort();
1005 }
1006
1007 if (msg == out) {
1008 printf("FAIL: The message should have changed %d\n", __LINE__);
1009 abort();
1010 }
1011
1012 verify_msg(out, cc_setup_national_patched_patched,
1013 ARRAY_SIZE(cc_setup_national_patched_patched));
1014 msgb_free(out);
1015
1016 /* go from international back to national */
1017 entry.mnc = "*";
1018 entry.option = "^\\+([0-9])";
1019 entry.text = "36";
1020 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1021 msg = msgb_alloc(4096, "test_dt_filter");
1022 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1023 parsed = bsc_nat_parse(msg);
1024 if (!parsed) {
1025 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
1026 abort();
1027 }
1028
1029 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1030 if (!out) {
1031 printf("FAIL: A new message should be created %d.\n", __LINE__);
1032 abort();
1033 }
1034
1035 if (msg == out) {
1036 printf("FAIL: The message should have changed %d\n", __LINE__);
1037 abort();
1038 }
1039
1040 verify_msg(out, cc_setup_national_again,
1041 ARRAY_SIZE(cc_setup_national_again));
1042 msgb_free(out);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001043}
1044
Holger Hans Peter Freytherddf191e2013-06-25 11:44:01 +02001045static void test_setup_rewrite_prefix(void)
1046{
1047 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
1048 struct msgb *out;
1049 struct bsc_nat_parsed *parsed;
1050 const char *imsi = "27408000001234";
1051
1052 struct bsc_nat *nat = bsc_nat_alloc();
1053
1054 /* a fake list */
1055 struct osmo_config_list entries;
1056 struct osmo_config_entry entry;
1057
1058 INIT_LLIST_HEAD(&entries.entry);
1059 entry.mcc = "274";
1060 entry.mnc = "08";
1061 entry.option = "^0([1-9])";
1062 entry.text = "prefix_lookup";
1063 llist_add_tail(&entry.list, &entries.entry);
1064 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1065
1066 nat->num_rewr_trie = nat_rewrite_parse(nat, "prefixes.csv");
1067
1068 msgb_reset(msg);
1069 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
1070 parsed = bsc_nat_parse(msg);
1071 if (!parsed) {
1072 printf("FAIL: Could not parse ID resp\n");
1073 abort();
1074 }
1075
1076 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1077 if (!out) {
1078 printf("FAIL: A new message should be created.\n");
1079 abort();
1080 }
1081
1082 if (msg == out) {
1083 printf("FAIL: The message should have changed\n");
1084 abort();
1085 }
1086
1087 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1088 msgb_free(out);
1089
1090 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, NULL);
1091 talloc_free(nat);
1092}
1093
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001094static void test_sms_smsc_rewrite()
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001095{
1096 struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
1097 struct bsc_nat_parsed *parsed;
1098 const char *imsi = "515039900406700";
1099
1100 struct bsc_nat *nat = bsc_nat_alloc();
1101
1102 /* a fake list */
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001103 struct osmo_config_list smsc_entries, dest_entries, clear_entries;
1104 struct osmo_config_entry smsc_entry, dest_entry, clear_entry;
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001105
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001106 INIT_LLIST_HEAD(&smsc_entries.entry);
1107 INIT_LLIST_HEAD(&dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001108 INIT_LLIST_HEAD(&clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001109 smsc_entry.mcc = "^515039";
1110 smsc_entry.option = "639180000105()";
1111 smsc_entry.text = "6666666666667";
1112 llist_add_tail(&smsc_entry.list, &smsc_entries.entry);
1113 dest_entry.mcc = "515";
1114 dest_entry.mnc = "03";
1115 dest_entry.option = "^0049";
1116 dest_entry.text = "";
1117 llist_add_tail(&dest_entry.list, &dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001118 clear_entry.mcc = "^515039";
1119 clear_entry.option = "^0049";
1120 clear_entry.text = "";
1121 llist_add_tail(&clear_entry.list, &clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001122
1123 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
1124 bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001125 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001126
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001127 printf("Testing SMSC rewriting.\n");
1128
1129 /*
1130 * Check if the SMSC address is changed
1131 */
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001132 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1133 parsed = bsc_nat_parse(msg);
1134 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001135 printf("FAIL: Could not parse SMS\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001136 abort();
1137 }
1138
1139 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1140 if (out == msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001141 printf("FAIL: This should have changed.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001142 abort();
1143 }
1144
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +01001145 verify_msg(out, smsc_rewrite_patched, ARRAY_SIZE(smsc_rewrite_patched));
1146 msgb_free(out);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001147
1148 /* clear out the filter for SMSC */
1149 printf("Attempting to only rewrite the HDR\n");
1150 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL);
1151 msg = msgb_alloc(4096, "SMSC rewrite");
1152 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1153 parsed = bsc_nat_parse(msg);
1154 if (!parsed) {
1155 printf("FAIL: Could not parse SMS\n");
1156 abort();
1157 }
1158
1159 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1160 if (out == msg) {
1161 printf("FAIL: This should have changed.\n");
1162 abort();
1163 }
1164
1165 verify_msg(out, smsc_rewrite_patched_hdr, ARRAY_SIZE(smsc_rewrite_patched_hdr));
1166 msgb_free(out);
1167
1168 /* clear out the next filter */
1169 printf("Attempting to change nothing.\n");
1170 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL);
1171 msg = msgb_alloc(4096, "SMSC rewrite");
1172 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1173 parsed = bsc_nat_parse(msg);
1174 if (!parsed) {
1175 printf("FAIL: Could not parse SMS\n");
1176 abort();
1177 }
1178
1179 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1180 if (out != msg) {
1181 printf("FAIL: This should not have changed.\n");
1182 abort();
1183 }
1184
1185 verify_msg(out, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1186 msgb_free(out);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001187}
1188
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001189static void test_sms_number_rewrite(void)
1190{
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001191 struct msgb *msg, *out;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001192 struct bsc_nat_parsed *parsed;
1193 const char *imsi = "515039900406700";
1194
1195 struct bsc_nat *nat = bsc_nat_alloc();
1196
1197 /* a fake list */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001198 struct osmo_config_list num_entries, clear_entries;
1199 struct osmo_config_entry num_entry, clear_entry;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001200
1201 INIT_LLIST_HEAD(&num_entries.entry);
1202 num_entry.mcc = "^515039";
1203 num_entry.option = "^0049()";
1204 num_entry.text = "0032";
1205 llist_add_tail(&num_entry.list, &num_entries.entry);
1206
1207 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_num_rewr, &num_entries);
1208
1209 printf("Testing SMS TP-DA rewriting.\n");
1210
1211 /*
1212 * Check if the SMSC address is changed
1213 */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001214 msg = msgb_alloc(4096, "SMSC rewrite");
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001215 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1216 parsed = bsc_nat_parse(msg);
1217 if (!parsed) {
1218 printf("FAIL: Could not parse SMS\n");
1219 abort();
1220 }
1221
1222 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1223 if (out == msg) {
1224 printf("FAIL: This should have changed.\n");
1225 abort();
1226 }
1227
1228 verify_msg(out, smsc_rewrite_num_patched,
1229 ARRAY_SIZE(smsc_rewrite_num_patched));
1230 msgb_free(out);
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001231
1232 /*
1233 * Now with TP-SRR rewriting enabled
1234 */
1235 INIT_LLIST_HEAD(&clear_entries.entry);
1236 clear_entry.mcc = "^515039";
1237 clear_entry.option = "";
1238 clear_entry.text = "";
1239 llist_add_tail(&clear_entry.list, &clear_entries.entry);
1240 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
1241
1242 msg = msgb_alloc(4096, "SMSC rewrite");
1243 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1244 parsed = bsc_nat_parse(msg);
1245 if (!parsed) {
1246 printf("FAIL: Could not parse SMS\n");
1247 abort();
1248 }
1249
1250 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1251 if (out == msg) {
1252 printf("FAIL: This should have changed.\n");
1253 abort();
1254 }
1255
1256 verify_msg(out, smsc_rewrite_num_patched_tp_srr,
1257 ARRAY_SIZE(smsc_rewrite_num_patched_tp_srr));
1258 msgb_free(out);
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001259}
1260
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001261static void test_barr_list_parsing(void)
1262{
1263 int rc;
1264 int cm, lu;
1265 struct rb_node *node;
1266 struct rb_root root = RB_ROOT;
1267 struct osmo_config_list *lst = osmo_config_list_parse(NULL, "barr.cfg");
1268 if (lst == NULL)
1269 abort();
1270
1271 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1272 if (rc != 0)
1273 abort();
1274 talloc_free(lst);
1275
1276
1277 for (node = rb_first(&root); node; node = rb_next(node)) {
1278 struct bsc_nat_barr_entry *entry;
1279 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1280 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1281 entry->cm_reject_cause, entry->lu_reject_cause);
1282 }
1283
1284 /* do the look up now.. */
1285 rc = bsc_nat_barr_find(&root, "12123119", &cm, &lu);
1286 if (!rc) {
1287 printf("Failed to find the IMSI.\n");
1288 abort();
1289 }
1290
1291 if (cm != 3 || lu != 4) {
1292 printf("Found CM(%d) and LU(%d)\n", cm, lu);
1293 abort();
1294 }
1295
1296 /* empty and check that it is empty */
1297 bsc_nat_barr_adapt(NULL, &root, NULL);
1298 if (!RB_EMPTY_ROOT(&root)) {
1299 printf("Failed to empty the list.\n");
1300 abort();
1301 }
1302
1303 /* check that dup results in an error */
1304 lst = osmo_config_list_parse(NULL, "barr_dup.cfg");
1305 if (lst == NULL) {
1306 printf("Failed to parse list with dups\n");
1307 abort();
1308 }
1309
1310 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1311 if (rc != -1) {
1312 printf("It should have failed due dup\n");
1313 abort();
1314 }
1315 talloc_free(lst);
1316
1317 /* dump for reference */
1318 for (node = rb_first(&root); node; node = rb_next(node)) {
1319 struct bsc_nat_barr_entry *entry;
1320 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1321 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1322 entry->cm_reject_cause, entry->lu_reject_cause);
1323
1324 }
1325}
1326
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001327static void test_nat_extract_lac()
1328{
1329 int res;
1330 struct bsc_connection *bsc;
1331 struct bsc_nat *nat;
1332 struct nat_sccp_connection con;
1333 struct bsc_nat_parsed *parsed;
1334 struct msgb *msg = msgb_alloc(4096, "test-message");
1335
1336 printf("Testing LAC extraction from SCCP CR\n");
1337
1338 /* initialize the testcase */
1339 nat = bsc_nat_alloc();
1340 bsc = bsc_connection_alloc(nat);
1341 bsc->cfg = bsc_config_alloc(nat, "foo");
1342
1343 memset(&con, 0, sizeof(con));
1344 con.bsc = bsc;
1345
1346 /* create the SCCP CR */
1347 msg->l2h = msgb_put(msg, ARRAY_SIZE(bssmap_cr));
1348 memcpy(msg->l2h, bssmap_cr, ARRAY_SIZE(bssmap_cr));
1349
1350 /* parse it and pass it on */
1351 parsed = bsc_nat_parse(msg);
1352 res = bsc_nat_extract_lac(bsc, &con, parsed, msg);
1353 OSMO_ASSERT(res == 0);
1354
1355 /* verify the LAC */
1356 OSMO_ASSERT(con.lac == 8210);
1357 OSMO_ASSERT(con.ci == 50000);
1358}
1359
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001360int main(int argc, char **argv)
1361{
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +08001362 sccp_set_log_area(DSCCP);
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +02001363 osmo_init_logging(&log_info);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001364
1365 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001366 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001367 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +02001368 test_mgcp_ass_tracking();
1369 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +02001370 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +02001371 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +08001372 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +08001373 test_dt_filter();
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001374 test_setup_rewrite();
Holger Hans Peter Freytherddf191e2013-06-25 11:44:01 +02001375 test_setup_rewrite_prefix();
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001376 test_sms_smsc_rewrite();
1377 test_sms_number_rewrite();
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +01001378 test_mgcp_allocations();
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001379 test_barr_list_parsing();
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001380 test_nat_extract_lac();
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001381
1382 printf("Testing execution completed.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001383 return 0;
1384}
Holger Hans Peter Freytherc3271872012-11-05 14:54:56 +01001385
1386/* stub */
1387void bsc_nat_send_mgcp_to_msc(struct bsc_nat *nat, struct msgb *msg)
1388{
1389 abort();
1390}