aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-03-30 05:57:42 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-03-30 05:57:42 +0200
commitd44d4c8c8b9b751f60b10dcac37e05a31ccddc88 (patch)
tree1aa4d2a7a7acf3208a79112073ed5ad584222dc4
parentaf0e1d7a859a94857cf8042a8e392d6e13b27c24 (diff)
nat: Move paging by lac handling code into the utils file
Moving it here means we can more easily test this code, there is one behaviour change with the code that we only support paging messages with one LAC and will silently ignore the others.
-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)