]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxtables: XTTYPE_UINT32RC support
authorJan Engelhardt <jengelh@medozas.de>
Sun, 27 Feb 2011 22:41:10 +0000 (23:41 +0100)
committerJan Engelhardt <jengelh@medozas.de>
Wed, 6 Apr 2011 11:12:55 +0000 (13:12 +0200)
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
include/xtables.h.in
xtoptions.c

index dc074bc099d1f9f45838c4d3138be501e1cd7cd1..3e596e0c130c95f8f7e243b9674934ed17125187 100644 (file)
@@ -48,11 +48,13 @@ struct in_addr;
 /**
  * %XTTYPE_NONE:       option takes no argument
  * %XTTYPE_UINT*:      standard integer
+ * %XTTYPE_UINT*RC:    colon-separated range of standard integers
  */
 enum xt_option_type {
        XTTYPE_NONE,
        XTTYPE_UINT8,
        XTTYPE_UINT32,
+       XTTYPE_UINT32RC,
 };
 
 /**
@@ -96,6 +98,7 @@ struct xt_option_entry {
  * @data:      per-extension data block
  * @xflags:    options of the extension that have been used
  * @invert:    whether option was used with !
+ * @nvals:     number of results in uXX_multi
  * @val:       parsed result
  */
 struct xt_option_call {
@@ -104,9 +107,10 @@ struct xt_option_call {
        void *data;
        unsigned int xflags;
        bool invert;
+       uint8_t nvals;
        union {
                uint8_t u8;
-               uint32_t u32;
+               uint32_t u32, u32_range[2];
        } val;
 };
 
index 693c06d65ec61af89ef472346c29002ca8d66793..03c629e06b9c42fff1c35a73f3b2770545047df5 100644 (file)
@@ -113,14 +113,66 @@ static void xtopt_parse_int(struct xt_option_call *cb)
        }
 }
 
+/**
+ * Multiple integer parse routine.
+ *
+ * This function is capable of parsing any number of fields. Only the first
+ * two values from the string will be put into @cb however (and as such,
+ * @cb->val.uXX_range is just that large) to cater for the few extensions that
+ * do not have a range[2] field, but {min, max}, and which cannot use
+ * XTOPT_POINTER.
+ */
+static void xtopt_parse_mint(struct xt_option_call *cb)
+{
+       const struct xt_option_entry *entry = cb->entry;
+       const char *arg = cb->arg;
+       uint32_t *put = XTOPT_MKPTR(cb);
+       unsigned int maxiter, value;
+       char *end = "";
+       char sep = ':';
+
+       maxiter = entry->size / sizeof(uint32_t);
+       if (maxiter == 0)
+               maxiter = 2; /* ARRAY_SIZE(cb->val.uXX_range) */
+       if (entry->size % sizeof(uint32_t) != 0)
+               xt_params->exit_err(OTHER_PROBLEM, "%s: memory block does "
+                       "not have proper size\n", __func__);
+
+       cb->nvals = 0;
+       for (arg = cb->arg; ; arg = end + 1) {
+               if (cb->nvals == maxiter)
+                       xt_params->exit_err(PARAMETER_PROBLEM, "%s: Too many "
+                               "components for option \"--%s\" (max: %u)\n",
+                               cb->ext_name, entry->name, maxiter);
+               if (!xtables_strtoui(arg, &end, &value, 0, UINT32_MAX))
+                       xt_params->exit_err(PARAMETER_PROBLEM,
+                               "%s: bad value for option \"--%s\", "
+                               "or out of range (0-%u).\n",
+                               cb->ext_name, entry->name, UINT32_MAX);
+               if (*end != '\0' && *end != sep)
+                       xt_params->exit_err(PARAMETER_PROBLEM,
+                               "%s: Argument to \"--%s\" has unexpected "
+                               "characters.\n", cb->ext_name, entry->name);
+               ++cb->nvals;
+               if (cb->nvals < ARRAY_SIZE(cb->val.u32_range))
+                       cb->val.u32_range[cb->nvals] = value;
+               if (entry->flags & XTOPT_PUT)
+                       *put++ = value;
+               if (*end == '\0')
+                       break;
+       }
+}
+
 static void (*const xtopt_subparse[])(struct xt_option_call *) = {
        [XTTYPE_UINT8]       = xtopt_parse_int,
        [XTTYPE_UINT32]      = xtopt_parse_int,
+       [XTTYPE_UINT32RC]    = xtopt_parse_mint,
 };
 
 static const size_t xtopt_psize[] = {
        [XTTYPE_UINT8]       = sizeof(uint8_t),
        [XTTYPE_UINT32]      = sizeof(uint32_t),
+       [XTTYPE_UINT32RC]    = sizeof(uint32_t[2]),
 };
 
 /**
@@ -180,7 +232,8 @@ void xtables_option_metavalidate(const char *name,
                                "%s: entry type of option \"--%s\" cannot be "
                                "combined with XTOPT_PUT\n",
                                name, entry->name);
-               if (xtopt_psize[entry->type] != entry->size)
+               if (xtopt_psize[entry->type] != -1 &&
+                   xtopt_psize[entry->type] != entry->size)
                        xt_params->exit_err(OTHER_PROBLEM,
                                "%s: option \"--%s\" points to a memory block "
                                "of wrong size (expected %zu, got %zu)\n",