/* BSC Multiplexer/NAT */

/*
 * (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010-2011 by On-Waves
 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#define _GNU_SOURCE
#include <getopt.h>

#include <openbsc/debug.h>
#include <openbsc/bsc_msc.h>
#include <openbsc/bsc_nat.h>
#include <openbsc/bsc_nat_sccp.h>
#include <openbsc/ipaccess.h>
#include <openbsc/abis_nm.h>
#include <openbsc/socket.h>
#include <openbsc/vty.h>

#include <osmocom/core/application.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/process.h>

#include <osmocom/gsm/gsm0808.h>
#include <osmocom/gsm/protocol/gsm_08_08.h>

#include <osmocom/vty/telnet_interface.h>
#include <osmocom/vty/vty.h>
#include <osmocom/vty/logging.h>

#include <osmocom/sccp/sccp.h>

#include "../../bscconfig.h"

#define SCCP_CLOSE_TIME 20
#define SCCP_CLOSE_TIME_TIMEOUT 19

static const char *config_file = "bsc-nat.cfg";
static struct in_addr local_addr;
static struct osmo_fd bsc_listen;
static const char *msc_ip = NULL;
static struct osmo_timer_list sccp_close;
static int daemonize = 0;

const char *openbsc_copyright =
	"Copyright (C) 2010 Holger Hans Peter Freyther and On-Waves\r\n"
	"License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n"
	"This is free software: you are free to change and redistribute it.\r\n"
	"There is NO WARRANTY, to the extent permitted by law.\r\n";

static struct bsc_nat *nat;
static void bsc_send_data(struct bsc_connection *bsc, const uint8_t *data, unsigned int length, int);
static void msc_send_reset(struct bsc_msc_connection *con);
static void bsc_stat_reject(int filter, struct bsc_connection *bsc, int normal);

struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num)
{
	struct bsc_config *conf;

	llist_for_each_entry(conf, &nat->bsc_configs, entry)
		if (conf->nr == num)
			return conf;

	return NULL;
}

static void queue_for_msc(struct bsc_msc_connection *con, struct msgb *msg)
{
	if (!con) {
		LOGP(DINP, LOGL_ERROR, "No MSC Connection assigned. Check your code.\n");
		msgb_free(msg);
		return;
	}


	if (osmo_wqueue_enqueue(&con->write_queue, msg) != 0) {
		LOGP(DINP, LOGL_ERROR, "Failed to enqueue the write.\n");
		msgb_free(msg);
	}
}

static void send_reset_ack(struct bsc_connection *bsc)
{
	static const uint8_t gsm_reset_ack[] = {
		0x09, 0x00, 0x03, 0x07, 0x0b, 0x04, 0x43, 0x01,
		0x00, 0xfe, 0x04, 0x43, 0x5c, 0x00, 0xfe, 0x03,
		0x00, 0x01, 0x31,
	};

	bsc_send_data(bsc, gsm_reset_ack, sizeof(gsm_reset_ack), IPAC_PROTO_SCCP);
}

static void send_ping(struct bsc_connection *bsc)
{
	static const uint8_t id_ping[] = {
		IPAC_MSGT_PING,
	};

	bsc_send_data(bsc, id_ping, sizeof(id_ping), IPAC_PROTO_IPACCESS);
}

static void send_pong(struct bsc_connection *bsc)
{
	static const uint8_t id_pong[] = {
		IPAC_MSGT_PONG,
	};

	bsc_send_data(bsc, id_pong, sizeof(id_pong), IPAC_PROTO_IPACCESS);
}

static void bsc_pong_timeout(void *_bsc)
{
	struct bsc_connection *bsc = _bsc;

	LOGP(DNAT, LOGL_ERROR, "BSC Nr: %d PONG timeout.\n", bsc->cfg->nr);
	bsc_close_connection(bsc);
}

static void bsc_ping_timeout(void *_bsc)
{
	struct bsc_connection *bsc = _bsc;

	if (bsc->nat->ping_timeout < 0)
		return;

	send_ping(bsc);

	/* send another ping in 20 seconds */
	osmo_timer_schedule(&bsc->ping_timeout, bsc->nat->ping_timeout, 0);

	/* also start a pong timer */
	osmo_timer_schedule(&bsc->pong_timeout, bsc->nat->pong_timeout, 0);
}

static void start_ping_pong(struct bsc_connection *bsc)
{
	bsc->pong_timeout.data = bsc;
	bsc->pong_timeout.cb = bsc_pong_timeout;
	bsc->ping_timeout.data = bsc;
	bsc->ping_timeout.cb = bsc_ping_timeout;

	bsc_ping_timeout(bsc);
}

static void send_id_ack(struct bsc_connection *bsc)
{
	static const uint8_t id_ack[] = {
		IPAC_MSGT_ID_ACK
	};

	bsc_send_data(bsc, id_ack, sizeof(id_ack), IPAC_PROTO_IPACCESS);
}

static void send_id_req(struct bsc_connection *bsc)
{
	static const uint8_t id_req[] = {
		IPAC_MSGT_ID_GET,
		0x01, IPAC_IDTAG_UNIT,
		0x01, IPAC_IDTAG_MACADDR,
		0x01, IPAC_IDTAG_LOCATION1,
		0x01, IPAC_IDTAG_LOCATION2,
		0x01, IPAC_IDTAG_EQUIPVERS,
		0x01, IPAC_IDTAG_SWVERSION,
		0x01, IPAC_IDTAG_UNITNAME,
		0x01, IPAC_IDTAG_SERNR,
	};

	bsc_send_data(bsc, id_req, sizeof(id_req), IPAC_PROTO_IPACCESS);
}

static struct msgb *nat_create_rlsd(struct sccp_connections *conn)
{
	struct sccp_connection_released *rel;
	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "rlsd");
	if (!msg) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate released.\n");
		return NULL;
	}

	msg->l2h = msgb_put(msg, sizeof(*rel));
	rel = (struct sccp_connection_released *) msg->l2h;
	rel->type = SCCP_MSG_TYPE_RLSD;
	rel->release_cause = SCCP_RELEASE_CAUSE_SCCP_FAILURE;
	rel->destination_local_reference = conn->remote_ref;
	rel->source_local_reference = conn->patched_ref;

	return msg;
}

static void nat_send_rlsd_ussd(struct bsc_nat *nat, struct sccp_connections *conn)
{
	struct msgb *msg;

	if (!nat->ussd_con)
		return;

	msg = nat_create_rlsd(conn);
	if (!msg)
		return;

	bsc_do_write(&nat->ussd_con->queue, msg, IPAC_PROTO_SCCP);
}

static void nat_send_rlsd_msc(struct sccp_connections *conn)
{
	struct msgb *msg;

	msg = nat_create_rlsd(conn);
	if (!msg)
		return;

	ipaccess_prepend_header(msg, IPAC_PROTO_SCCP);
	queue_for_msc(conn->msc_con, msg);
}

static void nat_send_rlsd_bsc(struct sccp_connections *conn)
{
	struct msgb *msg;
	struct sccp_connection_released *rel;

	msg = msgb_alloc_headroom(4096, 128, "rlsd");
	if (!msg) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate clear command.\n");
		return;
	}

	msg->l2h = msgb_put(msg, sizeof(*rel));
	rel = (struct sccp_connection_released *) msg->l2h;
	rel->type = SCCP_MSG_TYPE_RLSD;
	rel->release_cause = SCCP_RELEASE_CAUSE_SCCP_FAILURE;
	rel->destination_local_reference = conn->real_ref;
	rel->source_local_reference = conn->remote_ref;

	bsc_write(conn->bsc, msg, IPAC_PROTO_SCCP);
}

static struct msgb *nat_creat_clrc(struct sccp_connections *conn, uint8_t cause)
{
	struct msgb *msg;
	struct msgb *sccp;

	msg = gsm0808_create_clear_command(cause);
	if (!msg) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate clear command.\n");
		return NULL;
	}

	sccp = sccp_create_dt1(&conn->real_ref, msg->data, msg->len);
	if (!sccp) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate SCCP msg.\n");
		msgb_free(msg);
		return NULL;
	}

	msgb_free(msg);
	return sccp;
}

static int nat_send_clrc_bsc(struct sccp_connections *conn)
{
	struct msgb *sccp;

	sccp = nat_creat_clrc(conn, 0x20);
	if (!sccp)
		return -1;
	return bsc_write(conn->bsc, sccp, IPAC_PROTO_SCCP);
}

static void nat_send_rlc(struct bsc_msc_connection *msc_con,
			 struct sccp_source_reference *src,
			 struct sccp_source_reference *dst)
{
	struct sccp_connection_release_complete *rlc;
	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "rlc");
	if (!msg) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate clear command.\n");
		return;
	}

	msg->l2h = msgb_put(msg, sizeof(*rlc));
	rlc = (struct sccp_connection_release_complete *) msg->l2h;
	rlc->type = SCCP_MSG_TYPE_RLC;
	rlc->destination_local_reference = *dst;
	rlc->source_local_reference = *src;

	ipaccess_prepend_header(msg, IPAC_PROTO_SCCP);

	queue_for_msc(msc_con, msg);
}

static void send_mgcp_reset(struct bsc_connection *bsc)
{
	static const uint8_t mgcp_reset[] = {
	    "RSIP 1 13@mgw MGCP 1.0\r\n"
	};

	bsc_write_mgcp(bsc, mgcp_reset, sizeof mgcp_reset - 1);
}

/*
 * Below is the handling of messages coming
 * from the MSC and need to be forwarded to
 * a real BSC.
 */
static void initialize_msc_if_needed(struct bsc_msc_connection *msc_con)
{
	if (msc_con->first_contact)
		return;

	msc_con->first_contact = 1;
	msc_send_reset(msc_con);
}

static void send_id_get_response(struct bsc_msc_connection *msc_con)
{
	struct msgb *msg = bsc_msc_id_get_resp(nat->token);
	if (!msg)
		return;

	ipaccess_prepend_header(msg, IPAC_PROTO_IPACCESS);
	queue_for_msc(msc_con, msg);
}

/*
 * Currently we are lacking refcounting so we need to copy each message.
 */
static void bsc_send_data(struct bsc_connection *bsc, const uint8_t *data, unsigned int length, int proto)
{
	struct msgb *msg;

	if (length > 4096 - 128) {
		LOGP(DINP, LOGL_ERROR, "Can not send message of that size.\n");
		return;
	}

	msg = msgb_alloc_headroom(4096, 128, "to-bsc");
	if (!msg) {
		LOGP(DINP, LOGL_ERROR, "Failed to allocate memory for BSC msg.\n");
		return;
	}

	msg->l2h = msgb_put(msg, length);
	memcpy(msg->data, data, length);

	bsc_write(bsc, msg, proto);
}

/*
 * Update the release statistics
 */
static void bsc_stat_reject(int filter, struct bsc_connection *bsc, int normal)
{
	if (!bsc->cfg) {
		LOGP(DNAT, LOGL_ERROR, "BSC is not authenticated.");
		return;
	}

	if (filter >= 0) {
		LOGP(DNAT, LOGL_ERROR, "Connection was not rejected");
		return;
	}

	if (filter == -1)
		rate_ctr_inc(&bsc->cfg->stats.ctrg->ctr[BCFG_CTR_ILL_PACKET]);
	else if (normal)
		rate_ctr_inc(&bsc->cfg->stats.ctrg->ctr[BCFG_CTR_REJECTED_MSG]);
	else
		rate_ctr_inc(&bsc->cfg->stats.ctrg->ctr[BCFG_CTR_REJECTED_CR]);
}

/*
 * 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 = NAT_CON_END_LOCAL;
	con->msc_con = NULL;

	/* 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");
		}
	}

	nat_send_clrc_bsc(con);

	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)
{
	struct msgb *payload;
	struct msgb *refuse;

	if (con_type == NAT_CON_TYPE_LU)
		payload = gsm48_create_loc_upd_rej(GSM48_REJECT_PLMN_NOT_ALLOWED);
	else if (con_type == NAT_CON_TYPE_CM_SERV_REQ)
		payload = gsm48_create_mm_serv_rej(GSM48_REJECT_PLMN_NOT_ALLOWED);
	else {
		LOGP(DNAT, LOGL_ERROR, "Unknown connection type: %d\n", con_type);
		payload = NULL;
	}

	/*
	 * Some BSCs do not handle the payload inside a SCCP CREF msg
	 * so we will need to:
	 * 1.) Allocate a local connection and mark it as local..
	 * 2.) queue data for downstream.. and the RLC should delete everything
	 */
	if (payload) {
		struct msgb *cc, *udt, *clear, *rlsd;
		struct sccp_connections *con;
		con = create_sccp_src_ref(bsc, parsed);
		if (!con)
			goto send_refuse;

		/* declare it local and assign a unique remote_ref */
		con->con_type = NAT_CON_TYPE_LOCAL_REJECT;
		con->con_local = NAT_CON_END_LOCAL;
		con->has_remote_ref = 1;
		con->remote_ref = con->patched_ref;

		/* 1. create a confirmation */
		cc = sccp_create_cc(&con->remote_ref, &con->real_ref);
		if (!cc)
			goto send_refuse;

		/* 2. create the DT1 */
		gsm0808_prepend_dtap_header(payload, 0);
		udt = sccp_create_dt1(&con->real_ref, payload->data, payload->len);
		if (!udt) {
			msgb_free(cc);
			goto send_refuse;
		}

		/* 3. send a Clear Command */
		clear = nat_creat_clrc(con, 0x20);
		if (!clear) {
			msgb_free(cc);
			msgb_free(udt);
			goto send_refuse;
		}

		/* 4. send a RLSD */
		rlsd = sccp_create_rlsd(&con->remote_ref, &con->real_ref,
					SCCP_RELEASE_CAUSE_END_USER_ORIGINATED);
		if (!rlsd) {
			msgb_free(cc);
			msgb_free(udt);
			msgb_free(clear);
			goto send_refuse;
		}

		bsc_write(bsc, cc, IPAC_PROTO_SCCP);
		bsc_write(bsc, udt, IPAC_PROTO_SCCP);
		bsc_write(bsc, clear, IPAC_PROTO_SCCP);
		bsc_write(bsc, rlsd, IPAC_PROTO_SCCP);
		msgb_free(payload);
		return;
	}


send_refuse:
	if (payload)
		msgb_free(payload);

	refuse = sccp_create_refuse(parsed->src_local_ref,
				    SCCP_REFUSAL_SCCP_FAILURE, NULL, 0);
	if (!refuse) {
		LOGP(DNAT, LOGL_ERROR,
		     "Creating refuse msg failed for SCCP 0x%x on BSC Nr: %d.\n",
		      sccp_src_ref_to_int(parsed->src_local_ref), bsc->cfg->nr);
		return;
	}

	bsc_write(bsc, refuse, IPAC_PROTO_SCCP);
}

static void bsc_nat_send_paging(struct bsc_connection *bsc, struct msgb *msg)
{
	if (bsc->cfg->forbid_paging) {
		LOGP(DNAT, LOGL_DEBUG, "Paging forbidden for BTS: %d\n", bsc->cfg->nr);
		return;
	}

	bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), IPAC_PROTO_SCCP);
}

static void bsc_nat_handle_paging(struct bsc_nat *nat, struct msgb *msg)
{
	struct bsc_connection *bsc;
	const uint8_t *paging_start;
	int paging_length, i, ret;

	ret = bsc_nat_find_paging(msg, &paging_start, &paging_length);
	if (ret != 0) {
		LOGP(DNAT, LOGL_ERROR, "Could not parse paging message: %d\n", ret);
		return;
	}

	/* This is quite expensive now */
	for (i = 0; i < paging_length; i += 2) {
		unsigned int _lac = ntohs(*(unsigned int *) &paging_start[i]);
		unsigned int paged = 0;
		llist_for_each_entry(bsc, &nat->bsc_connections, list_entry) {
			if (!bsc->cfg)
				continue;
			if (!bsc->authenticated)
				continue;
			if (!bsc_config_handles_lac(bsc->cfg, _lac))
				continue;
			bsc_nat_send_paging(bsc, msg);
			paged += 1;
		}

		/* highlight a possible config issue */
		if (paged == 0)
			LOGP(DNAT, LOGL_ERROR, "No BSC for LAC %d/0x%d\n", _lac, _lac);

	}
}


/*
 * Update the auth status. This can be either a CIPHER MODE COMAMND or
 * a CM Serivce Accept. Maybe also LU Accept or such in the future.
 */
static void update_con_authorize(struct sccp_connections *con,
				 struct bsc_nat_parsed *parsed,
				 struct msgb *msg)
{
	if (!con)
		return;
	if (con->authorized)
		return;

	if (parsed->bssap == BSSAP_MSG_BSS_MANAGEMENT &&
	    parsed->gsm_type == BSS_MAP_MSG_CIPHER_MODE_CMD) {
		con->authorized = 1;
	} else if (parsed->bssap == BSSAP_MSG_DTAP) {
		uint8_t msg_type, proto;
		uint32_t len;
		struct gsm48_hdr *hdr48;
		hdr48 = bsc_unpack_dtap(parsed, msg, &len);
		if (!hdr48)
			return;

		proto = hdr48->proto_discr & 0x0f;
		msg_type = hdr48->msg_type & 0xbf;
		if (proto == GSM48_PDISC_MM &&
		    msg_type == GSM48_MT_MM_CM_SERV_ACC)
			con->authorized = 1;
	}
}

static int forward_sccp_to_bts(struct bsc_msc_connection *msc_con, struct msgb *msg)
{
	struct sccp_connections *con = NULL;
	struct bsc_connection *bsc;
	struct bsc_nat_parsed *parsed;
	int proto;

	/* filter, drop, patch the message? */
	parsed = bsc_nat_parse(msg);
	if (!parsed) {
		LOGP(DNAT, LOGL_ERROR, "Can not parse msg from BSC.\n");
		return -1;
	}

	if (bsc_nat_filter_ipa(DIR_BSC, msg, parsed))
		goto exit;

	proto = parsed->ipa_proto;

	/* Route and modify the SCCP packet */
	if (proto == IPAC_PROTO_SCCP) {
		switch (parsed->sccp_type) {
		case SCCP_MSG_TYPE_UDT:
			/* forward UDT messages to every BSC */
			goto send_to_all;
			break;
		case SCCP_MSG_TYPE_RLSD:
			if (con && con->con_local == NAT_CON_END_USSD) {
				LOGP(DNAT, LOGL_NOTICE, "RLSD for a USSD connection. Ignoring.\n");
				con = NULL;
			}
			/* fall through */
		case SCCP_MSG_TYPE_CREF:
		case SCCP_MSG_TYPE_DT1:
		case SCCP_MSG_TYPE_IT:
			con = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
			if (parsed->gsm_type == BSS_MAP_MSG_ASSIGMENT_RQST) {
				osmo_counter_inc(nat->stats.sccp.calls);

				if (con) {
					struct rate_ctr_group *ctrg;
					ctrg = con->bsc->cfg->stats.ctrg;
					rate_ctr_inc(&ctrg->ctr[BCFG_CTR_SCCP_CALLS]);
					if (bsc_mgcp_assign_patch(con, msg) != 0)
						LOGP(DNAT, LOGL_ERROR, "Failed to assign...\n");
				} else
					LOGP(DNAT, LOGL_ERROR, "Assignment command but no BSC.\n");
			} else if (con && con->con_local == NAT_CON_END_USSD &&
				   parsed->gsm_type == BSS_MAP_MSG_CLEAR_CMD) {
				LOGP(DNAT, LOGL_NOTICE, "Clear Command for USSD Connection. Ignoring.\n");
				con = NULL;
			}
			break;
		case SCCP_MSG_TYPE_CC:
			con = patch_sccp_src_ref_to_bsc(msg, parsed, nat);
			if (!con || update_sccp_src_ref(con, parsed) != 0)
				goto exit;
			break;
		case SCCP_MSG_TYPE_RLC:
			LOGP(DNAT, LOGL_ERROR, "Unexpected release complete from MSC.\n");
			goto exit;
			break;
		case SCCP_MSG_TYPE_CR:
			/* MSC never opens a SCCP connection, fall through */
		default:
			goto exit;
		}

		if (!con && parsed->sccp_type == SCCP_MSG_TYPE_RLSD) {
			LOGP(DNAT, LOGL_NOTICE, "Sending fake RLC on RLSD message to network.\n");
			/* Exchange src/dest for the reply */
			nat_send_rlc(msc_con, parsed->dest_local_ref, parsed->src_local_ref);
		} else if (!con)
			LOGP(DNAT, LOGL_ERROR, "Unknown connection for msg type: 0x%x from the MSC.\n", parsed->sccp_type);
	}

	talloc_free(parsed);
	if (!con)
		return -1;
	if (!con->bsc->authenticated) {
		LOGP(DNAT, LOGL_ERROR, "Selected BSC not authenticated.\n");
		return -1;
	}

	update_con_authorize(con, parsed, msg);

	bsc_send_data(con->bsc, msg->l2h, msgb_l2len(msg), proto);
	return 0;

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) {
		bsc_nat_handle_paging(nat, msg);
		goto exit;
	}
	/* currently send this to every BSC connected */
	llist_for_each_entry(bsc, &nat->bsc_connections, list_entry) {
		if (!bsc->authenticated)
			continue;

		bsc_send_data(bsc, msg->l2h, msgb_l2len(msg), parsed->ipa_proto);
	}

exit:
	talloc_free(parsed);
	return 0;
}

static void msc_connection_was_lost(struct bsc_msc_connection *con)
{
	struct bsc_connection *bsc, *tmp;

	LOGP(DMSC, LOGL_ERROR, "Closing all connections downstream.\n");
	llist_for_each_entry_safe(bsc, tmp, &nat->bsc_connections, list_entry)
		bsc_close_connection(bsc);

	bsc_mgcp_free_endpoints(nat);
	bsc_msc_schedule_connect(con);
}

static void msc_connection_connected(struct bsc_msc_connection *con)
{
	osmo_counter_inc(nat->stats.msc.reconn);
}

static void msc_send_reset(struct bsc_msc_connection *msc_con)
{
	static const uint8_t reset[] = {
		0x00, 0x12, 0xfd,
		0x09, 0x00, 0x03, 0x05, 0x07, 0x02, 0x42, 0xfe,
		0x02, 0x42, 0xfe, 0x06, 0x00, 0x04, 0x30, 0x04,
		0x01, 0x20
	};

	struct msgb *msg;

	msg = msgb_alloc_headroom(4096, 128, "08.08 reset");
	if (!msg) {
		LOGP(DMSC, LOGL_ERROR, "Failed to allocate reset msg.\n");
		return;
	}

	msg->l2h = msgb_put(msg, sizeof(reset));
	memcpy(msg->l2h, reset, msgb_l2len(msg));

	queue_for_msc(msc_con, msg);

	LOGP(DMSC, LOGL_NOTICE, "Scheduled GSM0808 reset msg for the MSC.\n");
}

static int ipaccess_msc_read_cb(struct osmo_fd *bfd)
{
	int error;
	struct bsc_msc_connection *msc_con;
	struct msgb *msg = ipaccess_read_msg(bfd, &error);
	struct ipaccess_head *hh;

	msc_con = (struct bsc_msc_connection *) bfd->data;

	if (!msg) {
		if (error == 0)
			LOGP(DNAT, LOGL_FATAL, "The connection the MSC was lost, exiting\n");
		else
			LOGP(DNAT, LOGL_ERROR, "Failed to parse ip access message: %d\n", error);

		bsc_msc_lost(msc_con);
		return -1;
	}

	LOGP(DNAT, LOGL_DEBUG, "MSG from MSC: %s proto: %d\n", osmo_hexdump(msg->data, msg->len), msg->l2h[0]);

	/* handle base message handling */
	hh = (struct ipaccess_head *) msg->data;
	ipaccess_rcvmsg_base(msg, bfd);

	/* initialize the networking. This includes sending a GSM08.08 message */
	if (hh->proto == IPAC_PROTO_IPACCESS) {
		if (msg->l2h[0] == IPAC_MSGT_ID_ACK)
			initialize_msc_if_needed(msc_con);
		else if (msg->l2h[0] == IPAC_MSGT_ID_GET)
			send_id_get_response(msc_con);
	} else if (hh->proto == IPAC_PROTO_SCCP)
		forward_sccp_to_bts(msc_con, msg);

	msgb_free(msg);
	return 0;
}

static int ipaccess_msc_write_cb(struct osmo_fd *bfd, struct msgb *msg)
{
	int rc;
	rc = write(bfd->fd, msg->data, msg->len);

	if (rc != msg->len) {
		LOGP(DNAT, LOGL_ERROR, "Failed to write MSG to MSC.\n");
		return -1;
	}

	return rc;
}

/*
 * Below is the handling of messages coming
 * from the BSC and need to be forwarded to
 * a real BSC.
 */

/*
 * Remove the connection from the connections list,
 * remove it from the patching of SCCP header lists
 * as well. Maybe in the future even close connection..
 */
void bsc_close_connection(struct bsc_connection *connection)
{
	struct sccp_connections *sccp_patch, *tmp;
	struct rate_ctr *ctr = NULL;

	/* stop the timeout timer */
	osmo_timer_del(&connection->id_timeout);
	osmo_timer_del(&connection->ping_timeout);
	osmo_timer_del(&connection->pong_timeout);

	if (connection->cfg)
		ctr = &connection->cfg->stats.ctrg->ctr[BCFG_CTR_DROPPED_SCCP];

	/* remove all SCCP connections */
	llist_for_each_entry_safe(sccp_patch, tmp, &nat->sccp_connections, list_entry) {
		if (sccp_patch->bsc != connection)
			continue;

		if (ctr)
			rate_ctr_inc(ctr);
		if (sccp_patch->has_remote_ref) {
			if (sccp_patch->con_local == NAT_CON_END_MSC)
				nat_send_rlsd_msc(sccp_patch);
			else if (sccp_patch->con_local == NAT_CON_END_USSD)
				nat_send_rlsd_ussd(nat, sccp_patch);
		}

		sccp_connection_destroy(sccp_patch);
	}

	/* close endpoints allocated by this BSC */
	bsc_mgcp_clear_endpoints_for(connection);

	osmo_fd_unregister(&connection->write_queue.bfd);
	close(connection->write_queue.bfd.fd);
	osmo_wqueue_clear(&connection->write_queue);
	llist_del(&connection->list_entry);

	talloc_free(connection);
}

static void bsc_maybe_close(struct bsc_connection *bsc)
{
	struct sccp_connections *sccp;
	if (!bsc->nat->blocked)
		return;

	/* are there any connections left */
	llist_for_each_entry(sccp, &bsc->nat->sccp_connections, list_entry)
		if (sccp->bsc == bsc)
			return;

	/* nothing left, close the BSC */
	LOGP(DNAT, LOGL_NOTICE, "Cleaning up BSC %d in blocking mode.\n",
	     bsc->cfg ? bsc->cfg->nr : -1);
	bsc_close_connection(bsc);
}

static void ipaccess_close_bsc(void *data)
{
	struct sockaddr_in sock;
	socklen_t len = sizeof(sock);
	struct bsc_connection *conn = data;


	getpeername(conn->write_queue.bfd.fd, (struct sockaddr *) &sock, &len);
	LOGP(DNAT, LOGL_ERROR, "BSC on %s didn't respond to identity request. Closing.\n",
	     inet_ntoa(sock.sin_addr));
	bsc_close_connection(conn);
}

static void ipaccess_auth_bsc(struct tlv_parsed *tvp, struct bsc_connection *bsc)
{
	struct bsc_config *conf;
	const char *token = (const char *) TLVP_VAL(tvp, IPAC_IDTAG_UNITNAME);
	const int len = TLVP_LEN(tvp, IPAC_IDTAG_UNITNAME);

	if (bsc->cfg) {
		LOGP(DNAT, LOGL_ERROR, "Reauth on fd %d bsc nr %d\n",
		     bsc->write_queue.bfd.fd, bsc->cfg->nr);
		return;
	}

	llist_for_each_entry(conf, &bsc->nat->bsc_configs, entry) {
		if (strncmp(conf->token, token, len) == 0) {
			rate_ctr_inc(&conf->stats.ctrg->ctr[BCFG_CTR_NET_RECONN]);
			bsc->authenticated = 1;
			bsc->cfg = conf;
			osmo_timer_del(&bsc->id_timeout);
			LOGP(DNAT, LOGL_NOTICE, "Authenticated bsc nr: %d on fd %d\n",
			     conf->nr, bsc->write_queue.bfd.fd);
			start_ping_pong(bsc);
			return;
		}
	}

	LOGP(DNAT, LOGL_ERROR, "No bsc found for token %s on fd: %d.\n", token,
	     bsc->write_queue.bfd.fd);
}

static void handle_con_stats(struct sccp_connections *con)
{
	struct rate_ctr_group *ctrg;
	int id = bsc_conn_type_to_ctr(con);

	if (id == -1)
		return;

	if (!con->bsc || !con->bsc->cfg)
		return;

	ctrg = con->bsc->cfg->stats.ctrg;
	rate_ctr_inc(&ctrg->ctr[id]);
}

static int forward_sccp_to_msc(struct bsc_connection *bsc, struct msgb *msg)
{
	int con_filter = 0;
	char *imsi = NULL;
	struct bsc_msc_connection *con_msc = NULL;
	struct bsc_connection *con_bsc = NULL;
	int con_type;
	struct bsc_nat_parsed *parsed;

	/* Parse and filter messages */
	parsed = bsc_nat_parse(msg);
	if (!parsed) {
		LOGP(DNAT, LOGL_ERROR, "Can not parse msg from BSC.\n");
		msgb_free(msg);
		return -1;
	}

	if (bsc_nat_filter_ipa(DIR_MSC, msg, parsed))
		goto exit;

	/*
	 * check authentication after filtering to not reject auth
	 * responses coming from the BSC. We have to make sure that
	 * nothing from the exit path will forward things to the MSC
	 */
	if (!bsc->authenticated) {
		LOGP(DNAT, LOGL_ERROR, "BSC is not authenticated.\n");
		msgb_free(msg);
		return -1;
	}


	/* 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:
			filter = bsc_nat_filter_sccp_cr(bsc, msg, parsed, &con_type, &imsi);
			if (filter < 0) {
				bsc_stat_reject(filter, bsc, 0);
				goto exit3;
			}

			if (!create_sccp_src_ref(bsc, parsed))
				goto exit2;
			con = patch_sccp_src_ref_to_msc(msg, parsed, bsc);
			con->msc_con = bsc->nat->msc_con;
			con_msc = con->msc_con;
			con->con_type = con_type;
			con->imsi_checked = filter;
			if (imsi)
				con->imsi = talloc_steal(con, imsi);
			imsi = NULL;
			con_bsc = con->bsc;
			handle_con_stats(con);
			break;
		case SCCP_MSG_TYPE_RLSD:
		case SCCP_MSG_TYPE_CREF:
		case SCCP_MSG_TYPE_DT1:
		case SCCP_MSG_TYPE_CC:
		case SCCP_MSG_TYPE_IT:
			con = patch_sccp_src_ref_to_msc(msg, parsed, bsc);
			if (con) {
				/* only filter non local connections */
				if (!con->con_local) {
					filter = bsc_nat_filter_dt(bsc, msg, con, parsed);
					if (filter < 0) {
						bsc_stat_reject(filter, bsc, 1);
						bsc_send_con_release(bsc, con);
						con = NULL;
						goto exit2;
					}

					/* hand data to a side channel */
					if (bsc_check_ussd(con, parsed, msg) == 1) 
						con->con_local = NAT_CON_END_USSD;

					/*
					 * Optionally rewrite setup message. This can
					 * replace the msg and the parsed structure becomes
					 * invalid.
					 */
					msg = bsc_nat_rewrite_setup(bsc->nat, msg, parsed, con->imsi);
					talloc_free(parsed);
					parsed = NULL;
				} else if (con->con_local == NAT_CON_END_USSD) {
					bsc_check_ussd(con, parsed, msg);
				}

				con_bsc = con->bsc;
				con_msc = con->msc_con;
				con_filter = con->con_local;
			}

			break;
		case SCCP_MSG_TYPE_RLC:
			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;
			}
			remove_sccp_src_ref(bsc, msg, parsed);
			bsc_maybe_close(bsc);
			break;
		case SCCP_MSG_TYPE_UDT:
			/* simply forward everything */
			con = NULL;
			break;
		default:
			LOGP(DNAT, LOGL_ERROR, "Not forwarding to msc sccp type: 0x%x\n", parsed->sccp_type);
			con = NULL;
			goto exit2;
			break;
		}
        } else if (parsed->ipa_proto == IPAC_PROTO_MGCP_OLD) {
                bsc_mgcp_forward(bsc, msg);
                goto exit2;
	} else {
		LOGP(DNAT, LOGL_ERROR, "Not forwarding unknown stream id: 0x%x\n", parsed->ipa_proto);
		goto exit2;
	}

	if (con_msc && con_bsc != bsc) {
		LOGP(DNAT, LOGL_ERROR, "The connection belongs to a different BTS: input: %d con: %d\n",
		     bsc->cfg->nr, con_bsc->cfg->nr);
		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,
			parsed ? parsed->ipa_proto : -1,
			parsed ? parsed->sccp_type : -1);
		goto exit2;
	}

	/* send the non-filtered but maybe modified msg */
	queue_for_msc(con_msc, msg);
	if (parsed)
		talloc_free(parsed);
	return 0;

exit:
	/* if we filter out the reset send an ack to the BSC */
	if (parsed->bssap == 0 && parsed->gsm_type == BSS_MAP_MSG_RESET) {
		send_reset_ack(bsc);
		send_reset_ack(bsc);
	} else if (parsed->ipa_proto == IPAC_PROTO_IPACCESS) {
		/* do we know who is handling this? */
		if (msg->l2h[0] == IPAC_MSGT_ID_RESP) {
			struct tlv_parsed tvp;
			int ret;
			ret = ipaccess_idtag_parse(&tvp,
					     (unsigned char *) msg->l2h + 2,
					     msgb_l2len(msg) - 2);
			if (ret < 0) {
				LOGP(DNAT, LOGL_ERROR, "ignoring IPA response "
					"message with malformed TLVs\n");
				return ret;
			}
			if (TLVP_PRESENT(&tvp, IPAC_IDTAG_UNITNAME))
				ipaccess_auth_bsc(&tvp, bsc);
		}

		goto exit2;
	}

exit2:
	if (imsi)
		talloc_free(imsi);
	talloc_free(parsed);
	msgb_free(msg);
	return -1;

exit3:
	/* send a SCCP Connection Refused */
	if (imsi)
		talloc_free(imsi);
	bsc_send_con_refuse(bsc, parsed, con_type);
	talloc_free(parsed);
	msgb_free(msg);
	return -1;
}

static int ipaccess_bsc_read_cb(struct osmo_fd *bfd)
{
	int error;
	struct bsc_connection *bsc = bfd->data;
	struct msgb *msg = ipaccess_read_msg(bfd, &error);
	struct ipaccess_head *hh;

	if (!msg) {
		if (error == 0)
			LOGP(DNAT, LOGL_ERROR,
			     "The connection to the BSC Nr: %d was lost. Cleaning it\n",
			     bsc->cfg ? bsc->cfg->nr : -1);
		else
			LOGP(DNAT, LOGL_ERROR,
			     "Stream error on BSC Nr: %d. Failed to parse ip access message: %d\n",
			     bsc->cfg ? bsc->cfg->nr : -1, error);

		bsc_close_connection(bsc);
		return -1;
	}


	LOGP(DNAT, LOGL_DEBUG, "MSG from BSC: %s proto: %d\n", osmo_hexdump(msg->data, msg->len), msg->l2h[0]);

	/* Handle messages from the BSC */
	hh = (struct ipaccess_head *) msg->data;

	/* stop the pong timeout */
	if (hh->proto == IPAC_PROTO_IPACCESS) {
		if (msg->l2h[0] == IPAC_MSGT_PONG) {
			osmo_timer_del(&bsc->pong_timeout);
			msgb_free(msg);
			return 0;
		} else if (msg->l2h[0] == IPAC_MSGT_PING) {
			send_pong(bsc);
			msgb_free(msg);
			return 0;
		}
	}

	/* FIXME: Currently no PONG is sent to the BSC */
	/* FIXME: Currently no ID ACK is sent to the BSC */
	forward_sccp_to_msc(bsc, msg);

	return 0;
}

static int ipaccess_listen_bsc_cb(struct osmo_fd *bfd, unsigned int what)
{
	struct bsc_connection *bsc;
	int fd, rc, on;
	struct sockaddr_in sa;
	socklen_t sa_len = sizeof(sa);

	if (!(what & BSC_FD_READ))
		return 0;

	fd = accept(bfd->fd, (struct sockaddr *) &sa, &sa_len);
	if (fd < 0) {
		perror("accept");
		return fd;
	}

	/* count the reconnect */
	osmo_counter_inc(nat->stats.bsc.reconn);

	/*
	 * if we are not connected to a msc... just close the socket
	 */
	if (!bsc_nat_msc_is_connected(nat)) {
		LOGP(DNAT, LOGL_NOTICE, "Disconnecting BSC due lack of MSC connection.\n");
		close(fd);
		return 0;
	}

	if (nat->blocked) {
		LOGP(DNAT, LOGL_NOTICE, "Disconnecting BSC due NAT being blocked.\n");
		close(fd);
		return 0;
	}

	on = 1;
	rc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
	if (rc != 0)
                LOGP(DNAT, LOGL_ERROR, "Failed to set TCP_NODELAY: %s\n", strerror(errno));

	rc = setsockopt(fd, IPPROTO_IP, IP_TOS,
			&nat->bsc_ip_dscp, sizeof(nat->bsc_ip_dscp));
	if (rc != 0)
		LOGP(DNAT, LOGL_ERROR, "Failed to set IP_TOS: %s\n", strerror(errno));

	/* todo... do something with the connection */
	/* todo... use GNUtls to see if we want to trust this as a BTS */

	/*
	 *
	 */
	bsc = bsc_connection_alloc(nat);
	if (!bsc) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate BSC struct.\n");
		close(fd);
		return -1;
	}

	bsc->write_queue.bfd.data = bsc;
	bsc->write_queue.bfd.fd = fd;
	bsc->write_queue.read_cb = ipaccess_bsc_read_cb;
	bsc->write_queue.write_cb = bsc_write_cb;
	bsc->write_queue.bfd.when = BSC_FD_READ;
	if (osmo_fd_register(&bsc->write_queue.bfd) < 0) {
		LOGP(DNAT, LOGL_ERROR, "Failed to register BSC fd.\n");
		close(fd);
		talloc_free(bsc);
		return -2;
	}

	LOGP(DNAT, LOGL_NOTICE, "BSC connection on %d with IP: %s\n",
		fd, inet_ntoa(sa.sin_addr));
	llist_add(&bsc->list_entry, &nat->bsc_connections);
	send_id_ack(bsc);
	send_id_req(bsc);
	send_mgcp_reset(bsc);

	/*
	 * start the hangup timer
	 */
	bsc->id_timeout.data = bsc;
	bsc->id_timeout.cb = ipaccess_close_bsc;
	osmo_timer_schedule(&bsc->id_timeout, nat->auth_timeout, 0);
	return 0;
}

static void print_usage()
{
	printf("Usage: bsc_nat\n");
}

static void print_help()
{
	printf("  Some useful help...\n");
	printf("  -h --help this text\n");
	printf("  -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
	printf("  -D --daemonize Fork the process into a background daemon\n");
	printf("  -s --disable-color\n");
	printf("  -c --config-file filename The config file to use.\n");
	printf("  -m --msc=IP. The address of the MSC.\n");
	printf("  -l --local=IP. The local address of this BSC.\n");
}

static void handle_options(int argc, char **argv)
{
	while (1) {
		int option_index = 0, c;
		static struct option long_options[] = {
			{"help", 0, 0, 'h'},
			{"debug", 1, 0, 'd'},
			{"config-file", 1, 0, 'c'},
			{"disable-color", 0, 0, 's'},
			{"timestamp", 0, 0, 'T'},
			{"msc", 1, 0, 'm'},
			{"local", 1, 0, 'l'},
			{0, 0, 0, 0}
		};

		c = getopt_long(argc, argv, "hd:sTPc:m:l:",
				long_options, &option_index);
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			print_usage();
			print_help();
			exit(0);
		case 's':
			log_set_use_color(osmo_stderr_target, 0);
			break;
		case 'd':
			log_parse_category_mask(osmo_stderr_target, optarg);
			break;
		case 'c':
			config_file = strdup(optarg);
			break;
		case 'T':
			log_set_print_timestamp(osmo_stderr_target, 1);
			break;
		case 'm':
			msc_ip = optarg;
			break;
		case 'l':
			inet_aton(optarg, &local_addr);
			break;
		default:
			/* ignore */
			break;
		}
	}
}

static void signal_handler(int signal)
{
	switch (signal) {
	case SIGABRT:
		/* in case of abort, we want to obtain a talloc report
		 * and then return to the caller, who will abort the process */
	case SIGUSR1:
		talloc_report_full(tall_bsc_ctx, stderr);
		break;
	default:
		break;
	}
}

static void sccp_close_unconfirmed(void *_data)
{
	int destroyed = 0;
	struct bsc_connection *bsc, *bsc_tmp;
	struct sccp_connections *conn, *tmp1;
	struct timespec now;
	clock_gettime(CLOCK_MONOTONIC, &now);

	llist_for_each_entry_safe(conn, tmp1, &nat->sccp_connections, list_entry) {
		if (conn->has_remote_ref)
			continue;

		int diff = (now.tv_sec - conn->creation_time.tv_sec) / 60;
		if (diff < SCCP_CLOSE_TIME_TIMEOUT)
			continue;

		LOGP(DNAT, LOGL_ERROR, "SCCP connection 0x%x/0x%x was never confirmed.\n",
		     sccp_src_ref_to_int(&conn->real_ref),
		     sccp_src_ref_to_int(&conn->patched_ref));
		sccp_connection_destroy(conn);
		destroyed = 1;
	}

	if (!destroyed)
		goto out;

	/* now close out any BSC */
	llist_for_each_entry_safe(bsc, bsc_tmp, &nat->bsc_connections, list_entry)
		bsc_maybe_close(bsc);

out:
	osmo_timer_schedule(&sccp_close, SCCP_CLOSE_TIME, 0);
}

extern void *tall_msgb_ctx;
extern void *tall_ctr_ctx;
static void talloc_init_ctx()
{
	tall_bsc_ctx = talloc_named_const(NULL, 0, "nat");
	tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
	tall_ctr_ctx = talloc_named_const(tall_bsc_ctx, 0, "counter");
}

extern enum node_type bsc_vty_go_parent(struct vty *vty);

static struct vty_app_info vty_info = {
	.name 		= "OsmoBSCNAT",
	.version	= PACKAGE_VERSION,
	.go_parent_cb	= bsc_vty_go_parent,
	.is_config_node	= bsc_vty_is_config_node,
};

int main(int argc, char **argv)
{
	int rc;

	talloc_init_ctx();

	osmo_init_logging(&log_info);

	nat = bsc_nat_alloc();
	if (!nat) {
		fprintf(stderr, "Failed to allocate the BSC nat.\n");
		return -4;
	}

	nat->mgcp_cfg = mgcp_config_alloc();
	if (!nat->mgcp_cfg) {
		fprintf(stderr, "Failed to allocate MGCP cfg.\n");
		return -5;
	}

	vty_info.copyright = openbsc_copyright;
	vty_init(&vty_info);
	logging_vty_add_cmds(&log_info);
	bsc_nat_vty_init(nat);


	/* parse options */
	local_addr.s_addr = INADDR_ANY;
	handle_options(argc, argv);

	rate_ctr_init(tall_bsc_ctx);

	/* init vty and parse */
	telnet_init(tall_bsc_ctx, NULL, 4244);
	if (mgcp_parse_config(config_file, nat->mgcp_cfg) < 0) {
		fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file);
		return -3;
	}

	/* over rule the VTY config */
	if (msc_ip)
		bsc_nat_set_msc_ip(nat, msc_ip);

	/* seed the PRNG */
	srand(time(NULL));

	/*
	 * Setup the MGCP code..
	 */
	if (bsc_mgcp_nat_init(nat) != 0)
		return -4;

	/* connect to the MSC */
	nat->msc_con = bsc_msc_create(nat, &nat->dests);
	if (!nat->msc_con) {
		fprintf(stderr, "Creating a bsc_msc_connection failed.\n");
		exit(1);
	}

	nat->msc_con->connection_loss = msc_connection_was_lost;
	nat->msc_con->connected = msc_connection_connected;
	nat->msc_con->write_queue.read_cb = ipaccess_msc_read_cb;
	nat->msc_con->write_queue.write_cb = ipaccess_msc_write_cb;;
	nat->msc_con->write_queue.bfd.data = nat->msc_con;
	bsc_msc_connect(nat->msc_con);

	/* wait for the BSC */
	rc = make_sock(&bsc_listen, IPPROTO_TCP, ntohl(local_addr.s_addr),
		       5000, 0, ipaccess_listen_bsc_cb, nat);
	if (rc != 0) {
		fprintf(stderr, "Failed to listen for BSC.\n");
		exit(1);
	}

	rc = bsc_ussd_init(nat);
	if (rc != 0) {
		LOGP(DNAT, LOGL_ERROR, "Failed to bind the USSD socket.\n");
		exit(1);
	}

	signal(SIGABRT, &signal_handler);
	signal(SIGUSR1, &signal_handler);
	osmo_init_ignore_signals();

	if (daemonize) {
		rc = osmo_daemonize();
		if (rc < 0) {
			perror("Error during daemonize");
			exit(1);
		}
	}

	/* recycle timer */
	sccp_set_log_area(DSCCP);
	sccp_close.cb = sccp_close_unconfirmed;
	sccp_close.data = NULL;
	osmo_timer_schedule(&sccp_close, SCCP_CLOSE_TIME, 0);

	while (1) {
		osmo_select_main(0);
	}

	return 0;
}

/* Close all connections handed out to the USSD module */
int bsc_close_ussd_connections(struct bsc_nat *nat)
{
	struct sccp_connections *con;
	llist_for_each_entry(con, &nat->sccp_connections, list_entry) {
		if (con->con_local != NAT_CON_END_USSD)
			continue;
		if (!con->bsc)
			continue;

		nat_send_clrc_bsc(con);
		nat_send_rlsd_bsc(con);
	}

	return 0;
}
