diff options
-rw-r--r-- | openbsc/include/openbsc/bsc_nat.h | 1 | ||||
-rw-r--r-- | openbsc/src/nat/bsc_nat.c | 33 | ||||
-rw-r--r-- | openbsc/src/nat/bsc_nat_utils.c | 40 | ||||
-rw-r--r-- | openbsc/tests/bsc-nat/Makefile.am | 3 |
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) |