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