From 1b6c7632e5e35ecce91f87a4ae36eca3103cfee2 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 24 May 2011 14:49:15 +0200 Subject: libxtables: unclutter xtopt_parse_mint ..by moving type-based actions into their own function. Signed-off-by: Jan Engelhardt --- xtoptions.c | 148 ++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 94 insertions(+), 54 deletions(-) (limited to 'xtoptions.c') diff --git a/xtoptions.c b/xtoptions.c index 1fc90ee8..30d70b0c 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -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. -- cgit v1.2.3