From 27640fc25516537fce5e85a1e4fc105b68adb7af Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 15 Sep 2010 00:14:48 +0800 Subject: nat: Improve the log message in case we have SCCP data without a connection Describe which kind of data we have and where it was coming from as this makes debugging a bit easier. --- openbsc/src/nat/bsc_nat.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'openbsc/src/nat/bsc_nat.c') diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index 6485102df..e82c1a613 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -767,7 +767,10 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) } if (!con_msc) { - LOGP(DNAT, LOGL_ERROR, "No connection found, dropping data.\n"); + LOGP(DNAT, LOGL_ERROR, "Not forwarding data bsc_nr: %d ipa: %d type: 0x%x\n", + bsc->cfg->nr, + parsed ? parsed->ipa_proto : -1, + parsed ? parsed->sccp_type : -1); goto exit2; } -- cgit v1.2.3 From 3837f99e89f9e02425726d4e32d4f413769b66ea Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 15 Sep 2010 00:38:54 +0800 Subject: nat: Keep the fiter status in the return message. --- openbsc/src/nat/bsc_nat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'openbsc/src/nat/bsc_nat.c') diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index e82c1a613..1f45e4587 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -708,10 +708,12 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) /* modify the SCCP entries */ if (parsed->ipa_proto == IPAC_PROTO_SCCP) { + int filter; struct sccp_connections *con; switch (parsed->sccp_type) { case SCCP_MSG_TYPE_CR: - if (bsc_nat_filter_sccp_cr(bsc, msg, parsed, &con_type) != 0) + filter = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &con_type); + if (filter != 0) goto exit3; if (!create_sccp_src_ref(bsc, parsed)) goto exit2; -- cgit v1.2.3 From 909e61fddcdd97ed1bb8c44951f12dc3590f6521 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 15 Sep 2010 00:41:19 +0800 Subject: nat: Remember if we have check the imsi. Return -1 if the IMSI should be filtered, 0 if the IMSI could not be checked and 1 if the IMSI was checked and allowed to pass. In the future this will be used to inspect every message coming by. --- openbsc/src/nat/bsc_nat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'openbsc/src/nat/bsc_nat.c') diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index 1f45e4587..31009bb30 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -713,7 +713,7 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) switch (parsed->sccp_type) { case SCCP_MSG_TYPE_CR: filter = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &con_type); - if (filter != 0) + if (filter < 0) goto exit3; if (!create_sccp_src_ref(bsc, parsed)) goto exit2; @@ -721,6 +721,7 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) con->msc_con = bsc->nat->msc_con; con_msc = con->msc_con; con->con_type = con_type; + con->imsi_checked = filter; con_bsc = con->bsc; break; case SCCP_MSG_TYPE_RLSD: -- cgit v1.2.3 From 74e0a1b91c87804d25eb16eed47f3f83f962de6c Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 15 Sep 2010 01:11:08 +0800 Subject: nat: Start inspecting every message coming from the BSC for the IMSI Return early in case the IMSI was already checked, if not we need to look at the connection and check if the message could contain a imsi we want/need to filter. --- openbsc/src/nat/bsc_nat.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'openbsc/src/nat/bsc_nat.c') diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index 31009bb30..c7d97aa45 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -731,9 +731,17 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) case SCCP_MSG_TYPE_IT: con = patch_sccp_src_ref_to_msc(msg, parsed, bsc); if (con) { - con_bsc = con->bsc; - con_msc = con->msc_con; - con_filter = con->con_local; + filter = bsc_nat_filter_dt(bsc, msg, con, parsed); + if (filter == 0) { + con_bsc = con->bsc; + con_msc = con->msc_con; + con_filter = con->con_local; + } else { + LOGP(DNAT, LOGL_ERROR, "Should drop the connection.\n"); + con_bsc = con->bsc; + con_msc = con->msc_con; + con_filter = con->con_local; + } } break; case SCCP_MSG_TYPE_RLC: -- cgit v1.2.3 From ac2763b47e49e99ea6b0d2bcf2d55fafc0721b50 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 15 Sep 2010 07:43:59 +0800 Subject: nat: Attempt to disconnect a connection when IMSI filtering happens Attempt to disconnect the connection and make both sides happy about this. Right now it only handles the LU and should be extended to the CM Service Request. --- openbsc/src/nat/bsc_nat.c | 64 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-) (limited to 'openbsc/src/nat/bsc_nat.c') diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index c7d97aa45..e71ab0fcf 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -303,6 +303,63 @@ static void bsc_send_data(struct bsc_connection *bsc, const uint8_t *data, unsig bsc_write(bsc, msg, proto); } +/* + * Release an established connection. We will have to release it to the BSC + * and to the network and we do it the following way. + * 1.) Give up on the MSC side + * 1.1) Send a RLSD message, it is a bit non standard but should work, we + * ignore the RLC... we might complain about it. Other options would + * be to send a Release Request, handle the Release Complete.. + * 1.2) Mark the data structure to be con_local and wait for 2nd + * + * 2.) Give up on the BSC side + * 2.1) Depending on the con type reject the service, or just close it + */ +static void bsc_send_con_release(struct bsc_connection *bsc, struct sccp_connections *con) +{ + struct msgb *rlsd; + /* 1. release the network */ + rlsd = sccp_create_rlsd(&con->patched_ref, &con->remote_ref, + SCCP_RELEASE_CAUSE_END_USER_ORIGINATED); + if (!rlsd) + LOGP(DNAT, LOGL_ERROR, "Failed to create RLSD message.\n"); + else { + ipaccess_prepend_header(rlsd, IPAC_PROTO_SCCP); + queue_for_msc(con->msc_con, rlsd); + } + con->con_local = 1; + + /* 2. release the BSC side */ + if (con->con_type == NAT_CON_TYPE_LU) { + struct msgb *payload, *udt; + payload = gsm48_create_loc_upd_rej(GSM48_REJECT_PLMN_NOT_ALLOWED); + + if (payload) { + gsm0808_prepend_dtap_header(payload, 0); + udt = sccp_create_dt1(&con->real_ref, payload->data, payload->len); + if (udt) + bsc_write(bsc, udt, IPAC_PROTO_SCCP); + else + LOGP(DNAT, LOGL_ERROR, "Failed to create DT1\n"); + + msgb_free(payload); + } else { + LOGP(DNAT, LOGL_ERROR, "Failed to allocate LU Reject.\n"); + } + } + + rlsd = sccp_create_rlsd(&con->remote_ref, &con->real_ref, + SCCP_RELEASE_CAUSE_END_USER_ORIGINATED); + if (!rlsd) { + LOGP(DNAT, LOGL_ERROR, "Failed to allocate RLSD for the BSC.\n"); + sccp_connection_destroy(con); + return; + } + + con->con_type = NAT_CON_TYPE_LOCAL_REJECT; + bsc_write(bsc, rlsd, IPAC_PROTO_SCCP); +} + static void bsc_send_con_refuse(struct bsc_connection *bsc, struct bsc_nat_parsed *parsed, int con_type) { @@ -737,10 +794,9 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) con_msc = con->msc_con; con_filter = con->con_local; } else { - LOGP(DNAT, LOGL_ERROR, "Should drop the connection.\n"); - con_bsc = con->bsc; - con_msc = con->msc_con; - con_filter = con->con_local; + bsc_send_con_release(bsc, con); + con = NULL; + goto exit2; } } break; -- cgit v1.2.3 From 09ecda49d7e12412d50e85109e3f3dc81d76927f Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 15 Sep 2010 17:39:44 +0800 Subject: nat: Check if the connection was filtered before the msc connection This way we avoid seeing many warnings that we will not forward data to the MSC. For the con_local connections that is actually the idea, we will not forward them to the MSC. --- openbsc/src/nat/bsc_nat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'openbsc/src/nat/bsc_nat.c') diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index e71ab0fcf..738b7ef39 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -833,6 +833,10 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) goto exit2; } + /* do not forward messages to the MSC */ + if (con_filter) + goto exit2; + if (!con_msc) { LOGP(DNAT, LOGL_ERROR, "Not forwarding data bsc_nr: %d ipa: %d type: 0x%x\n", bsc->cfg->nr, @@ -841,10 +845,6 @@ static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg) goto exit2; } - /* do not forward messages to the MSC */ - if (con_filter) - goto exit2; - /* send the non-filtered but maybe modified msg */ queue_for_msc(con_msc, msg); talloc_free(parsed); -- cgit v1.2.3