blob: 4a244dba375c6cf4ec71ef29fe5bf2342fd3a377 [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 Freyther06c9da62011-06-09 21:48:49 +0200786 if (gsm_parse_reg(nat_entry, &nat_entry->imsi_deny_re, &nat_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800787 cr_filter[i].nat_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200788 &cr_filter[i].nat_imsi_deny) != 0)
789 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200790 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_allow_re, &bsc_entry->imsi_allow,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800791 cr_filter[i].bsc_imsi_allow ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200792 &cr_filter[i].bsc_imsi_allow) != 0)
793 abort();
Holger Hans Peter Freyther06c9da62011-06-09 21:48:49 +0200794 if (gsm_parse_reg(bsc_entry, &bsc_entry->imsi_deny_re, &bsc_entry->imsi_deny,
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800795 cr_filter[i].bsc_imsi_deny ? 1 : 0,
Holger Hans Peter Freyther4c9557e2011-04-04 19:19:26 +0200796 &cr_filter[i].bsc_imsi_deny) != 0)
797 abort();
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800798
799 parsed = bsc_nat_parse(msg);
800 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100801 printf("FAIL: Failed to parse the message\n");
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800802 abort();
803 }
804
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100805 memset(&cause, 0, sizeof(cause));
806 res = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &contype, &imsi, &cause);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800807 if (res != cr_filter[i].result) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100808 printf("FAIL: Wrong result %d for test %d.\n", res, i);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800809 abort();
810 }
811
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800812 if (contype != cr_filter[i].contype) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100813 printf("FAIL: Wrong contype %d for test %d.\n", res, contype);
Holger Hans Peter Freyther19c0a842010-05-16 02:00:40 +0800814 abort();
815 }
816
Holger Hans Peter Freyther749497e2010-09-29 01:19:42 +0800817 talloc_steal(parsed, imsi);
Holger Hans Peter Freyther34a96ae2010-05-14 19:49:35 +0800818 talloc_free(parsed);
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800819 }
820
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +0800821 msgb_free(msg);
822}
823
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800824static void test_dt_filter()
825{
826 int i;
827 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
828 struct bsc_nat_parsed *parsed;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100829 struct bsc_nat_reject_cause cause;
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800830
831 struct bsc_nat *nat = bsc_nat_alloc();
832 struct bsc_connection *bsc = bsc_connection_alloc(nat);
Holger Hans Peter Freytherc279e392013-04-16 09:53:13 +0200833 struct nat_sccp_connection *con = talloc_zero(0, struct nat_sccp_connection);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800834
Holger Hans Peter Freyther0bd60f32010-10-08 22:08:29 +0800835 bsc->cfg = bsc_config_alloc(nat, "foo");
836 bsc_config_add_lac(bsc->cfg, 23);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800837 con->bsc = bsc;
838
839 msgb_reset(msg);
840 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
841
842 parsed = bsc_nat_parse(msg);
843 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100844 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800845 abort();
846 }
847
848 if (parsed->bssap != BSSAP_MSG_DTAP) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100849 printf("FAIL: It should be dtap\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800850 abort();
851 }
852
853 /* gsm_type is actually the size of the dtap */
854 if (parsed->gsm_type < msgb_l3len(msg) - 3) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100855 printf("FAIL: Not enough space for the content\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800856 abort();
857 }
858
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100859 memset(&cause, 0, sizeof(cause));
860 if (bsc_nat_filter_dt(bsc, msg, con, parsed, &cause) != 1) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100861 printf("FAIL: Should have passed..\n");
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800862 abort();
863 }
864
865 /* just some basic length checking... */
866 for (i = ARRAY_SIZE(id_resp); i >= 0; --i) {
867 msgb_reset(msg);
868 copy_to_msg(msg, id_resp, ARRAY_SIZE(id_resp));
869
870 parsed = bsc_nat_parse(msg);
871 if (!parsed)
872 continue;
873
874 con->imsi_checked = 0;
Holger Hans Peter Freytherbdf764a2012-12-17 14:35:03 +0100875 memset(&cause, 0, sizeof(cause));
876 bsc_nat_filter_dt(bsc, msg, con, parsed, &cause);
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +0800877 }
878}
879
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200880static void test_setup_rewrite()
881{
882 struct msgb *msg = msgb_alloc(4096, "test_dt_filter");
883 struct msgb *out;
884 struct bsc_nat_parsed *parsed;
885 const char *imsi = "27408000001234";
886
887 struct bsc_nat *nat = bsc_nat_alloc();
888
889 /* a fake list */
Pablo Neira Ayusoab46cf32011-05-07 13:11:20 +0200890 struct osmo_config_list entries;
891 struct osmo_config_entry entry;
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200892
893 INIT_LLIST_HEAD(&entries.entry);
894 entry.mcc = "274";
895 entry.mnc = "08";
896 entry.option = "^0([1-9])";
897 entry.text = "0049";
898 llist_add_tail(&entry.list, &entries.entry);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200899 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200900
901 /* verify that nothing changed */
902 msgb_reset(msg);
903 copy_to_msg(msg, cc_setup_international, ARRAY_SIZE(cc_setup_international));
904 parsed = bsc_nat_parse(msg);
905 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100906 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200907 abort();
908 }
909
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200910 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200911 if (msg != out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100912 printf("FAIL: The message should not have been changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200913 abort();
914 }
915
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100916 verify_msg(out, cc_setup_international, ARRAY_SIZE(cc_setup_international));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200917 talloc_free(parsed);
918
919 /* verify that something in the message changes */
920 msgb_reset(msg);
921 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
922 parsed = bsc_nat_parse(msg);
923 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100924 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200925 abort();
926 }
927
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200928 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200929 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100930 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200931 abort();
932 }
933
934 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100935 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200936 abort();
937 }
938
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100939 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +0200940 msgb_free(out);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200941
942 /* Make sure that a wildcard is matching */
943 entry.mnc = "*";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200944 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200945 msg = msgb_alloc(4096, "test_dt_filter");
946 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
947 parsed = bsc_nat_parse(msg);
948 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100949 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200950 abort();
951 }
952
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200953 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200954 if (!out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100955 printf("FAIL: A new message should be created.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200956 abort();
957 }
958
959 if (msg == out) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100960 printf("FAIL: The message should have changed\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200961 abort();
962 }
963
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100964 verify_msg(out, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200965 msgb_free(out);
966
967 /* Make sure that a wildcard is matching */
968 entry.mnc = "09";
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +0200969 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200970 msg = msgb_alloc(4096, "test_dt_filter");
971 copy_to_msg(msg, cc_setup_national, ARRAY_SIZE(cc_setup_national));
972 parsed = bsc_nat_parse(msg);
973 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100974 printf("FAIL: Could not parse ID resp\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200975 abort();
976 }
977
Holger Hans Peter Freytherdf8e6e92011-05-27 14:09:55 +0200978 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200979 if (out != msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +0100980 printf("FAIL: The message should be unchanged.\n");
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200981 abort();
982 }
983
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +0100984 verify_msg(out, cc_setup_national, ARRAY_SIZE(cc_setup_national));
Holger Hans Peter Freyther74779c62010-10-28 15:27:00 +0200985 msgb_free(out);
Holger Hans Peter Freytherdbd94492013-04-02 12:34:11 +0200986
987 /* Now see what happens to an international number */
988 entry.mnc = "*";
989 entry.option = "^\\+[0-9][0-9]([1-9])";
990 entry.text = "0036";
991 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
992 msg = msgb_alloc(4096, "test_dt_filter");
993 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
994 parsed = bsc_nat_parse(msg);
995 if (!parsed) {
996 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
997 abort();
998 }
999
1000 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1001 if (!out) {
1002 printf("FAIL: A new message should be created %d.\n", __LINE__);
1003 abort();
1004 }
1005
1006 if (msg == out) {
1007 printf("FAIL: The message should have changed %d\n", __LINE__);
1008 abort();
1009 }
1010
1011 verify_msg(out, cc_setup_national_patched_patched,
1012 ARRAY_SIZE(cc_setup_national_patched_patched));
1013 msgb_free(out);
1014
1015 /* go from international back to national */
1016 entry.mnc = "*";
1017 entry.option = "^\\+([0-9])";
1018 entry.text = "36";
1019 bsc_nat_num_rewr_entry_adapt(nat, &nat->num_rewr, &entries);
1020 msg = msgb_alloc(4096, "test_dt_filter");
1021 copy_to_msg(msg, cc_setup_national_patched, ARRAY_SIZE(cc_setup_national_patched));
1022 parsed = bsc_nat_parse(msg);
1023 if (!parsed) {
1024 printf("FAIL: Could not parse ID resp %d\n", __LINE__);
1025 abort();
1026 }
1027
1028 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1029 if (!out) {
1030 printf("FAIL: A new message should be created %d.\n", __LINE__);
1031 abort();
1032 }
1033
1034 if (msg == out) {
1035 printf("FAIL: The message should have changed %d\n", __LINE__);
1036 abort();
1037 }
1038
1039 verify_msg(out, cc_setup_national_again,
1040 ARRAY_SIZE(cc_setup_national_again));
1041 msgb_free(out);
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001042}
1043
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001044static void test_sms_smsc_rewrite()
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001045{
1046 struct msgb *msg = msgb_alloc(4096, "SMSC rewrite"), *out;
1047 struct bsc_nat_parsed *parsed;
1048 const char *imsi = "515039900406700";
1049
1050 struct bsc_nat *nat = bsc_nat_alloc();
1051
1052 /* a fake list */
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001053 struct osmo_config_list smsc_entries, dest_entries, clear_entries;
1054 struct osmo_config_entry smsc_entry, dest_entry, clear_entry;
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001055
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001056 INIT_LLIST_HEAD(&smsc_entries.entry);
1057 INIT_LLIST_HEAD(&dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001058 INIT_LLIST_HEAD(&clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001059 smsc_entry.mcc = "^515039";
1060 smsc_entry.option = "639180000105()";
1061 smsc_entry.text = "6666666666667";
1062 llist_add_tail(&smsc_entry.list, &smsc_entries.entry);
1063 dest_entry.mcc = "515";
1064 dest_entry.mnc = "03";
1065 dest_entry.option = "^0049";
1066 dest_entry.text = "";
1067 llist_add_tail(&dest_entry.list, &dest_entries.entry);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001068 clear_entry.mcc = "^515039";
1069 clear_entry.option = "^0049";
1070 clear_entry.text = "";
1071 llist_add_tail(&clear_entry.list, &clear_entries.entry);
Holger Hans Peter Freytheracc40312011-05-27 19:21:24 +02001072
1073 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, &smsc_entries);
1074 bsc_nat_num_rewr_entry_adapt(nat, &nat->tpdest_match, &dest_entries);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001075 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001076
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001077 printf("Testing SMSC rewriting.\n");
1078
1079 /*
1080 * Check if the SMSC address is changed
1081 */
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001082 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1083 parsed = bsc_nat_parse(msg);
1084 if (!parsed) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001085 printf("FAIL: Could not parse SMS\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001086 abort();
1087 }
1088
1089 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1090 if (out == msg) {
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001091 printf("FAIL: This should have changed.\n");
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001092 abort();
1093 }
1094
Holger Hans Peter Freyther50be1a92012-01-10 22:31:39 +01001095 verify_msg(out, smsc_rewrite_patched, ARRAY_SIZE(smsc_rewrite_patched));
1096 msgb_free(out);
Holger Hans Peter Freyther68368dd2012-01-10 22:39:07 +01001097
1098 /* clear out the filter for SMSC */
1099 printf("Attempting to only rewrite the HDR\n");
1100 bsc_nat_num_rewr_entry_adapt(nat, &nat->smsc_rewr, NULL);
1101 msg = msgb_alloc(4096, "SMSC rewrite");
1102 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1103 parsed = bsc_nat_parse(msg);
1104 if (!parsed) {
1105 printf("FAIL: Could not parse SMS\n");
1106 abort();
1107 }
1108
1109 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1110 if (out == msg) {
1111 printf("FAIL: This should have changed.\n");
1112 abort();
1113 }
1114
1115 verify_msg(out, smsc_rewrite_patched_hdr, ARRAY_SIZE(smsc_rewrite_patched_hdr));
1116 msgb_free(out);
1117
1118 /* clear out the next filter */
1119 printf("Attempting to change nothing.\n");
1120 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, NULL);
1121 msg = msgb_alloc(4096, "SMSC rewrite");
1122 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1123 parsed = bsc_nat_parse(msg);
1124 if (!parsed) {
1125 printf("FAIL: Could not parse SMS\n");
1126 abort();
1127 }
1128
1129 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1130 if (out != msg) {
1131 printf("FAIL: This should not have changed.\n");
1132 abort();
1133 }
1134
1135 verify_msg(out, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1136 msgb_free(out);
Holger Hans Peter Freyther9c205712011-05-27 17:14:15 +02001137}
1138
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001139static void test_sms_number_rewrite(void)
1140{
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001141 struct msgb *msg, *out;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001142 struct bsc_nat_parsed *parsed;
1143 const char *imsi = "515039900406700";
1144
1145 struct bsc_nat *nat = bsc_nat_alloc();
1146
1147 /* a fake list */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001148 struct osmo_config_list num_entries, clear_entries;
1149 struct osmo_config_entry num_entry, clear_entry;
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001150
1151 INIT_LLIST_HEAD(&num_entries.entry);
1152 num_entry.mcc = "^515039";
1153 num_entry.option = "^0049()";
1154 num_entry.text = "0032";
1155 llist_add_tail(&num_entry.list, &num_entries.entry);
1156
1157 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_num_rewr, &num_entries);
1158
1159 printf("Testing SMS TP-DA rewriting.\n");
1160
1161 /*
1162 * Check if the SMSC address is changed
1163 */
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001164 msg = msgb_alloc(4096, "SMSC rewrite");
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001165 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1166 parsed = bsc_nat_parse(msg);
1167 if (!parsed) {
1168 printf("FAIL: Could not parse SMS\n");
1169 abort();
1170 }
1171
1172 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1173 if (out == msg) {
1174 printf("FAIL: This should have changed.\n");
1175 abort();
1176 }
1177
1178 verify_msg(out, smsc_rewrite_num_patched,
1179 ARRAY_SIZE(smsc_rewrite_num_patched));
1180 msgb_free(out);
Holger Hans Peter Freyther09db1a42012-03-26 16:21:42 +02001181
1182 /*
1183 * Now with TP-SRR rewriting enabled
1184 */
1185 INIT_LLIST_HEAD(&clear_entries.entry);
1186 clear_entry.mcc = "^515039";
1187 clear_entry.option = "";
1188 clear_entry.text = "";
1189 llist_add_tail(&clear_entry.list, &clear_entries.entry);
1190 bsc_nat_num_rewr_entry_adapt(nat, &nat->sms_clear_tp_srr, &clear_entries);
1191
1192 msg = msgb_alloc(4096, "SMSC rewrite");
1193 copy_to_msg(msg, smsc_rewrite, ARRAY_SIZE(smsc_rewrite));
1194 parsed = bsc_nat_parse(msg);
1195 if (!parsed) {
1196 printf("FAIL: Could not parse SMS\n");
1197 abort();
1198 }
1199
1200 out = bsc_nat_rewrite_msg(nat, msg, parsed, imsi);
1201 if (out == msg) {
1202 printf("FAIL: This should have changed.\n");
1203 abort();
1204 }
1205
1206 verify_msg(out, smsc_rewrite_num_patched_tp_srr,
1207 ARRAY_SIZE(smsc_rewrite_num_patched_tp_srr));
1208 msgb_free(out);
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001209}
1210
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001211static void test_barr_list_parsing(void)
1212{
1213 int rc;
1214 int cm, lu;
1215 struct rb_node *node;
1216 struct rb_root root = RB_ROOT;
1217 struct osmo_config_list *lst = osmo_config_list_parse(NULL, "barr.cfg");
1218 if (lst == NULL)
1219 abort();
1220
1221 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1222 if (rc != 0)
1223 abort();
1224 talloc_free(lst);
1225
1226
1227 for (node = rb_first(&root); node; node = rb_next(node)) {
1228 struct bsc_nat_barr_entry *entry;
1229 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1230 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1231 entry->cm_reject_cause, entry->lu_reject_cause);
1232 }
1233
1234 /* do the look up now.. */
1235 rc = bsc_nat_barr_find(&root, "12123119", &cm, &lu);
1236 if (!rc) {
1237 printf("Failed to find the IMSI.\n");
1238 abort();
1239 }
1240
1241 if (cm != 3 || lu != 4) {
1242 printf("Found CM(%d) and LU(%d)\n", cm, lu);
1243 abort();
1244 }
1245
1246 /* empty and check that it is empty */
1247 bsc_nat_barr_adapt(NULL, &root, NULL);
1248 if (!RB_EMPTY_ROOT(&root)) {
1249 printf("Failed to empty the list.\n");
1250 abort();
1251 }
1252
1253 /* check that dup results in an error */
1254 lst = osmo_config_list_parse(NULL, "barr_dup.cfg");
1255 if (lst == NULL) {
1256 printf("Failed to parse list with dups\n");
1257 abort();
1258 }
1259
1260 rc = bsc_nat_barr_adapt(NULL, &root, lst);
1261 if (rc != -1) {
1262 printf("It should have failed due dup\n");
1263 abort();
1264 }
1265 talloc_free(lst);
1266
1267 /* dump for reference */
1268 for (node = rb_first(&root); node; node = rb_next(node)) {
1269 struct bsc_nat_barr_entry *entry;
1270 entry = rb_entry(node, struct bsc_nat_barr_entry, node);
1271 printf("IMSI: %s CM: %d LU: %d\n", entry->imsi,
1272 entry->cm_reject_cause, entry->lu_reject_cause);
1273
1274 }
1275}
1276
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001277static void test_nat_extract_lac()
1278{
1279 int res;
1280 struct bsc_connection *bsc;
1281 struct bsc_nat *nat;
1282 struct nat_sccp_connection con;
1283 struct bsc_nat_parsed *parsed;
1284 struct msgb *msg = msgb_alloc(4096, "test-message");
1285
1286 printf("Testing LAC extraction from SCCP CR\n");
1287
1288 /* initialize the testcase */
1289 nat = bsc_nat_alloc();
1290 bsc = bsc_connection_alloc(nat);
1291 bsc->cfg = bsc_config_alloc(nat, "foo");
1292
1293 memset(&con, 0, sizeof(con));
1294 con.bsc = bsc;
1295
1296 /* create the SCCP CR */
1297 msg->l2h = msgb_put(msg, ARRAY_SIZE(bssmap_cr));
1298 memcpy(msg->l2h, bssmap_cr, ARRAY_SIZE(bssmap_cr));
1299
1300 /* parse it and pass it on */
1301 parsed = bsc_nat_parse(msg);
1302 res = bsc_nat_extract_lac(bsc, &con, parsed, msg);
1303 OSMO_ASSERT(res == 0);
1304
1305 /* verify the LAC */
1306 OSMO_ASSERT(con.lac == 8210);
1307 OSMO_ASSERT(con.ci == 50000);
1308}
1309
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001310int main(int argc, char **argv)
1311{
Holger Hans Peter Freyther30e1ae92010-07-30 02:53:14 +08001312 sccp_set_log_area(DSCCP);
Holger Hans Peter Freyther67cd75f2011-05-12 16:02:07 +02001313 osmo_init_logging(&log_info);
Holger Hans Peter Freyther38f7c752010-06-15 18:48:36 +08001314
1315 test_filter();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001316 test_contrack();
Holger Hans Peter Freyther04fd9922010-03-30 06:51:53 +02001317 test_paging();
Holger Hans Peter Freytherfc9bd232010-04-01 03:55:27 +02001318 test_mgcp_ass_tracking();
1319 test_mgcp_find();
Holger Hans Peter Freyther76c83542010-04-01 06:48:52 +02001320 test_mgcp_rewrite();
Holger Hans Peter Freyther3c3bce12010-04-01 10:16:28 +02001321 test_mgcp_parse();
Holger Hans Peter Freyther0c08db12010-05-14 08:12:57 +08001322 test_cr_filter();
Holger Hans Peter Freyther32685402010-09-15 05:20:40 +08001323 test_dt_filter();
Holger Hans Peter Freyther73bbf892010-10-21 14:46:57 +02001324 test_setup_rewrite();
Holger Hans Peter Freyther8e60f622012-01-18 20:00:28 +01001325 test_sms_smsc_rewrite();
1326 test_sms_number_rewrite();
Holger Hans Peter Freythera9e93312011-02-26 11:38:00 +01001327 test_mgcp_allocations();
Holger Hans Peter Freyther1f8276e2013-01-01 11:25:09 +01001328 test_barr_list_parsing();
Holger Hans Peter Freytherb2b291d2013-04-16 13:23:43 +02001329 test_nat_extract_lac();
Holger Hans Peter Freytherf5ede522012-01-06 13:56:12 +01001330
1331 printf("Testing execution completed.\n");
Holger Hans Peter Freyther0b8f69d2010-06-15 18:45:38 +08001332 return 0;
1333}
Holger Hans Peter Freytherc3271872012-11-05 14:54:56 +01001334
1335/* stub */
1336void bsc_nat_send_mgcp_to_msc(struct bsc_nat *nat, struct msgb *msg)
1337{
1338 abort();
1339}