/* 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;

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