From b2b291d3efea54a60c2e5c50f8ac34a2f12125cd Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 16 Apr 2013 13:23:43 +0200 Subject: nat: Extract the LAC/CI from the Complete Layer3 Information Find the Cell Identifier from the Complete Layer3 Information and store it for future reference. We could begin to verify that the LAC/CI used really belongs to the BSC. --- openbsc/include/openbsc/bsc_nat.h | 3 ++ openbsc/include/openbsc/bsc_nat_sccp.h | 3 ++ openbsc/src/osmo-bsc_nat/bsc_nat.c | 5 +-- openbsc/src/osmo-bsc_nat/bsc_nat_utils.c | 62 ++++++++++++++++++++++++++++++++ openbsc/tests/bsc-nat/bsc_nat_test.c | 35 ++++++++++++++++++ openbsc/tests/bsc-nat/bsc_nat_test.ok | 1 + 6 files changed, 107 insertions(+), 2 deletions(-) diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h index c5234d45a..13939457b 100644 --- a/openbsc/include/openbsc/bsc_nat.h +++ b/openbsc/include/openbsc/bsc_nat.h @@ -502,4 +502,7 @@ struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat, int port); void bsc_nat_ctrl_del_pending(struct bsc_cmd_list *pending); int bsc_nat_handle_ctrlif_msg(struct bsc_connection *bsc, struct msgb *msg); +int bsc_nat_extract_lac(struct bsc_connection *bsc, struct nat_sccp_connection *con, + struct bsc_nat_parsed *parsed, struct msgb *msg); + #endif diff --git a/openbsc/include/openbsc/bsc_nat_sccp.h b/openbsc/include/openbsc/bsc_nat_sccp.h index a21684b7f..34aa6320a 100644 --- a/openbsc/include/openbsc/bsc_nat_sccp.h +++ b/openbsc/include/openbsc/bsc_nat_sccp.h @@ -80,6 +80,9 @@ struct nat_sccp_connection { int imsi_checked; char *imsi; + uint16_t lac; + uint16_t ci; + /* remember which Transactions we run over the bypass */ char ussd_ti[8]; diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c index 21f52871e..049680295 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c @@ -1,8 +1,8 @@ /* BSC Multiplexer/NAT */ /* - * (C) 2010-2012 by Holger Hans Peter Freyther - * (C) 2010-2012 by On-Waves + * (C) 2010-2013 by Holger Hans Peter Freyther + * (C) 2010-2013 by On-Waves * (C) 2009 by Harald Welte * All Rights Reserved * @@ -1056,6 +1056,7 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) con_msc = con->msc_con; con->con_type = con_type; con->imsi_checked = filter; + bsc_nat_extract_lac(bsc, con, parsed, msg); if (imsi) con->imsi = talloc_steal(con, imsi); imsi = NULL; diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c index b4c87d093..45c224ce8 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c @@ -502,3 +502,65 @@ int bsc_write_cb(struct osmo_fd *bfd, struct msgb *msg) return rc; } +static void extract_lac(const uint8_t *data, uint16_t *lac, uint16_t *ci) +{ + memcpy(lac, &data[0], sizeof(*lac)); + memcpy(ci, &data[2], sizeof(*ci)); + + *lac = ntohs(*lac); + *ci = ntohs(*ci); +} + +int bsc_nat_extract_lac(struct bsc_connection *bsc, + struct nat_sccp_connection *con, + struct bsc_nat_parsed *parsed, struct msgb *msg) +{ + int data_length; + const uint8_t *data; + struct tlv_parsed tp; + uint16_t lac, ci; + + if (parsed->gsm_type != BSS_MAP_MSG_COMPLETE_LAYER_3) { + LOGP(DNAT, LOGL_ERROR, "Can only extract LAC from Complete Layer3\n"); + return -1; + } + + if (!msg->l3h || msgb_l3len(msg) < 3) { + LOGP(DNAT, LOGL_ERROR, "Complete Layer3 mssage is too short.\n"); + 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)) { + LOGP(DNAT, LOGL_ERROR, "No CellIdentifier List inside paging msg.\n"); + return -2; + } + + data_length = TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER); + data = TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER); + + /* Attemt to get the LAC/CI from it */ + if (data[0] == CELL_IDENT_WHOLE_GLOBAL) { + if (data_length != 8) { + LOGP(DNAT, LOGL_ERROR, + "Ident too short: %d\n", data_length); + return -3; + } + extract_lac(&data[1 + 3], &lac, &ci); + } else if (data[0] == CELL_IDENT_LAC_AND_CI) { + if (data_length != 5) { + LOGP(DNAT, LOGL_ERROR, + "Ident too short: %d\n", data_length); + return -3; + } + extract_lac(&data[1], &lac, &ci); + } else { + LOGP(DNAT, LOGL_ERROR, + "Unhandled cell identifier: %d\n", data[0]); + return -1; + } + + con->lac = lac; + con->ci = ci; + return 0; +} diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.c b/openbsc/tests/bsc-nat/bsc_nat_test.c index 18668bb4b..cbc1f1821 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.c +++ b/openbsc/tests/bsc-nat/bsc_nat_test.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -1276,6 +1277,39 @@ static void test_barr_list_parsing(void) } } +static void test_nat_extract_lac() +{ + int res; + struct bsc_connection *bsc; + struct bsc_nat *nat; + struct nat_sccp_connection con; + struct bsc_nat_parsed *parsed; + struct msgb *msg = msgb_alloc(4096, "test-message"); + + printf("Testing LAC extraction from SCCP CR\n"); + + /* initialize the testcase */ + nat = bsc_nat_alloc(); + bsc = bsc_connection_alloc(nat); + bsc->cfg = bsc_config_alloc(nat, "foo"); + + memset(&con, 0, sizeof(con)); + con.bsc = bsc; + + /* create the SCCP CR */ + msg->l2h = msgb_put(msg, ARRAY_SIZE(bssmap_cr)); + memcpy(msg->l2h, bssmap_cr, ARRAY_SIZE(bssmap_cr)); + + /* parse it and pass it on */ + parsed = bsc_nat_parse(msg); + res = bsc_nat_extract_lac(bsc, &con, parsed, msg); + OSMO_ASSERT(res == 0); + + /* verify the LAC */ + OSMO_ASSERT(con.lac == 8210); + OSMO_ASSERT(con.ci == 50000); +} + int main(int argc, char **argv) { sccp_set_log_area(DSCCP); @@ -1295,6 +1329,7 @@ int main(int argc, char **argv) test_sms_number_rewrite(); test_mgcp_allocations(); test_barr_list_parsing(); + test_nat_extract_lac(); printf("Testing execution completed.\n"); return 0; diff --git a/openbsc/tests/bsc-nat/bsc_nat_test.ok b/openbsc/tests/bsc-nat/bsc_nat_test.ok index cbedc85af..ab04f4273 100644 --- a/openbsc/tests/bsc-nat/bsc_nat_test.ok +++ b/openbsc/tests/bsc-nat/bsc_nat_test.ok @@ -35,4 +35,5 @@ IMSI: 12123126 CM: 3 LU: 4 IMSI: 12123127 CM: 3 LU: 5 IMSI: 12123128 CM: 3 LU: 6 IMSI: 12123124 CM: 3 LU: 2 +Testing LAC extraction from SCCP CR Testing execution completed. -- cgit v1.2.3