aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/bsc_nat.h1
-rw-r--r--openbsc/src/nat/bsc_nat.c33
-rw-r--r--openbsc/src/nat/bsc_nat_utils.c40
-rw-r--r--openbsc/tests/bsc-nat/Makefile.am3
4 files changed, 48 insertions, 29 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index 5f730fe6b..158a97496 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -150,6 +150,7 @@ struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
*/
int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed);
int bsc_nat_vty_init(struct bsc_nat *nat);
+struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *bsc, struct msgb *msg);
/**
* SCCP patching and handling
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index 061396de8..e6978bfe1 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -227,34 +227,11 @@ send_to_all:
* message and then send it to the authenticated messages...
*/
if (parsed->ipa_proto == IPAC_PROTO_SCCP && parsed->gsm_type == BSS_MAP_MSG_PAGING) {
- int data_length;
- const u_int8_t *data;
- struct tlv_parsed tp;
- int i = 0;
-
- tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 3, msgb_l3len(msg) - 3, 0, 0);
- if (!TLVP_PRESENT(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST)) {
- LOGP(DNAT, LOGL_ERROR, "No CellIdentifier List inside paging msg.\n");
- goto exit;
- }
-
- data_length = TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST);
- data = TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST);
- if (data[0] != CELL_IDENT_LAC) {
- LOGP(DNAT, LOGL_ERROR, "Unhandled cell ident discrminator: %c\n", data[0]);
- goto exit;
- }
-
- /* go through each LAC and forward the message */
- for (i = 1; i < data_length - 1; i += 2) {
- unsigned int _lac = ntohs(*(unsigned int *) &data[i]);
- llist_for_each_entry(bsc, &nat->bsc_connections, list_entry) {
- if (!bsc->authenticated || _lac != bsc->lac)
- continue;
-
- bsc_write(bsc, msg->data, msg->len);
- }
- }
+ bsc = bsc_nat_find_bsc(nat, msg);
+ if (bsc)
+ bsc_write(bsc, msg->data, msg->len);
+ else
+ LOGP(DNAT, LOGL_ERROR, "Could not determine BSC for paging.\n");
goto exit;
}
diff --git a/openbsc/src/nat/bsc_nat_utils.c b/openbsc/src/nat/bsc_nat_utils.c
index a3242317b..2428cbc2e 100644
--- a/openbsc/src/nat/bsc_nat_utils.c
+++ b/openbsc/src/nat/bsc_nat_utils.c
@@ -24,9 +24,15 @@
#include <openbsc/bsc_nat.h>
#include <openbsc/gsm_data.h>
+#include <openbsc/bssap.h>
+#include <openbsc/debug.h>
+#include <osmocore/linuxlist.h>
#include <osmocore/talloc.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
struct bsc_nat *bsc_nat_alloc(void)
{
struct bsc_nat *nat = talloc_zero(tall_bsc_ctx, struct bsc_nat);
@@ -66,3 +72,37 @@ struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token, unsi
return conf;
}
+struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg)
+{
+ struct bsc_connection *bsc;
+ int data_length;
+ const u_int8_t *data;
+ struct tlv_parsed tp;
+ int i = 0;
+
+ tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 3, msgb_l3len(msg) - 3, 0, 0);
+ if (!TLVP_PRESENT(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST)) {
+ LOGP(DNAT, LOGL_ERROR, "No CellIdentifier List inside paging msg.\n");
+ return NULL;
+ }
+
+ data_length = TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST);
+ data = TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST);
+ if (data[0] != CELL_IDENT_LAC) {
+ LOGP(DNAT, LOGL_ERROR, "Unhandled cell ident discrminator: %c\n", data[0]);
+ return NULL;
+ }
+
+ /* Currently we only handle one BSC */
+ for (i = 1; i < data_length - 1; i += 2) {
+ unsigned int _lac = ntohs(*(unsigned int *) &data[i]);
+ llist_for_each_entry(bsc, &nat->bsc_connections, list_entry) {
+ if (!bsc->authenticated || _lac != bsc->lac)
+ continue;
+
+ return bsc;
+ }
+ }
+
+ return NULL;
+}
diff --git a/openbsc/tests/bsc-nat/Makefile.am b/openbsc/tests/bsc-nat/Makefile.am
index bb2bd06fd..7011fbd45 100644
--- a/openbsc/tests/bsc-nat/Makefile.am
+++ b/openbsc/tests/bsc-nat/Makefile.am
@@ -8,6 +8,7 @@ noinst_PROGRAMS = bsc_nat_test
bsc_nat_test_SOURCES = bsc_nat_test.c \
$(top_srcdir)/src/nat/bsc_filter.c \
$(top_srcdir)/src/nat/bsc_sccp.c \
- $(top_srcdir)/src/nat/bsc_nat_utils.c
+ $(top_srcdir)/src/nat/bsc_nat_utils.c \
+ $(top_srcdir)/src/bssap.c
bsc_nat_test_LDADD = $(top_builddir)/src/libbsc.a $(top_builddir)/src/libsccp.a $(LIBOSMOCORE_LIBS)