aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-01-30 11:53:30 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-01-30 11:53:30 +0100
commite7b9771c4deb1cd9c68f5282bdcb17b6e7b89107 (patch)
tree0add6ed66bba7c6599180398ab4a1c9bbbb98faa
parentd709900efae3f212ad78735f92cd97882ce80188 (diff)
[nat] Specify the direction of the message
Do not run into the situation where we need to filter in one direction but it should not be filtered..
-rw-r--r--openbsc/include/openbsc/bsc_nat.h8
-rw-r--r--openbsc/src/nat/bsc_filter.c29
-rw-r--r--openbsc/src/nat/bsc_nat.c4
-rw-r--r--openbsc/tests/bsc-nat/bsc_nat_test.c27
4 files changed, 45 insertions, 23 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index b8a533fff..8293a4b5c 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -26,10 +26,8 @@
#include <sccp/sccp_types.h>
#include "msgb.h"
-#define FILTER_NONE 0
-#define FILTER_TO_BSC 1
-#define FILTER_TO_MSC 2
-#define FILTER_TO_BOTH 3
+#define DIR_BSC 1
+#define DIR_MSC 2
/*
* For the NAT we will need to analyze and later patch
@@ -72,6 +70,6 @@ struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
/**
* filter based on IP Access header in both directions
*/
-int bsc_nat_filter_ipa(struct msgb *msg, struct bsc_nat_parsed *parsed);
+int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed);
#endif
diff --git a/openbsc/src/nat/bsc_filter.c b/openbsc/src/nat/bsc_filter.c
index 0727b33e6..ad2f6138f 100644
--- a/openbsc/src/nat/bsc_filter.c
+++ b/openbsc/src/nat/bsc_filter.c
@@ -39,6 +39,11 @@
#define ALLOW_ANY -1
+#define FILTER_TO_BSC 1
+#define FILTER_TO_MSC 2
+#define FILTER_TO_BOTH 3
+
+
struct bsc_pkt_filter {
int ipa_proto;
int dest_ssn;
@@ -60,7 +65,7 @@ static struct bsc_pkt_filter black_list[] = {
static struct bsc_pkt_filter white_list[] = {
/* allow IPAC_PROTO_SCCP messages to both sides */
- { IPAC_PROTO_SCCP, ALLOW_ANY, ALLOW_ANY, ALLOW_ANY, FILTER_NONE },
+ { IPAC_PROTO_SCCP, ALLOW_ANY, ALLOW_ANY, ALLOW_ANY, FILTER_TO_BOTH },
};
struct bsc_nat_parsed* bsc_nat_parse(struct msgb *msg)
@@ -117,12 +122,17 @@ struct bsc_nat_parsed* bsc_nat_parse(struct msgb *msg)
return parsed;
}
-int bsc_nat_filter_ipa(struct msgb *msg, struct bsc_nat_parsed *parsed)
+int bsc_nat_filter_ipa(int dir, struct msgb *msg, struct bsc_nat_parsed *parsed)
{
int i;
/* go through the blacklist now */
for (i = 0; i < ARRAY_SIZE(black_list); ++i) {
+ /* ignore the rule? */
+ if (black_list[i].filter_dir != FILTER_TO_BOTH
+ && black_list[i].filter_dir != dir)
+ continue;
+
/* the proto is not blacklisted */
if (black_list[i].ipa_proto != ALLOW_ANY
&& black_list[i].ipa_proto != parsed->ipa_proto)
@@ -146,16 +156,21 @@ int bsc_nat_filter_ipa(struct msgb *msg, struct bsc_nat_parsed *parsed)
/* blacklisted */
LOGP(DNAT, LOGL_NOTICE, "Blacklisted with rule %d\n", i);
- return black_list[i].filter_dir;
+ return 1;
} else {
/* blacklisted, we have no content sniffing yet */
LOGP(DNAT, LOGL_NOTICE, "Blacklisted with rule %d\n", i);
- return black_list[i].filter_dir;
+ return 1;
}
}
/* go through the whitelust now */
for (i = 0; i < ARRAY_SIZE(white_list); ++i) {
+ /* ignore the rule? */
+ if (white_list[i].filter_dir != FILTER_TO_BOTH
+ && white_list[i].filter_dir != dir)
+ continue;
+
/* the proto is not whitelisted */
if (white_list[i].ipa_proto != ALLOW_ANY
&& white_list[i].ipa_proto != parsed->ipa_proto)
@@ -179,12 +194,12 @@ int bsc_nat_filter_ipa(struct msgb *msg, struct bsc_nat_parsed *parsed)
/* whitelisted */
LOGP(DNAT, LOGL_NOTICE, "Whitelisted with rule %d\n", i);
- return FILTER_NONE;
+ return 0;
} else {
/* whitelisted */
- return FILTER_NONE;
+ return 0;
}
}
- return FILTER_TO_BOTH;
+ return 1;
}
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index 609a17d96..7a44d1783 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -112,7 +112,7 @@ static void forward_sccp_to_bts(struct msgb *msg)
return;
}
- if (bsc_nat_filter_ipa(msg, parsed))
+ if (bsc_nat_filter_ipa(DIR_BSC, msg, parsed))
goto exit;
/* currently send this to every BSC connected */
@@ -189,7 +189,7 @@ static int forward_sccp_to_msc(struct msgb *msg)
return -1;
}
- if (bsc_nat_filter_ipa(msg, parsed))
+ if (bsc_nat_filter_ipa(DIR_MSC, msg, parsed))
goto exit;
/* send the non-filtered but maybe modified msg */
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c
index 282f2515b..8d1bd9b88 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.c
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.c
@@ -90,6 +90,7 @@ static const u_int8_t bssmap_release_complete[] = {
struct filter_result {
const u_int8_t *data;
const u_int16_t length;
+ const int dir;
const int result;
};
@@ -97,42 +98,50 @@ static const struct filter_result results[] = {
{
.data = ipa_id,
.length = ARRAY_SIZE(ipa_id),
- .result = FILTER_TO_MSC,
+ .dir = DIR_MSC,
+ .result = 1,
},
{
.data = gsm_reset,
.length = ARRAY_SIZE(gsm_reset),
- .result = FILTER_TO_MSC,
+ .dir = DIR_MSC,
+ .result = 1,
},
{
.data = gsm_reset_ack,
.length = ARRAY_SIZE(gsm_reset_ack),
- .result = FILTER_TO_BSC,
+ .dir = DIR_BSC,
+ .result = 1,
},
{
.data = gsm_paging,
.length = ARRAY_SIZE(gsm_paging),
- .result = FILTER_NONE,
+ .dir = DIR_BSC,
+ .result = 0,
},
{
.data = bssmap_cr,
.length = ARRAY_SIZE(bssmap_cr),
- .result = FILTER_NONE,
+ .dir = DIR_MSC,
+ .result = 0,
},
{
.data = bssmap_cc,
.length = ARRAY_SIZE(bssmap_cc),
- .result = FILTER_NONE,
+ .dir = DIR_BSC,
+ .result = 0,
},
{
.data = bssmap_released,
.length = ARRAY_SIZE(bssmap_released),
- .result = FILTER_NONE,
+ .dir = DIR_MSC,
+ .result = 0,
},
{
.data = bssmap_release_complete,
.length = ARRAY_SIZE(bssmap_release_complete),
- .result = FILTER_NONE,
+ .dir = DIR_BSC,
+ .result = 0,
},
};
@@ -157,7 +166,7 @@ int main(int argc, char **argv)
continue;
}
- result = bsc_nat_filter_ipa(msg, parsed);
+ result = bsc_nat_filter_ipa(results[i].dir, msg, parsed);
if (result != results[i].result) {
fprintf(stderr, "FAIL: Not the expected result got: %d wanted: %d\n",
result, results[i].result);