/*
 * Message rewriting functionality
 */
/*
 * (C) 2010-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010-2013 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 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 <openbsc/bsc_nat.h>
#include <openbsc/bsc_nat_sccp.h>
#include <openbsc/bsc_msc.h>
#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
#include <openbsc/ipaccess.h>
#include <openbsc/nat_rewrite_trie.h>

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gsm/gsm0808.h>

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

#include <osmocom/sccp/sccp.h>

static char *trie_lookup(struct nat_rewrite *trie, const char *number,
			regoff_t off, void *ctx)
{
	struct nat_rewrite_rule *rule;

	if (!trie) {
		LOGP(DNAT, LOGL_ERROR,
			"Asked to do a table lookup but no table.\n");
		return NULL;
	}

	rule = nat_rewrite_lookup(trie, number);
	if (!rule) {
		LOGP(DNAT, LOGL_DEBUG,
			"Couldn't find a prefix rule for %s\n", number);
		return NULL;
	}

	return talloc_asprintf(ctx, "%s%s", rule->rewrite, &number[off]);
}

static char *match_and_rewrite_number(void *ctx, const char *number,
				const char *imsi, struct llist_head *list,
				struct nat_rewrite *trie)
{
	struct bsc_nat_num_rewr_entry *entry;
	char *new_number = NULL;

	/* need to find a replacement and then fix it */
	llist_for_each_entry(entry, list, list) {
		regmatch_t matches[2];

		/* check the IMSI match */
		if (regexec(&entry->msisdn_reg, imsi, 0, NULL, 0) != 0)
			continue;

		/* this regexp matches... */
		if (regexec(&entry->num_reg, number, 2, matches, 0) == 0
			&& matches[1].rm_eo != -1) {
			if (entry->is_prefix_lookup)
				new_number = trie_lookup(trie, number,
						matches[1].rm_so, ctx);
			else
				new_number = talloc_asprintf(ctx, "%s%s",
					entry->replace,
					&number[matches[1].rm_so]);
		}

		if (new_number)
			break;
	}

	return new_number;
}

static char *rewrite_isdn_number(struct bsc_nat *nat, struct llist_head *rewr_list,
				void *ctx, const char *imsi,
				struct gsm_mncc_number *called)
{
	char int_number[sizeof(called->number) + 2];
	char *number = called->number;

	if (llist_empty(&nat->num_rewr))
		return NULL;

	/* only ISDN plan */
	if (called->plan != 1)
		return NULL;

	/* international, prepend */
	if (called->type == 1) {
		int_number[0] = '+';
		memcpy(&int_number[1], number, strlen(number) + 1);
		number = int_number;
	}

	return match_and_rewrite_number(ctx, number,
					imsi, rewr_list, nat->num_rewr_trie);
}

static void update_called_number(struct gsm_mncc_number *called,
				const char *chosen_number)
{
	if (strncmp(chosen_number, "00", 2) == 0) {
		called->type = 1;
		strncpy(called->number, chosen_number + 2, sizeof(called->number));
	} else {
		/* rewrite international to unknown */
		if (called->type == 1)
			called->type = 0;
		strncpy(called->number, chosen_number, sizeof(called->number));
	}
}

/**
 * Rewrite non global numbers... according to rules based on the IMSI
 */
static struct msgb *rewrite_setup(struct bsc_nat *nat, struct msgb *msg,
				  struct bsc_nat_parsed *parsed, const char *imsi,
				  struct gsm48_hdr *hdr48, const uint32_t len)
{
	struct tlv_parsed tp;
	unsigned int payload_len;
	struct gsm_mncc_number called;
	struct msgb *out;
	char *new_number_pre = NULL, *new_number_post = NULL, *chosen_number;
	uint8_t *outptr;
	const uint8_t *msgptr;
	int sec_len;

	/* decode and rewrite the message */
	payload_len = len - sizeof(*hdr48);
	tlv_parse(&tp, &gsm48_att_tlvdef, hdr48->data, payload_len, 0, 0);

	/* no number, well let us ignore it */
	if (!TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD))
		return NULL;

	memset(&called, 0, sizeof(called));
	gsm48_decode_called(&called,
			    TLVP_VAL(&tp, GSM48_IE_CALLED_BCD) - 1);

	/* check if it looks international and stop */
	new_number_pre = rewrite_isdn_number(nat, &nat->num_rewr, msg, imsi, &called);

	if (!new_number_pre) {
		LOGP(DNAT, LOGL_DEBUG, "No IMSI match found, returning message.\n");
		return NULL;
	}

	if (strlen(new_number_pre) > sizeof(called.number)) {
		LOGP(DNAT, LOGL_ERROR, "Number is too long for structure.\n");
		talloc_free(new_number_pre);
		return NULL;
	}
	update_called_number(&called, new_number_pre);

	/* another run through the re-write engine with other rules */
	new_number_post = rewrite_isdn_number(nat, &nat->num_rewr_post, msg,
					imsi, &called);
	chosen_number = new_number_post ? new_number_post : new_number_pre;


	if (strlen(chosen_number) > sizeof(called.number)) {
		LOGP(DNAT, LOGL_ERROR, "Number is too long for structure.\n");
		talloc_free(new_number_pre);
		talloc_free(new_number_post);
		return NULL;
	}

	/*
	 * Need to create a new message now based on the old onew
	 * with a new number. We can sadly not patch this in place
	 * so we will need to regenerate it.
	 */

	out = msgb_alloc_headroom(4096, 128, "changed-setup");
	if (!out) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate.\n");
		talloc_free(new_number_pre);
		talloc_free(new_number_post);
		return NULL;
	}

	/* copy the header */
	outptr = msgb_put(out, sizeof(*hdr48));
	memcpy(outptr, hdr48, sizeof(*hdr48));

	/* copy everything up to the number */
	sec_len = TLVP_VAL(&tp, GSM48_IE_CALLED_BCD) - 2 - &hdr48->data[0];
	outptr = msgb_put(out, sec_len);
	memcpy(outptr, &hdr48->data[0], sec_len);

	/* create the new number */
	update_called_number(&called, chosen_number);
	gsm48_encode_called(out, &called);

	/* copy thre rest */
	msgptr = TLVP_VAL(&tp, GSM48_IE_CALLED_BCD) +
		 TLVP_LEN(&tp, GSM48_IE_CALLED_BCD);
	sec_len = payload_len - (msgptr - &hdr48->data[0]);
	outptr = msgb_put(out, sec_len);
	memcpy(outptr, msgptr, sec_len);

	talloc_free(new_number_pre);
	talloc_free(new_number_post);
	return out;
}

/**
 * Find a new SMSC address, returns an allocated string that needs to be
 * freed or is NULL.
 */
static char *find_new_smsc(struct bsc_nat *nat, void *ctx, const char *imsi,
			   const char *smsc_addr, const char *dest_nr)
{
	struct bsc_nat_num_rewr_entry *entry;
	char *new_number = NULL;
	uint8_t dest_match = llist_empty(&nat->tpdest_match);

	/* We will find a new number now */
	llist_for_each_entry(entry, &nat->smsc_rewr, list) {
		regmatch_t matches[2];

		/* check the IMSI match */
		if (regexec(&entry->msisdn_reg, imsi, 0, NULL, 0) != 0)
			continue;

		/* this regexp matches... */
		if (regexec(&entry->num_reg, smsc_addr, 2, matches, 0) == 0 &&
		    matches[1].rm_eo != -1)
			new_number = talloc_asprintf(ctx, "%s%s",
					entry->replace,
					&smsc_addr[matches[1].rm_so]);
		if (new_number)
			break;
	}

	if (!new_number)
		return NULL;

	/*
	 * now match the number against another list
	 */
	llist_for_each_entry(entry, &nat->tpdest_match, list) {
		/* check the IMSI match */
		if (regexec(&entry->msisdn_reg, imsi, 0, NULL, 0) != 0)
			continue;

		if (regexec(&entry->num_reg, dest_nr, 0, NULL, 0) == 0) {
			dest_match = 1;
			break;
		}
	}

	if (!dest_match) {
		talloc_free(new_number);
		return NULL;
	}

	return new_number;
}

/**
 * Clear the TP-SRR from the TPDU header
 */
static uint8_t sms_new_tpdu_hdr(struct bsc_nat *nat, const char *imsi,
				const char *dest_nr, uint8_t hdr)
{
	struct bsc_nat_num_rewr_entry *entry;

	/* We will find a new number now */
	llist_for_each_entry(entry, &nat->sms_clear_tp_srr, list) {
		/* check the IMSI match */
		if (regexec(&entry->msisdn_reg, imsi, 0, NULL, 0) != 0)
			continue;
		if (regexec(&entry->num_reg, dest_nr, 0, NULL, 0) != 0)
			continue;

		/* matched phone number and imsi */
		return hdr & ~0x20;
	}

	return hdr;
}

/**
 * Check if we need to rewrite the number. For this SMS.
 */
static char *sms_new_dest_nr(struct bsc_nat *nat, void *ctx,
			     const char *imsi, const char *dest_nr)
{
	return match_and_rewrite_number(ctx, dest_nr, imsi,
					&nat->sms_num_rewr, NULL);
}

/**
 * This is a helper for GSM 04.11 8.2.5.2 Destination address element
 */
void sms_encode_addr_element(struct msgb *out, const char *new_number,
			     int format, int tp_data)
{
	uint8_t new_addr_len;
	uint8_t new_addr[26];

	/*
	 * Copy the new number. We let libosmocore encode it, then set
	 * the extension followed after the length. Depending on if
	 * we want to write RP we will let the TLV code add the
	 * length for us or we need to use strlen... This is not very clear
	 * as of 03.40 and 04.11.
	 */
	new_addr_len = gsm48_encode_bcd_number(new_addr, ARRAY_SIZE(new_addr),
					       1, new_number);
	new_addr[1] = format;
	if (tp_data) {
		uint8_t *data = msgb_put(out, new_addr_len);
		memcpy(data, new_addr, new_addr_len);
		data[0] = strlen(new_number);
	} else {
		msgb_lv_put(out, new_addr_len - 1, new_addr + 1);
	}
}

static struct msgb *sms_create_new(uint8_t type, uint8_t ref,
				   struct gsm48_hdr *old_hdr48,
				   const uint8_t *orig_addr_ptr,
				   int orig_addr_len, const char *new_number,
				   const uint8_t *data_ptr, int data_len,
				   uint8_t tpdu_first_byte,
				   const int old_dest_len, const char *new_dest_nr)
{
	struct gsm48_hdr *new_hdr48;
	struct msgb *out;

	/*
	 * We need to re-create the patched structure. This is why we have
	 * saved the above pointers.
	 */
	out = msgb_alloc_headroom(4096, 128, "changed-smsc");
	if (!out) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate.\n");
		return NULL;
	}

	out->l2h = out->data;
	msgb_v_put(out, GSM411_MT_RP_DATA_MO);
	msgb_v_put(out, ref);
	msgb_lv_put(out, orig_addr_len, orig_addr_ptr);

	sms_encode_addr_element(out, new_number, 0x91, 0);


	/* Patch the TPDU from here on */

	/**
	 * Do we need to put a new TP-Destination-Address (TP-DA) here or
	 * can we copy the old thing? For the TP-DA we need to find out the
	 * new size.
	 */
	if (new_dest_nr) {
		uint8_t *data, *new_size;

		/* reserve the size and write the header */
		new_size = msgb_put(out, 1);
		out->l3h = new_size + 1;
		msgb_v_put(out, tpdu_first_byte);
		msgb_v_put(out, data_ptr[1]);

		/* encode the new number and put it */
		if (strncmp(new_dest_nr, "00", 2) == 0)
			sms_encode_addr_element(out, new_dest_nr + 2, 0x91, 1);
		else
			sms_encode_addr_element(out, new_dest_nr, 0x81, 1);

		/* Copy the rest after the TP-DS */
		data = msgb_put(out, data_len - 2 - 1 - old_dest_len);
		memcpy(data, &data_ptr[2 + 1 + old_dest_len], data_len - 2 - 1 - old_dest_len);

		/* fill in the new size */
		new_size[0] = msgb_l3len(out);
	} else {
		msgb_v_put(out, data_len);
		msgb_tv_fixed_put(out, tpdu_first_byte, data_len - 1, &data_ptr[1]);
	}

	/* prepend GSM 04.08 header */
	new_hdr48 = (struct gsm48_hdr *) msgb_push(out, sizeof(*new_hdr48) + 1);
	memcpy(new_hdr48, old_hdr48, sizeof(*old_hdr48));
	new_hdr48->data[0] = msgb_l2len(out);

	return out;
}

/**
 * Parse the SMS and check if it needs to be rewritten
 */
static struct msgb *rewrite_sms(struct bsc_nat *nat, struct msgb *msg,
				struct bsc_nat_parsed *parsed, const char *imsi,
				struct gsm48_hdr *hdr48, const uint32_t len)
{
	unsigned int payload_len;
	unsigned int cp_len;

	uint8_t ref;
	uint8_t orig_addr_len, *orig_addr_ptr;
	uint8_t dest_addr_len, *dest_addr_ptr;
	uint8_t data_len, *data_ptr;
	char smsc_addr[30];


	uint8_t dest_len, orig_dest_len;
	char _dest_nr[30];
	char *dest_nr;
	char *new_dest_nr;

	char *new_number = NULL;
	uint8_t tpdu_hdr;
	struct msgb *out;

	payload_len = len - sizeof(*hdr48);
	if (payload_len < 1) {
		LOGP(DNAT, LOGL_ERROR, "SMS too short for things. %d\n", payload_len);
		return NULL;
	}

	cp_len = hdr48->data[0];
	if (payload_len + 1 < cp_len) {
		LOGP(DNAT, LOGL_ERROR, "SMS RPDU can not fit in: %d %d\n", cp_len, payload_len);
		return NULL;
	}

	if (hdr48->data[1] != GSM411_MT_RP_DATA_MO)
		return NULL;

	if (cp_len < 5) {
		LOGP(DNAT, LOGL_ERROR, "RD-DATA can not fit in the CP len: %d\n", cp_len);
		return NULL;
	}

	/* RP */
	ref = hdr48->data[2];
	orig_addr_len = hdr48->data[3];
	orig_addr_ptr = &hdr48->data[4];

	/* the +1 is for checking if the following element has some space */
	if (cp_len < 3 + orig_addr_len + 1) {
		LOGP(DNAT, LOGL_ERROR, "RP-Originator addr does not fit: %d\n", orig_addr_len);
		return NULL;
	}

	dest_addr_len = hdr48->data[3 + orig_addr_len + 1];
	dest_addr_ptr = &hdr48->data[3 + orig_addr_len + 2];

	if (cp_len < 3 + orig_addr_len + 1 + dest_addr_len + 1) {
		LOGP(DNAT, LOGL_ERROR, "RP-Destination addr does not fit: %d\n", dest_addr_len);
		return NULL;
	}
	gsm48_decode_bcd_number(smsc_addr, ARRAY_SIZE(smsc_addr), dest_addr_ptr - 1, 1);

	data_len = hdr48->data[3 + orig_addr_len + 1 + dest_addr_len + 1];
	data_ptr = &hdr48->data[3 + orig_addr_len + 1 + dest_addr_len + 2];

	if (cp_len < 3 + orig_addr_len + 1 + dest_addr_len + 1 + data_len) {
		LOGP(DNAT, LOGL_ERROR, "RP-Data does not fit: %d\n", data_len);
		return NULL;
	}

	if (data_len < 3) {
		LOGP(DNAT, LOGL_ERROR, "SMS-SUBMIT is too short.\n");
		return NULL;
	}

	/* TP-PDU starts here */
	if ((data_ptr[0] & 0x03) != GSM340_SMS_SUBMIT_MS2SC)
		return NULL;

	/*
	 * look into the phone number. The length is in semi-octets, we will
	 * need to add the byte for the number type as well.
	 */
	orig_dest_len = data_ptr[2];
	dest_len = ((orig_dest_len + 1) / 2) + 1;
	if (data_len < dest_len + 3 || dest_len < 2) {
		LOGP(DNAT, LOGL_ERROR, "SMS-SUBMIT can not have TP-DestAddr.\n");
		return NULL;
	}

	if ((data_ptr[3] & 0x80) == 0) {
		LOGP(DNAT, LOGL_ERROR, "TP-DestAddr has extension. Not handled.\n");
		return NULL;
	}

	if ((data_ptr[3] & 0x0F) == 0) {
		LOGP(DNAT, LOGL_ERROR, "TP-DestAddr is of unknown type.\n");
		return NULL;
	}

	/**
	 * Besides of what I think I read in GSM 03.40 and 04.11 the TP-DA
	 * contains the semi-octets as length (strlen), change it to the
	 * the number of bytes, but then change it back.
	 */
	data_ptr[2] = dest_len;
	gsm48_decode_bcd_number(_dest_nr + 2, ARRAY_SIZE(_dest_nr) - 2,
				&data_ptr[2], 1);
	data_ptr[2] = orig_dest_len;
	if ((data_ptr[3] & 0x70) == 0x10) {
		_dest_nr[0] = _dest_nr[1] = '0';
		dest_nr = &_dest_nr[0];
	} else {
		dest_nr = &_dest_nr[2];
	}

	/**
	 * Call functions to rewrite the data
	 */
	tpdu_hdr = sms_new_tpdu_hdr(nat, imsi, dest_nr, data_ptr[0]);
	new_number = find_new_smsc(nat, msg, imsi, smsc_addr, dest_nr);
	new_dest_nr = sms_new_dest_nr(nat, msg, imsi, dest_nr);

	if (tpdu_hdr == data_ptr[0] && !new_number && !new_dest_nr)
		return NULL;

	out = sms_create_new(GSM411_MT_RP_DATA_MO, ref, hdr48,
			orig_addr_ptr, orig_addr_len,
			new_number ? new_number : smsc_addr,
			data_ptr, data_len, tpdu_hdr,
			dest_len, new_dest_nr);
	talloc_free(new_number);
	talloc_free(new_dest_nr);
	return out;
}

struct msgb *bsc_nat_rewrite_msg(struct bsc_nat *nat, struct msgb *msg, struct bsc_nat_parsed *parsed, const char *imsi)
{
	struct gsm48_hdr *hdr48;
	uint32_t len;
	uint8_t msg_type, proto;
	struct msgb *new_msg = NULL, *sccp;
	uint8_t link_id;

	if (!imsi || strlen(imsi) < 5)
		return msg;

	/* only care about DTAP messages */
	if (parsed->bssap != BSSAP_MSG_DTAP)
		return msg;
	if (!parsed->dest_local_ref)
		return msg;

	hdr48 = bsc_unpack_dtap(parsed, msg, &len);
	if (!hdr48)
		return msg;

	link_id = msg->l3h[1];
	proto = hdr48->proto_discr & 0x0f;
	msg_type = hdr48->msg_type & 0xbf;

	if (proto == GSM48_PDISC_CC && msg_type == GSM48_MT_CC_SETUP)
		new_msg = rewrite_setup(nat, msg, parsed, imsi, hdr48, len);
	else if (proto == GSM48_PDISC_SMS && msg_type == GSM411_MT_CP_DATA)
		new_msg = rewrite_sms(nat, msg, parsed, imsi, hdr48, len);

	if (!new_msg)
		return msg;

	/* wrap with DTAP, SCCP, then IPA. TODO: Stop copying */
	gsm0808_prepend_dtap_header(new_msg, link_id);
	sccp = sccp_create_dt1(parsed->dest_local_ref, new_msg->data, new_msg->len);
	talloc_free(new_msg);

	if (!sccp) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate.\n");
		return msg;
	}

	ipaccess_prepend_header(sccp, IPAC_PROTO_SCCP);

	/* the parsed hangs off from msg but it needs to survive */
	talloc_steal(sccp, parsed);
	msgb_free(msg);
	return sccp;
}

static void num_rewr_free_data(struct bsc_nat_num_rewr_entry *entry)
{
	regfree(&entry->msisdn_reg);
	regfree(&entry->num_reg);
	talloc_free(entry->replace);
}

void bsc_nat_num_rewr_entry_adapt(void *ctx, struct llist_head *head,
				  const struct osmo_config_list *list)
{
	struct bsc_nat_num_rewr_entry *entry, *tmp;
	struct osmo_config_entry *cfg_entry;

	/* free the old data */
	llist_for_each_entry_safe(entry, tmp, head, list) {
		num_rewr_free_data(entry);
		llist_del(&entry->list);
		talloc_free(entry);
	}


	if (!list)
		return;

	llist_for_each_entry(cfg_entry, &list->entry, list) {
		char *regexp;
		if (cfg_entry->text[0] == '+') {
			LOGP(DNAT, LOGL_ERROR,
				"Plus is not allowed in the number\n");
			continue;
		}

		entry = talloc_zero(ctx, struct bsc_nat_num_rewr_entry);
		if (!entry) {
			LOGP(DNAT, LOGL_ERROR,
				"Allocation of the num_rewr entry failed.\n");
			continue;
		}

		entry->replace = talloc_strdup(entry, cfg_entry->text);
		if (!entry->replace) {
			LOGP(DNAT, LOGL_ERROR,
				"Failed to copy the replacement text.\n");
			talloc_free(entry);
			continue;
		}

		if (strcmp("prefix_lookup", entry->replace) == 0)
			entry->is_prefix_lookup = 1;

		/* we will now build a regexp string */
		if (cfg_entry->mcc[0] == '^') {
			regexp = talloc_strdup(entry, cfg_entry->mcc);
		} else {
			regexp = talloc_asprintf(entry, "^%s%s",
					cfg_entry->mcc[0] == '*' ?
						"[0-9][0-9][0-9]" : cfg_entry->mcc,
					cfg_entry->mnc[0] == '*' ?
						"[0-9][0-9]" : cfg_entry->mnc);
		}

		if (!regexp) {
			LOGP(DNAT, LOGL_ERROR, "Failed to create a regexp string.\n");
			talloc_free(entry);
			continue;
		}

		if (regcomp(&entry->msisdn_reg, regexp, 0) != 0) {
			LOGP(DNAT, LOGL_ERROR,
				"Failed to compile regexp '%s'\n", regexp);
			talloc_free(regexp);
			talloc_free(entry);
			continue;
		}

		talloc_free(regexp);
		if (regcomp(&entry->num_reg, cfg_entry->option, REG_EXTENDED) != 0) {
			LOGP(DNAT, LOGL_ERROR,
				"Failed to compile regexp '%s'\n", cfg_entry->option);
			regfree(&entry->msisdn_reg);
			talloc_free(entry);
			continue;
		}

		/* we have copied the number */
		llist_add_tail(&entry->list, head);
	}
}
