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.
This commit is contained in:
parent
c279e39c12
commit
b2b291d3ef
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* BSC Multiplexer/NAT */
|
||||
|
||||
/*
|
||||
* (C) 2010-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010-2012 by On-Waves
|
||||
* (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010-2013 by On-Waves
|
||||
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* 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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <openbsc/bsc_nat_sccp.h>
|
||||
|
||||
#include <osmocom/core/application.h>
|
||||
#include <osmocom/core/backtrace.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
|
||||
#include <osmocom/sccp/sccp.h>
|
||||
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue