/* Code to restore the iptables state, from file by ip6tables-save. 
 * Author:  Andras Kis-Szabo <kisza@sch.bme.hu>
 *
 * based on iptables-restore
 * Authors:
 * 	Harald Welte <laforge@gnumonks.org>
 * 	Rusty Russell <rusty@linuxcare.com.au>
 *
 */

#include <getopt.h>
#include <sys/errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "ip6tables.h"
#include "libiptc/libip6tc.h"

#ifdef DEBUG
#define DEBUGP(x, args...) fprintf(stderr, x, ## args)
#else
#define DEBUGP(x, args...) 
#endif

extern int for_each_chain(int (*fn)(const ip6t_chainlabel, int, ip6tc_handle_t *), int verbose, int builtinstoo, ip6tc_handle_t *handle);
extern int flush_entries(const ip6t_chainlabel chain, int verbose, ip6tc_handle_t *handle);
extern int delete_chain(const ip6t_chainlabel chain, int verbose, ip6tc_handle_t *handle);

static int binary = 0, counters = 0, verbose = 0, noflush = 0;

/* Keeping track of external matches and targets.  */
static struct option options[] = {
	{ "binary", 0, 0, 'b' },
	{ "counters", 0, 0, 'c' },
/*	{ "verbose", 1, 0, 'v' }, */
	{ "help", 0, 0, 'h' },
	{ "noflush", 0, 0, 'n'},
	{ "modprobe", 1, 0, 'M'},
	{ 0 }
};

static void print_usage(const char *name, const char *version) __attribute__((noreturn));

static void print_usage(const char *name, const char *version)
{
	fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-h]\n"
			"	   [ --binary ]\n"
			"	   [ --counters ]\n"
			"	   [ --verbose ]\n"
			"	   [ --help ]\n"
			"	   [ --noflush ]\n"
		        "          [ --modprobe=<command>]\n", name);
		
	exit(1);
}

ip6tc_handle_t create_handle(const char *tablename, const char* modprobe)
{
	ip6tc_handle_t handle;

	handle = ip6tc_init(tablename);

	if (!handle) {
                /* try to insmod the module if iptc_init failed */
                ip6tables_insmod("ip6_tables", modprobe);
                handle = ip6tc_init(tablename);
	}

	if (!handle) {
		exit_error(PARAMETER_PROBLEM, "%s: unable to initialize"
			"table '%s'\n", program_name, tablename);
		exit(1);
	}
	return handle;
}

int parse_counters(char *string, struct ip6t_counters *ctr)
{
	return (sscanf(string, "[%llu:%llu]", &ctr->pcnt, &ctr->bcnt) == 2);
}

int main(int argc, char *argv[])
{
	ip6tc_handle_t handle;
	char buffer[10240];
	unsigned int line = 0;
	int c;
	char curtable[IP6T_TABLE_MAXNAMELEN + 1];
	char curchain[IP6T_FUNCTION_MAXNAMELEN + 1];
	FILE *in;
	const char *modprobe = 0;

	program_name = "ip6tables-restore";
	program_version = NETFILTER_VERSION;

#ifdef NO_SHARED_LIBS
	init_extensions();
#endif

	while ((c = getopt_long(argc, argv, "bcvhnM:", options, NULL)) != -1) {
		switch (c) {
			case 'b':
				binary = 1;
				break;
			case 'c':
				counters = 1;
				break;
			case 'h':
				print_usage("ip6tables-restore",
					    NETFILTER_VERSION);
				break;
			case 'n':
				noflush = 1;
				break;
			case 'M':
				modprobe = optarg;
				break;
		}
	}
	
	if (optind == argc - 1) {
		in = fopen(argv[optind], "r");
		if (!in) {
			fprintf(stderr, "Can't open %s: %s", argv[optind],
				strerror(errno));
			exit(1);
		}
	}
	else if (optind < argc) {
		fprintf(stderr, "Unknown arguments found on commandline");
		exit(1);
	}
	else in = stdin;
/*
	handle = iptc_init("filter");
	if (!handle)
		exit_error(VERSION_PROBLEM,
			   "can't initialize iptables-restore: %s",
			   iptc_strerror(errno));

	if (!clean_slate(&handle))
		exit_error(OTHER_PROBLEM, "Deleting old chains: %s",
			   iptc_strerror(errno));
*/
	/* Grab standard input. */
	while (fgets(buffer, sizeof(buffer), in)) {
		int ret;

		line++;
		if (buffer[0] == '\n') continue;
		else if (buffer[0] == '#') {
			if (verbose) fputs(buffer, stdout);
			continue;
		} else if (strcmp(buffer, "COMMIT\n") == 0) {
			DEBUGP("Calling commit\n");
			ret = ip6tc_commit(&handle);
		} else if (buffer[0] == '*') {
			/* New table */
			char *table;

			table = strtok(buffer+1, " \t\n");
			DEBUGP("line %u, table '%s'\n", line, table);
			if (!table) {
				exit_error(PARAMETER_PROBLEM, 
					"%s: line %u table name invalid\n",
					program_name, line);
				exit(1);
			}
			strncpy(curtable, table, IP6T_TABLE_MAXNAMELEN);

			handle = create_handle(table, modprobe);
			if (noflush == 0) {
				DEBUGP("Cleaning all chains of table '%s'\n",
					table);
				for_each_chain(flush_entries, verbose, 1, 
						&handle);
	
				DEBUGP("Deleting all user-defined chains "
				       "of table '%s'\n", table);
				for_each_chain(delete_chain, verbose, 0, 
						&handle) ;
			}

			ret = 1;

		} else if (buffer[0] == ':') {
			/* New chain. */
			char *policy, *chain;

			chain = strtok(buffer+1, " \t\n");
			DEBUGP("line %u, chain '%s'\n", line, chain);
			if (!chain) {
				exit_error(PARAMETER_PROBLEM,
					   "%s: line %u chain name invalid\n",
					   program_name, line);
				exit(1);
			}
			strncpy(curchain, chain, IP6T_FUNCTION_MAXNAMELEN);

			/* why the f... does iptc_builtin not work here ? */
			/* FIXME: abort if chain creation fails --RR */
//			if (!iptc_builtin(curchain, &handle)) {
				DEBUGP("Creating new chain '%s'\n", curchain);
				if (!ip6tc_create_chain(curchain, &handle))
				DEBUGP("unable to create chain '%s':%s\n", curchain,
					strerror(errno));
//			}

			policy = strtok(NULL, " \t\n");
			DEBUGP("line %u, policy '%s'\n", line, policy);
			if (!policy) {
				exit_error(PARAMETER_PROBLEM,
					   "%s: line %u policy invalid\n",
					   program_name, line);
				exit(1);
			}

			if (strcmp(policy, "-") != 0) {
				struct ip6t_counters count;

				if (counters) {
					char *ctrs;
					ctrs = strtok(NULL, " \t\n");

					parse_counters(ctrs, &count);

				} else {
					memset(&count, 0, 
					       sizeof(struct ip6t_counters));
				}

				DEBUGP("Setting policy of chain %s to %s\n",
					chain, policy);

				if (!ip6tc_set_policy(chain, policy, &count,
						     &handle))
					exit_error(OTHER_PROBLEM,
						"Can't set policy `%s'"
						" on `%s' line %u: %s\n",
						chain, policy, line,
						ip6tc_strerror(errno));
			}

			ret = 1;

		} else {
			char *newargv[1024];
			int i,a, argvsize;
			char *ptr = buffer;
			char *pcnt = NULL;
			char *bcnt = NULL;

			if (buffer[0] == '[') {
				ptr = strchr(buffer, ']');
				if (!ptr)
					exit_error(PARAMETER_PROBLEM,
						   "Bad line %u: need ]\n",
						   line);
				pcnt = strtok(buffer+1, ":");
				bcnt = strtok(NULL, "]");
			} 

			newargv[0] = argv[0];
			newargv[1] = "-t";
			newargv[2] = (char *) &curtable;
			newargv[3] = "-A";
			newargv[4] = (char *) &curchain;
			argvsize = 5;

			if (counters && pcnt && bcnt) {
				newargv[5] = "--set-counters";
				newargv[6] = (char *) pcnt;
				newargv[7] = (char *) bcnt;
				argvsize = 8;
			}
				
			// strtok initcialize!
			if ( buffer[0]!='[' )
			{
				if (!(newargv[argvsize] = strtok(buffer, " \t\n")))
					goto ImLaMeR;
					//break;
				argvsize++;
			}

			/* strtok: a function only a coder could love */
			for (i = argvsize; i < sizeof(newargv)/sizeof(char *); 
					i++) {
				if (!(newargv[i] = strtok(NULL, " \t\n")))
					break;
				ptr = NULL;
			}
ImLaMeR:		if (i == sizeof(newargv)/sizeof(char *)) {
				fprintf(stderr,
					"%s: line %u too many arguments\n",
					program_name, line);
				exit(1);
			}

			DEBUGP("===>calling do_command6(%u, argv, &%s, handle):\n",
					i, curtable);

			for (a = 0; a <= i; a++)
				DEBUGP("argv[%u]: %s\n", a, newargv[a]);

			ret = do_command6(i, newargv, &newargv[2], &handle);
		}
		if (!ret) {
			fprintf(stderr, "%s: line %u failed\n",
					program_name, line);
			exit(1);
		}
	}

	return 0;
}
