diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c index 588a9e247..e4db47f0b 100644 --- a/openbsc/src/nat/bsc_nat.c +++ b/openbsc/src/nat/bsc_nat.c @@ -270,7 +270,7 @@ static void initialize_msc_if_needed() static int forward_sccp_to_bts(struct msgb *msg) { - struct bsc_connection *bsc; + struct bsc_connection *bsc = NULL; struct bsc_nat_parsed *parsed; int rc; @@ -316,6 +316,46 @@ static int forward_sccp_to_bts(struct msgb *msg) return write(bsc->bsc_fd.fd, msg->data, msg->len); send_to_all: + /* + * Filter Paging from the network. We do not want to send a PAGING + * Command to every BSC in our network. We will analys the PAGING + * message and then send it to the authenticated messages... + */ + if (parsed->ipa_proto == IPAC_PROTO_SCCP && parsed->gsm_type == BSS_MAP_MSG_PAGING) { + int data_length; + const u_int8_t *data; + struct tlv_parsed tp; + int i = 0; + + 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"); + goto exit; + } + + data_length = TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST); + data = TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER_LIST); + if (data[0] != CELL_IDENT_LAC) { + LOGP(DNAT, LOGL_ERROR, "Unhandled cell ident discrminator: %c\n", data[0]); + goto exit; + } + + /* go through each LAC and forward the message */ + for (i = 1; i < data_length - 1; i += 2) { + unsigned int _lac = ntohs(*(unsigned int *) &data[i]); + llist_for_each_entry(bsc, &nat->bsc_connections, list_entry) { + if (!bsc->authenticated || _lac != bsc->lac) + continue; + + rc = write(bsc->bsc_fd.fd, msg->data, msg->len); + if (rc < msg->len) + LOGP(DNAT, LOGL_ERROR, + "Failed to write message to BTS: %d\n", rc); + } + } + + goto exit; + } /* currently send this to every BSC connected */ llist_for_each_entry(bsc, &nat->bsc_connections, list_entry) { if (!bsc->authenticated)