aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/bsc_nat.h2
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat.c55
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_utils.c36
-rw-r--r--openbsc/tests/bsc-nat/bsc_nat_test.c23
4 files changed, 59 insertions, 57 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index 8fbed5be7..e6f555cbf 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -306,7 +306,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 *nat, struct msgb *msg, int *_lac);
+int bsc_nat_find_paging(struct msgb *msg, const uint8_t **,int *len);
/**
* Content filtering.
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c
index 2146da1c4..ba273417a 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c
@@ -549,6 +549,50 @@ send_refuse:
bsc_write(bsc, refuse, IPAC_PROTO_SCCP);
}
+static void bsc_nat_send_paging(struct bsc_connection *bsc, struct msgb *msg)
+{
+ if (bsc->cfg->forbid_paging) {
+ LOGP(DNAT, LOGL_DEBUG, "Paging forbidden for BTS: %d\n", bsc->cfg->nr);
+ return;
+ }
+
+ bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), IPAC_PROTO_SCCP);
+}
+
+static void bsc_nat_handle_paging(struct bsc_nat *nat, struct msgb *msg)
+{
+ struct bsc_connection *bsc;
+ const uint8_t *paging_start;
+ int paging_length, i;
+
+ if (bsc_nat_find_paging(msg, &paging_start, &paging_length) != 0) {
+ LOGP(DNAT, LOGL_ERROR, "Could not parse paging message.\n");
+ return;
+ }
+
+ /* This is quite expensive now */
+ for (i = 0; i < paging_length; i += 2) {
+ unsigned int _lac = ntohs(*(unsigned int *) &paging_start[i]);
+ unsigned int paged = 0;
+ llist_for_each_entry(bsc, &nat->bsc_connections, list_entry) {
+ if (!bsc->cfg)
+ continue;
+ if (!bsc->authenticated)
+ continue;
+ if (!bsc_config_handles_lac(bsc->cfg, _lac))
+ continue;
+ bsc_nat_send_paging(bsc, msg);
+ paged += 1;
+ }
+
+ /* highlight a possible config issue */
+ if (paged == 0)
+ LOGP(DNAT, LOGL_ERROR, "No BSC for LAC %d/0x%d\n", _lac, _lac);
+
+ }
+}
+
+
/*
* Update the auth status. This can be either a CIPHER MODE COMAMND or
* a CM Serivce Accept. Maybe also LU Accept or such in the future.
@@ -677,16 +721,7 @@ 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 lac;
- bsc = bsc_nat_find_bsc(nat, msg, &lac);
- if (bsc && bsc->cfg->forbid_paging)
- LOGP(DNAT, LOGL_DEBUG, "Paging forbidden for BTS: %d\n", bsc->cfg->nr);
- else if (bsc)
- bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), parsed->ipa_proto);
- else if (lac != -1)
- LOGP(DNAT, LOGL_ERROR, "Could not determine BSC for paging on lac: %d/0x%x\n",
- lac, lac);
-
+ bsc_nat_handle_paging(nat, msg);
goto exit;
}
/* currently send this to every BSC connected */
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
index 4d1afe2df..0a565a9b7 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
@@ -208,25 +208,23 @@ void sccp_connection_destroy(struct sccp_connections *conn)
talloc_free(conn);
}
-struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg, int *lac_out)
+
+int bsc_nat_find_paging(struct msgb *msg,
+ const uint8_t **out_data, int *out_leng)
{
- struct bsc_connection *bsc;
int data_length;
const uint8_t *data;
struct tlv_parsed tp;
- int i = 0;
-
- *lac_out = -1;
if (!msg->l3h || msgb_l3len(msg) < 3) {
LOGP(DNAT, LOGL_ERROR, "Paging message is too short.\n");
- return NULL;
+ return -1;
}
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;
+ return -2;
}
data_length = TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST);
@@ -234,29 +232,15 @@ struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg, i
/* No need to try a different BSS */
if (data[0] == CELL_IDENT_BSS) {
- return NULL;
+ return -3;
} else if (data[0] != CELL_IDENT_LAC) {
LOGP(DNAT, LOGL_ERROR, "Unhandled cell ident discrminator: %d\n", data[0]);
- return NULL;
+ return -4;
}
- /* Currently we only handle one BSC */
- for (i = 1; i < data_length - 1; i += 2) {
- unsigned int _lac = ntohs(*(unsigned int *) &data[i]);
- *lac_out = _lac;
- llist_for_each_entry(bsc, &nat->bsc_connections, list_entry) {
- if (!bsc->cfg)
- continue;
- if (!bsc->authenticated)
- continue;
- if (!bsc_config_handles_lac(bsc->cfg, _lac))
- continue;
-
- return bsc;
- }
- }
-
- return NULL;
+ *out_data = &data[1];
+ *out_leng = data_length - 1;
+ return 0;
}
int bsc_write_mgcp(struct bsc_connection *bsc, const uint8_t *data, unsigned int length)
diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c
index 50da1e904..8c0abc262 100644
--- a/openbsc/tests/bsc-nat/bsc_nat_test.c
+++ b/openbsc/tests/bsc-nat/bsc_nat_test.c
@@ -384,12 +384,9 @@ static void test_contrack()
static void test_paging(void)
{
- int lac;
struct bsc_nat *nat;
struct bsc_connection *con;
- struct bsc_nat_parsed *parsed;
struct bsc_config *cfg;
- struct msgb *msg;
fprintf(stderr, "Testing paging by lac.\n");
@@ -400,34 +397,20 @@ static void test_paging(void)
bsc_config_add_lac(cfg, 23);
con->authenticated = 1;
llist_add(&con->list_entry, &nat->bsc_connections);
- msg = msgb_alloc(4096, "test");
-
- /* Test completely bad input */
- copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
- if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
- fprintf(stderr, "Should have not found anything.\n");
- abort();
- }
/* Test it by not finding it */
- copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
- parsed = bsc_nat_parse(msg);
- if (bsc_nat_find_bsc(nat, msg, &lac) != 0) {
- fprintf(stderr, "Should have not found aynthing.\n");
+ if (bsc_config_handles_lac(cfg, 8213) != 0) {
+ fprintf(stderr, "Should not be handled.\n");
abort();
}
- talloc_free(parsed);
/* Test by finding it */
bsc_config_del_lac(cfg, 23);
bsc_config_add_lac(cfg, 8213);
- copy_to_msg(msg, paging_by_lac_cmd, sizeof(paging_by_lac_cmd));
- parsed = bsc_nat_parse(msg);
- if (bsc_nat_find_bsc(nat, msg, &lac) != con) {
+ if (bsc_config_handles_lac(cfg, 8213) == 0) {
fprintf(stderr, "Should have found it.\n");
abort();
}
- talloc_free(parsed);
}
static void test_mgcp_allocations(void)