/* BSC Multiplexer/NAT */

/*
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010 by On-Waves
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <openbsc/bsc_nat.h>
#include <openbsc/bsc_nat_sccp.h>
#include <openbsc/ipaccess.h>
#include <openbsc/debug.h>

#include <osmocore/talloc.h>
#include <osmocore/protocol/gsm_08_08.h>

#include <osmocom/sccp/sccp.h>

/*
 * The idea is to have a simple struct describing a IPA packet with
 * SCCP SSN and the GSM 08.08 payload and decide. We will both have
 * a white and a blacklist of packets we want to handle.
 *
 * TODO: Implement a "NOT" in the filter language.
 */

#define ALLOW_ANY -1

#define FILTER_TO_BSC	1
#define FILTER_TO_MSC	2
#define FILTER_TO_BOTH	3


struct bsc_pkt_filter {
	int ipa_proto;
	int dest_ssn;
	int bssap;
	int gsm;
	int filter_dir;
};

static struct bsc_pkt_filter black_list[] = {
	/* filter reset messages to the MSC */
	{ IPAC_PROTO_SCCP, SCCP_SSN_BSSAP, 0, BSS_MAP_MSG_RESET, FILTER_TO_MSC },

	/* filter reset ack messages to the BSC */
	{ IPAC_PROTO_SCCP, SCCP_SSN_BSSAP, 0, BSS_MAP_MSG_RESET_ACKNOWLEDGE, FILTER_TO_BSC },

	/* filter ip access */
	{ IPAC_PROTO_IPACCESS, ALLOW_ANY, ALLOW_ANY, ALLOW_ANY, FILTER_TO_MSC },
};

static struct bsc_pkt_filter white_list[] = {
	/* allow IPAC_PROTO_SCCP messages to both sides */
	{ IPAC_PROTO_SCCP, ALLOW_ANY, ALLOW_ANY, ALLOW_ANY, FILTER_TO_BOTH },

	/* allow MGCP messages to both sides */
	{ IPAC_PROTO_MGCP, ALLOW_ANY, ALLOW_ANY, ALLOW_ANY, FILTER_TO_BOTH },
};

struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg)
{
	struct sccp_parse_result result;
	struct bsc_nat_parsed *parsed;
	struct ipaccess_head *hh;

	/* quick fail */
	if (msg->len < 4)
		return NULL;

	parsed = talloc_zero(msg, struct bsc_nat_parsed);
	if (!parsed)
		return NULL;

	/* more init */
	parsed->ipa_proto = parsed->called_ssn = parsed->calling_ssn = -1;
	parsed->sccp_type = parsed->bssap = parsed->gsm_type = -1;

	/* start parsing */
	hh = (struct ipaccess_head *) msg->data;
	parsed->ipa_proto = hh->proto;

	msg->l2h = &hh->data[0];

	/* do a size check on the input */
	if (ntohs(hh->len) != msgb_l2len(msg)) {
		LOGP(DINP, LOGL_ERROR, "Wrong input length?\n");
		talloc_free(parsed);
		return NULL;
	}

	/* analyze sccp down here */
	if (parsed->ipa_proto == IPAC_PROTO_SCCP) {
		memset(&result, 0, sizeof(result));
		if (sccp_parse_header(msg, &result) != 0) {
			talloc_free(parsed);
			return 0;
		}

		if (msg->l3h && msgb_l3len(msg) < 3) {
			LOGP(DNAT, LOGL_ERROR, "Not enough space or GSM payload\n");
			talloc_free(parsed);
			return 0;
		}

		parsed->sccp_type = sccp_determine_msg_type(msg);
		parsed->src_local_ref = result.source_local_reference;
		parsed->dest_local_ref = result.destination_local_reference;
		parsed->called_ssn = result.called.ssn;
		parsed->calling_ssn = result.calling.ssn;

		/* in case of connection confirm we have no payload */
		if (msg->l3h) {
			parsed->bssap = msg->l3h[0];
			parsed->gsm_type = msg->l3h[2];
		}
	}

	return parsed;
}

int bsc_nat_filter_ipa(int dir, struct msgb *msg, struct bsc_nat_parsed *parsed)
{
	int i;

	/* go through the blacklist now */
	for (i = 0; i < ARRAY_SIZE(black_list); ++i) {
		/* ignore the rule? */
		if (black_list[i].filter_dir != FILTER_TO_BOTH
		    && black_list[i].filter_dir != dir)
			continue;

		/* the proto is not blacklisted */
		if (black_list[i].ipa_proto != ALLOW_ANY
		    && black_list[i].ipa_proto != parsed->ipa_proto)
			continue;

		if (parsed->ipa_proto == IPAC_PROTO_SCCP) {
			/* the SSN is not blacklisted */
			if (black_list[i].dest_ssn != ALLOW_ANY
			    && black_list[i].dest_ssn != parsed->called_ssn)
				continue;

			/* bssap */
			if (black_list[i].bssap != ALLOW_ANY
			    && black_list[i].bssap != parsed->bssap)
				continue;

			/* gsm */
			if (black_list[i].gsm != ALLOW_ANY
			    && black_list[i].gsm != parsed->gsm_type)
				continue;

			/* blacklisted */
			LOGP(DNAT, LOGL_INFO, "Blacklisted with rule %d\n", i);
			return 1;
		} else {
			/* blacklisted, we have no content sniffing yet */
			LOGP(DNAT, LOGL_INFO, "Blacklisted with rule %d\n", i);
			return 1;
		}
	}

	/* go through the whitelust now */
	for (i = 0; i < ARRAY_SIZE(white_list); ++i) {
		/* ignore the rule? */
		if (white_list[i].filter_dir != FILTER_TO_BOTH
		    && white_list[i].filter_dir != dir)
			continue;

		/* the proto is not whitelisted */
		if (white_list[i].ipa_proto != ALLOW_ANY
		    && white_list[i].ipa_proto != parsed->ipa_proto)
			continue;

		if (parsed->ipa_proto == IPAC_PROTO_SCCP) {
			/* the SSN is not whitelisted */
			if (white_list[i].dest_ssn != ALLOW_ANY
			    && white_list[i].dest_ssn != parsed->called_ssn)
				continue;

			/* bssap */
			if (white_list[i].bssap != ALLOW_ANY
			    && white_list[i].bssap != parsed->bssap)
				continue;

			/* gsm */
			if (white_list[i].gsm != ALLOW_ANY
			    && white_list[i].gsm != parsed->gsm_type)
				continue;

			/* whitelisted */
			LOGP(DNAT, LOGL_INFO, "Whitelisted with rule %d\n", i);
			return 0;
		} else {
			/* whitelisted */
			return 0;
		}
	}

	return 1;
}
