From 3a32dcbb5512bfc1fd385c26fb906ce8562200da Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 14 Apr 2011 13:34:18 +0200 Subject: build: bump libxtables ABI version Adding the x6_* members to struct xtables_{match,target} caused a change requiring a bump. Signed-off-by: Jan Engelhardt --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index eb447e09..38b7b793 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_INIT([iptables], [1.4.10]) # See libtool.info "Libtool's versioning system" -libxtables_vcurrent=5 +libxtables_vcurrent=6 libxtables_vage=0 AC_CONFIG_HEADERS([config.h]) -- cgit v1.2.3 From d44c31ac8e52f34e058f44aba14f679abcc7edf9 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 14 Apr 2011 13:42:43 +0200 Subject: libxt_TEE: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_TEE.c | 103 +++++++------------------------------------------ 1 file changed, 14 insertions(+), 89 deletions(-) diff --git a/extensions/libxt_TEE.c b/extensions/libxt_TEE.c index 00a4de67..fd9a1b23 100644 --- a/extensions/libxt_TEE.c +++ b/extensions/libxt_TEE.c @@ -25,15 +25,19 @@ #include enum { - FLAG_GATEWAY = 1 << 0, - FLAG_OIF = 1 << 1, + O_GATEWAY = 0, + O_OIF, }; -static const struct option tee_tg_opts[] = { - {.name = "gateway", .has_arg = true, .val = 'g'}, - {.name = "oif", .has_arg = true, .val = 'o'}, - {NULL}, +#define s struct xt_tee_tginfo +static const struct xt_option_entry tee_tg_opts[] = { + {.name = "gateway", .id = O_GATEWAY, .type = XTTYPE_ONEHOST, + .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, gw)}, + {.name = "oif", .id = O_OIF, .type = XTTYPE_STRING, + .flags = XTOPT_PUT, XTOPT_POINTER(s, oif)}, + XTOPT_TABLEEND, }; +#undef s static void tee_tg_help(void) { @@ -44,83 +48,6 @@ static void tee_tg_help(void) "\n"); } -static int tee_tg_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct xt_tee_tginfo *info = (void *)(*target)->data; - const struct in_addr *ia; - - switch (c) { - case 'g': - if (*flags & FLAG_GATEWAY) - xtables_error(PARAMETER_PROBLEM, - "Cannot specify --gateway more than once"); - - ia = xtables_numeric_to_ipaddr(optarg); - if (ia == NULL) - xtables_error(PARAMETER_PROBLEM, - "Invalid IP address %s", optarg); - - memcpy(&info->gw, ia, sizeof(*ia)); - *flags |= FLAG_GATEWAY; - return true; - case 'o': - if (*flags & FLAG_OIF) - xtables_error(PARAMETER_PROBLEM, - "Cannot specify --oif more than once"); - if (strlen(optarg) >= sizeof(info->oif)) - xtables_error(PARAMETER_PROBLEM, - "oif name too long"); - strcpy(info->oif, optarg); - *flags |= FLAG_OIF; - return true; - } - - return false; -} - -static int tee_tg6_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct xt_tee_tginfo *info = (void *)(*target)->data; - const struct in6_addr *ia; - - switch (c) { - case 'g': - if (*flags & FLAG_GATEWAY) - xtables_error(PARAMETER_PROBLEM, - "Cannot specify --gateway more than once"); - - ia = xtables_numeric_to_ip6addr(optarg); - if (ia == NULL) - xtables_error(PARAMETER_PROBLEM, - "Invalid IP address %s", optarg); - - memcpy(&info->gw, ia, sizeof(*ia)); - *flags |= FLAG_GATEWAY; - return true; - case 'o': - if (*flags & FLAG_OIF) - xtables_error(PARAMETER_PROBLEM, - "Cannot specify --oif more than once"); - if (strlen(optarg) >= sizeof(info->oif)) - xtables_error(PARAMETER_PROBLEM, - "oif name too long"); - strcpy(info->oif, optarg); - *flags |= FLAG_OIF; - return true; - } - - return false; -} - -static void tee_tg_check(unsigned int flags) -{ - if (flags == 0) - xtables_error(PARAMETER_PROBLEM, "TEE target: " - "--gateway parameter required"); -} - static void tee_tg_print(const void *ip, const struct xt_entry_target *target, int numeric) { @@ -173,11 +100,10 @@ static struct xtables_target tee_tg_reg = { .size = XT_ALIGN(sizeof(struct xt_tee_tginfo)), .userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)), .help = tee_tg_help, - .parse = tee_tg_parse, - .final_check = tee_tg_check, .print = tee_tg_print, .save = tee_tg_save, - .extra_opts = tee_tg_opts, + .x6_parse = xtables_option_parse, + .x6_options = tee_tg_opts, }; static struct xtables_target tee_tg6_reg = { @@ -188,11 +114,10 @@ static struct xtables_target tee_tg6_reg = { .size = XT_ALIGN(sizeof(struct xt_tee_tginfo)), .userspacesize = XT_ALIGN(sizeof(struct xt_tee_tginfo)), .help = tee_tg_help, - .parse = tee_tg6_parse, - .final_check = tee_tg_check, .print = tee_tg6_print, .save = tee_tg6_save, - .extra_opts = tee_tg_opts, + .x6_parse = xtables_option_parse, + .x6_options = tee_tg_opts, }; void _init(void) -- cgit v1.2.3 From 44517bda3d8130638882f69478a8091316f30cbb Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 14 Apr 2011 13:54:24 +0200 Subject: xtoptions: respect return value in xtables_getportbyname If ret was negative, ntohs may make it positive, which is undesired. Signed-off-by: Jan Engelhardt --- xtoptions.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xtoptions.c b/xtoptions.c index c3cc40e6..8478d26d 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -379,6 +379,8 @@ static int xtables_getportbyname(const char *name) } } freeaddrinfo(res); + if (ret < 0) + return ret; return ntohs(ret); } -- cgit v1.2.3 From 61cc52b6f9edfa3efb1d0c9ea9531abb42828ec2 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 29 Apr 2011 01:25:14 +0200 Subject: libxt_TOS: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_TOS.c | 137 ++++++++++++++++++++----------------------------- include/xtables.h.in | 5 ++ xtoptions.c | 81 +++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 80 deletions(-) diff --git a/extensions/libxt_TOS.c b/extensions/libxt_TOS.c index 58ff2fc7..cef58765 100644 --- a/extensions/libxt_TOS.c +++ b/extensions/libxt_TOS.c @@ -2,7 +2,7 @@ * Shared library add-on to iptables to add TOS target support * * Copyright © CC Computer Consultants GmbH, 2007 - * Contact: Jan Engelhardt + * Contact: Jan Engelhardt */ #include #include @@ -20,20 +20,33 @@ struct ipt_tos_target_info { }; enum { - FLAG_TOS = 1 << 0, + O_SET_TOS = 0, + O_AND_TOS, + O_OR_TOS, + O_XOR_TOS, + F_SET_TOS = 1 << O_SET_TOS, + F_AND_TOS = 1 << O_AND_TOS, + F_OR_TOS = 1 << O_OR_TOS, + F_XOR_TOS = 1 << O_XOR_TOS, + F_ANY = F_SET_TOS | F_AND_TOS | F_OR_TOS | F_XOR_TOS, }; -static const struct option tos_tg_opts_v0[] = { - {.name = "set-tos", .has_arg = true, .val = '='}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry tos_tg_opts_v0[] = { + {.name = "set-tos", .id = O_SET_TOS, .type = XTTYPE_TOSMASK, + .excl = F_ANY, .max = 0xFF}, + XTOPT_TABLEEND, }; -static const struct option tos_tg_opts[] = { - {.name = "set-tos", .has_arg = true, .val = '='}, - {.name = "and-tos", .has_arg = true, .val = '&'}, - {.name = "or-tos", .has_arg = true, .val = '|'}, - {.name = "xor-tos", .has_arg = true, .val = '^'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry tos_tg_opts[] = { + {.name = "set-tos", .id = O_SET_TOS, .type = XTTYPE_TOSMASK, + .excl = F_ANY, .max = 0x3F}, + {.name = "and-tos", .id = O_AND_TOS, .type = XTTYPE_UINT8, + .excl = F_ANY}, + {.name = "or-tos", .id = O_OR_TOS, .type = XTTYPE_UINT8, + .excl = F_ANY}, + {.name = "xor-tos", .id = O_XOR_TOS, .type = XTTYPE_UINT8, + .excl = F_ANY}, + XTOPT_TABLEEND, }; static void tos_tg_help_v0(void) @@ -78,84 +91,48 @@ XTABLES_VERSION); ); } -static int tos_tg_parse_v0(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void tos_tg_parse_v0(struct xt_option_call *cb) { - struct ipt_tos_target_info *info = (void *)(*target)->data; - struct tos_value_mask tvm; - - switch (c) { - case '=': - xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS); - xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert); - if (!tos_parse_symbolic(optarg, &tvm, 0xFF)) - xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg); - if (tvm.mask != 0xFF) - xtables_error(PARAMETER_PROBLEM, "tos match: Your kernel " - "is too old to support anything besides " - "/0xFF as a mask."); - info->tos = tvm.value; - *flags |= FLAG_TOS; - return true; - } - - return false; + struct ipt_tos_target_info *info = cb->data; + + xtables_option_parse(cb); + if (cb->val.tos_mask != 0xFF) + xtables_error(PARAMETER_PROBLEM, "tos match: Your kernel " + "is too old to support anything besides " + "/0xFF as a mask."); + info->tos = cb->val.tos_value; } -static int tos_tg_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void tos_tg_parse(struct xt_option_call *cb) { - struct xt_tos_target_info *info = (void *)(*target)->data; - struct tos_value_mask tvm; - unsigned int bits; - - switch (c) { - case '=': /* --set-tos */ - xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS); - xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert); - if (!tos_parse_symbolic(optarg, &tvm, 0x3F)) - xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg); - info->tos_value = tvm.value; - info->tos_mask = tvm.mask; - break; + struct xt_tos_target_info *info = cb->data; - case '&': /* --and-tos */ - xtables_param_act(XTF_ONLY_ONCE, "TOS", "--and-tos", *flags & FLAG_TOS); - xtables_param_act(XTF_NO_INVERT, "TOS", "--and-tos", invert); - if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) - xtables_param_act(XTF_BAD_VALUE, "TOS", "--and-tos", optarg); + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SET_TOS: + info->tos_value = cb->val.tos_value; + info->tos_mask = cb->val.tos_mask; + break; + case O_AND_TOS: info->tos_value = 0; - info->tos_mask = ~bits; + info->tos_mask = ~cb->val.u8; break; - - case '|': /* --or-tos */ - xtables_param_act(XTF_ONLY_ONCE, "TOS", "--or-tos", *flags & FLAG_TOS); - xtables_param_act(XTF_NO_INVERT, "TOS", "--or-tos", invert); - if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) - xtables_param_act(XTF_BAD_VALUE, "TOS", "--or-tos", optarg); - info->tos_value = bits; - info->tos_mask = bits; + case O_OR_TOS: + info->tos_value = cb->val.u8; + info->tos_mask = cb->val.u8; break; - - case '^': /* --xor-tos */ - xtables_param_act(XTF_ONLY_ONCE, "TOS", "--xor-tos", *flags & FLAG_TOS); - xtables_param_act(XTF_NO_INVERT, "TOS", "--xor-tos", invert); - if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) - xtables_param_act(XTF_BAD_VALUE, "TOS", "--xor-tos", optarg); - info->tos_value = bits; + case O_XOR_TOS: + info->tos_value = cb->val.u8; info->tos_mask = 0; break; } - - *flags |= FLAG_TOS; - return true; } -static void tos_tg_check(unsigned int flags) +static void tos_tg_check(struct xt_fcheck_call *cb) { - if (flags == 0) + if (!(cb->xflags & F_ANY)) xtables_error(PARAMETER_PROBLEM, - "TOS: The --set-tos parameter is required"); + "TOS: An action is required"); } static void tos_tg_print_v0(const void *ip, @@ -215,11 +192,11 @@ static struct xtables_target tos_tg_reg[] = { .size = XT_ALIGN(sizeof(struct xt_tos_target_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)), .help = tos_tg_help_v0, - .parse = tos_tg_parse_v0, - .final_check = tos_tg_check, .print = tos_tg_print_v0, .save = tos_tg_save_v0, - .extra_opts = tos_tg_opts_v0, + .x6_parse = tos_tg_parse_v0, + .x6_fcheck = tos_tg_check, + .x6_options = tos_tg_opts_v0, }, { .version = XTABLES_VERSION, @@ -229,11 +206,11 @@ static struct xtables_target tos_tg_reg[] = { .size = XT_ALIGN(sizeof(struct xt_tos_target_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)), .help = tos_tg_help, - .parse = tos_tg_parse, - .final_check = tos_tg_check, .print = tos_tg_print, .save = tos_tg_save, - .extra_opts = tos_tg_opts, + .x6_parse = tos_tg_parse, + .x6_fcheck = tos_tg_check, + .x6_options = tos_tg_opts, }, }; diff --git a/include/xtables.h.in b/include/xtables.h.in index a9a9ffad..b06ab613 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -50,6 +50,7 @@ struct in_addr; * %XTTYPE_UINT*: standard integer * %XTTYPE_UINT*RC: colon-separated range of standard integers * %XTTYPE_STRING: arbitrary string + * %XTTYPE_TOSMASK: 8-bit TOS value with optional mask * %XTTYPE_MARKMASK32: 32-bit mark with optional mask * %XTTYPE_SYSLOGLEVEL: syslog level by name or number * %XTTYPE_ONEHOST: one host or address (union nf_inet_addr) @@ -67,6 +68,7 @@ enum xt_option_type { XTTYPE_UINT32RC, XTTYPE_UINT64RC, XTTYPE_STRING, + XTTYPE_TOSMASK, XTTYPE_MARKMASK32, XTTYPE_SYSLOGLEVEL, XTTYPE_ONEHOST, @@ -131,6 +133,9 @@ struct xt_option_call { uint32_t u32, u32_range[2]; uint64_t u64, u64_range[2]; union nf_inet_addr inetaddr; + struct { + uint8_t tos_value, tos_mask; + }; struct { uint32_t mark, mask; }; diff --git a/xtoptions.c b/xtoptions.c index 8478d26d..69e43e95 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -19,8 +19,12 @@ #include #include #include +#include #include "xtables.h" #include "xshared.h" +#ifndef IPTOS_NORMALSVC +# define IPTOS_NORMALSVC 0 +#endif #define XTOPT_MKPTR(cb) \ ((void *)((char *)(cb)->data + (cb)->entry->ptroff)) @@ -33,6 +37,10 @@ struct syslog_level { uint8_t level; }; +struct tos_value_mask { + uint8_t value, mask; +}; + /** * Creates getopt options from the x6-style option map, and assigns each a * getopt id. @@ -232,6 +240,78 @@ static void xtopt_parse_string(struct xt_option_call *cb) p[z] = '\0'; } +static const struct tos_symbol_info { + unsigned char value; + const char *name; +} tos_symbol_names[] = { + {IPTOS_LOWDELAY, "Minimize-Delay"}, + {IPTOS_THROUGHPUT, "Maximize-Throughput"}, + {IPTOS_RELIABILITY, "Maximize-Reliability"}, + {IPTOS_MINCOST, "Minimize-Cost"}, + {IPTOS_NORMALSVC, "Normal-Service"}, + {}, +}; + +/* + * tos_parse_numeric - parse a string like "15/255" + * + * @str: input string + * @tvm: (value/mask) tuple + * @max: maximum allowed value (must be pow(2,some_int)-1) + */ +static bool tos_parse_numeric(const char *str, struct xt_option_call *cb, + unsigned int max) +{ + unsigned int value; + char *end; + + xtables_strtoui(str, &end, &value, 0, max); + cb->val.tos_value = value; + cb->val.tos_mask = max; + + if (*end == '/') { + const char *p = end + 1; + + if (!xtables_strtoui(p, &end, &value, 0, max)) + xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", + str); + cb->val.tos_mask = value; + } + + if (*end != '\0') + xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", str); + return true; +} + +/** + * @str: input string + * @tvm: (value/mask) tuple + * @def_mask: mask to force when a symbolic name is used + */ +static void xtopt_parse_tosmask(struct xt_option_call *cb) +{ + const struct tos_symbol_info *symbol; + char *tmp; + + if (xtables_strtoui(cb->arg, &tmp, NULL, 0, UINT8_MAX)) { + tos_parse_numeric(cb->arg, cb, UINT8_MAX); + return; + } + /* + * This is our way we deal with different defaults + * for different revisions. + */ + cb->val.tos_mask = cb->entry->max; + for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) + if (strcasecmp(cb->arg, symbol->name) == 0) { + cb->val.tos_value = symbol->value; + return; + } + + xtables_error(PARAMETER_PROBLEM, "Symbolic name \"%s\" is unknown", + cb->arg); +} + /** * Validate the input for being conformant to "mark[/mask]". */ @@ -413,6 +493,7 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = { [XTTYPE_UINT32RC] = xtopt_parse_mint, [XTTYPE_UINT64RC] = xtopt_parse_mint, [XTTYPE_STRING] = xtopt_parse_string, + [XTTYPE_TOSMASK] = xtopt_parse_tosmask, [XTTYPE_MARKMASK32] = xtopt_parse_markmask, [XTTYPE_SYSLOGLEVEL] = xtopt_parse_sysloglevel, [XTTYPE_ONEHOST] = xtopt_parse_onehost, -- cgit v1.2.3 From d8f591993eb610b41f3170a94a879edd24ad348a Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 29 Apr 2011 02:12:56 +0200 Subject: libxt_tos: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_tos.c | 88 +++++++++++++++++++------------------------------- 1 file changed, 33 insertions(+), 55 deletions(-) diff --git a/extensions/libxt_tos.c b/extensions/libxt_tos.c index 8b83e180..7646a4f3 100644 --- a/extensions/libxt_tos.c +++ b/extensions/libxt_tos.c @@ -21,12 +21,19 @@ struct ipt_tos_info { }; enum { - FLAG_TOS = 1 << 0, + O_TOS = 1 << 0, }; -static const struct option tos_mt_opts[] = { - {.name = "tos", .has_arg = true, .val = 't'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry tos_mt_opts_v0[] = { + {.name = "tos", .id = O_TOS, .type = XTTYPE_TOSMASK, + .flags = XTOPT_MAND, .max = 0xFF}, + XTOPT_TABLEEND, +}; + +static const struct xt_option_entry tos_mt_opts[] = { + {.name = "tos", .id = O_TOS, .type = XTTYPE_TOSMASK, + .flags = XTOPT_MAND, .max = 0x3F}, + XTOPT_TABLEEND, }; static void tos_mt_help(void) @@ -46,56 +53,29 @@ static void tos_mt_help(void) printf("\n"); } -static int tos_mt_parse_v0(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void tos_mt_parse_v0(struct xt_option_call *cb) { - struct ipt_tos_info *info = (void *)(*match)->data; - struct tos_value_mask tvm; - - switch (c) { - case 't': - xtables_param_act(XTF_ONLY_ONCE, "tos", "--tos", *flags & FLAG_TOS); - if (!tos_parse_symbolic(optarg, &tvm, 0xFF)) - xtables_param_act(XTF_BAD_VALUE, "tos", "--tos", optarg); - if (tvm.mask != 0xFF) - xtables_error(PARAMETER_PROBLEM, "tos: Your kernel is " - "too old to support anything besides /0xFF " - "as a mask."); - info->tos = tvm.value; - if (invert) - info->invert = true; - *flags |= FLAG_TOS; - return true; - } - return false; + struct ipt_tos_info *info = cb->data; + + xtables_option_parse(cb); + if (cb->val.tos_mask != 0xFF) + xtables_error(PARAMETER_PROBLEM, "tos: Your kernel is " + "too old to support anything besides /0xFF " + "as a mask."); + info->tos = cb->val.tos_value; + if (cb->invert) + info->invert = true; } -static int tos_mt_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void tos_mt_parse(struct xt_option_call *cb) { - struct xt_tos_match_info *info = (void *)(*match)->data; - struct tos_value_mask tvm = {.mask = 0xFF}; - - switch (c) { - case 't': - xtables_param_act(XTF_ONLY_ONCE, "tos", "--tos", *flags & FLAG_TOS); - if (!tos_parse_symbolic(optarg, &tvm, 0x3F)) - xtables_param_act(XTF_BAD_VALUE, "tos", "--tos", optarg); - info->tos_value = tvm.value; - info->tos_mask = tvm.mask; - if (invert) - info->invert = true; - *flags |= FLAG_TOS; - return true; - } - return false; -} + struct xt_tos_match_info *info = cb->data; -static void tos_mt_check(unsigned int flags) -{ - if (flags == 0) - xtables_error(PARAMETER_PROBLEM, - "tos: --tos parameter required"); + xtables_option_parse(cb); + info->tos_value = cb->val.tos_value; + info->tos_mask = cb->val.tos_mask; + if (cb->invert) + info->invert = true; } static void tos_mt_print_v0(const void *ip, const struct xt_entry_match *match, @@ -150,11 +130,10 @@ static struct xtables_match tos_mt_reg[] = { .size = XT_ALIGN(sizeof(struct ipt_tos_info)), .userspacesize = XT_ALIGN(sizeof(struct ipt_tos_info)), .help = tos_mt_help, - .parse = tos_mt_parse_v0, - .final_check = tos_mt_check, .print = tos_mt_print_v0, .save = tos_mt_save_v0, - .extra_opts = tos_mt_opts, + .x6_parse = tos_mt_parse_v0, + .x6_options = tos_mt_opts_v0, }, { .version = XTABLES_VERSION, @@ -164,11 +143,10 @@ static struct xtables_match tos_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_tos_match_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_tos_match_info)), .help = tos_mt_help, - .parse = tos_mt_parse, - .final_check = tos_mt_check, .print = tos_mt_print, .save = tos_mt_save, - .extra_opts = tos_mt_opts, + .x6_parse = tos_mt_parse, + .x6_options = tos_mt_opts, }, }; -- cgit v1.2.3 From ee1fbbe536c6dd3a252886815314cf910d672ca6 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 29 Apr 2011 02:19:52 +0200 Subject: extensions: remove unused TOS code Signed-off-by: Jan Engelhardt --- extensions/tos_values.c | 58 ------------------------------------------------- 1 file changed, 58 deletions(-) diff --git a/extensions/tos_values.c b/extensions/tos_values.c index c5efd9d7..6dc4743c 100644 --- a/extensions/tos_values.c +++ b/extensions/tos_values.c @@ -23,64 +23,6 @@ static const struct tos_symbol_info { {}, }; -/* - * tos_parse_numeric - parse sth. like "15/255" - * - * @str: input string - * @tvm: (value/mask) tuple - * @max: maximum allowed value (must be pow(2,some_int)-1) - */ -static bool tos_parse_numeric(const char *str, struct tos_value_mask *tvm, - unsigned int max) -{ - unsigned int value; - char *end; - - xtables_strtoui(str, &end, &value, 0, max); - tvm->value = value; - tvm->mask = max; - - if (*end == '/') { - const char *p = end + 1; - - if (!xtables_strtoui(p, &end, &value, 0, max)) - xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", - str); - tvm->mask = value; - } - - if (*end != '\0') - xtables_error(PARAMETER_PROBLEM, "Illegal value: \"%s\"", str); - return true; -} - -/** - * @str: input string - * @tvm: (value/mask) tuple - * @def_mask: mask to force when a symbolic name is used - */ -static bool tos_parse_symbolic(const char *str, struct tos_value_mask *tvm, - unsigned int def_mask) -{ - static const unsigned int max = UINT8_MAX; - const struct tos_symbol_info *symbol; - char *tmp; - - if (xtables_strtoui(str, &tmp, NULL, 0, max)) - return tos_parse_numeric(str, tvm, max); - - /* Do not consider ECN bits when using preset names */ - tvm->mask = def_mask; - for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol) - if (strcasecmp(str, symbol->name) == 0) { - tvm->value = symbol->value; - return true; - } - - xtables_error(PARAMETER_PROBLEM, "Symbolic name \"%s\" is unknown", str); - return false; -} - static bool tos_try_print_symbolic(const char *prefix, uint8_t value, uint8_t mask) { -- cgit v1.2.3 From f30231a02e145020fb47524f9a0daeb498a4f7d0 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 17 Apr 2011 13:33:50 +0200 Subject: libxtables: XTTYPE_PORTRC support Signed-off-by: Jan Engelhardt --- include/xtables.h.in | 6 +++++- xtoptions.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/include/xtables.h.in b/include/xtables.h.in index b06ab613..0cd9f9f8 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -56,6 +56,8 @@ struct in_addr; * %XTTYPE_ONEHOST: one host or address (union nf_inet_addr) * %XTTYPE_PORT: 16-bit port name or number * %XTTYPE_PORT_NE: 16-bit port name or number, stored as network-endian + * %XTTYPE_PORTRC: colon-separated port range (names acceptable) + * %XTTYPE_PORTRC_NE: same as %XTTYPE_PORTRC, stored in network-endian */ enum xt_option_type { XTTYPE_NONE, @@ -74,6 +76,8 @@ enum xt_option_type { XTTYPE_ONEHOST, XTTYPE_PORT, XTTYPE_PORT_NE, + XTTYPE_PORTRC, + XTTYPE_PORTRC_NE, }; /** @@ -129,7 +133,7 @@ struct xt_option_call { uint8_t nvals; union { uint8_t u8, u8_range[2], syslog_level; - uint16_t u16, u16_range[2], port; + uint16_t u16, u16_range[2], port, port_range[2]; uint32_t u32, u32_range[2]; uint64_t u64, u64_range[2]; union nf_inet_addr inetaddr; diff --git a/xtoptions.c b/xtoptions.c index 69e43e95..5b1df889 100644 --- a/xtoptions.c +++ b/xtoptions.c @@ -483,6 +483,61 @@ static void xtopt_parse_port(struct xt_option_call *cb) *(uint16_t *)XTOPT_MKPTR(cb) = cb->val.port; } +static void xtopt_parse_mport(struct xt_option_call *cb) +{ + static const size_t esize = sizeof(uint16_t); + const struct xt_option_entry *entry = cb->entry; + char *lo_arg, *wp_arg, *arg; + unsigned int maxiter; + int value; + + wp_arg = lo_arg = strdup(cb->arg); + if (lo_arg == NULL) + xt_params->exit_err(RESOURCE_PROBLEM, "strdup"); + + maxiter = entry->size / esize; + if (maxiter == 0) + maxiter = 2; /* ARRAY_SIZE(cb->val.port_range) */ + if (entry->size % esize != 0) + xt_params->exit_err(OTHER_PROBLEM, "%s: memory block does " + "not have proper size\n", __func__); + + cb->val.port_range[0] = 0; + cb->val.port_range[1] = UINT16_MAX; + cb->nvals = 0; + + while ((arg = strsep(&wp_arg, ":")) != NULL) { + 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 (*arg == '\0') { + ++cb->nvals; + continue; + } + + value = xtables_getportbyname(arg); + if (value < 0) + xt_params->exit_err(PARAMETER_PROBLEM, + "Port \"%s\" does not resolve to " + "anything.\n", arg); + if (entry->type == XTTYPE_PORTRC_NE) + value = htons(value); + if (cb->nvals < ARRAY_SIZE(cb->val.port_range)) + cb->val.port_range[cb->nvals] = value; + ++cb->nvals; + } + + if (cb->nvals == 1) { + cb->val.port_range[1] = cb->val.port_range[0]; + ++cb->nvals; + } + if (entry->flags & XTOPT_PUT) + memcpy(XTOPT_MKPTR(cb), cb->val.port_range, sizeof(uint16_t) * + (cb->nvals <= maxiter ? cb->nvals : maxiter)); + free(lo_arg); +} + static void (*const xtopt_subparse[])(struct xt_option_call *) = { [XTTYPE_UINT8] = xtopt_parse_int, [XTTYPE_UINT16] = xtopt_parse_int, @@ -499,6 +554,8 @@ static void (*const xtopt_subparse[])(struct xt_option_call *) = { [XTTYPE_ONEHOST] = xtopt_parse_onehost, [XTTYPE_PORT] = xtopt_parse_port, [XTTYPE_PORT_NE] = xtopt_parse_port, + [XTTYPE_PORTRC] = xtopt_parse_mport, + [XTTYPE_PORTRC_NE] = xtopt_parse_mport, }; static const size_t xtopt_psize[] = { @@ -515,6 +572,8 @@ static const size_t xtopt_psize[] = { [XTTYPE_ONEHOST] = sizeof(union nf_inet_addr), [XTTYPE_PORT] = sizeof(uint16_t), [XTTYPE_PORT_NE] = sizeof(uint16_t), + [XTTYPE_PORTRC] = sizeof(uint16_t[2]), + [XTTYPE_PORTRC_NE] = sizeof(uint16_t[2]), }; /** -- cgit v1.2.3 From 2e73af96178f0ed7ebbd99478f1bc05ec5c86dc7 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 19 Apr 2011 15:44:48 +0200 Subject: libxt_udp: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_udp.c | 95 ++++++++++++++++---------------------------------- 1 file changed, 30 insertions(+), 65 deletions(-) diff --git a/extensions/libxt_udp.c b/extensions/libxt_udp.c index 505b3c88..d4930725 100644 --- a/extensions/libxt_udp.c +++ b/extensions/libxt_udp.c @@ -1,14 +1,15 @@ -/* Shared library add-on to iptables to add UDP support. */ -#include +#include #include #include -#include -#include -#include -#include +#include #include #include +enum { + O_SOURCE_PORT = 0, + O_DEST_PORT, +}; + static void udp_help(void) { printf( @@ -21,36 +22,19 @@ static void udp_help(void) " match destination port(s)\n"); } -static const struct option udp_opts[] = { - {.name = "source-port", .has_arg = true, .val = '1'}, - {.name = "sport", .has_arg = true, .val = '1'}, /* synonym */ - {.name = "destination-port", .has_arg = true, .val = '2'}, - {.name = "dport", .has_arg = true, .val = '2'}, /* synonym */ - XT_GETOPT_TABLEEND, +#define s struct xt_udp +static const struct xt_option_entry udp_opts[] = { + {.name = "source-port", .id = O_SOURCE_PORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, spts)}, + {.name = "sport", .id = O_SOURCE_PORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, spts)}, + {.name = "destination-port", .id = O_DEST_PORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, dpts)}, + {.name = "dport", .id = O_DEST_PORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, dpts)}, + XTOPT_TABLEEND, }; - -static void -parse_udp_ports(const char *portstring, uint16_t *ports) -{ - char *buffer; - char *cp; - - buffer = strdup(portstring); - if ((cp = strchr(buffer, ':')) == NULL) - ports[0] = ports[1] = xtables_parse_port(buffer, "udp"); - else { - *cp = '\0'; - cp++; - - ports[0] = buffer[0] ? xtables_parse_port(buffer, "udp") : 0; - ports[1] = cp[0] ? xtables_parse_port(cp, "udp") : 0xFFFF; - - if (ports[0] > ports[1]) - xtables_error(PARAMETER_PROBLEM, - "invalid portrange (min > max)"); - } - free(buffer); -} +#undef s static void udp_init(struct xt_entry_match *m) { @@ -59,40 +43,21 @@ static void udp_init(struct xt_entry_match *m) udpinfo->spts[1] = udpinfo->dpts[1] = 0xFFFF; } -#define UDP_SRC_PORTS 0x01 -#define UDP_DST_PORTS 0x02 - -static int -udp_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void udp_parse(struct xt_option_call *cb) { - struct xt_udp *udpinfo = (struct xt_udp *)(*match)->data; - - switch (c) { - case '1': - if (*flags & UDP_SRC_PORTS) - xtables_error(PARAMETER_PROBLEM, - "Only one `--source-port' allowed"); - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - parse_udp_ports(optarg, udpinfo->spts); - if (invert) + struct xt_udp *udpinfo = cb->data; + + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SOURCE_PORT: + if (cb->invert) udpinfo->invflags |= XT_UDP_INV_SRCPT; - *flags |= UDP_SRC_PORTS; break; - - case '2': - if (*flags & UDP_DST_PORTS) - xtables_error(PARAMETER_PROBLEM, - "Only one `--destination-port' allowed"); - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - parse_udp_ports(optarg, udpinfo->dpts); - if (invert) + case O_DEST_PORT: + if (cb->invert) udpinfo->invflags |= XT_UDP_INV_DSTPT; - *flags |= UDP_DST_PORTS; break; } - - return 1; } static char * @@ -195,10 +160,10 @@ static struct xtables_match udp_match = { .userspacesize = XT_ALIGN(sizeof(struct xt_udp)), .help = udp_help, .init = udp_init, - .parse = udp_parse, .print = udp_print, .save = udp_save, - .extra_opts = udp_opts, + .x6_parse = udp_parse, + .x6_options = udp_opts, }; void -- cgit v1.2.3 From 753bbed383cde1c18e05b5b726b6c28afbde3a3c Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 20 Apr 2011 10:17:33 +0200 Subject: libxt_dccp: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_dccp.c | 134 +++++++++++++++--------------------------------- 1 file changed, 40 insertions(+), 94 deletions(-) diff --git a/extensions/libxt_dccp.c b/extensions/libxt_dccp.c index ee8e0095..5aff262a 100644 --- a/extensions/libxt_dccp.c +++ b/extensions/libxt_dccp.c @@ -5,15 +5,12 @@ * This program is distributed under the terms of GNU GPL v2, 1991 * */ -#include +#include #include #include #include -#include #include -#include - -#include +#include #include #include #include @@ -26,6 +23,13 @@ #define DEBUGP(format, fist...) #endif +enum { + O_SOURCE_PORT = 0, + O_DEST_PORT, + O_DCCP_TYPES, + O_DCCP_OPTION, +}; + static void dccp_help(void) { printf( @@ -36,41 +40,23 @@ static void dccp_help(void) " --dport ...\n"); } -static const struct option dccp_opts[] = { - {.name = "source-port", .has_arg = true, .val = '1'}, - {.name = "sport", .has_arg = true, .val = '1'}, - {.name = "destination-port", .has_arg = true, .val = '2'}, - {.name = "dport", .has_arg = true, .val = '2'}, - {.name = "dccp-types", .has_arg = true, .val = '3'}, - {.name = "dccp-option", .has_arg = true, .val = '4'}, - XT_GETOPT_TABLEEND, +#define s struct xt_dccp_info +static const struct xt_option_entry dccp_opts[] = { + {.name = "source-port", .id = O_SOURCE_PORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, spts)}, + {.name = "sport", .id = O_SOURCE_PORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, spts)}, + {.name = "destination-port", .id = O_DEST_PORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, dpts)}, + {.name = "dport", .id = O_DEST_PORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, dpts)}, + {.name = "dccp-types", .id = O_DCCP_TYPES, .type = XTTYPE_STRING}, + {.name = "dccp-option", .id = O_DCCP_OPTION, .type = XTTYPE_UINT8, + .min = 1, .max = UINT8_MAX, .flags = XTOPT_PUT, + XTOPT_POINTER(s, option)}, + XTOPT_TABLEEND, }; - -static void -parse_dccp_ports(const char *portstring, - uint16_t *ports) -{ - char *buffer; - char *cp; - - buffer = strdup(portstring); - DEBUGP("%s\n", portstring); - if ((cp = strchr(buffer, ':')) == NULL) { - ports[0] = ports[1] = xtables_parse_port(buffer, "dccp"); - } - else { - *cp = '\0'; - cp++; - - ports[0] = buffer[0] ? xtables_parse_port(buffer, "dccp") : 0; - ports[1] = cp[0] ? xtables_parse_port(cp, "dccp") : 0xFFFF; - - if (ports[0] > ports[1]) - xtables_error(PARAMETER_PROBLEM, - "invalid portrange (min > max)"); - } - free(buffer); -} +#undef s static const char *const dccp_pkt_types[] = { [DCCP_PKT_REQUEST] = "REQUEST", @@ -110,74 +96,34 @@ parse_dccp_types(const char *typestring) return typemask; } -static uint8_t parse_dccp_option(char *optstring) +static void dccp_parse(struct xt_option_call *cb) { - unsigned int ret; - - if (!xtables_strtoui(optstring, NULL, &ret, 1, UINT8_MAX)) - xtables_error(PARAMETER_PROBLEM, "Bad DCCP option \"%s\"", - optstring); - - return ret; -} + struct xt_dccp_info *einfo = cb->data; -static int -dccp_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - struct xt_dccp_info *einfo - = (struct xt_dccp_info *)(*match)->data; - - switch (c) { - case '1': - if (*flags & XT_DCCP_SRC_PORTS) - xtables_error(PARAMETER_PROBLEM, - "Only one `--source-port' allowed"); + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SOURCE_PORT: einfo->flags |= XT_DCCP_SRC_PORTS; - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - parse_dccp_ports(optarg, einfo->spts); - if (invert) + if (cb->invert) einfo->invflags |= XT_DCCP_SRC_PORTS; - *flags |= XT_DCCP_SRC_PORTS; break; - - case '2': - if (*flags & XT_DCCP_DEST_PORTS) - xtables_error(PARAMETER_PROBLEM, - "Only one `--destination-port' allowed"); + case O_DEST_PORT: einfo->flags |= XT_DCCP_DEST_PORTS; - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - parse_dccp_ports(optarg, einfo->dpts); - if (invert) + if (cb->invert) einfo->invflags |= XT_DCCP_DEST_PORTS; - *flags |= XT_DCCP_DEST_PORTS; break; - - case '3': - if (*flags & XT_DCCP_TYPE) - xtables_error(PARAMETER_PROBLEM, - "Only one `--dccp-types' allowed"); + case O_DCCP_TYPES: einfo->flags |= XT_DCCP_TYPE; - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - einfo->typemask = parse_dccp_types(optarg); - if (invert) + einfo->typemask = parse_dccp_types(cb->arg); + if (cb->invert) einfo->invflags |= XT_DCCP_TYPE; - *flags |= XT_DCCP_TYPE; break; - - case '4': - if (*flags & XT_DCCP_OPTION) - xtables_error(PARAMETER_PROBLEM, - "Only one `--dccp-option' allowed"); + case O_DCCP_OPTION: einfo->flags |= XT_DCCP_OPTION; - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - einfo->option = parse_dccp_option(optarg); - if (invert) + if (cb->invert) einfo->invflags |= XT_DCCP_OPTION; - *flags |= XT_DCCP_OPTION; break; } - return 1; } static char * @@ -333,10 +279,10 @@ static struct xtables_match dccp_match = { .size = XT_ALIGN(sizeof(struct xt_dccp_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_dccp_info)), .help = dccp_help, - .parse = dccp_parse, .print = dccp_print, .save = dccp_save, - .extra_opts = dccp_opts, + .x6_parse = dccp_parse, + .x6_options = dccp_opts, }; void _init(void) -- cgit v1.2.3