/* BSC Multiplexer/NAT */

/*
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010 by on-waves.com
 * 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/bssap.h>
#include <openbsc/ipaccess.h>
#include <openbsc/debug.h>

#include <osmocore/talloc.h>

#include <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 },
};

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];

	/* 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_NOTICE, "Blacklisted with rule %d\n", i);
			return 1;
		} else {
			/* blacklisted, we have no content sniffing yet */
			LOGP(DNAT, LOGL_NOTICE, "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_NOTICE, "Whitelisted with rule %d\n", i);
			return 0;
		} else {
			/* whitelisted */
			return 0;
		}
	}

	return 1;
}
