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.
This commit is contained in:
Holger Hans Peter Freyther 2010-03-30 05:57:42 +02:00
parent af0e1d7a85
commit d44d4c8c8b
4 changed files with 48 additions and 29 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)