summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--iptables/Makefile.am6
-rw-r--r--iptables/ip6tables-restore.c391
-rw-r--r--iptables/iptables-restore.c154
3 files changed, 113 insertions, 438 deletions
diff --git a/iptables/Makefile.am b/iptables/Makefile.am
index 581dc32b..a21dadb7 100644
--- a/iptables/Makefile.am
+++ b/iptables/Makefile.am
@@ -13,18 +13,18 @@ if ENABLE_STATIC
xtables_legacy_multi_CFLAGS += -DALL_INCLUSIVE
endif
if ENABLE_IPV4
-xtables_legacy_multi_SOURCES += iptables-save.c iptables-restore.c \
+xtables_legacy_multi_SOURCES += iptables-save.c \
iptables-standalone.c iptables.c
xtables_legacy_multi_CFLAGS += -DENABLE_IPV4
xtables_legacy_multi_LDADD += ../libiptc/libip4tc.la ../extensions/libext4.a
endif
if ENABLE_IPV6
-xtables_legacy_multi_SOURCES += ip6tables-save.c ip6tables-restore.c \
+xtables_legacy_multi_SOURCES += ip6tables-save.c \
ip6tables-standalone.c ip6tables.c
xtables_legacy_multi_CFLAGS += -DENABLE_IPV6
xtables_legacy_multi_LDADD += ../libiptc/libip6tc.la ../extensions/libext6.a
endif
-xtables_legacy_multi_SOURCES += xshared.c
+xtables_legacy_multi_SOURCES += xshared.c iptables-restore.c
xtables_legacy_multi_LDADD += ../libxtables/libxtables.la -lm
# iptables using nf_tables api
diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c
deleted file mode 100644
index 3706b981..00000000
--- a/iptables/ip6tables-restore.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* 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>
- * This code is distributed under the terms of GNU GPL v2
- */
-
-#include <getopt.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "ip6tables.h"
-#include "xshared.h"
-#include "xtables.h"
-#include "libiptc/libip6tc.h"
-#include "ip6tables-multi.h"
-
-static int counters, verbose, noflush, wait;
-
-static struct timeval wait_interval = {
- .tv_sec = 1,
-};
-
-/* Keeping track of external matches and targets. */
-static const struct option options[] = {
- {.name = "counters", .has_arg = 0, .val = 'c'},
- {.name = "verbose", .has_arg = 0, .val = 'v'},
- {.name = "version", .has_arg = 0, .val = 'V'},
- {.name = "test", .has_arg = 0, .val = 't'},
- {.name = "help", .has_arg = 0, .val = 'h'},
- {.name = "noflush", .has_arg = 0, .val = 'n'},
- {.name = "modprobe", .has_arg = 1, .val = 'M'},
- {.name = "table", .has_arg = 1, .val = 'T'},
- {.name = "wait", .has_arg = 2, .val = 'w'},
- {.name = "wait-interval", .has_arg = 2, .val = 'W'},
- {NULL},
-};
-
-#define prog_name ip6tables_globals.program_name
-#define prog_vers ip6tables_globals.program_version
-
-static void print_usage(const char *name, const char *version)
-{
- fprintf(stderr, "Usage: %s [-c] [-v] [-V] [-t] [-h] [-n] [-w secs] [-W usecs] [-T table] [-M command]\n"
- " [ --counters ]\n"
- " [ --verbose ]\n"
- " [ --version]\n"
- " [ --test ]\n"
- " [ --help ]\n"
- " [ --noflush ]\n"
- " [ --wait=<seconds>\n"
- " [ --wait-interval=<usecs>\n"
- " [ --table=<TABLE> ]\n"
- " [ --modprobe=<command> ]\n", name);
-}
-
-static struct xtc_handle *create_handle(const char *tablename)
-{
- struct xtc_handle *handle;
-
- handle = ip6tc_init(tablename);
-
- if (!handle) {
- /* try to insmod the module if iptc_init failed */
- xtables_load_ko(xtables_modprobe_program, false);
- handle = ip6tc_init(tablename);
- }
-
- if (!handle) {
- xtables_error(PARAMETER_PROBLEM, "%s: unable to initialize "
- "table '%s'\n", prog_name, tablename);
- exit(1);
- }
- return handle;
-}
-
-int ip6tables_restore_main(int argc, char *argv[])
-{
- struct xtc_handle *handle = NULL;
- char buffer[10240];
- int c, lock;
- char curtable[XT_TABLE_MAXNAMELEN + 1] = {};
- FILE *in;
- int in_table = 0, testing = 0;
- const char *tablename = NULL;
- const struct xtc_ops *ops = &ip6tc_ops;
-
- line = 0;
- lock = XT_LOCK_NOT_ACQUIRED;
-
- ip6tables_globals.program_name = "ip6tables-restore";
- c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
- if (c < 0) {
- fprintf(stderr, "%s/%s Failed to initialize xtables\n",
- ip6tables_globals.program_name,
- ip6tables_globals.program_version);
- exit(1);
- }
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions6();
-#endif
-
- while ((c = getopt_long(argc, argv, "bcvVthnwWM:T:", options, NULL)) != -1) {
- switch (c) {
- case 'b':
- fprintf(stderr, "-b/--binary option is not implemented\n");
- break;
- case 'c':
- counters = 1;
- break;
- case 'v':
- verbose = 1;
- break;
- case 'V':
- printf("%s v%s (legacy)\n", prog_name, prog_vers);
- exit(0);
- case 't':
- testing = 1;
- break;
- case 'h':
- print_usage("ip6tables-restore",
- IPTABLES_VERSION);
- exit(0);
- case 'n':
- noflush = 1;
- break;
- case 'w':
- wait = parse_wait_time(argc, argv);
- break;
- case 'W':
- parse_wait_interval(argc, argv, &wait_interval);
- break;
- case 'M':
- xtables_modprobe_program = optarg;
- break;
- case 'T':
- tablename = optarg;
- break;
- default:
- fprintf(stderr,
- "Try `ip6tables-restore -h' for more information.\n");
- exit(1);
- }
- }
-
- if (optind == argc - 1) {
- in = fopen(argv[optind], "re");
- if (!in) {
- fprintf(stderr, "Can't open %s: %s\n", argv[optind],
- strerror(errno));
- exit(1);
- }
- }
- else if (optind < argc) {
- fprintf(stderr, "Unknown arguments found on commandline\n");
- exit(1);
- }
- else in = stdin;
-
- if (!wait_interval.tv_sec && !wait) {
- fprintf(stderr, "Option --wait-interval requires option --wait\n");
- exit(1);
- }
-
- /* Grab standard input. */
- while (fgets(buffer, sizeof(buffer), in)) {
- int ret = 0;
-
- line++;
- if (buffer[0] == '\n')
- continue;
- else if (buffer[0] == '#') {
- if (verbose)
- fputs(buffer, stdout);
- continue;
- } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) {
- if (!testing) {
- DEBUGP("Calling commit\n");
- ret = ops->commit(handle);
- ops->free(handle);
- handle = NULL;
- } else {
- DEBUGP("Not calling commit, testing\n");
- ret = 1;
- }
-
- /* Done with the current table, release the lock. */
- if (lock >= 0) {
- xtables_unlock(lock);
- lock = XT_LOCK_NOT_ACQUIRED;
- }
-
- in_table = 0;
- } else if ((buffer[0] == '*') && (!in_table)) {
- /* Acquire a lock before we create a new table handle */
- lock = xtables_lock_or_exit(wait, &wait_interval);
-
- /* New table */
- char *table;
-
- table = strtok(buffer+1, " \t\n");
- DEBUGP("line %u, table '%s'\n", line, table);
- if (!table) {
- xtables_error(PARAMETER_PROBLEM,
- "%s: line %u table name invalid\n",
- xt_params->program_name, line);
- exit(1);
- }
- strncpy(curtable, table, XT_TABLE_MAXNAMELEN);
- curtable[XT_TABLE_MAXNAMELEN] = '\0';
-
- if (tablename != NULL && strcmp(tablename, table) != 0) {
- if (lock >= 0) {
- xtables_unlock(lock);
- lock = XT_LOCK_NOT_ACQUIRED;
- }
- continue;
- }
- if (handle)
- ops->free(handle);
-
- handle = create_handle(table);
- if (noflush == 0) {
- DEBUGP("Cleaning all chains of table '%s'\n",
- table);
- for_each_chain6(flush_entries6, verbose, 1,
- handle);
-
- DEBUGP("Deleting all user-defined chains "
- "of table '%s'\n", table);
- for_each_chain6(delete_chain6, verbose, 0,
- handle);
- }
-
- ret = 1;
- in_table = 1;
-
- } else if ((buffer[0] == ':') && (in_table)) {
- /* New chain. */
- char *policy, *chain;
-
- chain = strtok(buffer+1, " \t\n");
- DEBUGP("line %u, chain '%s'\n", line, chain);
- if (!chain) {
- xtables_error(PARAMETER_PROBLEM,
- "%s: line %u chain name invalid\n",
- xt_params->program_name, line);
- exit(1);
- }
-
- if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
- xtables_error(PARAMETER_PROBLEM,
- "Invalid chain name `%s' "
- "(%u chars max)",
- chain, XT_EXTENSION_MAXNAMELEN - 1);
-
- if (ops->builtin(chain, handle) <= 0) {
- if (noflush && ops->is_chain(chain, handle)) {
- DEBUGP("Flushing existing user defined chain '%s'\n", chain);
- if (!ops->flush_entries(chain, handle))
- xtables_error(PARAMETER_PROBLEM,
- "error flushing chain "
- "'%s':%s\n", chain,
- strerror(errno));
- } else {
- DEBUGP("Creating new chain '%s'\n", chain);
- if (!ops->create_chain(chain, handle))
- xtables_error(PARAMETER_PROBLEM,
- "error creating chain "
- "'%s':%s\n", chain,
- strerror(errno));
- }
- }
-
- policy = strtok(NULL, " \t\n");
- DEBUGP("line %u, policy '%s'\n", line, policy);
- if (!policy) {
- xtables_error(PARAMETER_PROBLEM,
- "%s: line %u policy invalid\n",
- xt_params->program_name, line);
- exit(1);
- }
-
- if (strcmp(policy, "-") != 0) {
- struct xt_counters count = {};
-
- if (counters) {
- char *ctrs;
- ctrs = strtok(NULL, " \t\n");
-
- if (!ctrs || !parse_counters(ctrs, &count))
- xtables_error(PARAMETER_PROBLEM,
- "invalid policy counters "
- "for chain '%s'\n", chain);
- }
-
- DEBUGP("Setting policy of chain %s to %s\n",
- chain, policy);
-
- if (!ops->set_policy(chain, policy, &count,
- handle))
- xtables_error(OTHER_PROBLEM,
- "Can't set policy `%s'"
- " on `%s' line %u: %s\n",
- policy, chain, line,
- ops->strerror(errno));
- }
-
- ret = 1;
-
- } else if (in_table) {
- int a;
- char *pcnt = NULL;
- char *bcnt = NULL;
- char *parsestart;
-
- if (buffer[0] == '[') {
- /* we have counters in our input */
- char *ptr = strchr(buffer, ']');
-
- if (!ptr)
- xtables_error(PARAMETER_PROBLEM,
- "Bad line %u: need ]\n",
- line);
-
- pcnt = strtok(buffer+1, ":");
- if (!pcnt)
- xtables_error(PARAMETER_PROBLEM,
- "Bad line %u: need :\n",
- line);
-
- bcnt = strtok(NULL, "]");
- if (!bcnt)
- xtables_error(PARAMETER_PROBLEM,
- "Bad line %u: need ]\n",
- line);
-
- /* start command parsing after counter */
- parsestart = ptr + 1;
- } else {
- /* start command parsing at start of line */
- parsestart = buffer;
- }
-
- add_argv(argv[0], 0);
- add_argv("-t", 0);
- add_argv(curtable, 0);
-
- if (counters && pcnt && bcnt) {
- add_argv("--set-counters", 0);
- add_argv((char *) pcnt, 0);
- add_argv((char *) bcnt, 0);
- }
-
- add_param_to_argv(parsestart, line);
-
- DEBUGP("calling do_command6(%u, argv, &%s, handle):\n",
- newargc, curtable);
-
- for (a = 0; a < newargc; a++)
- DEBUGP("argv[%u]: %s\n", a, newargv[a]);
-
- ret = do_command6(newargc, newargv,
- &newargv[2], &handle, true);
-
- free_argv();
- fflush(stdout);
- }
- if (tablename != NULL && strcmp(tablename, curtable) != 0)
- continue;
- if (!ret) {
- fprintf(stderr, "%s: line %u failed\n",
- xt_params->program_name, line);
- exit(1);
- }
- }
- if (in_table) {
- fprintf(stderr, "%s: COMMIT expected at line %u\n",
- xt_params->program_name, line + 1);
- exit(1);
- }
-
- fclose(in);
- return 0;
-}
diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
index daee5fd9..575e619c 100644
--- a/iptables/iptables-restore.c
+++ b/iptables/iptables-restore.c
@@ -12,10 +12,13 @@
#include <stdio.h>
#include <stdlib.h>
#include "iptables.h"
+#include "ip6tables.h"
#include "xshared.h"
#include "xtables.h"
#include "libiptc/libiptc.h"
+#include "libiptc/libip6tc.h"
#include "iptables-multi.h"
+#include "ip6tables-multi.h"
static int counters, verbose, noflush, wait;
@@ -38,9 +41,6 @@ static const struct option options[] = {
{NULL},
};
-#define prog_name iptables_globals.program_name
-#define prog_vers iptables_globals.program_version
-
static void print_usage(const char *name, const char *version)
{
fprintf(stderr, "Usage: %s [-c] [-v] [-V] [-t] [-h] [-n] [-w secs] [-W usecs] [-T table] [-M command]\n"
@@ -56,28 +56,42 @@ static void print_usage(const char *name, const char *version)
" [ --modprobe=<command> ]\n", name);
}
-static struct xtc_handle *create_handle(const char *tablename)
+struct iptables_restore_cb {
+ const struct xtc_ops *ops;
+
+ int (*for_each_chain)(int (*fn)(const xt_chainlabel,
+ int, struct xtc_handle *),
+ int verbose, int builtinstoo,
+ struct xtc_handle *handle);
+ int (*flush_entries)(const xt_chainlabel, int, struct xtc_handle *);
+ int (*delete_chain)(const xt_chainlabel, int, struct xtc_handle *);
+ int (*do_command)(int argc, char *argv[], char **table,
+ struct xtc_handle **handle, bool restore);
+};
+
+static struct xtc_handle *
+create_handle(struct iptables_restore_cb *cb, const char *tablename)
{
struct xtc_handle *handle;
- handle = iptc_init(tablename);
+ handle = cb->ops->init(tablename);
if (!handle) {
/* try to insmod the module if iptc_init failed */
xtables_load_ko(xtables_modprobe_program, false);
- handle = iptc_init(tablename);
+ handle = cb->ops->init(tablename);
}
if (!handle) {
xtables_error(PARAMETER_PROBLEM, "%s: unable to initialize "
- "table '%s'\n", prog_name, tablename);
+ "table '%s'\n", xt_params->program_name, tablename);
exit(1);
}
return handle;
}
-int
-iptables_restore_main(int argc, char *argv[])
+static int
+ip46tables_restore_main(struct iptables_restore_cb *cb, int argc, char *argv[])
{
struct xtc_handle *handle = NULL;
char buffer[10240];
@@ -86,24 +100,10 @@ iptables_restore_main(int argc, char *argv[])
FILE *in;
int in_table = 0, testing = 0;
const char *tablename = NULL;
- const struct xtc_ops *ops = &iptc_ops;
line = 0;
lock = XT_LOCK_NOT_ACQUIRED;
- iptables_globals.program_name = "iptables-restore";
- c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
- if (c < 0) {
- fprintf(stderr, "%s/%s Failed to initialize xtables\n",
- iptables_globals.program_name,
- iptables_globals.program_version);
- exit(1);
- }
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
- init_extensions();
- init_extensions4();
-#endif
-
while ((c = getopt_long(argc, argv, "bcvVthnwWM:T:", options, NULL)) != -1) {
switch (c) {
case 'b':
@@ -116,13 +116,15 @@ iptables_restore_main(int argc, char *argv[])
verbose = 1;
break;
case 'V':
- printf("%s v%s (legacy)\n", prog_name, prog_vers);
+ printf("%s v%s (legacy)\n",
+ xt_params->program_name,
+ xt_params->program_version);
exit(0);
case 't':
testing = 1;
break;
case 'h':
- print_usage("iptables-restore",
+ print_usage(xt_params->program_name,
IPTABLES_VERSION);
exit(0);
case 'n':
@@ -142,7 +144,8 @@ iptables_restore_main(int argc, char *argv[])
break;
default:
fprintf(stderr,
- "Try `iptables-restore -h' for more information.\n");
+ "Try `%s -h' for more information.\n",
+ xt_params->program_name);
exit(1);
}
}
@@ -180,8 +183,8 @@ iptables_restore_main(int argc, char *argv[])
} else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) {
if (!testing) {
DEBUGP("Calling commit\n");
- ret = ops->commit(handle);
- ops->free(handle);
+ ret = cb->ops->commit(handle);
+ cb->ops->free(handle);
handle = NULL;
} else {
DEBUGP("Not calling commit, testing\n");
@@ -213,7 +216,7 @@ iptables_restore_main(int argc, char *argv[])
strncpy(curtable, table, XT_TABLE_MAXNAMELEN);
curtable[XT_TABLE_MAXNAMELEN] = '\0';
- if (tablename && (strcmp(tablename, table) != 0)) {
+ if (tablename && strcmp(tablename, table) != 0) {
if (lock >= 0) {
xtables_unlock(lock);
lock = XT_LOCK_NOT_ACQUIRED;
@@ -221,18 +224,18 @@ iptables_restore_main(int argc, char *argv[])
continue;
}
if (handle)
- ops->free(handle);
+ cb->ops->free(handle);
- handle = create_handle(table);
+ handle = create_handle(cb, table);
if (noflush == 0) {
DEBUGP("Cleaning all chains of table '%s'\n",
table);
- for_each_chain4(flush_entries4, verbose, 1,
+ cb->for_each_chain(cb->flush_entries, verbose, 1,
handle);
DEBUGP("Deleting all user-defined chains "
"of table '%s'\n", table);
- for_each_chain4(delete_chain4, verbose, 0,
+ cb->for_each_chain(cb->delete_chain, verbose, 0,
handle);
}
@@ -258,17 +261,17 @@ iptables_restore_main(int argc, char *argv[])
"(%u chars max)",
chain, XT_EXTENSION_MAXNAMELEN - 1);
- if (ops->builtin(chain, handle) <= 0) {
- if (noflush && ops->is_chain(chain, handle)) {
+ if (cb->ops->builtin(chain, handle) <= 0) {
+ if (noflush && cb->ops->is_chain(chain, handle)) {
DEBUGP("Flushing existing user defined chain '%s'\n", chain);
- if (!ops->flush_entries(chain, handle))
+ if (!cb->ops->flush_entries(chain, handle))
xtables_error(PARAMETER_PROBLEM,
"error flushing chain "
"'%s':%s\n", chain,
strerror(errno));
} else {
DEBUGP("Creating new chain '%s'\n", chain);
- if (!ops->create_chain(chain, handle))
+ if (!cb->ops->create_chain(chain, handle))
xtables_error(PARAMETER_PROBLEM,
"error creating chain "
"'%s':%s\n", chain,
@@ -294,20 +297,20 @@ iptables_restore_main(int argc, char *argv[])
if (!ctrs || !parse_counters(ctrs, &count))
xtables_error(PARAMETER_PROBLEM,
- "invalid policy counters "
- "for chain '%s'\n", chain);
+ "invalid policy counters "
+ "for chain '%s'\n", chain);
}
DEBUGP("Setting policy of chain %s to %s\n",
chain, policy);
- if (!ops->set_policy(chain, policy, &count,
+ if (!cb->ops->set_policy(chain, policy, &count,
handle))
xtables_error(OTHER_PROBLEM,
"Can't set policy `%s'"
" on `%s' line %u: %s\n",
policy, chain, line,
- ops->strerror(errno));
+ cb->ops->strerror(errno));
}
ret = 1;
@@ -358,19 +361,19 @@ iptables_restore_main(int argc, char *argv[])
add_param_to_argv(parsestart, line);
- DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
+ DEBUGP("calling do_command(%u, argv, &%s, handle):\n",
newargc, curtable);
for (a = 0; a < newargc; a++)
DEBUGP("argv[%u]: %s\n", a, newargv[a]);
- ret = do_command4(newargc, newargv,
+ ret = cb->do_command(newargc, newargv,
&newargv[2], &handle, true);
free_argv();
fflush(stdout);
}
- if (tablename && (strcmp(tablename, curtable) != 0))
+ if (tablename && strcmp(tablename, curtable) != 0)
continue;
if (!ret) {
fprintf(stderr, "%s: line %u failed\n",
@@ -387,3 +390,66 @@ iptables_restore_main(int argc, char *argv[])
fclose(in);
return 0;
}
+
+
+#if defined ENABLE_IPV4
+struct iptables_restore_cb ipt_restore_cb = {
+ .ops = &iptc_ops,
+ .for_each_chain = for_each_chain4,
+ .flush_entries = flush_entries4,
+ .delete_chain = delete_chain4,
+ .do_command = do_command4,
+};
+
+int
+iptables_restore_main(int argc, char *argv[])
+{
+ int c;
+
+ iptables_globals.program_name = "iptables-restore";
+ c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
+ if (c < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+ iptables_globals.program_name,
+ iptables_globals.program_version);
+ exit(1);
+ }
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions4();
+#endif
+
+ return ip46tables_restore_main(&ipt_restore_cb, argc, argv);
+}
+#endif
+
+#if defined ENABLE_IPV6
+struct iptables_restore_cb ip6t_restore_cb = {
+ .ops = &ip6tc_ops,
+ .for_each_chain = for_each_chain6,
+ .flush_entries = flush_entries6,
+ .delete_chain = delete_chain6,
+ .do_command = do_command6,
+};
+
+int
+ip6tables_restore_main(int argc, char *argv[])
+{
+ int c;
+
+ ip6tables_globals.program_name = "ip6tables-restore";
+ c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
+ if (c < 0) {
+ fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+ ip6tables_globals.program_name,
+ ip6tables_globals.program_version);
+ exit(1);
+ }
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+ init_extensions();
+ init_extensions6();
+#endif
+
+ return ip46tables_restore_main(&ip6t_restore_cb, argc, argv);
+}
+#endif