Hi,

userspace syncronization/fix part I :)

ip6tables.c
- sync with iptables (grr)
        the code is changed in several place, and meybe its behaviour, too.
        I played with the new code for several hours, it's worked for me, but
        ...
- verbose error msg at dload()
- proto name 'bug' fix (the same as in ipv4 - find_match())
- interface name interpretation ( ppp+ ppp.2 ...)
- match list: ip6tables used an 'appended' list - changed to 'prepended' one
- KMGT in the number formats
- some IP6T_ALIGN problem ... (in do_command6())
- removed old comments (remained codes from the ancient times)
- options for the pkt counters added

ip6tables.8
- corrections to the new command

regards,

        kisza

-- 
    Andras Kis-Szabo       Security Development, Design and Audit
-------------------------/        Zorp, NetFilter and IPv6
 [EMAIL PROTECTED] /-----Member of the BUTE-MIS-SEARCHlab---------->
--- netfilter/userspace/ip6tables.c.old Sat Mar  2 23:07:05 2002
+++ netfilter/userspace/ip6tables.c     Sun Mar  3 00:53:55 2002
@@ -97,9 +97,10 @@
 #define OPT_VIANAMEIN  0x00080U
 #define OPT_VIANAMEOUT 0x00100U
 #define OPT_LINENUMBERS 0x00200U
-#define NUMBER_OF_OPT  10
+#define OPT_COUNTERS   0x00400U
+#define NUMBER_OF_OPT  11
 static const char optflags[NUMBER_OF_OPT]
-= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '3'};
+= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '3', 'c'};
 
 static struct option original_opts[] = {
        { "append", 1, 0, 'A' },
@@ -130,6 +131,8 @@
        { "version", 0, 0, 'V' },
        { "help", 2, 0, 'h' },
        { "line-numbers", 0, 0, '0' },
+       { "modprobe", 1, 0, 'M' },
+       { "set-counters", 1, 0, 'c' },
        { 0 }
 };
 
@@ -168,7 +171,7 @@
 /*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x'},
 /*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x'},
 /*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x'},
-/*CHECK*/     {'x','+','+','+','x',' ','x','+','+','x'},
+/*CHECK*/     {'x','+','+','+','x',' ','x',' ',' ','x'},
 /*RENAME*/    {'x','x','x','x','x',' ','x','x','x','x'}
 };
 
@@ -245,6 +248,7 @@
 in6addrcpy(struct in6_addr *dst, struct in6_addr *src)
 {
        memcpy(dst, src, sizeof(struct in6_addr));
+       /* dst->s6_addr = src->s6_addr; */
 }
 
 void
@@ -325,14 +329,19 @@
 "  --in-interface -i [!] input name[+]\n"
 "                              network interface name ([+] for wildcard)\n"
 "  --jump      -j target\n"
-"                              target for rule\n"
+"                              target for rule (may load target extension)\n"
+"  --match     -m match\n"
+"                              extended match (may load extension)\n"
 "  --numeric   -n              numeric output of addresses and ports\n"
 "  --out-interface -o [!] output name[+]\n"
 "                              network interface name ([+] for wildcard)\n"
 "  --table     -t table        table to manipulate (default: `filter')\n"
 "  --verbose   -v              verbose mode\n"
+"  --line-numbers              print line numbers when listing\n"
 "  --exact     -x              expand numbers (display exact values)\n"
 /*"[!] --fragment      -f              match second or further fragments only\n"*/
+"  --modprobe=<command>                try to insert modules using this command\n"
+"  --set-counters PKTS BYTES   set the counter during insert/append\n"
 "[!] --version -V              print package version.\n");
 
        /* Print out any special helps. A user might like to be able to add a --help 
@@ -554,7 +563,7 @@
        int l = ipv6_prefix_length(addrp);
        if (l == -1)
                return addr_to_numeric(addrp);
-       sprintf(buf, "%d", l);
+       sprintf(buf, "/%d", l);
        return buf;
 }
 
@@ -634,7 +643,7 @@
        return &maskaddr;
 }
 
-static void
+void
 parse_hostnetworkmask(const char *name, struct in6_addr **addrpp,
                      struct in6_addr *maskp, unsigned int *naddrs)
 {
@@ -715,7 +724,8 @@
                                           name);
                } else if (tryload == LOAD_MUST_SUCCEED)
                        exit_error(PARAMETER_PROBLEM,
-                                  "Couldn't load match `%s'\n", name);
+                                  "Couldn't load match `%s':%s\n",
+                                  name, dlerror());
        }
 #else
        if (ptr && !ptr->loaded) {
@@ -726,8 +736,8 @@
        }
 #endif
 
-        if (ptr)
-                ptr->used = 1;
+       if (ptr)
+               ptr->used = 1;
 
 
        return ptr;
@@ -739,13 +749,18 @@
 {
        unsigned int proto;
 
-       if (string_to_number(pname, 0, 255, &proto) != -1) 
-               return find_match(proto_to_name(proto, nolookup), tryload);
+       if (string_to_number(pname, 0, 255, &proto) != -1) {
+               char *protoname = proto_to_name(proto, nolookup);
+
+               if (protoname)
+                       return find_match(protoname, tryload);
+       } else
+               return find_match(pname, tryload);
 
-       return find_match(pname, tryload);
+       return NULL;
 }
 
-static u_int16_t
+u_int16_t
 parse_protocol(const char *s)
 {
        unsigned int proto;
@@ -795,19 +810,20 @@
        else if (vianame[vialen - 1] == '+') {
                memset(mask, 0xFF, vialen - 1);
                memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1);
-               /* Remove `+' */
-               vianame[vialen - 1] = '\0';
+               /* Don't remove `+' here! -HW */
        } else {
                /* Include nul-terminator in match */
                memset(mask, 0xFF, vialen + 1);
                memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1);
-       }
-       for (i = 0; vianame[i]; i++) {
-               if (!isalnum(vianame[i]) && vianame[i] != '_') {
-                       printf("Warning: wierd character in interface"
-                              " `%s' (No aliases, :, ! or *).\n",
-                              vianame);
-                       break;
+               for (i = 0; vianame[i]; i++) {
+                       if (!isalnum(vianame[i]) 
+                           && vianame[i] != '_' 
+                           && vianame[i] != '.') {
+                               printf("Warning: wierd character in interface"
+                                      " `%s' (No aliases, :, ! or *).\n",
+                                      vianame);
+                               break;
+                       }
                }
        }
 }
@@ -816,9 +832,9 @@
 static int
 parse_rulenumber(const char *rule)
 {
-       unsigned int rulenum; 
+       unsigned int rulenum;
 
-       if (string_to_number(rule, 1, INT_MAX, &rulenum))
+       if (string_to_number(rule, 1, INT_MAX, &rulenum) == -1)
                exit_error(PARAMETER_PROBLEM,
                           "Invalid rule number `%s'", rule);
 
@@ -858,10 +874,10 @@
        number = strtol(s, &end, 0);
        if (*end == '\0' && end != s) {
                /* we parsed a number, let's see if we want this */
-               if (errno != ERANGE && min <= number && number <= max) {
+               if (errno != ERANGE && min <= number && number <= max) {
                        *ret = number;
                        return 0;
-              }
+               }
        }
        return -1;
 }
@@ -920,7 +936,7 @@
                                           name);
                } else if (tryload == LOAD_MUST_SUCCEED)
                        exit_error(PARAMETER_PROBLEM,
-                                  "Couldn't load target `%s'%s\n", 
+                                  "Couldn't load target `%s':%s\n",
                                   name, dlerror());
        }
 #else
@@ -932,8 +948,8 @@
        }
 #endif
 
-        if (ptr)
-                ptr->used = 1;
+       if (ptr)
+               ptr->used = 1;
 
        return ptr;
 }
@@ -965,6 +981,8 @@
 void
 register_match6(struct ip6tables_match *me)
 {
+       struct ip6tables_match **i;
+
        if (strcmp(me->version, program_version) != 0) {
                fprintf(stderr, "%s: match `%s' v%s (I'm v%s).\n",
                        program_name, me->name, me->version, program_version);
@@ -977,19 +995,19 @@
                exit(1);
        }
 
-        if (me->size != IP6T_ALIGN(me->size)) {
-                fprintf(stderr, "%s: match `%s' has invalid size %u.\n",
-                        program_name, me->name, me->size);
-                exit(1);
-        }
+       if (me->size != IP6T_ALIGN(me->size)) {
+               fprintf(stderr, "%s: match `%s' has invalid size %u.\n",
+                       program_name, me->name, me->size);
+               exit(1);
+       }
+
+       /* Append to list. */
+       for (i = &ip6tables_matches; *i; i = &(*i)->next);
+       me->next = NULL;
+       *i = me;
 
-       /* Prepend to list. */
-       me->next = ip6tables_matches;
-       ip6tables_matches = me;
        me->m = NULL;
        me->mflags = 0;
-
-       /* opts = merge_options(opts, me->extra_opts, &me->option_offset);*/
 }
 
 void
@@ -1007,42 +1025,45 @@
                exit(1);
        }
 
-        if (me->size != IP6T_ALIGN(me->size)) {
-                fprintf(stderr, "%s: target `%s' has invalid size %u.\n",
-                        program_name, me->name, me->size);
-                exit(1);
-        }
+       if (me->size != IP6T_ALIGN(me->size)) {
+               fprintf(stderr, "%s: target `%s' has invalid size %u.\n",
+                       program_name, me->name, me->size);
+               exit(1);
+       }
 
        /* Prepend to list. */
        me->next = ip6tables_targets;
        ip6tables_targets = me;
        me->t = NULL;
        me->tflags = 0;
-
-       /*opts = merge_options(opts, me->extra_opts, &me->option_offset);*/
 }
 
 static void
 print_num(u_int64_t number, unsigned int format)
 {
-        if (format & FMT_KILOMEGAGIGA) {
-                if (number > 99999) {
-                        number = (number + 500) / 1000;
-                        if (number > 9999) {
-                                number = (number + 500) / 1000;
-                                if (number > 9999) {
-                                        number = (number + 500) / 1000;
-                                        printf(FMT("%4lluG ","%lluG "),number);
-                                }
-                                else printf(FMT("%4lluM ","%lluM "), number);
-                        } else
-                                printf(FMT("%4lluK ","%lluK "), number);
-                } else
-                        printf(FMT("%5llu ","%llu "), number);
-        } else
-                printf(FMT("%8llu ","%llu "), number);
+       if (format & FMT_KILOMEGAGIGA) {
+               if (number > 99999) {
+                       number = (number + 500) / 1000;
+                       if (number > 9999) {
+                               number = (number + 500) / 1000;
+                               if (number > 9999) {
+                                       number = (number + 500) / 1000;
+                                       if (number > 9999) {
+                                               number = (number + 500) / 1000;
+                                               printf(FMT("%4lluT ","%lluT "), 
+number);
+                                       }
+                                       else printf(FMT("%4lluG ","%lluG "), number);
+                               }
+                               else printf(FMT("%4lluM ","%lluM "), number);
+                       } else
+                               printf(FMT("%4lluK ","%lluK "), number);
+               } else
+                       printf(FMT("%5llu ","%llu "), number);
+       } else
+               printf(FMT("%8llu ","%llu "), number);
 }
 
+
 static void
 print_header(unsigned int format, const char *chain, ip6tc_handle_t *handle)
 {
@@ -1052,13 +1073,11 @@
        if (pol) {
                printf(" (policy %s", pol);
                if (!(format & FMT_NOCOUNTS)) {
-                       /*printf(" %llu packets, %llu bytes",
-                              counters.pcnt, counters.bcnt);*/
-                        fputc(' ', stdout);
-                        print_num(counters.pcnt, (format|FMT_NOTABLE));
-                        fputs("packets, ", stdout);
-                        print_num(counters.bcnt, (format|FMT_NOTABLE));
-                        fputs("bytes", stdout);
+                       fputc(' ', stdout);
+                       print_num(counters.pcnt, (format|FMT_NOTABLE));
+                       fputs("packets, ", stdout);
+                       print_num(counters.bcnt, (format|FMT_NOTABLE));
+                       fputs("bytes", stdout);
                }
                printf(")\n");
        } else {
@@ -1094,6 +1113,7 @@
        printf("\n");
 }
 
+
 static int
 print_match(const struct ip6t_entry_match *m,
            const struct ip6t_ip6 *ip,
@@ -1104,8 +1124,8 @@
        if (match) {
                if (match->print)
                        match->print(ip, m, numeric);
-                else
-                        printf("%s ", match->name);
+               else
+                       printf("%s ", match->name);
        } else {
                if (m->u.user.name[0])
                        printf("UNKNOWN match `%s' ", m->u.user.name);
@@ -1151,8 +1171,7 @@
 
        fputc(fw->ipv6.invflags & IP6T_INV_PROTO ? '!' : ' ', stdout);
        {
-               char *pname = proto_to_name(fw->ipv6.proto, 
-                                           format&FMT_NUMERIC);
+               char *pname = proto_to_name(fw->ipv6.proto, format&FMT_NUMERIC);
                if (pname)
                        printf(FMT("%-5s", "%s "), pname);
                else
@@ -1162,8 +1181,8 @@
        if (format & FMT_OPTIONS) {
                if (format & FMT_NOTABLE)
                        fputs("opt ", stdout);
-               fputc(' ', stdout);
-               fputc(' ', stdout);
+               fputc(' ', stdout); /* Invert flag of FRAG */
+               fputc(' ', stdout); /* -f */
                fputc(' ', stdout);
        }
 
@@ -1178,10 +1197,6 @@
 
                if (fw->ipv6.iniface[0] != '\0') {
                        strcat(iface, fw->ipv6.iniface);
-                       /* If it doesn't compare the nul-term, it's a
-                          wildcard. */
-                       if (fw->ipv6.iniface_mask[strlen(fw->ipv6.iniface)] == 0)
-                               strcat(iface, "+");
                }
                else if (format & FMT_NUMERIC) strcat(iface, "*");
                else strcat(iface, "any");
@@ -1195,10 +1210,6 @@
 
                if (fw->ipv6.outiface[0] != '\0') {
                        strcat(iface, fw->ipv6.outiface);
-                       /* If it doesn't compare the nul-term, it's a
-                          wildcard. */
-                       if (fw->ipv6.outiface_mask[strlen(fw->ipv6.outiface)] == 0)
-                               strcat(iface, "+");
                }
                else if (format & FMT_NUMERIC) strcat(iface, "*");
                else strcat(iface, "any");
@@ -1211,9 +1222,9 @@
                printf(FMT("%-19s ","%s "), "anywhere");
        else {
                if (format & FMT_NUMERIC)
-                       sprintf(buf, "%s/", addr_to_numeric(&(fw->ipv6.src)));
+                       sprintf(buf, "%s", addr_to_numeric(&(fw->ipv6.src)));
                else
-                       sprintf(buf, "%s/", addr_to_anyname(&(fw->ipv6.src)));
+                       sprintf(buf, "%s", addr_to_anyname(&(fw->ipv6.src)));
                strcat(buf, mask_to_numeric(&(fw->ipv6.smsk)));
                printf(FMT("%-19s ","%s "), buf);
        }
@@ -1224,9 +1235,9 @@
                printf(FMT("%-19s","-> %s"), "anywhere");
        else {
                if (format & FMT_NUMERIC)
-                       sprintf(buf, "%s/", addr_to_numeric(&(fw->ipv6.dst)));
+                       sprintf(buf, "%s", addr_to_numeric(&(fw->ipv6.dst)));
                else
-                       sprintf(buf, "%s/", addr_to_anyname(&(fw->ipv6.dst)));
+                       sprintf(buf, "%s", addr_to_anyname(&(fw->ipv6.dst)));
                strcat(buf, mask_to_numeric(&(fw->ipv6.dmsk)));
                printf(FMT("%-19s","-> %s"), buf);
        }
@@ -1338,34 +1349,32 @@
 
        size = sizeof(struct ip6t_entry);
        for (m = ip6tables_matches; m; m = m->next) {
-                if (!m->used)
-                        continue;
+               if (!m->used)
+                       continue;
 
                size += IP6T_ALIGN(sizeof(struct ip6t_entry_match)) + m->size;
        }
 
        mask = fw_calloc(1, size
-                        + sizeof(struct ip6t_entry_target)
+                        + IP6T_ALIGN(sizeof(struct ip6t_entry_target))
                         + ip6tables_targets->size);
 
        memset(mask, 0xFF, sizeof(struct ip6t_entry));
        mptr = mask + sizeof(struct ip6t_entry);
 
        for (m = ip6tables_matches; m; m = m->next) {
-                if (!m->used)
-                        continue;
+               if (!m->used)
+                       continue;
 
                memset(mptr, 0xFF,
-                      IP6T_ALIGN(sizeof(struct ip6t_entry_match)) + 
-                      m->userspacesize);
+                      IP6T_ALIGN(sizeof(struct ip6t_entry_match))
+                      + m->userspacesize);
                mptr += IP6T_ALIGN(sizeof(struct ip6t_entry_match)) + m->size;
        }
 
        memset(mptr, 0xFF, 
               IP6T_ALIGN(sizeof(struct ip6t_entry_target))
               + ip6tables_targets->userspacesize);
-       /*mptr += sizeof(struct ip6t_entry_target);
-       memset(mptr, 0xFF, ip6tables_targets->userspacesize);*/
 
        return mask;
 }
@@ -1409,16 +1418,15 @@
 {
        int ret = 1;
        unsigned int i, j;
-       struct ip6t_entry ipfw = *fw;
        const char *msg;
 
        for (i = 0; i < nsaddrs; i++) {
-               ipfw.ipv6.src = saddrs[i];
+               fw->ipv6.src = saddrs[i];
                for (j = 0; j < ndaddrs; j++) {
-                       ipfw.ipv6.dst = daddrs[j];
+                       fw->ipv6.dst = daddrs[j];
                        if (verbose)
                                print_firewall_line(fw, *handle);
-                       msg = ip6tc_check_packet(chain, &ipfw, handle);
+                       msg = ip6tc_check_packet(chain, fw, handle);
                        if (!msg) ret = 0;
                        else printf("%s\n", msg);
                }
@@ -1464,7 +1472,6 @@
         return ret;
 }
 
-/*static int*/
 int
 flush_entries(const ip6t_chainlabel chain, int verbose,
              ip6tc_handle_t *handle)
@@ -1489,7 +1496,6 @@
        return ip6tc_zero_entries(chain, handle);
 }
 
-/*static int*/
 int
 delete_chain(const ip6t_chainlabel chain, int verbose,
             ip6tc_handle_t *handle)
@@ -1557,61 +1563,61 @@
 
 static char *get_modprobe(void)
 {
-        int procfile;
-        char *ret;
+       int procfile;
+       char *ret;
 
-        procfile = open(PROC_SYS_MODPROBE, O_RDONLY);
-        if (procfile < 0)
-                return NULL;
-
-        ret = malloc(1024);
-        if (ret) {
-                switch (read(procfile, ret, 1024)) {
-                case -1: goto fail;
-                case 1024: goto fail; /* Partial read.  Wierd */
-                }
-                if (ret[strlen(ret)-1]=='\n')
-                        ret[strlen(ret)-1]=0;
-                close(procfile);
-                return ret;
-        }
+       procfile = open(PROC_SYS_MODPROBE, O_RDONLY);
+       if (procfile < 0)
+               return NULL;
+
+       ret = malloc(1024);
+       if (ret) {
+               switch (read(procfile, ret, 1024)) {
+               case -1: goto fail;
+               case 1024: goto fail; /* Partial read.  Wierd */
+               }
+               if (ret[strlen(ret)-1]=='\n') 
+                       ret[strlen(ret)-1]=0;
+               close(procfile);
+               return ret;
+       }
  fail:
-        free(ret);
-        close(procfile);
-        return NULL;
+       free(ret);
+       close(procfile);
+       return NULL;
 }
 
 int ip6tables_insmod(const char *modname, const char *modprobe)
 {
-        char *buf = NULL;
-        char *argv[3];
-
-        /* If they don't explicitly set it, read out of kernel */
-        if (!modprobe) {
-                buf = get_modprobe();
-                if (!buf)
-                        return -1;
-                modprobe = buf;
-        }
+       char *buf = NULL;
+       char *argv[3];
 
-        switch (fork()) {
-        case 0:
-                argv[0] = (char *)modprobe;
-                argv[1] = (char *)modname;
-                argv[2] = NULL;
-                execv(argv[0], argv);
-
-                /* not usually reached */
-                exit(0);
-        case -1:
-                return -1;
+       /* If they don't explicitly set it, read out of kernel */
+       if (!modprobe) {
+               buf = get_modprobe();
+               if (!buf)
+                       return -1;
+               modprobe = buf;
+       }
+
+       switch (fork()) {
+       case 0:
+               argv[0] = (char *)modprobe;
+               argv[1] = (char *)modname;
+               argv[2] = NULL;
+               execv(argv[0], argv);
+
+               /* not usually reached */
+               exit(0);
+       case -1:
+               return -1;
 
-        default: /* parent */
-                wait(NULL);
-        }
+       default: /* parent */
+               wait(NULL);
+       }
 
-        free(buf);
-        return 0;
+       free(buf);
+       return 0;
 }
 
 static struct ip6t_entry *
@@ -1625,8 +1631,8 @@
 
        size = sizeof(struct ip6t_entry);
        for (m = matches; m; m = m->next) {
-                if (!m->used)
-                        continue;
+               if (!m->used)
+                       continue;
 
                size += m->m->u.match_size;
        }
@@ -1638,8 +1644,8 @@
 
        size = 0;
        for (m = matches; m; m = m->next) {
-                if (!m->used)
-                        continue;
+               if (!m->used)
+                       continue;
 
                memcpy(e->elems + size, m->m, m->m->u.match_size);
                size += m->m->u.match_size;
@@ -1661,42 +1667,43 @@
        const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
        const char *policy = NULL, *newname = NULL;
        unsigned int rulenum = 0, options = 0, command = 0;
+       const char *pcnt = NULL, *bcnt = NULL;
        int ret = 1;
        struct ip6tables_match *m;
        struct ip6tables_target *target = NULL;
        struct ip6tables_target *t;
        const char *jumpto = "";
        char *protocol = NULL;
+       const char *modprobe = NULL;
        char icmp6p[] = "icmpv6";
-        const char *modprobe = NULL;
 
        memset(&fw, 0, sizeof(fw));
 
        opts = original_opts;
        global_option_offset = 0;
 
-        /* re-set optind to 0 in case do_command gets called
+       /* re-set optind to 0 in case do_command gets called
         * a second time */
        optind = 0;
 
-        /* clear mflags in case do_command gets called a second time
-         * (we clear the global list of all matches for security)*/
-        for (m = ip6tables_matches; m; m = m->next) {
-                m->mflags = 0;
-                m->used = 0;
-        }
+       /* clear mflags in case do_command gets called a second time
+        * (we clear the global list of all matches for security)*/
+       for (m = ip6tables_matches; m; m = m->next) {
+               m->mflags = 0;
+               m->used = 0;
+       }
 
-        for (t = ip6tables_targets; t; t = t->next) {
-                t->tflags = 0;
-                t->used = 0;
-        }
+       for (t = ip6tables_targets; t; t = t->next) {
+               t->tflags = 0;
+               t->used = 0;
+       }
 
        /* Suppress error messages: we may add new options if we
            demand-load a protocol. */
        opterr = 0;
 
        while ((c = getopt_long(argc, argv,
-          "-A:C:D:R:I:L::F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:x",
+          "-A:C:D:R:I:L::F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvnt:m:xc:",
                                           opts, NULL)) != -1) {
                switch (c) {
                        /*
@@ -1801,7 +1808,7 @@
                                exit_error(PARAMETER_PROBLEM,
                                           "-%c requires old-chain-name and "
                                           "new-chain-name",
-                                           cmd2char(CMD_RENAME_CHAIN));        
+                                           cmd2char(CMD_RENAME_CHAIN));
                        break;
 
                case 'P':
@@ -1875,13 +1882,14 @@
                        set_option(&options, OPT_JUMP, &fw.ipv6.invflags,
                                   invert);
                        jumpto = parse_target(optarg);
+                       /* TRY_LOAD (may be chain name) */
                        target = find_target(jumpto, TRY_LOAD);
 
                        if (target) {
                                size_t size;
 
-                               size = IP6T_ALIGN(sizeof(struct ip6t_entry_target)
-                                                + target->size);
+                               size = IP6T_ALIGN(sizeof(struct ip6t_entry_target))
+                                       + target->size;
 
                                target->t = fw_calloc(1, size);
                                target->t->u.target_size = size;
@@ -1929,8 +1937,8 @@
                                           "unexpected ! flag before --match");
 
                        m = find_match(optarg, LOAD_MUST_SUCCEED);
-                       size = IP6T_ALIGN(sizeof(struct ip6t_entry_match)
-                                        + m->size);
+                       size = IP6T_ALIGN(sizeof(struct ip6t_entry_match))
+                                        + m->size;
                        m->m = fw_calloc(1, size);
                        m->m->u.match_size = size;
                        strcpy(m->m->u.user.name, m->name);
@@ -1969,6 +1977,36 @@
                                   invert);
                        break;
 
+               case 'M':
+                       modprobe = optarg;
+                       break;
+
+               case 'c':
+
+                       set_option(&options, OPT_COUNTERS, &fw.ipv6.invflags,
+                                  invert);
+                       pcnt = optarg;
+                       if (optind < argc && argv[optind][0] != '-'
+                           && argv[optind][0] != '!')
+                               bcnt = argv[optind++];
+                       else
+                               exit_error(PARAMETER_PROBLEM,
+                                       "-%c requires packet and byte counter",
+                                       opt2char(OPT_COUNTERS));
+
+                       if (sscanf(pcnt, "%llu", &fw.counters.pcnt) != 1)
+                               exit_error(PARAMETER_PROBLEM,
+                                       "-%c packet counter not numeric",
+                                       opt2char(OPT_COUNTERS));
+
+                       if (sscanf(bcnt, "%llu", &fw.counters.bcnt) != 1)
+                               exit_error(PARAMETER_PROBLEM,
+                                       "-%c byte counter not numeric",
+                                       opt2char(OPT_COUNTERS));
+                       
+                       break;
+
+
                case 1: /* non option */
                        if (optarg[0] == '!' && optarg[1] == '\0') {
                                if (invert)
@@ -1991,8 +2029,8 @@
                                               &target->tflags,
                                               &fw, &target->t))) {
                                for (m = ip6tables_matches; m; m = m->next) {
-                                        if (!m->used)
-                                                continue;
+                                       if (!m->used)
+                                               continue;
 
                                        if (m->parse(c - m->option_offset,
                                                     argv, invert,
@@ -2014,16 +2052,16 @@
                                        /* Try loading protocol */
                                        size_t size;
 
-                                       size = IP6T_ALIGN(sizeof(struct 
ip6t_entry_match)
-                                                        + m->size);
+                                       size = IP6T_ALIGN(sizeof(struct 
+ip6t_entry_match))
+                                                        + m->size;
 
                                        m->m = fw_calloc(1, size);
                                        m->m->u.match_size = size;
                                        strcpy(m->m->u.user.name, m->name);
                                        m->init(m->m, &fw.nfcache);
 
-                                        opts = merge_options(opts,
-                                            m->extra_opts, &m->option_offset);
+                                       opts = merge_options(opts,
+                                           m->extra_opts, &m->option_offset);
 
                                        optind--;
                                        continue;
@@ -2038,13 +2076,13 @@
        }
 
        for (m = ip6tables_matches; m; m = m->next) {
-                if (!m->used)
-                        continue;
+               if (!m->used)
+                       continue;
 
                m->final_check(m->mflags);
        }
 
-       if (target) 
+       if (target)
                target->final_check(target->tflags);
 
        /* Fix me: must put inverse options checking here --MN */
@@ -2094,57 +2132,57 @@
                           "chain name `%s' too long (must be under %i chars)",
                           chain, IP6T_FUNCTION_MAXNAMELEN);
 
-        /* only allocate handle if we weren't called with a handle */
-        if (!*handle)
-                *handle = ip6tc_init(*table);
-
-        if (!*handle) {
-                /* try to insmod the module if iptc_init failed */
-                ip6tables_insmod("ip6_tables", modprobe);
-                *handle = ip6tc_init(*table);
-        }
+       /* only allocate handle if we weren't called with a handle */
+       if (!*handle)
+               *handle = ip6tc_init(*table);
+
+       if (!*handle) {
+               /* try to insmod the module if iptc_init failed */
+               ip6tables_insmod("ip6_tables", modprobe);
+               *handle = ip6tc_init(*table);
+       }
 
-        if (!*handle)
-                exit_error(VERSION_PROBLEM,
-                           "can't initialize ip6tables table `%s': %s",
-                           *table, ip6tc_strerror(errno));
+       if (!*handle)
+               exit_error(VERSION_PROBLEM,
+                       "can't initialize ip6tables table `%s': %s",
+                       *table, ip6tc_strerror(errno));
 
        if (command == CMD_CHECK
            || command == CMD_APPEND
            || command == CMD_DELETE
            || command == CMD_INSERT
            || command == CMD_REPLACE) {
-                if (strcmp(chain, "PREROUTING") == 0
-                    || strcmp(chain, "INPUT") == 0) {
-                        /* -o not valid with incoming packets. */
-                        if (options & OPT_VIANAMEOUT)
-                                exit_error(PARAMETER_PROBLEM,
-                                           "Can't use -%c with %s\n",
-                                           opt2char(OPT_VIANAMEOUT),
-                                           chain);
-                        /* -i required with -C */
-                        if (command == CMD_CHECK && !(options & OPT_VIANAMEIN))
-                                exit_error(PARAMETER_PROBLEM,
-                                           "Need -%c with %s\n",
-                                           opt2char(OPT_VIANAMEIN),
-                                           chain);
-                }
-
-                if (strcmp(chain, "POSTROUTING") == 0
-                    || strcmp(chain, "OUTPUT") == 0) {
-                        /* -i not valid with outgoing packets */
-                        if (options & OPT_VIANAMEIN)
-                                exit_error(PARAMETER_PROBLEM,
-                                           "Can't use -%c with %s\n",
-                                           opt2char(OPT_VIANAMEIN),
-                                           chain);
-                        /* -o required with -C */
-                        if (command == CMD_CHECK && !(options&OPT_VIANAMEOUT))
-                                exit_error(PARAMETER_PROBLEM,
-                                           "Need -%c with %s\n",
-                                           opt2char(OPT_VIANAMEOUT),
-                                           chain);
-                }
+               if (strcmp(chain, "PREROUTING") == 0
+                   || strcmp(chain, "INPUT") == 0) {
+                       /* -o not valid with incoming packets. */
+                       if (options & OPT_VIANAMEOUT)
+                               exit_error(PARAMETER_PROBLEM,
+                                          "Can't use -%c with %s\n",
+                                          opt2char(OPT_VIANAMEOUT),
+                                          chain);
+                       /* -i required with -C */
+                       if (command == CMD_CHECK && !(options & OPT_VIANAMEIN))
+                               exit_error(PARAMETER_PROBLEM,
+                                          "Need -%c with %s\n",
+                                          opt2char(OPT_VIANAMEIN),
+                                          chain);
+               }
+
+               if (strcmp(chain, "POSTROUTING") == 0
+                   || strcmp(chain, "OUTPUT") == 0) {
+                       /* -i not valid with outgoing packets */
+                       if (options & OPT_VIANAMEIN)
+                               exit_error(PARAMETER_PROBLEM,
+                                          "Can't use -%c with %s\n",
+                                          opt2char(OPT_VIANAMEIN),
+                                          chain);
+                       /* -o required with -C */
+                       if (command == CMD_CHECK && !(options&OPT_VIANAMEOUT))
+                               exit_error(PARAMETER_PROBLEM,
+                                          "Need -%c with %s\n",
+                                          opt2char(OPT_VIANAMEOUT),
+                                          chain);
+               }
 
                if (target && ip6tc_is_chain(jumpto, *handle)) {
                        printf("Warning: using chain %s, not extension\n",
@@ -2172,22 +2210,11 @@
                }
 
                if (!target) {
-#if 0
-                       struct ip6t_entry_target unknown_target;
-
-                       /* Don't know it.  Must be extension with no
-                           options? */
-                       unknown_target.u.target_size = sizeof(unknown_target);
-                       strcpy(unknown_target.u.user.name, jumpto);
-
-                       e = generate_entry(&fw, ip6tables_matches,
-                                          &unknown_target);
-#endif
-                        /* it is no chain, and we can't load a plugin.
-                         * We cannot know if the plugin is corrupt, non
-                         * existant OR if the user just misspelled a
-                         * chain. */
-                        find_target(jumpto, LOAD_MUST_SUCCEED);
+                       /* it is no chain, and we can't load a plugin.
+                        * We cannot know if the plugin is corrupt, non
+                        * existant OR if the user just misspelled a
+                        * chain. */
+                       find_target(jumpto, LOAD_MUST_SUCCEED);
                } else {
                        e = generate_entry(&fw, ip6tables_matches, target->t);
                }
--- netfilter/userspace/ip6tables.8.old Sun Mar  3 00:57:44 2002
+++ netfilter/userspace/ip6tables.8     Sun Mar  3 01:01:53 2002
@@ -268,13 +268,13 @@
 .\" precedes the "-f" flag, the rule will only match head fragments, or
 .\" unfragmented packets.
 .\" .TP
-.\" .B "-c, --set-counters " "PKTS BYTES"
-.\" This enables the administrater to initialize the packet and byte
-.\" counters of a rule (during
-.\" .B INSERT,
-.\" .B APPEND,
-.\" .B REPLACE
-.\" operations)
+.B "-c, --set-counters " "PKTS BYTES"
+This enables the administrater to initialize the packet and byte
+counters of a rule (during
+.B INSERT,
+.B APPEND,
+.B REPLACE
+operations)
 .SS "OTHER OPTIONS"
 The following additional options can be specified:
 .TP

Reply via email to