blob: 3320e0694e7f5e7ca91045f578bbf3e19f993d25 [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;
Jacob Erlbecka52ac662013-11-29 13:43:45 +0100627 const int expected_payload_type = mgcp_messages[i].payload_type;
628 int payload_type = -1;
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200629
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200630 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200631
Jacob Erlbecka52ac662013-11-29 13:43:45 +0100632 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e,
633 ip, port);
634
635 if (payload_type != -1) {
636 fprintf(stderr, "Found media payload type %d in SDP data\n",
637 payload_type);
638 if (payload_type != expected_payload_type) {
639 printf("Wrong payload type %d (expected %d)\n",
640 payload_type, expected_payload_type);
641 abort();
642 }
643 }
644
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200645 if (msgb_l2len(output) != strlen(patc)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100646 printf("Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
647 printf("String '%s' vs '%s'\n", (const char *) output->l2h, patc);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200648 abort();
649 }
650
651 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100652 printf("Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200653 abort();
654 }
655
656 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200657 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200658 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200659}
660
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200661static void test_mgcp_parse(void)
662{
663 int code, ci;
664 char transaction[60];
665
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100666 printf("Testing MGCP response parsing.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200667
668 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100669 printf("Failed to parse CRCX resp.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200670 abort();
671 }
672
673 if (code != 200) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100674 printf("Failed to parse the CODE properly. Got: %d\n", code);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200675 abort();
676 }
677
678 if (strcmp(transaction, "23265295") != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100679 printf("Failed to parse transaction id: '%s'\n", transaction);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200680 abort();
681 }
682
683 ci = bsc_mgcp_extract_ci(crcx_resp);
684 if (ci != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100685 printf("Failed to parse the CI. Got: %d\n", ci);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200686 abort();
687 }
688}
689
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800690struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800691 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800692 int length;
693 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800694 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800695
696 const char *bsc_imsi_allow;
697 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800698 const char *nat_imsi_deny;
699};
700
701static struct cr_filter cr_filter[] = {
702 {
703 .data = bssmap_cr,
704 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800705 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800706 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800707 },
708 {
709 .data = bss_lu,
710 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800711 .result = 1,
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 Freytherf1924982010-05-15 23:54:04 +0800715 .data = pag_resp,
716 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800717 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800718 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800719 },
720 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800721 /* nat deny is before blank/null BSC */
722 .data = bss_lu,
723 .length = sizeof(bss_lu),
724 .result = -3,
725 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800726 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800727 },
728 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800729 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800730 .data = bss_lu,
731 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800732 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800733 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800734 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800735 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800736 },
737 {
738 /* BSC allow is before NAT deny */
739 .data = bss_lu,
740 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800741 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800742 .bsc_imsi_allow = "[0-9]*",
743 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800744 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800745 },
746 {
747 /* filter as deny is first */
748 .data = bss_lu,
749 .length = sizeof(bss_lu),
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200750 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800751 .bsc_imsi_deny = "[0-9]*",
752 .bsc_imsi_allow = "[0-9]*",
753 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800754 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800755 },
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200756 {
757 /* deny by nat rule */
758 .data = bss_lu,
759 .length = sizeof(bss_lu),
760 .result = -3,
761 .bsc_imsi_deny = "000[0-9]*",
762 .nat_imsi_deny = "[0-9]*",
763 .contype = NAT_CON_TYPE_LU,
764 },
765 {
766 /* deny by bsc rule */
767 .data = bss_lu,
768 .length = sizeof(bss_lu),
769 .result = -2,
770 .bsc_imsi_deny = "[0-9]*",
771 .contype = NAT_CON_TYPE_LU,
772 },
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800773
774};
775
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800776static void test_cr_filter()
777{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800778 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800779 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800780 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800781 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800782 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100783 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800784
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800785 struct bsc_nat *nat = bsc_nat_alloc();
786 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800787 bsc->cfg = bsc_config_alloc(nat, "foo");
788 bsc_config_add_lac(bsc->cfg, 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800789 bsc->cfg->acc_lst_name = "bsc";
790 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800791
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800792 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
793 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
794
795 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
796 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
797
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800798 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800799 char *imsi;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800800 msgb_reset(msg);
801 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
802
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200803 if (gsm_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800804 cr_filter[i].nat_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200805 &cr_filter[i].nat_imsi_deny) != 0)
806 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200807 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800808 cr_filter[i].bsc_imsi_allow ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200809 &cr_filter[i].bsc_imsi_allow) != 0)
810 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200811 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800812 cr_filter[i].bsc_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200813 &cr_filter[i].bsc_imsi_deny) != 0)
814 abort();
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800815
816 parsed = bsc_nat_parse(msg);
817 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100818 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800819 abort();
820 }
821
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100822 memset(&cause, 0, sizeof(cause));
823 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi, &cause);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800824 if (res != cr_filter[i].result) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100825 printf("FAIL: Wrong result %d for test %d.\n", res, i);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800826 abort();
827 }
828
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800829 if (contype != cr_filter[i].contype) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100830 printf("FAIL: Wrong contype %d for test %d.\n", res, contype);
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800831 abort();
832 }
833
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800834 talloc_steal(parsed, imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800835 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800836 }
837
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800838 msgb_free(msg);
Holger Hans Peter Freyther3615a302013-06-25 12:03:36 +0200839 talloc_free(nat);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800840}
841
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800842static void test_dt_filter()
843{
844 int i;
845 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
846 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100847 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800848
849 struct bsc_nat *nat = bsc_nat_alloc();
850 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200851 struct nat_sccp_connection *con = talloc_zero(0, struct nat_sccp_connection);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800852
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800853 bsc->cfg = bsc_config_alloc(nat, "foo");
854 bsc_config_add_lac(bsc->cfg, 23);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800855 con->bsc = bsc;
856
857 msgb_reset(msg);
858 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
859
860 parsed = bsc_nat_parse(msg);
861 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100862 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800863 abort();
864 }
865
866 if (parsed->bssap != BSSAP_MSG_DTAP) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100867 printf("FAIL: It should be dtap\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800868 abort();
869 }
870
871 /* gsm_type is actually the size of the dtap */
872 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100873 printf("FAIL: Not enough space for the content\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800874 abort();
875 }
876
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100877 memset(&cause, 0, sizeof(cause));
878 if (bsc_nat_filter_dt(bsc, msg, con, parsed, &cause) != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100879 printf("FAIL: Should have passed..\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800880 abort();
881 }
882
883 /* just some basic length checking... */
884 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
885 msgb_reset(msg);
886 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
887
888 parsed = bsc_nat_parse(msg);
889 if (!parsed)
890 continue;
891
892 con->imsi_checked = 0;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100893 memset(&cause, 0, sizeof(cause));
894 bsc_nat_filter_dt(bsc, msg, con, parsed, &cause);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800895 }
896}
897
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200898static void test_setup_rewrite()
899{
900 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
901 struct msgb *out;
902 struct bsc_nat_parsed *parsed;
903 const char *imsi = "27408000001234";
904
905 struct bsc_nat *nat = bsc_nat_alloc();
906
907 /* a fake list */
Pablo Neira Ayusoab46cf32011-05-07 13:11:20 +0200908 struct osmo_config_list entries;
909 struct osmo_config_entry entry;
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200910
911 INIT_LLIST_HEAD(&entries.entry);
912 entry.mcc = "274";
913 entry.mnc = "08";
914 entry.option = "^0([1-9])";
915 entry.text = "0049";
916 llist_add_tail(&entry.list, &entries.entry);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200917 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200918
919 /* verify that nothing changed */
920 msgb_reset(msg);
921 copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
922 parsed = bsc_nat_parse(msg);
923 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100924 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200925 abort();
926 }
927
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200928 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200929 if (msg != out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100930 printf("FAIL: The message should not have been changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200931 abort();
932 }
933
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100934 verify_msg(out, cc_setup_international, ARRAY_SIZE(cc_setup_international));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200935 talloc_free(parsed);
936
937 /* verify that something in the message changes */
938 msgb_reset(msg);
939 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
940 parsed = bsc_nat_parse(msg);
941 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100942 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200943 abort();
944 }
945
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200946 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200947 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100948 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200949 abort();
950 }
951
952 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100953 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200954 abort();
955 }
956
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100957 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200958 msgb_free(out);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200959
960 /* Make sure that a wildcard is matching */
961 entry.mnc = "*";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200962 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200963 msg = msgb_alloc(4096, "test_dt_filter");
964 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
965 parsed = bsc_nat_parse(msg);
966 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100967 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200968 abort();
969 }
970
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200971 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200972 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100973 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200974 abort();
975 }
976
977 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100978 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200979 abort();
980 }
981
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100982 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200983 msgb_free(out);
984
985 /* Make sure that a wildcard is matching */
986 entry.mnc = "09";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200987 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200988 msg = msgb_alloc(4096, "test_dt_filter");
989 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
990 parsed = bsc_nat_parse(msg);
991 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100992 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200993 abort();
994 }
995
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200996 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200997 if (out != msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100998 printf("FAIL: The message should be unchanged.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200999 abort();
1000 }
1001
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +01001002 verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +02001003 msgb_free(out);
Holger Hans Peter Freytherdbd94492013-04-02 12:34:11 +02001004
1005 /* Now see what happens to an international number */
1006 entry.mnc = "*";
1007 entry.option = "^\\+[0-9][0-9]([1-9])";
1008 entry.text = "0036";
1009 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1010 msg = msgb_alloc(4096, "test_dt_filter");
1011 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1012 parsed = bsc_nat_parse(msg);
1013 if (!parsed) {
1014 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
1015 abort();
1016 }
1017
1018 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1019 if (!out) {
1020 printf("FAIL: A new message should be created %d.\n", __LINE__);
1021 abort();
1022 }
1023
1024 if (msg == out) {
1025 printf("FAIL: The message should have changed %d\n", __LINE__);
1026 abort();
1027 }
1028
1029 verify_msg(out, cc_setup_national_patched_patched,
1030 ARRAY_SIZE(cc_setup_national_patched_patched));
1031 msgb_free(out);
1032
1033 /* go from international back to national */
1034 entry.mnc = "*";
1035 entry.option = "^\\+([0-9])";
1036 entry.text = "36";
1037 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1038 msg = msgb_alloc(4096, "test_dt_filter");
1039 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1040 parsed = bsc_nat_parse(msg);
1041 if (!parsed) {
1042 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
1043 abort();
1044 }
1045
1046 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1047 if (!out) {
1048 printf("FAIL: A new message should be created %d.\n", __LINE__);
1049 abort();
1050 }
1051
1052 if (msg == out) {
1053 printf("FAIL: The message should have changed %d\n", __LINE__);
1054 abort();
1055 }
1056
1057 verify_msg(out, cc_setup_national_again,
1058 ARRAY_SIZE(cc_setup_national_again));
1059 msgb_free(out);
Holger Hans Peter Freyther3615a302013-06-25 12:03:36 +02001060 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, NULL);
1061 talloc_free(nat);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001062}
1063
Holger Hans Peter Freytherddf191e2013-06-25 11:44:01 +02001064static void test_setup_rewrite_prefix(void)
1065{
1066 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
1067 struct msgb *out;
1068 struct bsc_nat_parsed *parsed;
1069 const char *imsi = "27408000001234";
1070
1071 struct bsc_nat *nat = bsc_nat_alloc();
1072
1073 /* a fake list */
1074 struct osmo_config_list entries;
1075 struct osmo_config_entry entry;
1076
1077 INIT_LLIST_HEAD(&entries.entry);
1078 entry.mcc = "274";
1079 entry.mnc = "08";
1080 entry.option = "^0([1-9])";
1081 entry.text = "prefix_lookup";
1082 llist_add_tail(&entry.list, &entries.entry);
1083 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1084
1085 nat->num_rewr_trie = nat_rewrite_parse(nat, "prefixes.csv");
1086
1087 msgb_reset(msg);
1088 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
1089 parsed = bsc_nat_parse(msg);
1090 if (!parsed) {
1091 printf("FAIL: Could not parse ID resp\n");
1092 abort();
1093 }
1094
1095 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1096 if (!out) {
1097 printf("FAIL: A new message should be created.\n");
1098 abort();
1099 }
1100
1101 if (msg == out) {
1102 printf("FAIL: The message should have changed\n");
1103 abort();
1104 }
1105
1106 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1107 msgb_free(out);
1108
1109 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, NULL);
1110 talloc_free(nat);
1111}
1112
Holger Hans Peter Freyther67e423c2013-06-25 15:38:31 +02001113static void test_setup_rewrite_post(void)
1114{
1115 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
1116 struct msgb *out;
1117 struct bsc_nat_parsed *parsed;
1118 const char *imsi = "27408000001234";
1119
1120 struct bsc_nat *nat = bsc_nat_alloc();
1121
1122 /* a fake list */
1123 struct osmo_config_list entries;
1124 struct osmo_config_entry entry;
1125 struct osmo_config_list entries_post;
1126 struct osmo_config_entry entry_post;
1127
1128 INIT_LLIST_HEAD(&entries.entry);
1129 entry.mcc = "274";
1130 entry.mnc = "08";
1131 entry.option = "^0([1-9])";
1132 entry.text = "0049";
1133 llist_add_tail(&entry.list, &entries.entry);
1134 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1135
1136 /* attempt to undo the previous one */
1137 INIT_LLIST_HEAD(&entries_post.entry);
1138 entry_post.mcc = "274";
1139 entry_post.mnc = "08";
1140 entry_post.option = "^\\+49([1-9])";
1141 entry_post.text = "prefix_lookup";
1142 llist_add_tail(&entry_post.list, &entries_post.entry);
1143 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr_post, &entries_post);
1144
1145 nat->num_rewr_trie = nat_rewrite_parse(nat, "prefixes.csv");
1146
1147 msgb_reset(msg);
1148 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
1149 parsed = bsc_nat_parse(msg);
1150 if (!parsed) {
1151 printf("FAIL: Could not parse ID resp\n");
1152 abort();
1153 }
1154
1155 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1156 if (!out) {
1157 printf("FAIL: A new message should be created.\n");
1158 abort();
1159 }
1160
1161 if (msg == out) {
1162 printf("FAIL: The message should have changed\n");
1163 abort();
1164 }
1165
1166 verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national));
1167 msgb_free(out);
1168
1169 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, NULL);
1170 talloc_free(nat);
1171}
1172
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001173static void test_sms_smsc_rewrite()
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001174{
1175 struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
1176 struct bsc_nat_parsed *parsed;
1177 const char *imsi = "515039900406700";
1178
1179 struct bsc_nat *nat = bsc_nat_alloc();
1180
1181 /* a fake list */
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001182 struct osmo_config_list smsc_entries, dest_entries, clear_entries;
1183 struct osmo_config_entry smsc_entry, dest_entry, clear_entry;
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001184
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001185 INIT_LLIST_HEAD(&smsc_entries.entry);
1186 INIT_LLIST_HEAD(&dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001187 INIT_LLIST_HEAD(&clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001188 smsc_entry.mcc = "^515039";
1189 smsc_entry.option = "639180000105()";
1190 smsc_entry.text = "6666666666667";
1191 llist_add_tail(&smsc_entry.list, &smsc_entries.entry);
1192 dest_entry.mcc = "515";
1193 dest_entry.mnc = "03";
1194 dest_entry.option = "^0049";
1195 dest_entry.text = "";
1196 llist_add_tail(&dest_entry.list, &dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001197 clear_entry.mcc = "^515039";
1198 clear_entry.option = "^0049";
1199 clear_entry.text = "";
1200 llist_add_tail(&clear_entry.list, &clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001201
1202 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
1203 bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001204 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001205
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001206 printf("Testing SMSC rewriting.\n");
1207
1208 /*
1209 * Check if the SMSC address is changed
1210 */
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001211 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1212 parsed = bsc_nat_parse(msg);
1213 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001214 printf("FAIL: Could not parse SMS\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001215 abort();
1216 }
1217
1218 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1219 if (out == msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001220 printf("FAIL: This should have changed.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001221 abort();
1222 }
1223
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +01001224 verify_msg(out, smsc_rewrite_patched, ARRAY_SIZE(smsc_rewrite_patched));
1225 msgb_free(out);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001226
1227 /* clear out the filter for SMSC */
1228 printf("Attempting to only rewrite the HDR\n");
1229 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL);
1230 msg = msgb_alloc(4096, "SMSC rewrite");
1231 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1232 parsed = bsc_nat_parse(msg);
1233 if (!parsed) {
1234 printf("FAIL: Could not parse SMS\n");
1235 abort();
1236 }
1237
1238 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1239 if (out == msg) {
1240 printf("FAIL: This should have changed.\n");
1241 abort();
1242 }
1243
1244 verify_msg(out, smsc_rewrite_patched_hdr, ARRAY_SIZE(smsc_rewrite_patched_hdr));
1245 msgb_free(out);
1246
1247 /* clear out the next filter */
1248 printf("Attempting to change nothing.\n");
1249 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL);
1250 msg = msgb_alloc(4096, "SMSC rewrite");
1251 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1252 parsed = bsc_nat_parse(msg);
1253 if (!parsed) {
1254 printf("FAIL: Could not parse SMS\n");
1255 abort();
1256 }
1257
1258 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1259 if (out != msg) {
1260 printf("FAIL: This should not have changed.\n");
1261 abort();
1262 }
1263
1264 verify_msg(out, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1265 msgb_free(out);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001266}
1267
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001268static void test_sms_number_rewrite(void)
1269{
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001270 struct msgb *msg, *out;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001271 struct bsc_nat_parsed *parsed;
1272 const char *imsi = "515039900406700";
1273
1274 struct bsc_nat *nat = bsc_nat_alloc();
1275
1276 /* a fake list */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001277 struct osmo_config_list num_entries, clear_entries;
1278 struct osmo_config_entry num_entry, clear_entry;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001279
1280 INIT_LLIST_HEAD(&num_entries.entry);
1281 num_entry.mcc = "^515039";
1282 num_entry.option = "^0049()";
1283 num_entry.text = "0032";
1284 llist_add_tail(&num_entry.list, &num_entries.entry);
1285
1286 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_num_rewr, &num_entries);
1287
1288 printf("Testing SMS TP-DA rewriting.\n");
1289
1290 /*
1291 * Check if the SMSC address is changed
1292 */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001293 msg = msgb_alloc(4096, "SMSC rewrite");
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001294 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1295 parsed = bsc_nat_parse(msg);
1296 if (!parsed) {
1297 printf("FAIL: Could not parse SMS\n");
1298 abort();
1299 }
1300
1301 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1302 if (out == msg) {
1303 printf("FAIL: This should have changed.\n");
1304 abort();
1305 }
1306
1307 verify_msg(out, smsc_rewrite_num_patched,
1308 ARRAY_SIZE(smsc_rewrite_num_patched));
1309 msgb_free(out);
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001310
1311 /*
1312 * Now with TP-SRR rewriting enabled
1313 */
1314 INIT_LLIST_HEAD(&clear_entries.entry);
1315 clear_entry.mcc = "^515039";
1316 clear_entry.option = "";
1317 clear_entry.text = "";
1318 llist_add_tail(&clear_entry.list, &clear_entries.entry);
1319 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
1320
1321 msg = msgb_alloc(4096, "SMSC rewrite");
1322 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1323 parsed = bsc_nat_parse(msg);
1324 if (!parsed) {
1325 printf("FAIL: Could not parse SMS\n");
1326 abort();
1327 }
1328
1329 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1330 if (out == msg) {
1331 printf("FAIL: This should have changed.\n");
1332 abort();
1333 }
1334
1335 verify_msg(out, smsc_rewrite_num_patched_tp_srr,
1336 ARRAY_SIZE(smsc_rewrite_num_patched_tp_srr));
1337 msgb_free(out);
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001338}
1339
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001340static void test_barr_list_parsing(void)
1341{
1342 int rc;
1343 int cm, lu;
1344 struct rb_node *node;
1345 struct rb_root root = RB_ROOT;
1346 struct osmo_config_list *lst = osmo_config_list_parse(NULL, "barr.cfg");
1347 if (lst == NULL)
1348 abort();
1349
1350 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1351 if (rc != 0)
1352 abort();
1353 talloc_free(lst);
1354
1355
1356 for (node = rb_first(&root); node; node = rb_next(node)) {
1357 struct bsc_nat_barr_entry *entry;
1358 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1359 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1360 entry->cm_reject_cause, entry->lu_reject_cause);
1361 }
1362
1363 /* do the look up now.. */
1364 rc = bsc_nat_barr_find(&root, "12123119", &cm, &lu);
1365 if (!rc) {
1366 printf("Failed to find the IMSI.\n");
1367 abort();
1368 }
1369
1370 if (cm != 3 || lu != 4) {
1371 printf("Found CM(%d) and LU(%d)\n", cm, lu);
1372 abort();
1373 }
1374
1375 /* empty and check that it is empty */
1376 bsc_nat_barr_adapt(NULL, &root, NULL);
1377 if (!RB_EMPTY_ROOT(&root)) {
1378 printf("Failed to empty the list.\n");
1379 abort();
1380 }
1381
1382 /* check that dup results in an error */
1383 lst = osmo_config_list_parse(NULL, "barr_dup.cfg");
1384 if (lst == NULL) {
1385 printf("Failed to parse list with dups\n");
1386 abort();
1387 }
1388
1389 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1390 if (rc != -1) {
1391 printf("It should have failed due dup\n");
1392 abort();
1393 }
1394 talloc_free(lst);
1395
1396 /* dump for reference */
1397 for (node = rb_first(&root); node; node = rb_next(node)) {
1398 struct bsc_nat_barr_entry *entry;
1399 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1400 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1401 entry->cm_reject_cause, entry->lu_reject_cause);
1402
1403 }
1404}
1405
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001406static void test_nat_extract_lac()
1407{
1408 int res;
1409 struct bsc_connection *bsc;
1410 struct bsc_nat *nat;
1411 struct nat_sccp_connection con;
1412 struct bsc_nat_parsed *parsed;
1413 struct msgb *msg = msgb_alloc(4096, "test-message");
1414
1415 printf("Testing LAC extraction from SCCP CR\n");
1416
1417 /* initialize the testcase */
1418 nat = bsc_nat_alloc();
1419 bsc = bsc_connection_alloc(nat);
1420 bsc->cfg = bsc_config_alloc(nat, "foo");
1421
1422 memset(&con, 0, sizeof(con));
1423 con.bsc = bsc;
1424
1425 /* create the SCCP CR */
1426 msg->l2h = msgb_put(msg, ARRAY_SIZE(bssmap_cr));
1427 memcpy(msg->l2h, bssmap_cr, ARRAY_SIZE(bssmap_cr));
1428
1429 /* parse it and pass it on */
1430 parsed = bsc_nat_parse(msg);
1431 res = bsc_nat_extract_lac(bsc, &con, parsed, msg);
1432 OSMO_ASSERT(res == 0);
1433
1434 /* verify the LAC */
1435 OSMO_ASSERT(con.lac == 8210);
1436 OSMO_ASSERT(con.ci == 50000);
1437}
1438
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001439int main(int argc, char **argv)
1440{
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +08001441 sccp_set_log_area(DSCCP);
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +02001442 osmo_init_logging(&log_info);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001443
1444 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001445 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001446 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +02001447 test_mgcp_ass_tracking();
1448 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +02001449 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +02001450 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +08001451 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +08001452 test_dt_filter();
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001453 test_setup_rewrite();
Holger Hans Peter Freytherddf191e2013-06-25 11:44:01 +02001454 test_setup_rewrite_prefix();
Holger Hans Peter Freyther67e423c2013-06-25 15:38:31 +02001455 test_setup_rewrite_post();
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001456 test_sms_smsc_rewrite();
1457 test_sms_number_rewrite();
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +01001458 test_mgcp_allocations();
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001459 test_barr_list_parsing();
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001460 test_nat_extract_lac();
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001461
1462 printf("Testing execution completed.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001463 return 0;
1464}
Holger Hans Peter Freytherc3271872012-11-05 14:54:56 +01001465
1466/* stub */
1467void bsc_nat_send_mgcp_to_msc(struct bsc_nat *nat, struct msgb *msg)
1468{
1469 abort();
1470}