]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
ip6tables-(save/restore) sync with IPv4 code
authorHarald Welte <laforge@gnumonks.org>
Thu, 4 Oct 2001 08:30:46 +0000 (08:30 +0000)
committerHarald Welte <laforge@gnumonks.org>
Thu, 4 Oct 2001 08:30:46 +0000 (08:30 +0000)
ip6tables-restore.c
ip6tables-save.c

index 40804eef7e7035803805df380985159657f6ee19..5be8a1f5eaa83b18d7baf09d60ffc42593d7261b 100644 (file)
@@ -79,6 +79,28 @@ int parse_counters(char *string, struct ip6t_counters *ctr)
        return (sscanf(string, "[%llu:%llu]", &ctr->pcnt, &ctr->bcnt) == 2);
 }
 
+/* global new argv and argc */
+static char *newargv[255];
+static int newargc;
+
+/* function adding one argument to newargv, updating newargc 
+ *  * returns true if argument added, false otherwise */
+static int add_argv(char *what) {
+        if (what && ((newargc + 1) < sizeof(newargv)/sizeof(char *))) {
+                newargv[newargc] = strdup(what);
+                newargc++;
+                return 1;
+        } else
+                return 0;
+}
+
+static void free_argv(void) {
+        int i;
+
+        for (i = 0; i < newargc; i++)
+                free(newargv[i]);
+}
+
 int main(int argc, char *argv[])
 {
        ip6tc_handle_t handle;
@@ -86,7 +108,6 @@ int main(int argc, char *argv[])
        unsigned int line = 0;
        int c;
        char curtable[IP6T_TABLE_MAXNAMELEN + 1];
-       char curchain[IP6T_FUNCTION_MAXNAMELEN + 1];
        FILE *in;
        const char *modprobe = 0;
 
@@ -131,17 +152,7 @@ int main(int argc, char *argv[])
                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;
@@ -195,16 +206,15 @@ int main(int argc, char *argv[])
                                           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)) {
+                       if (!ip6tc_builtin(chain, 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));
-//                     }
+                               if (!ip6tc_create_chain(chain, &handle))
+                                        exit_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);
@@ -244,66 +254,111 @@ int main(int argc, char *argv[])
                        ret = 1;
 
                } else {
-                       char *newargv[1024];
-                       int i,a, argvsize;
+                       int a;
                        char *ptr = buffer;
                        char *pcnt = NULL;
                        char *bcnt = NULL;
+                        char *parsestart;
+
+                        /* the parser */
+                        char *param_start, *curchar;
+                        int quote_open;
+
+                        /* reset the newargv */
+                        newargc = 0;
 
                        if (buffer[0] == '[') {
+                                /* we have counters in our input */
                                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;
+                               pcnt = strtok(buffer+1, ":");
+                                if (!pcnt)
+                                        exit_error(PARAMETER_PROBLEM,
+                                                   "Bad line %u: need :\n",
+                                                   line);
 
+                               bcnt = strtok(NULL, "]");
+                                if (!bcnt)
+                                        exit_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]);
+                        add_argv("-t");
+                        add_argv((char *) &curtable);
+
+/* IP6TABLES doesn't support this
                        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++)
+                        /* After fighting with strtok enough, here's now
+                         * a 'real' parser. According to Rusty I'm now no
+                         * longer a real hacker, but I can live with that */
+
+                        quote_open = 0;
+                        param_start = parsestart;
+
+                        for (curchar = parsestart; *curchar; curchar++) {
+                                if (*curchar == '"') {
+                                        if (quote_open) {
+                                                quote_open = 0;
+                                                *curchar = ' ';
+                                        } else {
+                                                quote_open = 1;
+                                                param_start++;
+                                        }
+                                }
+                                if (*curchar == ' '
+                                    || *curchar == '\t'
+                                    || * curchar == '\n') {
+                                        char param_buffer[1024];
+                                        int param_len = curchar-param_start;
+
+                                        if (quote_open)
+                                                continue;
+
+                                        if (!param_len) {
+                                                /* two spaces? */
+                                                param_start++;
+                                                continue;
+                                        }
+
+                                        /* end of one parameter */
+                                        strncpy(param_buffer, param_start,
+                                                param_len);
+                                        *(param_buffer+param_len) = '\0';
+                                        add_argv(param_buffer);
+                                        param_start += param_len + 1;
+                                } else {
+                                        /* regular character, skip */
+                                }
+                        }
+
+                       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(i, newargv, &newargv[2], &handle);
+                       ret = do_command6(newargc, newargv, 
+                                          &newargv[2], &handle);
+
+                        free_argv();
                }
                if (!ret) {
                        fprintf(stderr, "%s: line %u failed\n",
index 772f786c40a0633d1edf3ca3a1d3b5d76e8bd2ea..d3ad7090ea7610ea6a3cef646f1c12f693727f59 100644 (file)
@@ -152,7 +152,7 @@ static void print_ip(char *prefix, const struct in6_addr *ip, const struct in6_a
 /* We want this to be readable, so only print out neccessary fields.
  * Because that's the kind of world I want to live in.  */
 static void print_rule(const struct ip6t_entry *e, 
-               ip6tc_handle_t *h, int counters)
+               ip6tc_handle_t *h, const char *chain, int counters)
 {
        struct ip6t_entry_target *t;
        const char *target_name;
@@ -161,6 +161,9 @@ static void print_rule(const struct ip6t_entry *e,
        if (counters)
                printf("[%llu:%llu] ", e->counters.pcnt, e->counters.bcnt);
 
+       /* print chain name */
+       printf("-A %s ", chain);
+
        /* Print IP part. */
        print_ip("-s", &(e->ipv6.src), &(e->ipv6.smsk),
                        e->ipv6.invflags & IP6T_INV_SRCIP);     
@@ -267,11 +270,11 @@ static int do_output(const char *tablename)
                       NETFILTER_VERSION, ctime(&now));
                printf("*%s\n", tablename);
 
-               /* Dump out chain names */
+               /* Dump out chain names first, 
+                * thereby preventing dependency conflicts */
                for (chain = ip6tc_first_chain(&h);
                     chain;
                     chain = ip6tc_next_chain(&h)) {
-                       const struct ip6t_entry *e;
 
                        printf(":%s ", chain);
                        if (ip6tc_builtin(chain, h)) {
@@ -282,11 +285,17 @@ static int do_output(const char *tablename)
                        } else {
                                printf("- [0:0]\n");
                        }
+               }
+
+               for (chain = ip6tc_first_chain(&h);
+                    chain;
+                    chain = ip6tc_next_chain(&h)) {
+                    const struct ip6t_entry *e;
 
                        /* Dump out rules */
                        e = ip6tc_first_rule(chain, &h);
                        while(e) {
-                               print_rule(e, &h, counters);
+                               print_rule(e, &h, chain, counters);
                                e = ip6tc_next_rule(e, &h);
                        }
                }