]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxtables: unclutter xtopt_parse_mint
authorJan Engelhardt <jengelh@medozas.de>
Tue, 24 May 2011 12:49:15 +0000 (14:49 +0200)
committerJan Engelhardt <jengelh@medozas.de>
Tue, 24 May 2011 13:21:18 +0000 (15:21 +0200)
..by moving type-based actions into their own function.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
xtoptions.c

index 1fc90ee8294a28bfd8f61dafb044481d415ddf7c..30d70b0cf932850d7cfde11ee0032a8a62469da5 100644 (file)
@@ -41,6 +41,31 @@ struct tos_value_mask {
        uint8_t value, mask;
 };
 
+static const size_t xtopt_psize[] = {
+       /*
+        * All types not listed here, and thus essentially being initialized to
+        * zero have zero on purpose.
+        */
+       [XTTYPE_UINT8]       = sizeof(uint8_t),
+       [XTTYPE_UINT16]      = sizeof(uint16_t),
+       [XTTYPE_UINT32]      = sizeof(uint32_t),
+       [XTTYPE_UINT64]      = sizeof(uint64_t),
+       [XTTYPE_UINT8RC]     = sizeof(uint8_t[2]),
+       [XTTYPE_UINT16RC]    = sizeof(uint16_t[2]),
+       [XTTYPE_UINT32RC]    = sizeof(uint32_t[2]),
+       [XTTYPE_UINT64RC]    = sizeof(uint64_t[2]),
+       [XTTYPE_DOUBLE]      = sizeof(double),
+       [XTTYPE_STRING]      = -1,
+       [XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t),
+       [XTTYPE_HOST]        = sizeof(union nf_inet_addr),
+       [XTTYPE_HOSTMASK]    = sizeof(union nf_inet_addr),
+       [XTTYPE_PROTOCOL]    = sizeof(uint8_t),
+       [XTTYPE_PORT]        = sizeof(uint16_t),
+       [XTTYPE_PORTRC]      = sizeof(uint16_t[2]),
+       [XTTYPE_PLENMASK]    = sizeof(union nf_inet_addr),
+       [XTTYPE_ETHERMAC]    = sizeof(uint8_t[6]),
+};
+
 /**
  * Creates getopt options from the x6-style option map, and assigns each a
  * getopt id.
@@ -98,6 +123,9 @@ xtables_options_xfrm(struct option *orig_opts, struct option *oldopts,
        return merge;
 }
 
+/**
+ * Give the upper limit for a certain type.
+ */
 static uintmax_t xtopt_max_by_type(enum xt_option_type type)
 {
        switch (type) {
@@ -118,6 +146,26 @@ static uintmax_t xtopt_max_by_type(enum xt_option_type type)
        }
 }
 
+/**
+ * Return the size of a single entity based upon a type - predominantly an
+ * XTTYPE_UINT*RC type.
+ */
+static size_t xtopt_esize_by_type(enum xt_option_type type)
+{
+       switch (type) {
+       case XTTYPE_UINT8RC:
+               return xtopt_psize[XTTYPE_UINT8];
+       case XTTYPE_UINT16RC:
+               return xtopt_psize[XTTYPE_UINT16];
+       case XTTYPE_UINT32RC:
+               return xtopt_psize[XTTYPE_UINT32];
+       case XTTYPE_UINT64RC:
+               return xtopt_psize[XTTYPE_UINT64];
+       default:
+               return xtopt_psize[type];
+       }
+}
+
 /**
  * Require a simple integer.
  */
@@ -180,6 +228,48 @@ static void xtopt_parse_float(struct xt_option_call *cb)
                *(double *)XTOPT_MKPTR(cb) = cb->val.dbl;
 }
 
+/**
+ * Copy the parsed value to the appropriate entry in cb->val.
+ */
+static void xtopt_mint_value_to_cb(struct xt_option_call *cb, uintmax_t value)
+{
+       const struct xt_option_entry *entry = cb->entry;
+
+       if (cb->nvals >= ARRAY_SIZE(cb->val.u32_range))
+               return;
+       if (entry->type == XTTYPE_UINT8RC)
+               cb->val.u8_range[cb->nvals] = value;
+       else if (entry->type == XTTYPE_UINT16RC)
+               cb->val.u16_range[cb->nvals] = value;
+       else if (entry->type == XTTYPE_UINT32RC)
+               cb->val.u32_range[cb->nvals] = value;
+       else if (entry->type == XTTYPE_UINT64RC)
+               cb->val.u64_range[cb->nvals] = value;
+}
+
+/**
+ * Copy the parsed value to the data area, using appropriate type access.
+ */
+static void xtopt_mint_value_to_ptr(struct xt_option_call *cb, void **datap,
+                                   uintmax_t value)
+{
+       const struct xt_option_entry *entry = cb->entry;
+       void *data = *datap;
+
+       if (!(entry->flags & XTOPT_PUT))
+               return;
+       if (entry->type == XTTYPE_UINT8RC)
+               *(uint8_t *)data = value;
+       else if (entry->type == XTTYPE_UINT16RC)
+               *(uint16_t *)data = value;
+       else if (entry->type == XTTYPE_UINT32RC)
+               *(uint32_t *)data = value;
+       else if (entry->type == XTTYPE_UINT64RC)
+               *(uint64_t *)data = value;
+       data += xtopt_esize_by_type(entry->type);
+       *datap = data;
+}
+
 /**
  * Multiple integer parse routine.
  *
@@ -193,20 +283,14 @@ static void xtopt_parse_mint(struct xt_option_call *cb)
 {
        const struct xt_option_entry *entry = cb->entry;
        const char *arg = cb->arg;
-       size_t esize = sizeof(uint32_t);
+       size_t esize = xtopt_esize_by_type(entry->type);
        uintmax_t lmax = xtopt_max_by_type(entry->type);
-       char *put = XTOPT_MKPTR(cb);
+       void *put = XTOPT_MKPTR(cb);
        unsigned int maxiter;
        uintmax_t value;
        char *end = "";
        char sep = ':';
 
-       if (entry->type == XTTYPE_UINT8RC)
-               esize = sizeof(uint8_t);
-       else if (entry->type == XTTYPE_UINT16RC)
-               esize = sizeof(uint16_t);
-       else if (entry->type == XTTYPE_UINT64RC)
-               esize = sizeof(uint64_t);
        maxiter = entry->size / esize;
        if (maxiter == 0)
                maxiter = 2; /* ARRAY_SIZE(cb->val.uXX_range) */
@@ -230,28 +314,9 @@ static void xtopt_parse_mint(struct xt_option_call *cb)
                                "%s: Argument to \"--%s\" has unexpected "
                                "characters near \"%s\".\n",
                                cb->ext_name, entry->name, end);
-               if (cb->nvals < ARRAY_SIZE(cb->val.u32_range)) {
-                       if (entry->type == XTTYPE_UINT8RC)
-                               cb->val.u8_range[cb->nvals] = value;
-                       else if (entry->type == XTTYPE_UINT16RC)
-                               cb->val.u16_range[cb->nvals] = value;
-                       else if (entry->type == XTTYPE_UINT32RC)
-                               cb->val.u32_range[cb->nvals] = value;
-                       else if (entry->type == XTTYPE_UINT64RC)
-                               cb->val.u64_range[cb->nvals] = value;
-               }
+               xtopt_mint_value_to_cb(cb, value);
                ++cb->nvals;
-               if (entry->flags & XTOPT_PUT) {
-                       if (entry->type == XTTYPE_UINT8RC)
-                               *(uint8_t *)put = value;
-                       else if (entry->type == XTTYPE_UINT16RC)
-                               *(uint16_t *)put = value;
-                       else if (entry->type == XTTYPE_UINT32RC)
-                               *(uint32_t *)put = value;
-                       else if (entry->type == XTTYPE_UINT64RC)
-                               *(uint64_t *)put = value;
-                       put += esize;
-               }
+               xtopt_mint_value_to_ptr(cb, &put, value);
                if (*end == '\0')
                        break;
        }
@@ -726,31 +791,6 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = {
        [XTTYPE_ETHERMAC]    = xtopt_parse_ethermac,
 };
 
-static const size_t xtopt_psize[] = {
-       /*
-        * All types not listed here, and thus essentially being initialized to
-        * zero have zero on purpose.
-        */
-       [XTTYPE_UINT8]       = sizeof(uint8_t),
-       [XTTYPE_UINT16]      = sizeof(uint16_t),
-       [XTTYPE_UINT32]      = sizeof(uint32_t),
-       [XTTYPE_UINT64]      = sizeof(uint64_t),
-       [XTTYPE_UINT8RC]     = sizeof(uint8_t[2]),
-       [XTTYPE_UINT16RC]    = sizeof(uint16_t[2]),
-       [XTTYPE_UINT32RC]    = sizeof(uint32_t[2]),
-       [XTTYPE_UINT64RC]    = sizeof(uint64_t[2]),
-       [XTTYPE_DOUBLE]      = sizeof(double),
-       [XTTYPE_STRING]      = -1,
-       [XTTYPE_SYSLOGLEVEL] = sizeof(uint8_t),
-       [XTTYPE_HOST]        = sizeof(union nf_inet_addr),
-       [XTTYPE_HOSTMASK]    = sizeof(union nf_inet_addr),
-       [XTTYPE_PROTOCOL]    = sizeof(uint8_t),
-       [XTTYPE_PORT]        = sizeof(uint16_t),
-       [XTTYPE_PORTRC]      = sizeof(uint16_t[2]),
-       [XTTYPE_PLENMASK]    = sizeof(union nf_inet_addr),
-       [XTTYPE_ETHERMAC]    = sizeof(uint8_t[6]),
-};
-
 /**
  * The master option parsing routine. May be used for the ".x6_parse"
  * function pointer in extensions if fully automatic parsing is desired.