summaryrefslogtreecommitdiffstats
path: root/iptables-restore.c
diff options
context:
space:
mode:
authorMarc Boucher <marc@mbsi.ca>2000-03-20 06:03:29 +0000
committerMarc Boucher <marc@mbsi.ca>2000-03-20 06:03:29 +0000
commite6869a8f59d779ff4d5a0984c86d80db70784962 (patch)
treecbaf2a4e3f8249de3967b959a214c27ff5fdee2a /iptables-restore.c
reorganized tree after kernel merge
Diffstat (limited to 'iptables-restore.c')
-rw-r--r--iptables-restore.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/iptables-restore.c b/iptables-restore.c
new file mode 100644
index 00000000..9b4ece29
--- /dev/null
+++ b/iptables-restore.c
@@ -0,0 +1,154 @@
+/* Code to restore the iptables state, from file by iptables-save. */
+#include <getopt.h>
+#include <sys/errno.h>
+#include <string.h>
+#include <stdio.h>
+#include "packet-filter/userspace/iptables.h"
+#include "packet-filter/userspace/libiptc/libiptc.h"
+
+/* Keeping track of external matches and targets. */
+static struct option options[] = {
+ { "binary", 1, 0, 'b' },
+ { "counters", 1, 0, 'c' },
+ { "verbose", 1, 0, 'v' },
+ { "help", 1, 0, 'h' },
+ { 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", name);
+ exit(1);
+}
+
+static int clean_slate(iptc_handle_t *handle)
+{
+ /* Skip over builtins. */
+ const char *i, *last = IPTC_LABEL_OUTPUT;
+
+ /* Be careful iterating: it isn't safe during delete. */
+ /* Re-iterate after each delete successful */
+ while ((i = iptc_next_chain(last, handle)) != NULL) {
+ if (!iptc_flush_entries(i, handle)
+ || !iptc_delete_chain(i, handle))
+ return 0;
+ }
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ iptc_handle_t handle;
+ char buffer[10240];
+ int counters = 0, binary = 0, verbose = 0;
+ unsigned int line = 0;
+ int c;
+ const char *chain;
+ FILE *in;
+
+ program_name = "iptables-restore";
+ program_version = NETFILTER_VERSION;
+
+ /* Don't use getopt here; it would interfere 8-(. */
+ 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();
+ 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)
+ ret = iptc_commit(&handle);
+ else if (buffer[0] == ':') {
+ /* New chain. */
+ char *chain, *policy;
+
+ /* FIXME: Don't ignore counters. */
+ chain = strtok(buffer+1, " \t\n");
+ if (!chain) {
+ exit_error(PARAMETER_PROBLEM,
+ "%s: line %u chain name invalid\n",
+ program_name, line);
+ exit(1);
+ }
+ policy = strtok(NULL, " \t\n");
+ if (!policy) {
+ exit_error(PARAMETER_PROBLEM,
+ "%s: line %u policy invalid\n",
+ program_name, line);
+ exit(1);
+ }
+ if (strcmp(policy, "-") != 0
+ && !iptc_set_policy(chain, policy, &handle))
+ exit_error(OTHER_PROBLEM,
+ "Can't set policy `%s'"
+ " on `%s' line %u: %s\n",
+ chain, policy, line,
+ iptc_strerror(errno));
+ } else {
+ char *newargv[1024];
+ int i;
+ char *ptr = buffer;
+
+ /* FIXME: Don't ignore counters. */
+ if (buffer[0] == '[') {
+ ptr = strchr(buffer, ']');
+ if (!ptr)
+ exit_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
+ }
+
+ /* strtok: a function only a coder could love */
+ newargv[0] = argv[0];
+ for (i = 1; i < sizeof(newargv)/sizeof(char *); i++) {
+ if (!(newargv[i] = strtok(ptr, " \t\n")))
+ break;
+ ptr = NULL;
+ }
+ if (i == sizeof(newargv)/sizeof(char *)) {
+ fprintf(stderr,
+ "%s: line %u too many arguments\n",
+ program_name, line);
+ exit(1);
+ }
+
+ ret = do_command(i, newargv, &handle);
+ }
+ if (!ret) {
+ fprintf(stderr, "%s: line %u failed\n",
+ program_name, line);
+ exit(1);
+ }
+ }
+
+ return 0;
+}