/*
 * (C) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>
 *
 * 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.
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <iptables.h>
#include <time.h>
#include "xtables-multi.h"
#include "nft.h"

#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
#include <iptables.h>
#include <xtables.h>
#include <libiptc/libxtc.h>
#include <fcntl.h>
#include <getopt.h>
#include "xshared.h"
#include "nft-shared.h"

void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname,
		  bool invert)
{
	char iface[IFNAMSIZ];
	int ifaclen;

	if (ifname[0] == '\0')
		return;

	strcpy(iface, ifname);
	ifaclen = strlen(iface);
	if (iface[ifaclen - 1] == '+')
		iface[ifaclen - 1] = '*';

	xt_xlate_add(xl, "%s %s%s ", nftmeta, invert ? "!= " : "", iface);
}

int xlate_action(const struct iptables_command_state *cs, bool goto_set,
		 struct xt_xlate *xl)
{
	int ret = 1, numeric = cs->options & OPT_NUMERIC;

	/* If no target at all, add nothing (default to continue) */
	if (cs->target != NULL) {
		/* Standard target? */
		if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0)
			xt_xlate_add(xl, "accept");
		else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0)
			xt_xlate_add(xl, "drop");
		else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0)
			xt_xlate_add(xl, "return");
		else if (cs->target->xlate) {
			struct xt_xlate_tg_params params = {
				.ip		= (const void *)&cs->fw,
				.target		= cs->target->t,
				.numeric	= numeric,
				.escape_quotes	= !cs->restore,
			};
			ret = cs->target->xlate(xl, &params);
		}
		else
			return 0;
	} else if (strlen(cs->jumpto) > 0) {
		/* Not standard, then it's a go / jump to chain */
		if (goto_set)
			xt_xlate_add(xl, "goto %s", cs->jumpto);
		else
			xt_xlate_add(xl, "jump %s", cs->jumpto);
	}

	return ret;
}

int xlate_matches(const struct iptables_command_state *cs, struct xt_xlate *xl)
{
	struct xtables_rule_match *matchp;
	int ret = 1, numeric = cs->options & OPT_NUMERIC;

	for (matchp = cs->matches; matchp; matchp = matchp->next) {
		struct xt_xlate_mt_params params = {
			.ip		= (const void *)&cs->fw,
			.match		= matchp->match->m,
			.numeric	= numeric,
			.escape_quotes	= !cs->restore,
		};

		if (!matchp->match->xlate)
			return 0;

		ret = matchp->match->xlate(xl, &params);

		if (strcmp(matchp->match->name, "comment") != 0)
			xt_xlate_add(xl, " ");

		if (!ret)
			break;
	}
	return ret;
}

bool xlate_find_match(const struct iptables_command_state *cs, const char *p_name)
{
	struct xtables_rule_match *matchp;

	/* Skip redundant protocol, eg. ip protocol tcp tcp dport */
	for (matchp = cs->matches; matchp; matchp = matchp->next) {
		if (strcmp(matchp->match->name, p_name) == 0)
			return true;
	}
	return false;
}

const char *family2str[] = {
	[NFPROTO_IPV4]	= "ip",
	[NFPROTO_IPV6]	= "ip6",
};

static int nft_rule_xlate_add(struct nft_handle *h,
			      const struct nft_xt_cmd_parse *p,
			      const struct iptables_command_state *cs,
			      bool append)
{
	struct xt_xlate *xl = xt_xlate_alloc(10240);
	int ret;

	if (append) {
		xt_xlate_add(xl, "add rule %s %s %s ",
			   family2str[h->family], p->table, p->chain);
	} else {
		xt_xlate_add(xl, "insert rule %s %s %s ",
			   family2str[h->family], p->table, p->chain);
	}

	ret = h->ops->xlate(cs, xl);
	if (ret)
		printf("%s\n", xt_xlate_get(xl));

	xt_xlate_free(xl);
	return ret;
}

static int xlate(struct nft_handle *h, struct nft_xt_cmd_parse *p,
		 struct iptables_command_state *cs,
		 struct xtables_args *args, bool append,
		 int (*cb)(struct nft_handle *h,
			   const struct nft_xt_cmd_parse *p,
			   const struct iptables_command_state *cs,
			   bool append))
{
	unsigned int i, j;
	int ret = 1;

	for (i = 0; i < args->s.naddrs; i++) {
		switch (h->family) {
		case AF_INET:
			cs->fw.ip.src.s_addr = args->s.addr.v4[i].s_addr;
			cs->fw.ip.smsk.s_addr = args->s.mask.v4[i].s_addr;
			for (j = 0; j < args->d.naddrs; j++) {
				cs->fw.ip.dst.s_addr =
					args->d.addr.v4[j].s_addr;
				cs->fw.ip.dmsk.s_addr =
					args->d.mask.v4[j].s_addr;
				ret = cb(h, p, cs, append);
			}
			break;
		case AF_INET6:
			memcpy(&cs->fw6.ipv6.src,
			       &args->s.addr.v6[i], sizeof(struct in6_addr));
			memcpy(&cs->fw6.ipv6.smsk,
			       &args->s.mask.v6[i], sizeof(struct in6_addr));
			for (j = 0; j < args->d.naddrs; j++) {
				memcpy(&cs->fw6.ipv6.dst,
				       &args->d.addr.v6[j],
				       sizeof(struct in6_addr));
				memcpy(&cs->fw6.ipv6.dmsk,
				       &args->d.mask.v6[j],
				       sizeof(struct in6_addr));
				ret = cb(h, p, cs, append);
			}
			break;
		}
	}

	return ret;
}

static void print_ipt_cmd(int argc, char *argv[])
{
	int i;

	printf("# ");
	for (i = 1; i < argc; i++)
		printf("%s ", argv[i]);

	printf("\n");
}

static int do_command_xlate(struct nft_handle *h, int argc, char *argv[],
			    char **table, bool restore)
{
	int ret = 0;
	struct nft_xt_cmd_parse p = {
		.table		= *table,
		.restore	= restore,
	};
	struct iptables_command_state cs;
	struct xtables_args args = {
		.family = h->family,
	};

	do_parse(h, argc, argv, &p, &cs, &args);

	cs.restore = restore;

	if (!restore)
		printf("nft ");

	switch (p.command) {
	case CMD_APPEND:
		ret = 1;
		if (!xlate(h, &p, &cs, &args, true, nft_rule_xlate_add)) {
			print_ipt_cmd(argc, argv);
		}
		break;
	case CMD_DELETE:
		break;
	case CMD_DELETE_NUM:
		break;
	case CMD_CHECK:
		break;
	case CMD_REPLACE:
		break;
	case CMD_INSERT:
		ret = 1;
		if (!xlate(h, &p, &cs, &args, false, nft_rule_xlate_add)) {
			print_ipt_cmd(argc, argv);
		}
		break;
	case CMD_FLUSH:
		if (p.chain) {
			printf("flush chain %s %s %s\n",
				family2str[h->family], p.table, p.chain);
		} else {
			printf("flush table %s %s\n",
				family2str[h->family], p.table);
		}
		ret = 1;
		break;
	case CMD_ZERO:
		break;
	case CMD_ZERO_NUM:
		break;
	case CMD_LIST:
	case CMD_LIST|CMD_ZERO:
	case CMD_LIST|CMD_ZERO_NUM:
		printf("list table %s %s\n",
		       family2str[h->family], p.table);
		ret = 1;
		break;
	case CMD_LIST_RULES:
	case CMD_LIST_RULES|CMD_ZERO:
	case CMD_LIST_RULES|CMD_ZERO_NUM:
		break;
	case CMD_NEW_CHAIN:
		printf("add chain %s %s %s\n",
		       family2str[h->family], p.table, p.chain);
		ret = 1;
		break;
	case CMD_DELETE_CHAIN:
		printf("delete chain %s %s %s\n",
		       family2str[h->family], p.table, p.chain);
		ret = 1;
		break;
	case CMD_RENAME_CHAIN:
		break;
	case CMD_SET_POLICY:
		break;
	default:
		/* We should never reach this... */
		printf("Unsupported command?\n");
		exit(1);
	}

	xtables_rule_matches_free(&cs.matches);

	if (h->family == AF_INET) {
		free(args.s.addr.v4);
		free(args.s.mask.v4);
		free(args.d.addr.v4);
		free(args.d.mask.v4);
	} else if (h->family == AF_INET6) {
		free(args.s.addr.v6);
		free(args.s.mask.v6);
		free(args.d.addr.v6);
		free(args.d.mask.v6);
	}
	xtables_free_opts(1);

	return ret;
}

static void print_usage(const char *name, const char *version)
{
	fprintf(stderr, "%s %s "
			"(c) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>\n"
			"Usage: %s [-h] [-f]\n"
                        "	[ --help ]\n"
                        "	[ --file=<FILE> ]\n", name, version, name);
        exit(1);
}

static const struct option options[] = {
	{ .name = "help",	.has_arg = false,	.val = 'h' },
	{ .name = "file",	.has_arg = true,	.val = 'f' },
	{ NULL },
};

static int xlate_chain_user_add(struct nft_handle *h, const char *chain,
				const char *table)
{
	printf("add chain %s %s %s\n", family2str[h->family], table, chain);
	return 0;
}

static int commit(struct nft_handle *h)
{
	return 1;
}

static void xlate_table_new(struct nft_handle *h, const char *table)
{
	printf("add table %s %s\n", family2str[h->family], table);
}

static int xlate_chain_set(struct nft_handle *h, const char *table,
			   const char *chain, const char *policy,
			   const struct xt_counters *counters)
{
	const char *type = "filter";

	if (strcmp(table, "nat") == 0)
		type = "nat";

	printf("add chain %s %s %s { type %s ",
	       family2str[h->family], table, chain, type);
	if (strcmp(chain, "PREROUTING") == 0)
		printf("hook prerouting priority 0; ");
	else if (strcmp(chain, "INPUT") == 0)
		printf("hook input priority 0; ");
	else if (strcmp(chain, "FORWARD") == 0)
		printf("hook forward priority 0; ");
	else if (strcmp(chain, "OUTPUT") == 0)
		printf("hook output priority 0; ");
	else if (strcmp(chain, "POSTROUTING") == 0)
		printf("hook postrouting priority 0; ");

	if (strcmp(policy, "ACCEPT") == 0)
		printf("policy accept; ");
	else if (strcmp(policy, "DROP") == 0)
		printf("policy drop; ");

	printf("}\n");
	return 1;
}

static struct nft_xt_restore_cb cb_xlate = {
	.table_new	= xlate_table_new,
	.chain_set	= xlate_chain_set,
	.chain_user_add	= xlate_chain_user_add,
	.do_command	= do_command_xlate,
	.commit		= commit,
	.abort		= commit,
};

static int xtables_xlate_main(int family, const char *progname, int argc,
			      char *argv[])
{
	int ret;
	char *table = "filter";
	struct nft_handle h = {
		.family = family,
	};

	xtables_globals.program_name = progname;
	ret = xtables_init_all(&xtables_globals, family);
	if (ret < 0) {
		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
				xtables_globals.program_name,
				xtables_globals.program_version);
				exit(1);
	}
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
	init_extensions();
	init_extensions4();
#endif

	if (nft_init(&h, xtables_ipv4) < 0) {
		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
				xtables_globals.program_name,
				xtables_globals.program_version,
				strerror(errno));
		nft_fini(&h);
		exit(EXIT_FAILURE);
	}

	ret = do_command_xlate(&h, argc, argv, &table, false);
	if (!ret)
		fprintf(stderr, "Translation not implemented\n");

	nft_fini(&h);
	exit(!ret);
}

static int xtables_restore_xlate_main(int family, const char *progname,
				      int argc, char *argv[])
{
	int ret;
	struct nft_handle h = {
		.family = family,
	};
	const char *file = NULL;
	struct nft_xt_restore_parse p = {};
	time_t now = time(NULL);
	int c;

	xtables_globals.program_name = progname;
	ret = xtables_init_all(&xtables_globals, family);
	if (ret < 0) {
		fprintf(stderr, "%s/%s Failed to initialize xtables\n",
				xtables_globals.program_name,
				xtables_globals.program_version);
				exit(1);
	}
#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
	init_extensions();
	init_extensions4();
#endif

	if (nft_init(&h, xtables_ipv4) < 0) {
		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
				xtables_globals.program_name,
				xtables_globals.program_version,
				strerror(errno));
		nft_fini(&h);
		exit(EXIT_FAILURE);
	}

	opterr = 0;
	while ((c = getopt_long(argc, argv, "hf:", options, NULL)) != -1) {
		switch (c) {
		case 'h':
			print_usage(argv[0], IPTABLES_VERSION);
			exit(0);
		case 'f':
			file = optarg;
			break;
		}
	}

	if (file == NULL) {
		fprintf(stderr, "ERROR: missing file name\n");
		print_usage(argv[0], IPTABLES_VERSION);
		exit(0);
	}

	p.in = fopen(file, "r");
	if (p.in == NULL) {
		fprintf(stderr, "Cannot open file %s\n", file);
		exit(1);
	}

	printf("# Translated by %s v%s on %s",
	       argv[0], IPTABLES_VERSION, ctime(&now));
	xtables_restore_parse(&h, &p, &cb_xlate, argc, argv);
	printf("# Completed on %s", ctime(&now));

	nft_fini(&h);
	fclose(p.in);
	exit(0);
}

int xtables_ip4_xlate_main(int argc, char *argv[])
{
	return xtables_xlate_main(NFPROTO_IPV4, "iptables-translate",
				  argc, argv);
}

int xtables_ip6_xlate_main(int argc, char *argv[])
{
	return xtables_xlate_main(NFPROTO_IPV6, "ip6tables-translate",
				  argc, argv);
}

int xtables_ip4_xlate_restore_main(int argc, char *argv[])
{
	return xtables_restore_xlate_main(NFPROTO_IPV4,
					  "iptables-translate-restore",
					  argc, argv);
}

int xtables_ip6_xlate_restore_main(int argc, char *argv[])
{
	return xtables_restore_xlate_main(NFPROTO_IPV6,
					  "ip6tables-translate-restore",
					  argc, argv);
}
