blob: cbc1f182154087ef1c1f8351d22ae75c3be72fd4 [file] [log] [blame]
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001/*
2 * BSC NAT Message filtering
3 *
Holger Hans Peter Freytherdbd94492013-04-02 12:34:11 +02004 * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
5 * (C) 2010-2013 by On-Waves
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08006 *
7 * All Rights Reserved
8 *
9 * This program is free software; you can redistribute it and/or modify
Harald Welte9af6ddf2011-01-01 15:25:50 +010010 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080012 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
Harald Welte9af6ddf2011-01-01 15:25:50 +010019 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080021 *
22 */
23
24
25#include <openbsc/debug.h>
26#include <openbsc/gsm_data.h>
27#include <openbsc/bsc_nat.h>
Holger Hans Peter Freytherc2b31ed2010-07-31 05:17:17 +080028#include <openbsc/bsc_nat_sccp.h>
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080029
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +020030#include <osmocom/core/application.h>
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +020031#include <osmocom/core/backtrace.h>
Pablo Neira Ayuso928cb332011-03-26 22:08:53 +010032#include <osmocom/core/talloc.h>
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +080033
Harald Welted5db12c2010-08-03 15:11:51 +020034#include <osmocom/sccp/sccp.h>
Pablo Neira Ayuso928cb332011-03-26 22:08:53 +010035#include <osmocom/gsm/protocol/gsm_08_08.h>
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +080036
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080037#include <stdio.h>
38
39/* test messages for ipa */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080040static uint8_t ipa_id[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080041 0x00, 0x01, 0xfe, 0x06,
42};
43
44/* SCCP messages are below */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080045static uint8_t gsm_reset[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080046 0x00, 0x12, 0xfd,
47 0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
48 0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
49 0x01, 0x20,
50};
51
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080052static const uint8_t gsm_reset_ack[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080053 0x00, 0x13, 0xfd,
54 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
55 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
56 0x00, 0x01, 0x31,
57};
58
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080059static const uint8_t gsm_paging[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080060 0x00, 0x20, 0xfd,
61 0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
62 0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x10,
63 0x00, 0x0e, 0x52, 0x08, 0x08, 0x29, 0x47, 0x10,
64 0x02, 0x01, 0x31, 0x97, 0x61, 0x1a, 0x01, 0x06,
65};
66
67/* BSC -> MSC connection open */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080068static const uint8_t bssmap_cr[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080069 0x00, 0x2c, 0xfd,
70 0x01, 0x01, 0x02, 0x03, 0x02, 0x02, 0x04, 0x02,
71 0x42, 0xfe, 0x0f, 0x1f, 0x00, 0x1d, 0x57, 0x05,
72 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x12, 0xc3,
73 0x50, 0x17, 0x10, 0x05, 0x24, 0x11, 0x03, 0x33,
74 0x19, 0xa2, 0x08, 0x29, 0x47, 0x10, 0x02, 0x01,
75 0x31, 0x97, 0x61, 0x00
76};
77
78/* MSC -> BSC connection confirm */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080079static const uint8_t bssmap_cc[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080080 0x00, 0x0a, 0xfd,
81 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00,
82};
83
84/* MSC -> BSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080085static const uint8_t bssmap_released[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080086 0x00, 0x0e, 0xfd,
87 0x04, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00, 0x01, 0x0f,
88 0x02, 0x23, 0x42, 0x00,
89};
90
91/* BSC -> MSC released */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080092static const uint8_t bssmap_release_complete[] = {
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +080093 0x00, 0x07, 0xfd,
94 0x05, 0x01, 0x02, 0x03, 0x00, 0x00, 0x03
95};
96
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020097/* both directions IT timer */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +080098static const uint8_t connnection_it[] = {
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +020099 0x00, 0x0b, 0xfd,
100 0x10, 0x01, 0x02, 0x03, 0x01, 0x02, 0x03,
101 0x00, 0x00, 0x00, 0x00,
102};
103
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800104/* error in both directions */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800105static const uint8_t proto_error[] = {
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800106 0x00, 0x05, 0xfd,
107 0x0f, 0x22, 0x33, 0x44, 0x00,
108};
109
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200110/* MGCP wrap... */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800111static const uint8_t mgcp_msg[] = {
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200112 0x00, 0x03, 0xfc,
113 0x20, 0x20, 0x20,
114};
115
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800116/* location updating request */
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800117static const uint8_t bss_lu[] = {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800118 0x00, 0x2e, 0xfd,
119 0x01, 0x91, 0x45, 0x14, 0x02, 0x02, 0x04, 0x02,
120 0x42, 0xfe, 0x0f, 0x21, 0x00, 0x1f, 0x57, 0x05,
121 0x08, 0x00, 0x72, 0xf4, 0x80, 0x20, 0x14, 0xc3,
122 0x50, 0x17, 0x12, 0x05, 0x08, 0x70, 0x72, 0xf4,
123 0x80, 0xff, 0xfe, 0x30, 0x08, 0x29, 0x44, 0x50,
124 0x12, 0x03, 0x24, 0x01, 0x95, 0x00
125};
126
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800127/* paging response */
128static const uint8_t pag_resp[] = {
129 0x00, 0x2c, 0xfd, 0x01, 0xe5, 0x68,
130 0x14, 0x02, 0x02, 0x04, 0x02, 0x42, 0xfe, 0x0f,
131 0x1f, 0x00, 0x1d, 0x57, 0x05, 0x08, 0x00, 0x72,
132 0xf4, 0x80, 0x20, 0x16, 0xc3, 0x50, 0x17, 0x10,
133 0x06, 0x27, 0x01, 0x03, 0x30, 0x18, 0x96, 0x08,
134 0x29, 0x26, 0x30, 0x32, 0x11, 0x42, 0x01, 0x19,
135 0x00
136};
137
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800138struct filter_result {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800139 const uint8_t *data;
Holger Hans Peter Freythere2c15202010-07-23 19:09:21 +0800140 const uint16_t length;
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100141 const int dir;
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800142 const int result;
143};
144
145static const struct filter_result results[] = {
146 {
147 .data = ipa_id,
148 .length = ARRAY_SIZE(ipa_id),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100149 .dir = DIR_MSC,
150 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800151 },
152 {
153 .data = gsm_reset,
154 .length = ARRAY_SIZE(gsm_reset),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100155 .dir = DIR_MSC,
156 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800157 },
158 {
159 .data = gsm_reset_ack,
160 .length = ARRAY_SIZE(gsm_reset_ack),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100161 .dir = DIR_BSC,
162 .result = 1,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800163 },
164 {
165 .data = gsm_paging,
166 .length = ARRAY_SIZE(gsm_paging),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100167 .dir = DIR_BSC,
168 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800169 },
170 {
171 .data = bssmap_cr,
172 .length = ARRAY_SIZE(bssmap_cr),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100173 .dir = DIR_MSC,
174 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800175 },
176 {
177 .data = bssmap_cc,
178 .length = ARRAY_SIZE(bssmap_cc),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100179 .dir = DIR_BSC,
180 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800181 },
182 {
183 .data = bssmap_released,
184 .length = ARRAY_SIZE(bssmap_released),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100185 .dir = DIR_MSC,
186 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800187 },
188 {
189 .data = bssmap_release_complete,
190 .length = ARRAY_SIZE(bssmap_release_complete),
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100191 .dir = DIR_BSC,
192 .result = 0,
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800193 },
Holger Hans Peter Freythera128d912010-04-01 08:47:12 +0200194 {
195 .data = mgcp_msg,
196 .length = ARRAY_SIZE(mgcp_msg),
197 .dir = DIR_MSC,
198 .result = 0,
199 },
Holger Hans Peter Freyther0a6f62f2010-04-06 10:22:01 +0200200 {
201 .data = connnection_it,
202 .length = ARRAY_SIZE(connnection_it),
203 .dir = DIR_BSC,
204 .result = 0,
205 },
206 {
207 .data = connnection_it,
208 .length = ARRAY_SIZE(connnection_it),
209 .dir = DIR_MSC,
210 .result = 0,
211 },
Holger Hans Peter Freyther5e63f922010-04-21 15:45:26 +0800212 {
213 .data = proto_error,
214 .length = ARRAY_SIZE(proto_error),
215 .dir = DIR_BSC,
216 .result = 0,
217 },
218 {
219 .data = proto_error,
220 .length = ARRAY_SIZE(proto_error),
221 .dir = DIR_MSC,
222 .result = 0,
223 },
224
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800225};
226
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800227static void test_filter(void)
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800228{
229 int i;
230
231
232 /* start testinh with proper messages */
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100233 printf("Testing BSS Filtering.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800234 for (i = 0; i < ARRAY_SIZE(results); ++i) {
235 int result;
236 struct bsc_nat_parsed *parsed;
237 struct msgb *msg = msgb_alloc(4096, "test-message");
238
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100239 printf("Going to test item: %d\n", i);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800240 memcpy(msg->data, results[i].data, results[i].length);
241 msg->l2h = msgb_put(msg, results[i].length);
242
243 parsed = bsc_nat_parse(msg);
244 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100245 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800246 continue;
247 }
248
Holger Hans Peter Freyther1d6fb182010-01-30 11:53:30 +0100249 result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800250 if (result != results[i].result) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100251 printf("FAIL: Not the expected result got: %d wanted: %d\n",
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800252 result, results[i].result);
253 }
254
255 msgb_free(msg);
256 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800257}
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +0800258
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800259#include "bsc_data.c"
260
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800261static void copy_to_msg(struct msgb *msg, const uint8_t *data, unsigned int length)
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800262{
263 msgb_reset(msg);
264 msg->l2h = msgb_put(msg, length);
265 memcpy(msg->l2h, data, msgb_l2len(msg));
266}
267
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100268static void verify_msg(struct msgb *out, const uint8_t *ref, int ref_len)
269{
270 if (out->len != ref_len) {
Holger Hans Peter Freytherbe530122012-01-18 17:20:23 +0100271 printf("FAIL: The size should match: %d vs. %d\n",
272 out->len, ref_len);
273 printf("%s\n", osmo_hexdump(out->data, out->len));
274 printf("Wanted\n");
275 printf("%s\n", osmo_hexdump(ref, ref_len));
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100276 abort();
277 }
278
279 if (memcmp(out->data, ref, out->len) != 0) {
280 printf("FAIL: the data should be changed.\n");
281 printf("%s\n", osmo_hexdump(out->data, out->len));
282 printf("Wanted\n");
283 printf("%s\n", osmo_hexdump(ref, ref_len));
284 abort();
285 }
286}
287
288
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800289#define VERIFY(con_found, con, msg, ver, str) \
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100290 if (!con_found) { \
291 printf("Failed to find connection.\n"); \
292 abort(); \
293 } \
294 if (con_found->bsc != con) { \
295 printf("Got connection of the wrong BSC: %d\n", \
296 con_found->bsc->cfg->nr); \
297 abort(); \
298 } \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800299 if (memcmp(msg->data, ver, sizeof(ver)) != 0) { \
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100300 printf("Failed to patch the %s msg.\n", str); \
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800301 abort(); \
302 }
303
304/* test conn tracking once */
305static void test_contrack()
306{
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800307 struct bsc_nat *nat;
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800308 struct bsc_connection *con;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200309 struct nat_sccp_connection *con_found;
310 struct nat_sccp_connection *rc_con;
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800311 struct bsc_nat_parsed *parsed;
312 struct msgb *msg;
313
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100314 printf("Testing connection tracking.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800315 nat = bsc_nat_alloc();
316 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800317 con->cfg = bsc_config_alloc(nat, "foo");
318 bsc_config_add_lac(con->cfg, 23);
319 bsc_config_add_lac(con->cfg, 49);
320 bsc_config_add_lac(con->cfg, 42);
321 bsc_config_del_lac(con->cfg, 49);
322 bsc_config_add_lac(con->cfg, 1111);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800323 msg = msgb_alloc(4096, "test");
324
325 /* 1.) create a connection */
326 copy_to_msg(msg, bsc_cr, sizeof(bsc_cr));
327 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800328 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800329 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100330 printf("Con should not exist realref(%u)\n",
331 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800332 abort();
333 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800334 rc_con = create_sccp_src_ref(con, parsed);
335 if (!rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100336 printf("Failed to create a ref\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800337 abort();
338 }
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800339 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100340 if (!con_found) {
341 printf("Failed to find connection.\n");
342 abort();
343 }
344 if (con_found->bsc != con) {
345 printf("Got connection of the wrong BSC: %d\n",
346 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800347 abort();
348 }
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800349 if (con_found != rc_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100350 printf("Failed to find the right connection.\n");
Holger Hans Peter Freytherfa20c942010-05-16 16:51:31 +0800351 abort();
352 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800353 if (memcmp(msg->data, bsc_cr_patched, sizeof(bsc_cr_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100354 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800355 abort();
356 }
357 talloc_free(parsed);
358
359 /* 2.) get the cc */
360 copy_to_msg(msg, msc_cc, sizeof(msc_cc));
361 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freyther49c7fb52010-06-15 18:48:55 +0800362 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
363 VERIFY(con_found, con, msg, msc_cc_patched, "MSC CC");
364 if (update_sccp_src_ref(con_found, parsed) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100365 printf("Failed to update the SCCP con.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800366 abort();
367 }
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800368
369 /* 3.) send some data */
370 copy_to_msg(msg, bsc_dtap, sizeof(bsc_dtap));
371 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800372 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800373 VERIFY(con_found, con, msg, bsc_dtap_patched, "BSC DTAP");
374
375 /* 4.) receive some data */
376 copy_to_msg(msg, msc_dtap, sizeof(msc_dtap));
377 parsed = bsc_nat_parse(msg);
378 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
379 VERIFY(con_found, con, msg, msc_dtap_patched, "MSC DTAP");
380
381 /* 5.) close the connection */
382 copy_to_msg(msg, msc_rlsd, sizeof(msc_rlsd));
383 parsed = bsc_nat_parse(msg);
384 con_found = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
385 VERIFY(con_found, con, msg, msc_rlsd_patched, "MSC RLSD");
386
387 /* 6.) confirm the connection close */
388 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
389 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800390 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100391 if (!con_found) {
392 printf("Failed to find connection.\n");
393 abort();
394 }
395 if (con_found->bsc != con) {
396 printf("Got connection of the wrong BSC: %d\n",
397 con_found->bsc->cfg->nr);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800398 abort();
399 }
400 if (memcmp(msg->data, bsc_rlc_patched, sizeof(bsc_rlc_patched)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100401 printf("Failed to patch the BSC CR msg.\n");
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800402 abort();
403 }
404 remove_sccp_src_ref(con, msg, parsed);
Holger Hans Peter Freyther9d518552010-04-05 21:44:51 +0200405 talloc_free(parsed);
406
407 copy_to_msg(msg, bsc_rlc, sizeof(bsc_rlc));
408 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freytherb5513ca2010-04-21 18:56:12 +0800409 con_found = patch_sccp_src_ref_to_msc(msg, parsed, con);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800410
411 /* verify that it is gone */
412 if (con_found != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100413 printf("Con should not exist real_ref(%u)\n",
414 sccp_src_ref_to_int(&con_found->real_ref));
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800415 abort();
416 }
417 talloc_free(parsed);
418
419
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100420 bsc_config_free(con->cfg);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +0800421 talloc_free(nat);
422 msgb_free(msg);
423}
424
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200425static void test_paging(void)
426{
427 struct bsc_nat *nat;
428 struct bsc_connection *con;
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800429 struct bsc_config *cfg;
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200430
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100431 printf("Testing paging by lac.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200432
433 nat = bsc_nat_alloc();
434 con = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800435 cfg = bsc_config_alloc(nat, "unknown");
436 con->cfg = cfg;
437 bsc_config_add_lac(cfg, 23);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200438 con->authenticated = 1;
439 llist_add(&con->list_entry, &nat->bsc_connections);
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200440
441 /* Test it by not finding it */
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200442 if (bsc_config_handles_lac(cfg, 8213) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100443 printf("Should not be handled.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200444 abort();
445 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200446
447 /* Test by finding it */
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800448 bsc_config_del_lac(cfg, 23);
449 bsc_config_add_lac(cfg, 8213);
Holger Hans Peter Freyther1ffe98c2011-05-02 16:20:32 +0200450 if (bsc_config_handles_lac(cfg, 8213) == 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100451 printf("Should have found it.\n");
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200452 abort();
453 }
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +0200454}
455
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100456static void test_mgcp_allocations(void)
457{
458#if 0
459 struct bsc_connection *bsc;
460 struct bsc_nat *nat;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200461 struct nat_sccp_connection con;
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100462 int i, j, multiplex;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100463
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100464 printf("Testing MGCP.\n");
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100465 memset(&con, 0, sizeof(con));
466
467 nat = bsc_nat_alloc();
468 nat->bsc_endpoints = talloc_zero_array(nat,
469 struct bsc_endpoint,
470 65);
471 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100472 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100473
474 bsc = bsc_connection_alloc(nat);
475 bsc->cfg = bsc_config_alloc(nat, "foo");
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100476 bsc->cfg->max_endpoints = 60;
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100477 bsc_config_add_lac(bsc->cfg, 2323);
478 bsc->last_endpoint = 0x22;
479 con.bsc = bsc;
480
481 bsc_init_endps_if_needed(bsc);
482
483 i = 1;
484 do {
485 if (bsc_assign_endpoint(bsc, &con) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100486 printf("failed to allocate... on iteration %d\n", i);
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100487 break;
488 }
489 ++i;
490 } while(1);
491
Holger Hans Peter Freyther9ec030d2011-02-27 11:04:27 +0100492 multiplex = bsc_mgcp_nr_multiplexes(bsc->cfg->max_endpoints);
493 for (i = 0; i < multiplex; ++i) {
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +0100494 for (j = 0; j < 32; ++j)
495 printf("%d", bsc->_endpoint_status[i*32 + j]);
496 printf(": %d of %d\n", i*32 + 32, 32 * 8);
497 }
498#endif
499}
500
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200501static void test_mgcp_ass_tracking(void)
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800502{
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800503 struct bsc_connection *bsc;
504 struct bsc_nat *nat;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200505 struct nat_sccp_connection con;
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800506 struct bsc_nat_parsed *parsed;
507 struct msgb *msg;
508
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100509 printf("Testing MGCP.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800510 memset(&con, 0, sizeof(con));
511
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800512 nat = bsc_nat_alloc();
513 nat->bsc_endpoints = talloc_zero_array(nat,
514 struct bsc_endpoint,
515 33);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100516 nat->mgcp_cfg = mgcp_config_alloc();
Holger Hans Peter Freyther88ad7722011-02-28 00:56:17 +0100517 nat->mgcp_cfg->trunk.number_endpoints = 64;
Holger Hans Peter Freyther462b7d72012-10-24 21:53:40 +0200518 mgcp_endpoints_allocate(&nat->mgcp_cfg->trunk);
Holger Hans Peter Freyther7e0cc502011-02-25 12:43:58 +0100519
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800520 bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800521 bsc->cfg = bsc_config_alloc(nat, "foo");
522 bsc_config_add_lac(bsc->cfg, 2323);
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100523 bsc->last_endpoint = 0x1e;
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800524 con.bsc = bsc;
525
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800526 msg = msgb_alloc(4096, "foo");
527 copy_to_msg(msg, ass_cmd, sizeof(ass_cmd));
528 parsed = bsc_nat_parse(msg);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800529
530 if (msg->l2h[16] != 0 ||
531 msg->l2h[17] != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100532 printf("Input is not as expected.. %s 0x%x\n",
Pablo Neira Ayusoc0d17f22011-05-07 12:12:48 +0200533 osmo_hexdump(msg->l2h, msgb_l2len(msg)),
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800534 msg->l2h[17]);
535 abort();
536 }
537
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800538 if (bsc_mgcp_assign_patch(&con, msg) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100539 printf("Failed to handle assignment.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800540 abort();
541 }
542
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800543 if (con.msc_endp != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100544 printf("Timeslot should be 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800545 abort();
546 }
547
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100548 if (con.bsc_endp != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100549 printf("Assigned timeslot should have been 1.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800550 abort();
551 }
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100552 if (con.bsc->_endpoint_status[0x1] != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100553 printf("The status on the BSC is wrong.\n");
Holger Hans Peter Freyther45fd07d2010-08-28 18:22:14 +0800554 abort();
555 }
556
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800557 int multiplex, timeslot;
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100558 mgcp_endpoint_to_timeslot(0x1, &multiplex, &timeslot);
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800559
560 uint16_t cic = htons(timeslot & 0x1f);
561 if (memcmp(&cic, &msg->l2h[16], sizeof(cic)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100562 printf("Message was not patched properly\n");
563 printf("data cic: 0x%x %s\n", cic, osmo_hexdump(msg->l2h, msgb_l2len(msg)));
Holger Hans Peter Freythercd702372010-09-20 01:21:51 +0800564 abort();
565 }
566
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800567 talloc_free(parsed);
568
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800569 bsc_mgcp_dlcx(&con);
Holger Hans Peter Freytherd2df4ca2010-09-19 20:54:21 +0800570 if (con.bsc_endp != -1 || con.msc_endp != -1 ||
Holger Hans Peter Freyther86c1db62011-02-25 17:10:25 +0100571 con.bsc->_endpoint_status[1] != 0 || con.bsc->last_endpoint != 0x1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100572 printf("Clearing should remove the mapping.\n");
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800573 abort();
574 }
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800575
Holger Hans Peter Freyther9212d9d2011-02-27 11:18:41 +0100576 bsc_config_free(bsc->cfg);
Holger Hans Peter Freyther7b7eef62010-04-22 12:08:17 +0800577 talloc_free(nat);
Holger Hans Peter Freyther465313e2010-06-15 18:49:53 +0800578}
579
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200580/* test the code to find a given connection */
581static void test_mgcp_find(void)
582{
583 struct bsc_nat *nat;
584 struct bsc_connection *con;
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200585 struct nat_sccp_connection *sccp_con;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200586
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100587 printf("Testing finding of a BSC Connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200588
589 nat = bsc_nat_alloc();
590 con = bsc_connection_alloc(nat);
591 llist_add(&con->list_entry, &nat->bsc_connections);
592
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200593 sccp_con = talloc_zero(con, struct nat_sccp_connection);
Holger Hans Peter Freytherf4b34392010-08-28 16:08:39 +0800594 sccp_con->msc_endp = 12;
595 sccp_con->bsc_endp = 12;
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200596 sccp_con->bsc = con;
597 llist_add(&sccp_con->list_entry, &nat->sccp_connections);
598
599 if (bsc_mgcp_find_con(nat, 11) != NULL) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100600 printf("Found the wrong connection.\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200601 abort();
602 }
603
Holger Hans Peter Freyther08a1b162010-04-18 02:26:16 +0800604 if (bsc_mgcp_find_con(nat, 12) != sccp_con) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100605 printf("Didn't find the connection\n");
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200606 abort();
607 }
608
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +0200609 /* free everything */
610 talloc_free(nat);
611}
612
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200613static void test_mgcp_rewrite(void)
614{
615 int i;
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200616 struct msgb *output;
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100617 printf("Testing rewriting MGCP messages.\n");
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200618
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200619 for (i = 0; i < ARRAY_SIZE(mgcp_messages); ++i) {
620 const char *orig = mgcp_messages[i].orig;
621 const char *patc = mgcp_messages[i].patch;
622 const char *ip = mgcp_messages[i].ip;
623 const int port = mgcp_messages[i].port;
624
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200625 char *input = strdup(orig);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200626
Holger Hans Peter Freytherf7c86c52010-08-30 13:44:32 +0800627 output = bsc_mgcp_rewrite(input, strlen(input), 0x1e, ip, port);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200628 if (msgb_l2len(output) != strlen(patc)) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100629 printf("Wrong sizes for test: %d %d != %d != %d\n", i, msgb_l2len(output), strlen(patc), strlen(orig));
630 printf("String '%s' vs '%s'\n", (const char *) output->l2h, patc);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200631 abort();
632 }
633
634 if (memcmp(output->l2h, patc, msgb_l2len(output)) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100635 printf("Broken on %d msg: '%s'\n", i, (const char *) output->l2h);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200636 abort();
637 }
638
639 msgb_free(output);
Holger Hans Peter Freyther8d200652010-04-04 18:09:10 +0200640 free(input);
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200641 }
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +0200642}
643
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200644static void test_mgcp_parse(void)
645{
646 int code, ci;
647 char transaction[60];
648
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100649 printf("Testing MGCP response parsing.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200650
651 if (bsc_mgcp_parse_response(crcx_resp, &code, transaction) != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100652 printf("Failed to parse CRCX resp.\n");
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200653 abort();
654 }
655
656 if (code != 200) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100657 printf("Failed to parse the CODE properly. Got: %d\n", code);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200658 abort();
659 }
660
661 if (strcmp(transaction, "23265295") != 0) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100662 printf("Failed to parse transaction id: '%s'\n", transaction);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200663 abort();
664 }
665
666 ci = bsc_mgcp_extract_ci(crcx_resp);
667 if (ci != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100668 printf("Failed to parse the CI. Got: %d\n", ci);
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +0200669 abort();
670 }
671}
672
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800673struct cr_filter {
Holger Hans Peter Freytherdbd16fe2010-07-23 19:08:55 +0800674 const uint8_t *data;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800675 int length;
676 int result;
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800677 int contype;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800678
679 const char *bsc_imsi_allow;
680 const char *bsc_imsi_deny;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800681 const char *nat_imsi_deny;
682};
683
684static struct cr_filter cr_filter[] = {
685 {
686 .data = bssmap_cr,
687 .length = sizeof(bssmap_cr),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800688 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800689 .contype = NAT_CON_TYPE_CM_SERV_REQ,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800690 },
691 {
692 .data = bss_lu,
693 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800694 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800695 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800696 },
697 {
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800698 .data = pag_resp,
699 .length = sizeof(pag_resp),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800700 .result = 1,
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800701 .contype = NAT_CON_TYPE_PAG_RESP,
Holger Hans Peter Freytherf1924982010-05-15 23:54:04 +0800702 },
703 {
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800704 /* nat deny is before blank/null BSC */
705 .data = bss_lu,
706 .length = sizeof(bss_lu),
707 .result = -3,
708 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800709 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800710 },
711 {
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800712 /* BSC allow is before NAT deny */
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800713 .data = bss_lu,
714 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800715 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800716 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freythera0aeaa72010-05-14 23:07:58 +0800717 .bsc_imsi_allow = "2440[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800718 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800719 },
720 {
721 /* BSC allow is before NAT deny */
722 .data = bss_lu,
723 .length = sizeof(bss_lu),
Holger Hans Peter Freytherd880f542010-09-15 01:42:07 +0800724 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800725 .bsc_imsi_allow = "[0-9]*",
726 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800727 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800728 },
729 {
730 /* filter as deny is first */
731 .data = bss_lu,
732 .length = sizeof(bss_lu),
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200733 .result = 1,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800734 .bsc_imsi_deny = "[0-9]*",
735 .bsc_imsi_allow = "[0-9]*",
736 .nat_imsi_deny = "[0-9]*",
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800737 .contype = NAT_CON_TYPE_LU,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800738 },
Holger Hans Peter Freyther1fd60632010-10-19 20:55:33 +0200739 {
740 /* deny by nat rule */
741 .data = bss_lu,
742 .length = sizeof(bss_lu),
743 .result = -3,
744 .bsc_imsi_deny = "000[0-9]*",
745 .nat_imsi_deny = "[0-9]*",
746 .contype = NAT_CON_TYPE_LU,
747 },
748 {
749 /* deny by bsc rule */
750 .data = bss_lu,
751 .length = sizeof(bss_lu),
752 .result = -2,
753 .bsc_imsi_deny = "[0-9]*",
754 .contype = NAT_CON_TYPE_LU,
755 },
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800756
757};
758
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800759static void test_cr_filter()
760{
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800761 int i, res, contype;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800762 struct msgb *msg = msgb_alloc(4096, "test_cr_filter");
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800763 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800764 struct bsc_nat_acc_lst *nat_lst, *bsc_lst;
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800765 struct bsc_nat_acc_lst_entry *nat_entry, *bsc_entry;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100766 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800767
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800768 struct bsc_nat *nat = bsc_nat_alloc();
769 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800770 bsc->cfg = bsc_config_alloc(nat, "foo");
771 bsc_config_add_lac(bsc->cfg, 1234);
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800772 bsc->cfg->acc_lst_name = "bsc";
773 nat->acc_lst_name = "nat";
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800774
Holger Hans Peter Freytherd77c8172010-06-08 10:53:39 +0800775 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
776 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
777
778 bsc_entry = bsc_nat_acc_lst_entry_create(bsc_lst);
779 nat_entry = bsc_nat_acc_lst_entry_create(nat_lst);
780
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800781 for (i = 0; i < ARRAY_SIZE(cr_filter); ++i) {
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800782 char *imsi;
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800783 msgb_reset(msg);
784 copy_to_msg(msg, cr_filter[i].data, cr_filter[i].length);
785
Holger Hans Peter Freyther29c67032010-06-08 10:14:44 +0800786 nat_lst = bsc_nat_acc_lst_get(nat, "nat");
787 bsc_lst = bsc_nat_acc_lst_get(nat, "bsc");
Holger Hans Peter Freyther8affef52010-06-01 01:03:13 +0800788
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);
825}
826
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800827static void test_dt_filter()
828{
829 int i;
830 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
831 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100832 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800833
834 struct bsc_nat *nat = bsc_nat_alloc();
835 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200836 struct nat_sccp_connection *con = talloc_zero(0, struct nat_sccp_connection);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800837
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800838 bsc->cfg = bsc_config_alloc(nat, "foo");
839 bsc_config_add_lac(bsc->cfg, 23);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800840 con->bsc = bsc;
841
842 msgb_reset(msg);
843 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
844
845 parsed = bsc_nat_parse(msg);
846 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100847 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800848 abort();
849 }
850
851 if (parsed->bssap != BSSAP_MSG_DTAP) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100852 printf("FAIL: It should be dtap\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800853 abort();
854 }
855
856 /* gsm_type is actually the size of the dtap */
857 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100858 printf("FAIL: Not enough space for the content\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800859 abort();
860 }
861
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100862 memset(&cause, 0, sizeof(cause));
863 if (bsc_nat_filter_dt(bsc, msg, con, parsed, &cause) != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100864 printf("FAIL: Should have passed..\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800865 abort();
866 }
867
868 /* just some basic length checking... */
869 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
870 msgb_reset(msg);
871 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
872
873 parsed = bsc_nat_parse(msg);
874 if (!parsed)
875 continue;
876
877 con->imsi_checked = 0;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100878 memset(&cause, 0, sizeof(cause));
879 bsc_nat_filter_dt(bsc, msg, con, parsed, &cause);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800880 }
881}
882
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200883static void test_setup_rewrite()
884{
885 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
886 struct msgb *out;
887 struct bsc_nat_parsed *parsed;
888 const char *imsi = "27408000001234";
889
890 struct bsc_nat *nat = bsc_nat_alloc();
891
892 /* a fake list */
Pablo Neira Ayusoab46cf32011-05-07 13:11:20 +0200893 struct osmo_config_list entries;
894 struct osmo_config_entry entry;
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200895
896 INIT_LLIST_HEAD(&entries.entry);
897 entry.mcc = "274";
898 entry.mnc = "08";
899 entry.option = "^0([1-9])";
900 entry.text = "0049";
901 llist_add_tail(&entry.list, &entries.entry);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200902 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200903
904 /* verify that nothing changed */
905 msgb_reset(msg);
906 copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
907 parsed = bsc_nat_parse(msg);
908 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100909 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200910 abort();
911 }
912
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200913 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200914 if (msg != out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100915 printf("FAIL: The message should not have been changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200916 abort();
917 }
918
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100919 verify_msg(out, cc_setup_international, ARRAY_SIZE(cc_setup_international));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200920 talloc_free(parsed);
921
922 /* verify that something in the message changes */
923 msgb_reset(msg);
924 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
925 parsed = bsc_nat_parse(msg);
926 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100927 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200928 abort();
929 }
930
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200931 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200932 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100933 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200934 abort();
935 }
936
937 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100938 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200939 abort();
940 }
941
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100942 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200943 msgb_free(out);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200944
945 /* Make sure that a wildcard is matching */
946 entry.mnc = "*";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200947 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200948 msg = msgb_alloc(4096, "test_dt_filter");
949 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
950 parsed = bsc_nat_parse(msg);
951 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100952 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200953 abort();
954 }
955
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200956 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200957 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100958 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200959 abort();
960 }
961
962 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100963 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200964 abort();
965 }
966
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100967 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200968 msgb_free(out);
969
970 /* Make sure that a wildcard is matching */
971 entry.mnc = "09";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200972 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200973 msg = msgb_alloc(4096, "test_dt_filter");
974 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
975 parsed = bsc_nat_parse(msg);
976 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100977 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200978 abort();
979 }
980
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200981 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200982 if (out != msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100983 printf("FAIL: The message should be unchanged.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200984 abort();
985 }
986
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100987 verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200988 msgb_free(out);
Holger Hans Peter Freytherdbd94492013-04-02 12:34:11 +0200989
990 /* Now see what happens to an international number */
991 entry.mnc = "*";
992 entry.option = "^\\+[0-9][0-9]([1-9])";
993 entry.text = "0036";
994 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
995 msg = msgb_alloc(4096, "test_dt_filter");
996 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
997 parsed = bsc_nat_parse(msg);
998 if (!parsed) {
999 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
1000 abort();
1001 }
1002
1003 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1004 if (!out) {
1005 printf("FAIL: A new message should be created %d.\n", __LINE__);
1006 abort();
1007 }
1008
1009 if (msg == out) {
1010 printf("FAIL: The message should have changed %d\n", __LINE__);
1011 abort();
1012 }
1013
1014 verify_msg(out, cc_setup_national_patched_patched,
1015 ARRAY_SIZE(cc_setup_national_patched_patched));
1016 msgb_free(out);
1017
1018 /* go from international back to national */
1019 entry.mnc = "*";
1020 entry.option = "^\\+([0-9])";
1021 entry.text = "36";
1022 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1023 msg = msgb_alloc(4096, "test_dt_filter");
1024 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1025 parsed = bsc_nat_parse(msg);
1026 if (!parsed) {
1027 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
1028 abort();
1029 }
1030
1031 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1032 if (!out) {
1033 printf("FAIL: A new message should be created %d.\n", __LINE__);
1034 abort();
1035 }
1036
1037 if (msg == out) {
1038 printf("FAIL: The message should have changed %d\n", __LINE__);
1039 abort();
1040 }
1041
1042 verify_msg(out, cc_setup_national_again,
1043 ARRAY_SIZE(cc_setup_national_again));
1044 msgb_free(out);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001045}
1046
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001047static void test_sms_smsc_rewrite()
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001048{
1049 struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
1050 struct bsc_nat_parsed *parsed;
1051 const char *imsi = "515039900406700";
1052
1053 struct bsc_nat *nat = bsc_nat_alloc();
1054
1055 /* a fake list */
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001056 struct osmo_config_list smsc_entries, dest_entries, clear_entries;
1057 struct osmo_config_entry smsc_entry, dest_entry, clear_entry;
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001058
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001059 INIT_LLIST_HEAD(&smsc_entries.entry);
1060 INIT_LLIST_HEAD(&dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001061 INIT_LLIST_HEAD(&clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001062 smsc_entry.mcc = "^515039";
1063 smsc_entry.option = "639180000105()";
1064 smsc_entry.text = "6666666666667";
1065 llist_add_tail(&smsc_entry.list, &smsc_entries.entry);
1066 dest_entry.mcc = "515";
1067 dest_entry.mnc = "03";
1068 dest_entry.option = "^0049";
1069 dest_entry.text = "";
1070 llist_add_tail(&dest_entry.list, &dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001071 clear_entry.mcc = "^515039";
1072 clear_entry.option = "^0049";
1073 clear_entry.text = "";
1074 llist_add_tail(&clear_entry.list, &clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001075
1076 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
1077 bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001078 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001079
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001080 printf("Testing SMSC rewriting.\n");
1081
1082 /*
1083 * Check if the SMSC address is changed
1084 */
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001085 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1086 parsed = bsc_nat_parse(msg);
1087 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001088 printf("FAIL: Could not parse SMS\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001089 abort();
1090 }
1091
1092 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1093 if (out == msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001094 printf("FAIL: This should have changed.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001095 abort();
1096 }
1097
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +01001098 verify_msg(out, smsc_rewrite_patched, ARRAY_SIZE(smsc_rewrite_patched));
1099 msgb_free(out);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001100
1101 /* clear out the filter for SMSC */
1102 printf("Attempting to only rewrite the HDR\n");
1103 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL);
1104 msg = msgb_alloc(4096, "SMSC rewrite");
1105 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1106 parsed = bsc_nat_parse(msg);
1107 if (!parsed) {
1108 printf("FAIL: Could not parse SMS\n");
1109 abort();
1110 }
1111
1112 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1113 if (out == msg) {
1114 printf("FAIL: This should have changed.\n");
1115 abort();
1116 }
1117
1118 verify_msg(out, smsc_rewrite_patched_hdr, ARRAY_SIZE(smsc_rewrite_patched_hdr));
1119 msgb_free(out);
1120
1121 /* clear out the next filter */
1122 printf("Attempting to change nothing.\n");
1123 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL);
1124 msg = msgb_alloc(4096, "SMSC rewrite");
1125 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1126 parsed = bsc_nat_parse(msg);
1127 if (!parsed) {
1128 printf("FAIL: Could not parse SMS\n");
1129 abort();
1130 }
1131
1132 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1133 if (out != msg) {
1134 printf("FAIL: This should not have changed.\n");
1135 abort();
1136 }
1137
1138 verify_msg(out, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1139 msgb_free(out);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001140}
1141
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001142static void test_sms_number_rewrite(void)
1143{
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001144 struct msgb *msg, *out;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001145 struct bsc_nat_parsed *parsed;
1146 const char *imsi = "515039900406700";
1147
1148 struct bsc_nat *nat = bsc_nat_alloc();
1149
1150 /* a fake list */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001151 struct osmo_config_list num_entries, clear_entries;
1152 struct osmo_config_entry num_entry, clear_entry;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001153
1154 INIT_LLIST_HEAD(&num_entries.entry);
1155 num_entry.mcc = "^515039";
1156 num_entry.option = "^0049()";
1157 num_entry.text = "0032";
1158 llist_add_tail(&num_entry.list, &num_entries.entry);
1159
1160 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_num_rewr, &num_entries);
1161
1162 printf("Testing SMS TP-DA rewriting.\n");
1163
1164 /*
1165 * Check if the SMSC address is changed
1166 */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001167 msg = msgb_alloc(4096, "SMSC rewrite");
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001168 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1169 parsed = bsc_nat_parse(msg);
1170 if (!parsed) {
1171 printf("FAIL: Could not parse SMS\n");
1172 abort();
1173 }
1174
1175 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1176 if (out == msg) {
1177 printf("FAIL: This should have changed.\n");
1178 abort();
1179 }
1180
1181 verify_msg(out, smsc_rewrite_num_patched,
1182 ARRAY_SIZE(smsc_rewrite_num_patched));
1183 msgb_free(out);
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001184
1185 /*
1186 * Now with TP-SRR rewriting enabled
1187 */
1188 INIT_LLIST_HEAD(&clear_entries.entry);
1189 clear_entry.mcc = "^515039";
1190 clear_entry.option = "";
1191 clear_entry.text = "";
1192 llist_add_tail(&clear_entry.list, &clear_entries.entry);
1193 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
1194
1195 msg = msgb_alloc(4096, "SMSC rewrite");
1196 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1197 parsed = bsc_nat_parse(msg);
1198 if (!parsed) {
1199 printf("FAIL: Could not parse SMS\n");
1200 abort();
1201 }
1202
1203 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1204 if (out == msg) {
1205 printf("FAIL: This should have changed.\n");
1206 abort();
1207 }
1208
1209 verify_msg(out, smsc_rewrite_num_patched_tp_srr,
1210 ARRAY_SIZE(smsc_rewrite_num_patched_tp_srr));
1211 msgb_free(out);
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001212}
1213
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001214static void test_barr_list_parsing(void)
1215{
1216 int rc;
1217 int cm, lu;
1218 struct rb_node *node;
1219 struct rb_root root = RB_ROOT;
1220 struct osmo_config_list *lst = osmo_config_list_parse(NULL, "barr.cfg");
1221 if (lst == NULL)
1222 abort();
1223
1224 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1225 if (rc != 0)
1226 abort();
1227 talloc_free(lst);
1228
1229
1230 for (node = rb_first(&root); node; node = rb_next(node)) {
1231 struct bsc_nat_barr_entry *entry;
1232 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1233 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1234 entry->cm_reject_cause, entry->lu_reject_cause);
1235 }
1236
1237 /* do the look up now.. */
1238 rc = bsc_nat_barr_find(&root, "12123119", &cm, &lu);
1239 if (!rc) {
1240 printf("Failed to find the IMSI.\n");
1241 abort();
1242 }
1243
1244 if (cm != 3 || lu != 4) {
1245 printf("Found CM(%d) and LU(%d)\n", cm, lu);
1246 abort();
1247 }
1248
1249 /* empty and check that it is empty */
1250 bsc_nat_barr_adapt(NULL, &root, NULL);
1251 if (!RB_EMPTY_ROOT(&root)) {
1252 printf("Failed to empty the list.\n");
1253 abort();
1254 }
1255
1256 /* check that dup results in an error */
1257 lst = osmo_config_list_parse(NULL, "barr_dup.cfg");
1258 if (lst == NULL) {
1259 printf("Failed to parse list with dups\n");
1260 abort();
1261 }
1262
1263 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1264 if (rc != -1) {
1265 printf("It should have failed due dup\n");
1266 abort();
1267 }
1268 talloc_free(lst);
1269
1270 /* dump for reference */
1271 for (node = rb_first(&root); node; node = rb_next(node)) {
1272 struct bsc_nat_barr_entry *entry;
1273 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1274 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1275 entry->cm_reject_cause, entry->lu_reject_cause);
1276
1277 }
1278}
1279
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001280static void test_nat_extract_lac()
1281{
1282 int res;
1283 struct bsc_connection *bsc;
1284 struct bsc_nat *nat;
1285 struct nat_sccp_connection con;
1286 struct bsc_nat_parsed *parsed;
1287 struct msgb *msg = msgb_alloc(4096, "test-message");
1288
1289 printf("Testing LAC extraction from SCCP CR\n");
1290
1291 /* initialize the testcase */
1292 nat = bsc_nat_alloc();
1293 bsc = bsc_connection_alloc(nat);
1294 bsc->cfg = bsc_config_alloc(nat, "foo");
1295
1296 memset(&con, 0, sizeof(con));
1297 con.bsc = bsc;
1298
1299 /* create the SCCP CR */
1300 msg->l2h = msgb_put(msg, ARRAY_SIZE(bssmap_cr));
1301 memcpy(msg->l2h, bssmap_cr, ARRAY_SIZE(bssmap_cr));
1302
1303 /* parse it and pass it on */
1304 parsed = bsc_nat_parse(msg);
1305 res = bsc_nat_extract_lac(bsc, &con, parsed, msg);
1306 OSMO_ASSERT(res == 0);
1307
1308 /* verify the LAC */
1309 OSMO_ASSERT(con.lac == 8210);
1310 OSMO_ASSERT(con.ci == 50000);
1311}
1312
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001313int main(int argc, char **argv)
1314{
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +08001315 sccp_set_log_area(DSCCP);
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +02001316 osmo_init_logging(&log_info);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001317
1318 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001319 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001320 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +02001321 test_mgcp_ass_tracking();
1322 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +02001323 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +02001324 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +08001325 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +08001326 test_dt_filter();
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001327 test_setup_rewrite();
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001328 test_sms_smsc_rewrite();
1329 test_sms_number_rewrite();
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +01001330 test_mgcp_allocations();
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001331 test_barr_list_parsing();
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001332 test_nat_extract_lac();
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001333
1334 printf("Testing execution completed.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001335 return 0;
1336}
Holger Hans Peter Freytherc3271872012-11-05 14:54:56 +01001337
1338/* stub */
1339void bsc_nat_send_mgcp_to_msc(struct bsc_nat *nat, struct msgb *msg)
1340{
1341 abort();
1342}