mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-03 21:43:32 +00:00 
			
		
		
		
	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:
		@@ -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.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user