summaryrefslogtreecommitdiffstats
path: root/ip6tables-restore.c
diff options
context:
space:
mode:
authorlaforge <laforge>2001-02-27 09:59:48 +0000
committerlaforge <laforge>2001-02-27 09:59:48 +0000
commit0b536d78246f10e875c1977555f12985c56fa7c5 (patch)
tree829cc5e0c13154703fc385ff4618e76bdbce94d5 /ip6tables-restore.c
parent9a429943c16c491ba867ef7db1d64078dea645e9 (diff)
forgot to add those two...
Diffstat (limited to 'ip6tables-restore.c')
-rw-r--r--ip6tables-restore.c299
1 files changed, 299 insertions, 0 deletions
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;
+}