]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
Fix CONNMARK/connmark issues with 64bit kernel and 32bit userspace.
authorMartin Josefsson <gandalf@wlug.westbo.se>
Sat, 12 Feb 2005 21:40:16 +0000 (21:40 +0000)
committerMartin Josefsson <gandalf@wlug.westbo.se>
Sat, 12 Feb 2005 21:40:16 +0000 (21:40 +0000)
Also fixes a typo in CONNMARK, --mask set the mark, not the mask.

Initial patch by: Pablo Neira <pablo@eurodev.net>
Signed-off-by: Martin Josefsson <gandalf@wlug.westbo.se>
extensions/libipt_CONNMARK.c
extensions/libipt_connmark.c
include/linux/netfilter_ipv4/ipt_CONNMARK.h
include/linux/netfilter_ipv4/ipt_connmark.h

index 11cdc84aced69163a8cc29af7e1e9d5b76d260a1..d7bfeb8c6f23bf9abcdd0796335d326488c50546 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <iptables.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter_ipv4/ipt_CONNMARK.h>
+#include "../include/linux/netfilter_ipv4/ipt_CONNMARK.h"
 
 #if 0
 struct markinfo {
@@ -72,14 +72,25 @@ parse(int c, char **argv, int invert, unsigned int *flags,
        struct ipt_connmark_target_info *markinfo
                = (struct ipt_connmark_target_info *)(*target)->data;
 
+#ifdef KERNEL_64_USERSPACE_32
+       markinfo->mask = ~0ULL;
+#else
+       markinfo->mask = ~0UL;
+#endif
+
        switch (c) {
                char *end;
        case '1':
                markinfo->mode = IPT_CONNMARK_SET;
-               markinfo->mask = ~0;
+#ifdef KERNEL_64_USERSPACE_32
+               markinfo->mark = strtoull(optarg, &end, 0);
+               if (*end == '/' && end[1] != '\0')
+                   markinfo->mask = strtoull(end+1, &end, 0);
+#else
                markinfo->mark = strtoul(optarg, &end, 0);
                if (*end == '/' && end[1] != '\0')
                    markinfo->mask = strtoul(end+1, &end, 0);
+#endif
                if (*end != '\0' || end == optarg)
                        exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
                if (*flags)
@@ -89,7 +100,6 @@ parse(int c, char **argv, int invert, unsigned int *flags,
                break;
        case '2':
                markinfo->mode = IPT_CONNMARK_SAVE;
-               markinfo->mask = ~0;
                if (*flags)
                        exit_error(PARAMETER_PROBLEM,
                                   "CONNMARK target: Can't specify --save-mark twice");
@@ -97,7 +107,6 @@ parse(int c, char **argv, int invert, unsigned int *flags,
                break;
        case '3':
                markinfo->mode = IPT_CONNMARK_RESTORE;
-               markinfo->mask = ~0;
                if (*flags)
                        exit_error(PARAMETER_PROBLEM,
                                   "CONNMARK target: Can't specify --restore-mark twice");
@@ -107,9 +116,13 @@ parse(int c, char **argv, int invert, unsigned int *flags,
                if (!*flags)
                        exit_error(PARAMETER_PROBLEM,
                                   "CONNMARK target: Can't specify --mask without a operation");
-               markinfo->mark = strtoul(optarg, &end, 0);
+#ifdef KERNEL_64_USERSPACE_32
+               markinfo->mask = strtoull(optarg, &end, 0);
+#else
+               markinfo->mask = strtoul(optarg, &end, 0);
+#endif
                if (*end != '\0' || end == optarg)
-                       exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
+                       exit_error(PARAMETER_PROBLEM, "Bad MASK value `%s'", optarg);
                break;
        default:
                return 0;
@@ -126,6 +139,37 @@ final_check(unsigned int flags)
                           "CONNMARK target: No operation specified");
 }
 
+#ifdef KERNEL_64_USERSPACE_32
+static void
+print_mark(unsigned long long mark)
+{
+       printf("0x%llx", mark);
+}
+
+static void
+print_mask(const char *text, unsigned long long mask)
+{
+       if (mask != ~0ULL)
+               printf("%s%llx", text, mask);
+}
+
+#else
+
+static void
+print_mark(unsigned long mark)
+{
+       printf("0x%lx", mark);
+}
+
+static void
+print_mask(const char *text, unsigned long mask)
+{
+       if (mask != ~0UL)
+               printf("%s%lx", text, mask);
+}
+#endif
+
+
 /* Prints out the target info. */
 static void
 print(const struct ipt_ip *ip,
@@ -136,21 +180,19 @@ print(const struct ipt_ip *ip,
                (const struct ipt_connmark_target_info *)target->data;
        switch (markinfo->mode) {
        case IPT_CONNMARK_SET:
-           printf("CONNMARK set 0x%lx", markinfo->mark);
-           if (markinfo->mask != ~0)
-               printf("/0x%lx", markinfo->mask);
+           printf("CONNMARK set ");
+           print_mark(markinfo->mark);
+           print_mask("/", markinfo->mask);
            printf(" ");
            break;
        case IPT_CONNMARK_SAVE:
            printf("CONNMARK save ");
-           if (markinfo->mask != ~0)
-               printf("mask 0x%lx", markinfo->mask);
+           print_mask("mask ", markinfo->mask);
            printf(" ");
            break;
        case IPT_CONNMARK_RESTORE:
            printf("CONNMARK restore ");
-           if (markinfo->mask != ~0)
-               printf("mask 0x%lx", markinfo->mask);
+           print_mask("mask ", markinfo->mask);
            break;
        default:
            printf("ERROR: UNKNOWN CONNMARK MODE ");
@@ -167,20 +209,18 @@ save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
 
        switch (markinfo->mode) {
        case IPT_CONNMARK_SET:
-           printf("--set-mark 0x%lx", markinfo->mark);
-           if (markinfo->mask != ~0)
-               printf("/0x%lx", markinfo->mask);
+           printf("--set-mark ");
+           print_mark(markinfo->mark);
+           print_mask("/", markinfo->mask);
            printf(" ");
            break;
        case IPT_CONNMARK_SAVE:
            printf("--save-mark ");
-           if (markinfo->mask != ~0)
-               printf("--mask 0x%lx", markinfo->mask);
+           print_mask("--mask ", markinfo->mask);
            break;
        case IPT_CONNMARK_RESTORE:
            printf("--restore-mark ");
-           if (markinfo->mask != ~0)
-               printf("--mask 0x%lx", markinfo->mask);
+           print_mask("--mask ", markinfo->mask);
            break;
        default:
            printf("ERROR: UNKNOWN CONNMARK MODE ");
index 6afb78ec916bb9ee6ffb4b040df78164277545bc..5bb249127646fe011fdebe512e45919813900216 100644 (file)
@@ -26,7 +26,7 @@
 #include <getopt.h>
 
 #include <iptables.h>
-#include <linux/netfilter_ipv4/ipt_connmark.h>
+#include "../include/linux/netfilter_ipv4/ipt_connmark.h"
 
 /* Function which prints out usage message. */
 static void
@@ -66,11 +66,17 @@ parse(int c, char **argv, int invert, unsigned int *flags,
                char *end;
        case '1':
                check_inverse(optarg, &invert, &optind, 0);
+#ifdef KERNEL_64_USERSPACE_32
+               markinfo->mark = strtoull(optarg, &end, 0);
+               markinfo->mask = ~0ULL;
+               if (*end == '/')
+                       markinfo->mask = strtoull(end+1, &end, 0);
+#else
                markinfo->mark = strtoul(optarg, &end, 0);
-               if (*end == '/') {
+               markinfo->mask = ~0UL;
+               if (*end == '/')
                        markinfo->mask = strtoul(end+1, &end, 0);
-               } else
-                       markinfo->mask = ~0;
+#endif
                if (*end != '\0' || end == optarg)
                        exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
                if (invert)
@@ -84,14 +90,25 @@ parse(int c, char **argv, int invert, unsigned int *flags,
        return 1;
 }
 
+#ifdef KERNEL_64_USERSPACE_32
+static void
+print_mark(unsigned long long mark, unsigned long long mask, int numeric)
+{
+       if(mask != ~0ULL)
+               printf("0x%llx/0x%llx ", mark, mask);
+       else
+               printf("0x%llx ", mark);
+}
+#else
 static void
 print_mark(unsigned long mark, unsigned long mask, int numeric)
 {
-       if(mask != ~0)
+       if(mask != ~0UL)
                printf("0x%lx/0x%lx ", mark, mask);
        else
                printf("0x%lx ", mark);
 }
+#endif
 
 /* Final check; must have specified --mark. */
 static void
index d3c02536fc4c471063f56930673cc24a94ede8cb..0148539be73e7ca77e0dcdddbf4bf73526f62852 100644 (file)
@@ -17,8 +17,13 @@ enum {
 };
 
 struct ipt_connmark_target_info {
+#ifdef KERNEL_64_USERSPACE_32
+       unsigned long long mark;
+       unsigned long long mask;
+#else
        unsigned long mark;
        unsigned long mask;
+#endif
        u_int8_t mode;
 };
 
index 46573270d9aa23781d0d2dd4a2bbf3688149b24b..151e2687080cc985329cd76df3747fb4523104a4 100644 (file)
  */
 
 struct ipt_connmark_info {
+#ifdef KERNEL_64_USERSPACE_32
+       unsigned long long mark, mask;
+#else
        unsigned long mark, mask;
+#endif
        u_int8_t invert;
 };