forgot to add those two...
diff --git a/ip6tables-restore.c b/ip6tables-restore.c
new file mode 100644
index 0000000..9ebc577
--- /dev/null
+++ b/ip6tables-restore.c
@@ -0,0 +1,299 @@
+/* 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'},
+	{ 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", name);
+		
+	exit(1);
+}
+
+ip6tc_handle_t create_handle(const char *tablename)
+{
+	ip6tc_handle_t handle;
+
+	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;
+
+	program_name = "ip6tables-restore";
+	program_version = NETFILTER_VERSION;
+
+	while ((c = getopt_long(argc, argv, "bcvhn", 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;
+		}
+	}
+	
+	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);
+			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;
+}