From 60756e7f8be9242b606f1b5fbcb38f45e4de29c5 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 15:21:24 +0100 Subject: libxt_MARK: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_MARK.c | 202 +++++++++++++++++++----------------------------- extensions/libxt_mark.c | 95 ++++++----------------- 2 files changed, 104 insertions(+), 193 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c index 885cf2f2..556dbde5 100644 --- a/extensions/libxt_MARK.c +++ b/extensions/libxt_MARK.c @@ -1,12 +1,6 @@ -/* Shared library add-on to iptables to add MARK target support. */ #include #include -#include -#include -#include - #include -#include #include /* Version 0 */ @@ -27,7 +21,18 @@ struct xt_mark_target_info_v1 { }; enum { - F_MARK = 1 << 0, + O_SET_MARK = 0, + O_AND_MARK, + O_OR_MARK, + O_XOR_MARK, + O_SET_XMARK, + F_SET_MARK = 1 << O_SET_MARK, + F_AND_MARK = 1 << O_AND_MARK, + F_OR_MARK = 1 << O_OR_MARK, + F_XOR_MARK = 1 << O_XOR_MARK, + F_SET_XMARK = 1 << O_SET_XMARK, + F_ANY = F_SET_MARK | F_AND_MARK | F_OR_MARK | + F_XOR_MARK | F_SET_XMARK, }; static void MARK_help(void) @@ -39,20 +44,28 @@ static void MARK_help(void) " --or-mark value Binary OR the nfmark with value\n"); } -static const struct option MARK_opts[] = { - {.name = "set-mark", .has_arg = true, .val = '1'}, - {.name = "and-mark", .has_arg = true, .val = '2'}, - {.name = "or-mark", .has_arg = true, .val = '3'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry MARK_opts[] = { + {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_UINT32, + .excl = F_ANY}, + {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32, + .excl = F_ANY}, + {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32, + .excl = F_ANY}, + XTOPT_TABLEEND, }; -static const struct option mark_tg_opts[] = { - {.name = "set-xmark", .has_arg = true, .val = 'X'}, - {.name = "set-mark", .has_arg = true, .val = '='}, - {.name = "and-mark", .has_arg = true, .val = '&'}, - {.name = "or-mark", .has_arg = true, .val = '|'}, - {.name = "xor-mark", .has_arg = true, .val = '^'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry mark_tg_opts[] = { + {.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32, + .excl = F_ANY}, + {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32, + .excl = F_ANY}, + {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32, + .excl = F_ANY}, + {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32, + .excl = F_ANY}, + {.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32, + .excl = F_ANY}, + XTOPT_TABLEEND, }; static void mark_tg_help(void) @@ -67,137 +80,80 @@ static void mark_tg_help(void) "\n"); } -/* Function which parses command options; returns true if it - ate an option */ -static int -MARK_parse_v0(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void MARK_parse_v0(struct xt_option_call *cb) { - struct xt_mark_target_info *markinfo - = (struct xt_mark_target_info *)(*target)->data; - unsigned int mark = 0; + struct xt_mark_target_info *markinfo = cb->data; - switch (c) { - case '1': - if (!xtables_strtoui(optarg, NULL, &mark, 0, UINT32_MAX)) - xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg); - markinfo->mark = mark; - if (*flags) - xtables_error(PARAMETER_PROBLEM, - "MARK target: Can't specify --set-mark twice"); - *flags = 1; + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SET_MARK: + markinfo->mark = cb->val.mark; break; - case '2': - xtables_error(PARAMETER_PROBLEM, - "MARK target: kernel too old for --and-mark"); - case '3': + default: xtables_error(PARAMETER_PROBLEM, - "MARK target: kernel too old for --or-mark"); + "MARK target: kernel too old for --%s", + cb->entry->name); } - - return 1; } -static void MARK_check(unsigned int flags) +static void MARK_check(struct xt_fcheck_call *cb) { - if (!flags) + if (cb->xflags == 0) xtables_error(PARAMETER_PROBLEM, "MARK target: Parameter --set/and/or-mark" " is required"); } -static int -MARK_parse_v1(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void MARK_parse_v1(struct xt_option_call *cb) { - struct xt_mark_target_info_v1 *markinfo - = (struct xt_mark_target_info_v1 *)(*target)->data; - unsigned int mark = 0; + struct xt_mark_target_info_v1 *markinfo = cb->data; - switch (c) { - case '1': + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SET_MARK: markinfo->mode = XT_MARK_SET; break; - case '2': + case O_AND_MARK: markinfo->mode = XT_MARK_AND; break; - case '3': + case O_OR_MARK: markinfo->mode = XT_MARK_OR; break; } - - if (!xtables_strtoui(optarg, NULL, &mark, 0, UINT32_MAX)) - xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg); - markinfo->mark = mark; - if (*flags) - xtables_error(PARAMETER_PROBLEM, - "MARK target: Can't specify --set-mark twice"); - - *flags = 1; - return 1; + markinfo->mark = cb->val.u32; } -static int mark_tg_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void mark_tg_parse(struct xt_option_call *cb) { - struct xt_mark_tginfo2 *info = (void *)(*target)->data; - unsigned int value, mask = UINT32_MAX; - char *end; + struct xt_mark_tginfo2 *info = cb->data; - switch (c) { - case 'X': /* --set-xmark */ - case '=': /* --set-mark */ - xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK); - xtables_param_act(XTF_NO_INVERT, "MARK", "--set-xmark/--set-mark", invert); - if (!xtables_strtoui(optarg, &end, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg); - if (*end == '/') - if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg); - if (*end != '\0') - xtables_param_act(XTF_BAD_VALUE, "MARK", "--set-xmark/--set-mark", optarg); - info->mark = value; - info->mask = mask; - - if (c == '=') - info->mask = value | mask; + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SET_XMARK: + info->mark = cb->val.mark; + info->mask = cb->val.mask; break; - - case '&': /* --and-mark */ - xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK); - xtables_param_act(XTF_NO_INVERT, "MARK", "--and-mark", invert); - if (!xtables_strtoui(optarg, NULL, &mask, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "MARK", "--and-mark", optarg); + case O_SET_MARK: + info->mark = cb->val.mark; + info->mask = cb->val.mark | cb->val.mask; + break; + case O_AND_MARK: info->mark = 0; - info->mask = ~mask; + info->mask = ~cb->val.u32; break; - - case '|': /* --or-mark */ - xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK); - xtables_param_act(XTF_NO_INVERT, "MARK", "--or-mark", invert); - if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "MARK", "--or-mark", optarg); - info->mark = value; - info->mask = value; + case O_OR_MARK: + info->mark = info->mask = cb->val.u32; break; - - case '^': /* --xor-mark */ - xtables_param_act(XTF_ONE_ACTION, "MARK", *flags & F_MARK); - xtables_param_act(XTF_NO_INVERT, "MARK", "--xor-mark", invert); - if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "MARK", "--xor-mark", optarg); - info->mark = value; + case O_XOR_MARK: + info->mark = cb->val.u32; info->mask = 0; break; } - - *flags |= F_MARK; - return true; } -static void mark_tg_check(unsigned int flags) +static void mark_tg_check(struct xt_fcheck_call *cb) { - if (flags == 0) + if (cb->xflags == 0) xtables_error(PARAMETER_PROBLEM, "MARK: One of the --set-xmark, " "--{and,or,xor,set}-mark options is required"); } @@ -298,11 +254,11 @@ static struct xtables_target mark_tg_reg[] = { .size = XT_ALIGN(sizeof(struct xt_mark_target_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info)), .help = MARK_help, - .parse = MARK_parse_v0, - .final_check = MARK_check, .print = MARK_print_v0, .save = MARK_save_v0, - .extra_opts = MARK_opts, + .x6_parse = MARK_parse_v0, + .x6_fcheck = MARK_check, + .x6_options = MARK_opts, }, { .family = NFPROTO_IPV4, @@ -312,11 +268,11 @@ static struct xtables_target mark_tg_reg[] = { .size = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)), .userspacesize = XT_ALIGN(sizeof(struct xt_mark_target_info_v1)), .help = MARK_help, - .parse = MARK_parse_v1, - .final_check = MARK_check, .print = MARK_print_v1, .save = MARK_save_v1, - .extra_opts = MARK_opts, + .x6_parse = MARK_parse_v1, + .x6_fcheck = MARK_check, + .x6_options = MARK_opts, }, { .version = XTABLES_VERSION, @@ -326,11 +282,11 @@ static struct xtables_target mark_tg_reg[] = { .size = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), .userspacesize = XT_ALIGN(sizeof(struct xt_mark_tginfo2)), .help = mark_tg_help, - .parse = mark_tg_parse, - .final_check = mark_tg_check, .print = mark_tg_print, .save = mark_tg_save, - .extra_opts = mark_tg_opts, + .x6_parse = mark_tg_parse, + .x6_fcheck = mark_tg_check, + .x6_options = mark_tg_opts, }, }; diff --git a/extensions/libxt_mark.c b/extensions/libxt_mark.c index d3c17277..7f8c995c 100644 --- a/extensions/libxt_mark.c +++ b/extensions/libxt_mark.c @@ -1,11 +1,5 @@ -/* Shared library add-on to iptables to add NFMARK matching support. */ #include #include -#include -#include -#include -#include - #include #include @@ -15,7 +9,7 @@ struct xt_mark_info { }; enum { - F_MARK = 1 << 0, + O_MARK = 0, }; static void mark_mt_help(void) @@ -25,62 +19,32 @@ static void mark_mt_help(void) "[!] --mark value[/mask] Match nfmark value with optional mask\n"); } -static const struct option mark_mt_opts[] = { - {.name = "mark", .has_arg = true, .val = '1'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry mark_mt_opts[] = { + {.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32, + .flags = XTOPT_MAND | XTOPT_INVERT}, + XTOPT_TABLEEND, }; -static int mark_mt_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void mark_mt_parse(struct xt_option_call *cb) { - struct xt_mark_mtinfo1 *info = (void *)(*match)->data; - unsigned int mark, mask = UINT32_MAX; - char *end; - - switch (c) { - case '1': /* --mark */ - xtables_param_act(XTF_ONLY_ONCE, "mark", "--mark", *flags & F_MARK); - if (!xtables_strtoui(optarg, &end, &mark, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg); - if (*end == '/') - if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg); - if (*end != '\0') - xtables_param_act(XTF_BAD_VALUE, "mark", "--mark", optarg); - - if (invert) - info->invert = true; - info->mark = mark; - info->mask = mask; - *flags |= F_MARK; - return true; - } - return false; + struct xt_mark_mtinfo1 *info = cb->data; + + xtables_option_parse(cb); + if (cb->invert) + info->invert = true; + info->mark = cb->val.mark; + info->mask = cb->val.mask; } -static int -mark_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void mark_parse(struct xt_option_call *cb) { - struct xt_mark_info *markinfo = (struct xt_mark_info *)(*match)->data; - - switch (c) { - char *end; - case '1': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - markinfo->mark = strtoul(optarg, &end, 0); - if (*end == '/') { - markinfo->mask = strtoul(end+1, &end, 0); - } else - markinfo->mask = 0xffffffff; - if (*end != '\0' || end == optarg) - xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg); - if (invert) - markinfo->invert = 1; - *flags = 1; - break; - } - return 1; + struct xt_mark_info *markinfo = cb->data; + + xtables_option_parse(cb); + if (cb->invert) + markinfo->invert = 1; + markinfo->mark = cb->val.mark; + markinfo->mask = cb->val.mask; } static void print_mark(unsigned int mark, unsigned int mask) @@ -91,13 +55,6 @@ static void print_mark(unsigned int mark, unsigned int mask) printf(" 0x%x", mark); } -static void mark_mt_check(unsigned int flags) -{ - if (flags == 0) - xtables_error(PARAMETER_PROBLEM, - "mark match: The --mark option is required"); -} - static void mark_mt_print(const void *ip, const struct xt_entry_match *match, int numeric) { @@ -154,11 +111,10 @@ static struct xtables_match mark_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_mark_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_mark_info)), .help = mark_mt_help, - .parse = mark_parse, - .final_check = mark_mt_check, .print = mark_print, .save = mark_save, - .extra_opts = mark_mt_opts, + .x6_parse = mark_parse, + .x6_options = mark_mt_opts, }, { .version = XTABLES_VERSION, @@ -168,11 +124,10 @@ static struct xtables_match mark_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)), .userspacesize = XT_ALIGN(sizeof(struct xt_mark_mtinfo1)), .help = mark_mt_help, - .parse = mark_mt_parse, - .final_check = mark_mt_check, .print = mark_mt_print, .save = mark_mt_save, - .extra_opts = mark_mt_opts, + .x6_parse = mark_mt_parse, + .x6_options = mark_mt_opts, }, }; -- cgit v1.2.3 From 7299fa4b615d7f7ee12cde444266f6b31f667f9f Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 15:54:58 +0100 Subject: libxt_CONNMARK: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_CONNMARK.c | 271 ++++++++++++++++++-------------------------- extensions/libxt_connmark.c | 98 +++++----------- 2 files changed, 134 insertions(+), 235 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_CONNMARK.c b/extensions/libxt_CONNMARK.c index dbb9dc50..5d5351e3 100644 --- a/extensions/libxt_CONNMARK.c +++ b/extensions/libxt_CONNMARK.c @@ -20,13 +20,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include -#include -#include -#include - #include -#include #include struct xt_connmark_target_info { @@ -36,8 +32,28 @@ struct xt_connmark_target_info { }; enum { - F_MARK = 1 << 0, - F_SR_MARK = 1 << 1, + O_SET_MARK = 0, + O_SAVE_MARK, + O_RESTORE_MARK, + O_AND_MARK, + O_OR_MARK, + O_XOR_MARK, + O_SET_XMARK, + O_CTMASK, + O_NFMASK, + O_MASK, + F_SET_MARK = 1 << O_SET_MARK, + F_SAVE_MARK = 1 << O_SAVE_MARK, + F_RESTORE_MARK = 1 << O_RESTORE_MARK, + F_AND_MARK = 1 << O_AND_MARK, + F_OR_MARK = 1 << O_OR_MARK, + F_XOR_MARK = 1 << O_XOR_MARK, + F_SET_XMARK = 1 << O_SET_XMARK, + F_CTMASK = 1 << O_CTMASK, + F_NFMASK = 1 << O_NFMASK, + F_MASK = 1 << O_MASK, + F_OP_ANY = F_SET_MARK | F_SAVE_MARK | F_RESTORE_MARK | + F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK, }; static void CONNMARK_help(void) @@ -49,27 +65,44 @@ static void CONNMARK_help(void) " --restore-mark [--mask mask] Restore saved nfmark value\n"); } -static const struct option CONNMARK_opts[] = { - {.name = "set-mark", .has_arg = true, .val = '1'}, - {.name = "save-mark", .has_arg = false, .val = '2'}, - {.name = "restore-mark", .has_arg = false, .val = '3'}, - {.name = "mask", .has_arg = true, .val = '4'}, - XT_GETOPT_TABLEEND, +#define s struct xt_connmark_target_info +static const struct xt_option_entry CONNMARK_opts[] = { + {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32, + .excl = F_OP_ANY}, + {.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE, + .excl = F_OP_ANY}, + {.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE, + .excl = F_OP_ANY}, + {.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32}, + XTOPT_TABLEEND, }; - -static const struct option connmark_tg_opts[] = { - {.name = "set-xmark", .has_arg = true, .val = '='}, - {.name = "set-mark", .has_arg = true, .val = '-'}, - {.name = "and-mark", .has_arg = true, .val = '&'}, - {.name = "or-mark", .has_arg = true, .val = '|'}, - {.name = "xor-mark", .has_arg = true, .val = '^'}, - {.name = "save-mark", .has_arg = false, .val = 'S'}, - {.name = "restore-mark", .has_arg = false, .val = 'R'}, - {.name = "ctmask", .has_arg = true, .val = 'c'}, - {.name = "nfmask", .has_arg = true, .val = 'n'}, - {.name = "mask", .has_arg = true, .val = 'm'}, - XT_GETOPT_TABLEEND, +#undef s + +#define s struct xt_connmark_tginfo1 +static const struct xt_option_entry connmark_tg_opts[] = { + {.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32, + .excl = F_OP_ANY}, + {.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32, + .excl = F_OP_ANY}, + {.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32, + .excl = F_OP_ANY}, + {.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32, + .excl = F_OP_ANY}, + {.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32, + .excl = F_OP_ANY}, + {.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE, + .excl = F_OP_ANY}, + {.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE, + .excl = F_OP_ANY}, + {.name = "ctmask", .id = O_CTMASK, .type = XTTYPE_UINT32, + .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, ctmask)}, + {.name = "nfmask", .id = O_NFMASK, .type = XTTYPE_UINT32, + .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, nfmask)}, + {.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32, + .excl = F_CTMASK | F_NFMASK}, + XTOPT_TABLEEND, }; +#undef s static void connmark_tg_help(void) { @@ -101,163 +134,75 @@ static void connmark_tg_init(struct xt_entry_target *target) info->nfmask = UINT32_MAX; } -static int -CONNMARK_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void CONNMARK_parse(struct xt_option_call *cb) { - struct xt_connmark_target_info *markinfo - = (struct xt_connmark_target_info *)(*target)->data; + struct xt_connmark_target_info *markinfo = cb->data; - switch (c) { - char *end; - case '1': + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SET_MARK: markinfo->mode = XT_CONNMARK_SET; - - markinfo->mark = strtoul(optarg, &end, 0); - if (*end == '/' && end[1] != '\0') - markinfo->mask = strtoul(end+1, &end, 0); - - if (*end != '\0' || end == optarg) - xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg); - if (*flags) - xtables_error(PARAMETER_PROBLEM, - "CONNMARK target: Can't specify --set-mark twice"); - *flags = 1; + markinfo->mark = cb->val.mark; + markinfo->mask = cb->val.mask; break; - case '2': + case O_SAVE_MARK: markinfo->mode = XT_CONNMARK_SAVE; - if (*flags) - xtables_error(PARAMETER_PROBLEM, - "CONNMARK target: Can't specify --save-mark twice"); - *flags = 1; break; - case '3': + case O_RESTORE_MARK: markinfo->mode = XT_CONNMARK_RESTORE; - if (*flags) - xtables_error(PARAMETER_PROBLEM, - "CONNMARK target: Can't specify --restore-mark twice"); - *flags = 1; break; - case '4': - if (!*flags) - xtables_error(PARAMETER_PROBLEM, - "CONNMARK target: Can't specify --mask without a operation"); - markinfo->mask = strtoul(optarg, &end, 0); - - if (*end != '\0' || end == optarg) - xtables_error(PARAMETER_PROBLEM, "Bad MASK value \"%s\"", optarg); + case O_MASK: + markinfo->mask = cb->val.u32; break; } - - return 1; } -static int connmark_tg_parse(int c, char **argv, int invert, - unsigned int *flags, const void *entry, - struct xt_entry_target **target) +static void connmark_tg_parse(struct xt_option_call *cb) { - struct xt_connmark_tginfo1 *info = (void *)(*target)->data; - unsigned int value, mask = UINT32_MAX; - char *end; + struct xt_connmark_tginfo1 *info = cb->data; - switch (c) { - case '=': /* --set-xmark */ - case '-': /* --set-mark */ - xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); - if (!xtables_strtoui(optarg, &end, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg); - if (*end == '/') - if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg); - if (*end != '\0') - xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg); + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SET_XMARK: info->mode = XT_CONNMARK_SET; - info->ctmark = value; - info->ctmask = mask; - if (c == '-') - info->ctmask |= value; - *flags |= F_MARK; - return true; - - case '&': /* --and-mark */ - xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); - if (!xtables_strtoui(optarg, NULL, &mask, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--and-mark", optarg); + info->ctmark = cb->val.mark; + info->ctmask = cb->val.mask; + break; + case O_SET_MARK: + info->mode = XT_CONNMARK_SET; + info->ctmark = cb->val.mark; + info->ctmask = cb->val.mark | cb->val.mask; + break; + case O_AND_MARK: info->mode = XT_CONNMARK_SET; info->ctmark = 0; - info->ctmask = ~mask; - *flags |= F_MARK; - return true; - - case '|': /* --or-mark */ - xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); - if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--or-mark", optarg); + info->ctmask = ~cb->val.u32; + break; + case O_OR_MARK: info->mode = XT_CONNMARK_SET; - info->ctmark = value; - info->ctmask = value; - *flags |= F_MARK; - return true; - - case '^': /* --xor-mark */ - xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); - if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--xor-mark", optarg); + info->ctmark = cb->val.u32; + info->ctmask = cb->val.u32; + break; + case O_XOR_MARK: info->mode = XT_CONNMARK_SET; - info->ctmark = value; + info->ctmark = cb->val.u32; info->ctmask = 0; - *flags |= F_MARK; - return true; - - case 'S': /* --save-mark */ - xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); + break; + case O_SAVE_MARK: info->mode = XT_CONNMARK_SAVE; - *flags |= F_MARK | F_SR_MARK; - return true; - - case 'R': /* --restore-mark */ - xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); + break; + case O_RESTORE_MARK: info->mode = XT_CONNMARK_RESTORE; - *flags |= F_MARK | F_SR_MARK; - return true; - - case 'n': /* --nfmask */ - if (!(*flags & F_SR_MARK)) - xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark " - "or --restore-mark is required for " - "--nfmask"); - if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--nfmask", optarg); - info->nfmask = value; - return true; - - case 'c': /* --ctmask */ - if (!(*flags & F_SR_MARK)) - xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark " - "or --restore-mark is required for " - "--ctmask"); - if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--ctmask", optarg); - info->ctmask = value; - return true; - - case 'm': /* --mask */ - if (!(*flags & F_SR_MARK)) - xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark " - "or --restore-mark is required for " - "--mask"); - if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--mask", optarg); - info->nfmask = info->ctmask = value; - return true; + break; + case O_MASK: + info->nfmask = info->ctmask = cb->val.u32; + break; } - - return false; } -static void connmark_tg_check(unsigned int flags) +static void connmark_tg_check(struct xt_fcheck_call *cb) { - if (!flags) + if (!(cb->xflags & F_OP_ANY)) xtables_error(PARAMETER_PROBLEM, "CONNMARK target: No operation specified"); } @@ -412,11 +357,11 @@ static struct xtables_target connmark_tg_reg[] = { .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_target_info)), .help = CONNMARK_help, .init = CONNMARK_init, - .parse = CONNMARK_parse, - .final_check = connmark_tg_check, .print = CONNMARK_print, .save = CONNMARK_save, - .extra_opts = CONNMARK_opts, + .x6_parse = CONNMARK_parse, + .x6_fcheck = connmark_tg_check, + .x6_options = CONNMARK_opts, }, { .version = XTABLES_VERSION, @@ -427,11 +372,11 @@ static struct xtables_target connmark_tg_reg[] = { .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)), .help = connmark_tg_help, .init = connmark_tg_init, - .parse = connmark_tg_parse, - .final_check = connmark_tg_check, .print = connmark_tg_print, .save = connmark_tg_save, - .extra_opts = connmark_tg_opts, + .x6_parse = connmark_tg_parse, + .x6_fcheck = connmark_tg_check, + .x6_options = connmark_tg_opts, }, }; diff --git a/extensions/libxt_connmark.c b/extensions/libxt_connmark.c index a0e89fe7..6f1d5323 100644 --- a/extensions/libxt_connmark.c +++ b/extensions/libxt_connmark.c @@ -20,12 +20,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include -#include -#include -#include -#include - #include #include @@ -35,7 +31,7 @@ struct xt_connmark_info { }; enum { - F_MARK = 1 << 0, + O_MARK = 0, }; static void connmark_mt_help(void) @@ -45,65 +41,32 @@ static void connmark_mt_help(void) "[!] --mark value[/mask] Match ctmark value with optional mask\n"); } -static const struct option connmark_mt_opts[] = { - {.name = "mark", .has_arg = true, .val = '1'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry connmark_mt_opts[] = { + {.name = "mark", .id = O_MARK, .type = XTTYPE_MARKMASK32, + .flags = XTOPT_MAND | XTOPT_INVERT}, + XTOPT_TABLEEND, }; -static int -connmark_mt_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void connmark_mt_parse(struct xt_option_call *cb) { - struct xt_connmark_mtinfo1 *info = (void *)(*match)->data; - unsigned int mark, mask = UINT32_MAX; - char *end; - - switch (c) { - case '1': /* --mark */ - xtables_param_act(XTF_ONLY_ONCE, "connmark", "--mark", *flags & F_MARK); - if (!xtables_strtoui(optarg, &end, &mark, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg); - if (*end == '/') - if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg); - if (*end != '\0') - xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg); - - if (invert) - info->invert = true; - info->mark = mark; - info->mask = mask; - *flags |= F_MARK; - return true; - } - return false; + struct xt_connmark_mtinfo1 *info = cb->data; + + xtables_option_parse(cb); + if (cb->invert) + info->invert = true; + info->mark = cb->val.mark; + info->mask = cb->val.mask; } -static int -connmark_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void connmark_parse(struct xt_option_call *cb) { - struct xt_connmark_info *markinfo = (struct xt_connmark_info *)(*match)->data; - - switch (c) { - char *end; - case '1': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - - markinfo->mark = strtoul(optarg, &end, 0); - markinfo->mask = 0xffffffffUL; - - if (*end == '/') - markinfo->mask = strtoul(end+1, &end, 0); - - if (*end != '\0' || end == optarg) - xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg); - if (invert) - markinfo->invert = 1; - *flags = 1; - break; - } - return 1; + struct xt_connmark_info *markinfo = cb->data; + + xtables_option_parse(cb); + markinfo->mark = cb->val.mark; + markinfo->mask = cb->val.mask; + if (cb->invert) + markinfo->invert = 1; } static void print_mark(unsigned int mark, unsigned int mask) @@ -114,13 +77,6 @@ static void print_mark(unsigned int mark, unsigned int mask) printf(" 0x%x", mark); } -static void connmark_mt_check(unsigned int flags) -{ - if (flags == 0) - xtables_error(PARAMETER_PROBLEM, - "connmark: The --mark option is required"); -} - static void connmark_print(const void *ip, const struct xt_entry_match *match, int numeric) { @@ -175,11 +131,10 @@ static struct xtables_match connmark_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_connmark_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_info)), .help = connmark_mt_help, - .parse = connmark_parse, - .final_check = connmark_mt_check, .print = connmark_print, .save = connmark_save, - .extra_opts = connmark_mt_opts, + .x6_parse = connmark_parse, + .x6_options = connmark_mt_opts, }, { .version = XTABLES_VERSION, @@ -189,11 +144,10 @@ static struct xtables_match connmark_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)), .help = connmark_mt_help, - .parse = connmark_mt_parse, - .final_check = connmark_mt_check, .print = connmark_mt_print, .save = connmark_mt_save, - .extra_opts = connmark_mt_opts, + .x6_parse = connmark_mt_parse, + .x6_options = connmark_mt_opts, }, }; -- cgit v1.2.3 From 1e6c1ee1bf2822d5fdf61725148700a410fb8b86 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 16:58:24 +0100 Subject: libxt_quota: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_quota.c | 67 +++++++++++------------------------------------- 1 file changed, 15 insertions(+), 52 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_quota.c b/extensions/libxt_quota.c index e3699ad7..988f404f 100644 --- a/extensions/libxt_quota.c +++ b/extensions/libxt_quota.c @@ -3,18 +3,18 @@ * * Sam Johnston */ -#include -#include #include -#include -#include #include - #include -static const struct option quota_opts[] = { - {.name = "quota", .has_arg = true, .val = '1'}, - XT_GETOPT_TABLEEND, +enum { + O_QUOTA = 0, +}; + +static const struct xt_option_entry quota_opts[] = { + {.name = "quota", .id = O_QUOTA, .type = XTTYPE_UINT64, + .flags = XTOPT_MAND | XTOPT_INVERT}, + XTOPT_TABLEEND, }; static void quota_help(void) @@ -40,49 +40,13 @@ quota_save(const void *ip, const struct xt_entry_match *match) printf(" --quota %llu", (unsigned long long) q->quota); } -/* parse quota option */ -static int -parse_quota(const char *s, uint64_t * quota) -{ - *quota = strtoull(s, NULL, 10); - -#ifdef DEBUG_XT_QUOTA - printf("Quota: %llu\n", *quota); -#endif - - if (*quota == UINT64_MAX) - xtables_error(PARAMETER_PROBLEM, "quota invalid: '%s'\n", s); - else - return 1; -} - -static int -quota_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void quota_parse(struct xt_option_call *cb) { - struct xt_quota_info *info = (struct xt_quota_info *) (*match)->data; - - switch (c) { - case '1': - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, "quota: unexpected '!'"); - if (!parse_quota(optarg, &info->quota)) - xtables_error(PARAMETER_PROBLEM, - "bad quota: '%s'", optarg); + struct xt_quota_info *info = cb->data; - if (invert) - info->flags |= XT_QUOTA_INVERT; - *flags |= 1; - break; - } - return 1; -} - -static void quota_check(unsigned int flags) -{ - if (flags == 0) - xtables_error(PARAMETER_PROBLEM, - "quota: the --quota argument must be specified\n"); + xtables_option_parse(cb); + if (cb->invert) + info->flags |= XT_QUOTA_INVERT; } static struct xtables_match quota_match = { @@ -92,11 +56,10 @@ static struct xtables_match quota_match = { .size = XT_ALIGN(sizeof (struct xt_quota_info)), .userspacesize = offsetof(struct xt_quota_info, master), .help = quota_help, - .parse = quota_parse, - .final_check = quota_check, .print = quota_print, .save = quota_save, - .extra_opts = quota_opts, + .x6_parse = quota_parse, + .x6_options = quota_opts, }; void -- cgit v1.2.3 From 5d8e61ef4636383ca47cd748cd7457a238de37a6 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 16:02:03 +0100 Subject: libxt_devgroup: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_devgroup.c | 201 +++++++++----------------------------------- 1 file changed, 41 insertions(+), 160 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_devgroup.c b/extensions/libxt_devgroup.c index 26248687..a925dd08 100644 --- a/extensions/libxt_devgroup.c +++ b/extensions/libxt_devgroup.c @@ -2,14 +2,10 @@ * * Copyright (c) 2011 Patrick McHardy */ -#include #include -#include #include #include #include -#include -#include #include #include @@ -23,200 +19,84 @@ static void devgroup_help(void) } enum { - XT_DEVGROUP_OPT_SRCGROUP = 1, - XT_DEVGROUP_OPT_DSTGROUP, + O_SRC_GROUP = 0, + O_DST_GROUP, }; -static const struct option devgroup_opts[] = { - { .name = "src-group", .has_arg = true, .val = XT_DEVGROUP_OPT_SRCGROUP }, - { .name = "dst-group", .has_arg = true, .val = XT_DEVGROUP_OPT_DSTGROUP }, - XT_GETOPT_TABLEEND, -}; - -struct devgroupname { - unsigned int id; - char *name; - int len; - struct devgroupname *next; +static const struct xt_option_entry devgroup_opts[] = { + {.name = "src-group", .id = O_SRC_GROUP, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + {.name = "dst-group", .id = O_DST_GROUP, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + XTOPT_TABLEEND, }; /* array of devgroups from /etc/iproute2/group_map */ -static struct devgroupname *devgroups; -/* 1 if loading failed */ -static int rdberr; +static struct xtables_lmap *devgroups; -static void load_devgroups(void) +static void devgroup_init(struct xt_entry_match *match) { - const char* rfnm = "/etc/iproute2/group_map"; - char buf[512]; - FILE *fil; - char *cur, *nxt; - int id; - struct devgroupname *oldnm = NULL, *newnm = NULL; - - fil = fopen(rfnm, "r"); - if (!fil) { - rdberr = 1; - return; - } - - while (fgets(buf, sizeof(buf), fil)) { - cur = buf; - while ((*cur == ' ') || (*cur == '\t')) - cur++; - if ((*cur == '#') || (*cur == '\n') || (*cur == 0)) - continue; - - /* iproute2 allows hex and dec format */ - errno = 0; - id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16); - if ((nxt == cur) || errno) - continue; - - /* same boundaries as in iproute2 */ - if (id < 0 || id > 255) - continue; - cur = nxt; - - if (!isspace(*cur)) - continue; - while ((*cur == ' ') || (*cur == '\t')) - cur++; - if ((*cur == '#') || (*cur == '\n') || (*cur == 0)) - continue; - nxt = cur; - while ((*nxt != 0) && !isspace(*nxt)) - nxt++; - if (nxt == cur) - continue; - - /* found valid data */ - newnm = malloc(sizeof(struct devgroupname)); - if (newnm == NULL) { - perror("libxt_devgroup: malloc failed"); - exit(1); - } - newnm->id = id; - newnm->len = nxt - cur; - newnm->name = malloc(newnm->len + 1); - if (newnm->name == NULL) { - perror("libxt_devgroup: malloc failed"); - exit(1); - } - strncpy(newnm->name, cur, newnm->len); - newnm->name[newnm->len] = 0; - newnm->next = NULL; - - if (oldnm) - oldnm->next = newnm; - else - devgroups = newnm; - oldnm = newnm; - } - - fclose(fil); -} - -/* get devgroup id for name, -1 if error/not found */ -static int devgroup_name2id(const char* name) -{ - struct devgroupname* cur; - - if ((devgroups == NULL) && (rdberr == 0)) - load_devgroups(); - cur = devgroups; - if (cur == NULL) - return -1; - while (cur) { - if (!strncmp(name, cur->name, cur->len + 1)) - return cur->id; - cur = cur->next; - } - return -1; -} - -/* get devgroup name for id, NULL if error/not found */ -static const char *devgroup_id2name(int id) -{ - struct devgroupname* cur; - - if ((devgroups == NULL) && (rdberr == 0)) - load_devgroups(); - cur = devgroups; - if (cur == NULL) - return NULL; - while (cur) { - if (id == cur->id) - return cur->name; - cur = cur->next; - } - return NULL; + const char file[] = "/etc/iproute2/group_map"; + devgroups = xtables_lmap_init(file); + if (devgroups == NULL && errno != ENOENT) + fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno)); } -static int devgroup_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void devgroup_parse(struct xt_option_call *cb) { - struct xt_devgroup_info *info = (struct xt_devgroup_info *)(*match)->data; + struct xt_devgroup_info *info = cb->data; unsigned int id; char *end; - switch (c) { - case XT_DEVGROUP_OPT_SRCGROUP: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - end = optarg; - info->src_group = strtoul(optarg, &end, 0); - if (end != optarg && (*end == '/' || *end == '\0')) { + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SRC_GROUP: + info->src_group = strtoul(cb->arg, &end, 0); + if (end != cb->arg && (*end == '/' || *end == '\0')) { if (*end == '/') info->src_mask = strtoul(end+1, &end, 0); else info->src_mask = 0xffffffff; - if (*end != '\0' || end == optarg) + if (*end != '\0' || end == cb->arg) xtables_error(PARAMETER_PROBLEM, "Bad src-group value `%s'", - optarg); + cb->arg); } else { - id = devgroup_name2id(optarg); + id = xtables_lmap_name2id(devgroups, cb->arg); if (id == -1) xtables_error(PARAMETER_PROBLEM, "Device group `%s' not found", - optarg); + cb->arg); info->src_group = id; info->src_mask = 0xffffffff; } - info->flags |= XT_DEVGROUP_MATCH_SRC; - if (invert) + if (cb->invert) info->flags |= XT_DEVGROUP_INVERT_SRC; - *flags |= c; break; - case XT_DEVGROUP_OPT_DSTGROUP: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - end = optarg; - info->dst_group = strtoul(optarg, &end, 0); - if (end != optarg && (*end == '/' || *end == '\0')) { + case O_DST_GROUP: + info->dst_group = strtoul(cb->arg, &end, 0); + if (end != cb->arg && (*end == '/' || *end == '\0')) { if (*end == '/') info->dst_mask = strtoul(end+1, &end, 0); else info->dst_mask = 0xffffffff; - if (*end != '\0' || end == optarg) + if (*end != '\0' || end == cb->arg) xtables_error(PARAMETER_PROBLEM, "Bad dst-group value `%s'", - optarg); + cb->arg); } else { - id = devgroup_name2id(optarg); + id = xtables_lmap_name2id(devgroups, cb->arg); if (id == -1) xtables_error(PARAMETER_PROBLEM, "Device group `%s' not found", - optarg); + cb->arg); info->dst_group = id; info->dst_mask = 0xffffffff; } - info->flags |= XT_DEVGROUP_MATCH_DST; - if (invert) + if (cb->invert) info->flags |= XT_DEVGROUP_INVERT_DST; - *flags |= c; break; } - return 1; } static void @@ -228,7 +108,7 @@ print_devgroup(unsigned int id, unsigned int mask, int numeric) printf("0x%x/0x%x", id, mask); else { if (numeric == 0) - name = devgroup_id2name(id); + name = xtables_lmap_id2name(devgroups, id); if (name) printf("%s", name); else @@ -269,9 +149,9 @@ static void devgroup_save(const void *ip, const struct xt_entry_match *match) devgroup_show("--", info, 0); } -static void devgroup_check(unsigned int flags) +static void devgroup_check(struct xt_fcheck_call *cb) { - if (!flags) + if (cb->xflags == 0) xtables_error(PARAMETER_PROBLEM, "devgroup match: You must specify either " "'--src-group' or '--dst-group'"); @@ -283,12 +163,13 @@ static struct xtables_match devgroup_mt_reg = { .family = NFPROTO_UNSPEC, .size = XT_ALIGN(sizeof(struct xt_devgroup_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_devgroup_info)), + .init = devgroup_init, .help = devgroup_help, - .parse = devgroup_parse, - .final_check = devgroup_check, .print = devgroup_print, .save = devgroup_save, - .extra_opts = devgroup_opts, + .x6_parse = devgroup_parse, + .x6_fcheck = devgroup_check, + .x6_options = devgroup_opts, }; void _init(void) -- cgit v1.2.3 From f04d48879fea70451148d7867d5a388efe63b48f Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 16:38:51 +0100 Subject: libipt_realm: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libipt_realm.c | 202 +++++++++------------------------------------- 1 file changed, 39 insertions(+), 163 deletions(-) (limited to 'extensions') diff --git a/extensions/libipt_realm.c b/extensions/libipt_realm.c index 17b1754e..b60c57ee 100644 --- a/extensions/libipt_realm.c +++ b/extensions/libipt_realm.c @@ -1,12 +1,7 @@ -/* Shared library add-on to iptables to add realm matching support. */ -#include #include -#include #include #include #include -#include -#include #if defined(__GLIBC__) && __GLIBC__ == 2 #include #else @@ -15,6 +10,10 @@ #include #include +enum { + O_REALM = 0, +}; + static void realm_help(void) { printf( @@ -23,165 +22,49 @@ static void realm_help(void) " Match realm\n"); } -static const struct option realm_opts[] = { - {.name = "realm", .has_arg = true, .val = '1'}, - XT_GETOPT_TABLEEND, -}; - -struct realmname { - int id; - char* name; - int len; - struct realmname* next; +static const struct xt_option_entry realm_opts[] = { + {.name = "realm", .id = O_REALM, .type = XTTYPE_STRING, + .flags = XTOPT_MAND | XTOPT_INVERT}, + XTOPT_TABLEEND, }; /* array of realms from /etc/iproute2/rt_realms */ -static struct realmname *realms; -/* 1 if loading failed */ -static int rdberr; +static struct xtables_lmap *realms; -static void load_realms(void) +static void realm_init(struct xt_entry_match *m) { - const char* rfnm = "/etc/iproute2/rt_realms"; - char buf[512]; - FILE *fil; - char *cur, *nxt; - int id; - struct realmname *oldnm = NULL, *newnm = NULL; - - fil = fopen(rfnm, "re"); - if (!fil) { - rdberr = 1; - return; - } - - while (fgets(buf, sizeof(buf), fil)) { - cur = buf; - while ((*cur == ' ') || (*cur == '\t')) - cur++; - if ((*cur == '#') || (*cur == '\n') || (*cur == 0)) - continue; - - /* iproute2 allows hex and dec format */ - errno = 0; - id = strtoul(cur, &nxt, strncmp(cur, "0x", 2) ? 10 : 16); - if ((nxt == cur) || errno) - continue; - - /* same boundaries as in iproute2 */ - if (id < 0 || id > 255) - continue; - cur = nxt; - - if (!isspace(*cur)) - continue; - while ((*cur == ' ') || (*cur == '\t')) - cur++; - if ((*cur == '#') || (*cur == '\n') || (*cur == 0)) - continue; - nxt = cur; - while ((*nxt != 0) && !isspace(*nxt)) - nxt++; - if (nxt == cur) - continue; - - /* found valid data */ - newnm = malloc(sizeof(struct realmname)); - if (newnm == NULL) { - perror("libipt_realm: malloc failed"); - exit(1); - } - newnm->id = id; - newnm->len = nxt - cur; - newnm->name = malloc(newnm->len + 1); - if (newnm->name == NULL) { - perror("libipt_realm: malloc failed"); - exit(1); - } - strncpy(newnm->name, cur, newnm->len); - newnm->name[newnm->len] = 0; - newnm->next = NULL; - - if (oldnm) - oldnm->next = newnm; - else - realms = newnm; - oldnm = newnm; - } - - fclose(fil); + const char file[] = "/etc/iproute2/rt_realms"; + realms = xtables_lmap_init(file); + if (realms == NULL && errno != ENOENT) + fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno)); } -/* get realm id for name, -1 if error/not found */ -static int realm_name2id(const char* name) +static void realm_parse(struct xt_option_call *cb) { - struct realmname* cur; - - if ((realms == NULL) && (rdberr == 0)) - load_realms(); - cur = realms; - if (cur == NULL) - return -1; - while (cur) { - if (!strncmp(name, cur->name, cur->len + 1)) - return cur->id; - cur = cur->next; - } - return -1; -} - -/* get realm name for id, NULL if error/not found */ -static const char *realm_id2name(int id) -{ - struct realmname* cur; - - if ((realms == NULL) && (rdberr == 0)) - load_realms(); - cur = realms; - if (cur == NULL) - return NULL; - while (cur) { - if (id == cur->id) - return cur->name; - cur = cur->next; - } - return NULL; -} - -static int realm_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - struct ipt_realm_info *realminfo = (struct ipt_realm_info *)(*match)->data; + struct ipt_realm_info *realminfo = cb->data; int id; + char *end; - switch (c) { - char *end; - case '1': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - end = optarg = optarg; - realminfo->id = strtoul(optarg, &end, 0); - if (end != optarg && (*end == '/' || *end == '\0')) { - if (*end == '/') - realminfo->mask = strtoul(end+1, &end, 0); - else - realminfo->mask = 0xffffffff; - if (*end != '\0' || end == optarg) - xtables_error(PARAMETER_PROBLEM, - "Bad realm value `%s'", optarg); - } else { - id = realm_name2id(optarg); - if (id == -1) - xtables_error(PARAMETER_PROBLEM, - "Realm `%s' not found", optarg); - realminfo->id = id; + xtables_option_parse(cb); + realminfo->id = strtoul(cb->arg, &end, 0); + if (end != cb->arg && (*end == '/' || *end == '\0')) { + if (*end == '/') + realminfo->mask = strtoul(end+1, &end, 0); + else realminfo->mask = 0xffffffff; - } - if (invert) - realminfo->invert = 1; - *flags = 1; - break; + if (*end != '\0' || end == cb->arg) + xtables_error(PARAMETER_PROBLEM, + "Bad realm value \"%s\"", cb->arg); + } else { + id = xtables_lmap_name2id(realms, cb->arg); + if (id == -1) + xtables_error(PARAMETER_PROBLEM, + "Realm \"%s\" not found", cb->arg); + realminfo->id = id; + realminfo->mask = 0xffffffff; } - return 1; + if (cb->invert) + realminfo->invert = 1; } static void @@ -193,7 +76,7 @@ print_realm(unsigned long id, unsigned long mask, int numeric) printf(" 0x%lx/0x%lx", id, mask); else { if (numeric == 0) - name = realm_id2name(id); + name = xtables_lmap_id2name(realms, id); if (name) printf(" %s", name); else @@ -224,13 +107,6 @@ static void realm_save(const void *ip, const struct xt_entry_match *match) print_realm(ri->id, ri->mask, 0); } -static void realm_check(unsigned int flags) -{ - if (!flags) - xtables_error(PARAMETER_PROBLEM, - "realm match: You must specify `--realm'"); -} - static struct xtables_match realm_mt_reg = { .name = "realm", .version = XTABLES_VERSION, @@ -238,11 +114,11 @@ static struct xtables_match realm_mt_reg = { .size = XT_ALIGN(sizeof(struct ipt_realm_info)), .userspacesize = XT_ALIGN(sizeof(struct ipt_realm_info)), .help = realm_help, - .parse = realm_parse, - .final_check = realm_check, + .init = realm_init, .print = realm_print, .save = realm_save, - .extra_opts = realm_opts, + .x6_parse = realm_parse, + .x6_options = realm_opts, }; void _init(void) -- cgit v1.2.3 From c15f9e3f6d8552cddfc858b115d996c7cf5b47e9 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 17:00:49 +0100 Subject: libxt_length: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_length.c | 92 +++++++++-------------------------------------- 1 file changed, 17 insertions(+), 75 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_length.c b/extensions/libxt_length.c index a12aefef..4f3a3318 100644 --- a/extensions/libxt_length.c +++ b/extensions/libxt_length.c @@ -1,14 +1,11 @@ -/* Shared library add-on to iptables to add packet length matching support. */ -#include #include -#include -#include -#include -#include - #include #include +enum { + O_LENGTH = 0, +}; + static void length_help(void) { printf( @@ -17,75 +14,21 @@ static void length_help(void) " of values (inclusive)\n"); } -static const struct option length_opts[] = { - {.name = "length", .has_arg = true, .val = '1'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry length_opts[] = { + {.name = "length", .id = O_LENGTH, .type = XTTYPE_UINT16RC, + .flags = XTOPT_MAND | XTOPT_INVERT}, + XTOPT_TABLEEND, }; -static uint16_t -parse_length(const char *s) -{ - unsigned int len; - - if (!xtables_strtoui(s, NULL, &len, 0, UINT32_MAX)) - xtables_error(PARAMETER_PROBLEM, "length invalid: \"%s\"\n", s); - else - return len; -} - -/* If a single value is provided, min and max are both set to the value */ -static void -parse_lengths(const char *s, struct xt_length_info *info) -{ - char *buffer; - char *cp; - - buffer = strdup(s); - if ((cp = strchr(buffer, ':')) == NULL) - info->min = info->max = parse_length(buffer); - else { - *cp = '\0'; - cp++; - - info->min = buffer[0] ? parse_length(buffer) : 0; - info->max = cp[0] ? parse_length(cp) : 0xFFFF; - } - free(buffer); - - if (info->min > info->max) - xtables_error(PARAMETER_PROBLEM, - "length min. range value `%u' greater than max. " - "range value `%u'", info->min, info->max); - -} - -static int -length_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void length_parse(struct xt_option_call *cb) { - struct xt_length_info *info = (struct xt_length_info *)(*match)->data; - - switch (c) { - case '1': - if (*flags) - xtables_error(PARAMETER_PROBLEM, - "length: `--length' may only be " - "specified once"); - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - parse_lengths(optarg, info); - if (invert) - info->invert = 1; - *flags = 1; - break; - } - return 1; -} + struct xt_length_info *info = cb->data; -static void length_check(unsigned int flags) -{ - if (!flags) - xtables_error(PARAMETER_PROBLEM, - "length: You must specify `--length'"); + xtables_option_parse(cb); + info->min = cb->val.u16_range[0]; + info->max = (cb->nvals == 2) ? cb->val.u16_range[1] : UINT16_MAX; + if (cb->invert) + info->invert = 1; } static void @@ -118,11 +61,10 @@ static struct xtables_match length_match = { .size = XT_ALIGN(sizeof(struct xt_length_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_length_info)), .help = length_help, - .parse = length_parse, - .final_check = length_check, .print = length_print, .save = length_save, - .extra_opts = length_opts, + .x6_parse = length_parse, + .x6_options = length_opts, }; void _init(void) -- cgit v1.2.3 From ba77b9b142b55c856b0a2950eddece7ad7e6bfbc Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 17:04:35 +0100 Subject: libxt_tcpmss: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_tcpmss.c | 92 +++++++++++------------------------------------ 1 file changed, 20 insertions(+), 72 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_tcpmss.c b/extensions/libxt_tcpmss.c index 3dc35286..c7c59717 100644 --- a/extensions/libxt_tcpmss.c +++ b/extensions/libxt_tcpmss.c @@ -1,14 +1,11 @@ -/* Shared library add-on to iptables to add tcp MSS matching support. */ -#include #include -#include -#include -#include -#include - #include #include +enum { + O_TCPMSS = 0, +}; + static void tcpmss_help(void) { printf( @@ -17,71 +14,23 @@ static void tcpmss_help(void) " (only valid for TCP SYN or SYN/ACK packets)\n"); } -static const struct option tcpmss_opts[] = { - {.name = "mss", .has_arg = true, .val = '1'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry tcpmss_opts[] = { + {.name = "mss", .id = O_TCPMSS, .type = XTTYPE_UINT16RC, + .flags = XTOPT_MAND | XTOPT_INVERT}, + XTOPT_TABLEEND, }; -static uint16_t -parse_tcp_mssvalue(const char *mssvalue) -{ - unsigned int mssvaluenum; - - if (xtables_strtoui(mssvalue, NULL, &mssvaluenum, 0, UINT16_MAX)) - return mssvaluenum; - - xtables_error(PARAMETER_PROBLEM, - "Invalid mss `%s' specified", mssvalue); -} - -static void -parse_tcp_mssvalues(const char *mssvaluestring, - uint16_t *mss_min, uint16_t *mss_max) -{ - char *buffer; - char *cp; - - buffer = strdup(mssvaluestring); - if ((cp = strchr(buffer, ':')) == NULL) - *mss_min = *mss_max = parse_tcp_mssvalue(buffer); - else { - *cp = '\0'; - cp++; - - *mss_min = buffer[0] ? parse_tcp_mssvalue(buffer) : 0; - *mss_max = cp[0] ? parse_tcp_mssvalue(cp) : 0xFFFF; - } - free(buffer); -} - -static int -tcpmss_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - struct xt_tcpmss_match_info *mssinfo = - (struct xt_tcpmss_match_info *)(*match)->data; - - switch (c) { - case '1': - if (*flags) - xtables_error(PARAMETER_PROBLEM, - "Only one `--mss' allowed"); - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - parse_tcp_mssvalues(optarg, - &mssinfo->mss_min, &mssinfo->mss_max); - if (invert) - mssinfo->invert = 1; - *flags = 1; - break; - } - return 1; -} - -static void tcpmss_check(unsigned int flags) +static void tcpmss_parse(struct xt_option_call *cb) { - if (!flags) - xtables_error(PARAMETER_PROBLEM, - "tcpmss match: You must specify `--mss'"); + struct xt_tcpmss_match_info *mssinfo = cb->data; + + xtables_option_parse(cb); + mssinfo->mss_min = cb->val.u16_range[0]; + mssinfo->mss_max = mssinfo->mss_min; + if (cb->nvals == 2) + mssinfo->mss_max = cb->val.u16_range[1]; + if (cb->invert) + mssinfo->invert = 1; } static void @@ -114,11 +63,10 @@ static struct xtables_match tcpmss_match = { .size = XT_ALIGN(sizeof(struct xt_tcpmss_match_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_tcpmss_match_info)), .help = tcpmss_help, - .parse = tcpmss_parse, - .final_check = tcpmss_check, .print = tcpmss_print, .save = tcpmss_save, - .extra_opts = tcpmss_opts, + .x6_parse = tcpmss_parse, + .x6_options = tcpmss_opts, }; void _init(void) -- cgit v1.2.3 From 09631dc60ce41bc484a42fcf4d4ddf7036820bd1 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 17:19:10 +0100 Subject: libxt_connbytes: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_connbytes.c | 107 +++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 69 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_connbytes.c b/extensions/libxt_connbytes.c index 1d3391ae..46a7e4b9 100644 --- a/extensions/libxt_connbytes.c +++ b/extensions/libxt_connbytes.c @@ -1,14 +1,14 @@ -/* Shared library add-on to iptables to add byte tracking support. */ -#include #include -#include #include -#include -#include #include -#include #include +enum { + O_CONNBYTES = 0, + O_CONNBYTES_DIR, + O_CONNBYTES_MODE, +}; + static void connbytes_help(void) { printf( @@ -18,87 +18,57 @@ static void connbytes_help(void) " --connbytes-mode [packets, bytes, avgpkt]\n"); } -static const struct option connbytes_opts[] = { - {.name = "connbytes", .has_arg = true, .val = '1'}, - {.name = "connbytes-dir", .has_arg = true, .val = '2'}, - {.name = "connbytes-mode", .has_arg = true, .val = '3'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry connbytes_opts[] = { + {.name = "connbytes", .id = O_CONNBYTES, .type = XTTYPE_UINT64RC, + .flags = XTOPT_MAND | XTOPT_INVERT}, + {.name = "connbytes-dir", .id = O_CONNBYTES_DIR, .type = XTTYPE_STRING, + .flags = XTOPT_MAND}, + {.name = "connbytes-mode", .id = O_CONNBYTES_MODE, + .type = XTTYPE_STRING, .flags = XTOPT_MAND}, + XTOPT_TABLEEND, }; -static void -parse_range(const char *arg, struct xt_connbytes_info *si) -{ - char *colon,*p; - - si->count.from = strtoul(arg,&colon,10); - if (*colon != ':') - xtables_error(PARAMETER_PROBLEM, "Bad range \"%s\"", arg); - si->count.to = strtoul(colon+1,&p,10); - if (p == colon+1) { - /* second number omited */ - si->count.to = 0xffffffff; - } - if (si->count.from > si->count.to) - xtables_error(PARAMETER_PROBLEM, "%llu should be less than %llu", - (unsigned long long)si->count.from, - (unsigned long long)si->count.to); -} - -static int -connbytes_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void connbytes_parse(struct xt_option_call *cb) { - struct xt_connbytes_info *sinfo = (struct xt_connbytes_info *)(*match)->data; - unsigned long i; - - switch (c) { - case '1': - if (xtables_check_inverse(optarg, &invert, &optind, 0, argv)) - optind++; - - parse_range(optarg, sinfo); - if (invert) { + struct xt_connbytes_info *sinfo = cb->data; + unsigned long long i; + + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_CONNBYTES: + sinfo->count.from = cb->val.u64_range[0]; + sinfo->count.to = cb->val.u64_range[0]; + if (cb->nvals == 2) + sinfo->count.to = cb->val.u64_range[1]; + if (cb->invert) { i = sinfo->count.from; sinfo->count.from = sinfo->count.to; sinfo->count.to = i; } - *flags |= 1; break; - case '2': - if (!strcmp(optarg, "original")) + case O_CONNBYTES_DIR: + if (strcmp(cb->arg, "original") == 0) sinfo->direction = XT_CONNBYTES_DIR_ORIGINAL; - else if (!strcmp(optarg, "reply")) + else if (strcmp(cb->arg, "reply") == 0) sinfo->direction = XT_CONNBYTES_DIR_REPLY; - else if (!strcmp(optarg, "both")) + else if (strcmp(cb->arg, "both") == 0) sinfo->direction = XT_CONNBYTES_DIR_BOTH; else xtables_error(PARAMETER_PROBLEM, - "Unknown --connbytes-dir `%s'", optarg); - - *flags |= 2; + "Unknown --connbytes-dir `%s'", cb->arg); break; - case '3': - if (!strcmp(optarg, "packets")) + case O_CONNBYTES_MODE: + if (strcmp(cb->arg, "packets") == 0) sinfo->what = XT_CONNBYTES_PKTS; - else if (!strcmp(optarg, "bytes")) + else if (strcmp(cb->arg, "bytes") == 0) sinfo->what = XT_CONNBYTES_BYTES; - else if (!strcmp(optarg, "avgpkt")) + else if (strcmp(cb->arg, "avgpkt") == 0) sinfo->what = XT_CONNBYTES_AVGPKT; else xtables_error(PARAMETER_PROBLEM, - "Unknown --connbytes-mode `%s'", optarg); - *flags |= 4; + "Unknown --connbytes-mode `%s'", cb->arg); break; } - - return 1; -} - -static void connbytes_check(unsigned int flags) -{ - if (flags != 7) - xtables_error(PARAMETER_PROBLEM, "You must specify `--connbytes'" - "`--connbytes-dir' and `--connbytes-mode'"); } static void print_mode(const struct xt_connbytes_info *sinfo) @@ -185,11 +155,10 @@ static struct xtables_match connbytes_match = { .size = XT_ALIGN(sizeof(struct xt_connbytes_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_connbytes_info)), .help = connbytes_help, - .parse = connbytes_parse, - .final_check = connbytes_check, .print = connbytes_print, .save = connbytes_save, - .extra_opts = connbytes_opts, + .x6_parse = connbytes_parse, + .x6_options = connbytes_opts, }; void _init(void) -- cgit v1.2.3 From a05562e1e2fb2e18f34d29ec57c4217a3014d1f2 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 17:47:03 +0100 Subject: libxt_CT: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_CT.c | 74 +++++++++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 46 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c index 38ee17b1..7b93bfaf 100644 --- a/extensions/libxt_CT.c +++ b/extensions/libxt_CT.c @@ -1,9 +1,5 @@ -#include #include #include -#include -#include -#include #include #include #include @@ -20,22 +16,26 @@ static void ct_help(void) ); } -enum ct_options { - CT_OPT_NOTRACK = 0x1, - CT_OPT_HELPER = 0x2, - CT_OPT_CTEVENTS = 0x4, - CT_OPT_EXPEVENTS = 0x8, - CT_OPT_ZONE = 0x10, +enum { + O_NOTRACK = 0, + O_HELPER, + O_CTEVENTS, + O_EXPEVENTS, + O_ZONE, }; -static const struct option ct_opts[] = { - {.name = "notrack", .has_arg = false, .val = CT_OPT_NOTRACK}, - {.name = "helper", .has_arg = true, .val = CT_OPT_HELPER}, - {.name = "ctevents", .has_arg = true, .val = CT_OPT_CTEVENTS}, - {.name = "expevents", .has_arg = true, .val = CT_OPT_EXPEVENTS}, - {.name = "zone", .has_arg = true, .val = CT_OPT_ZONE}, - XT_GETOPT_TABLEEND, +#define s struct xt_ct_target_info +static const struct xt_option_entry ct_opts[] = { + {.name = "notrack", .id = O_NOTRACK, .type = XTTYPE_NONE}, + {.name = "helper", .id = O_HELPER, .type = XTTYPE_STRING, + .flags = XTOPT_PUT, XTOPT_POINTER(s, helper)}, + {.name = "ctevents", .id = O_CTEVENTS, .type = XTTYPE_STRING}, + {.name = "expevents", .id = O_EXPEVENTS, .type = XTTYPE_STRING}, + {.name = "zone", .id = O_ZONE, .type = XTTYPE_UINT16, + .flags = XTOPT_PUT, XTOPT_POINTER(s, zone)}, + XTOPT_TABLEEND, }; +#undef s struct event_tbl { const char *name; @@ -96,40 +96,22 @@ static void ct_print_events(const char *pfx, const struct event_tbl *tbl, } } -static int ct_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void ct_parse(struct xt_option_call *cb) { - struct xt_ct_target_info *info = (struct xt_ct_target_info *)(*target)->data; - unsigned int zone; + struct xt_ct_target_info *info = cb->data; - switch (c) { - case CT_OPT_NOTRACK: - xtables_param_act(XTF_ONLY_ONCE, "CT", "--notrack", *flags & CT_OPT_NOTRACK); + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_NOTRACK: info->flags |= XT_CT_NOTRACK; break; - case CT_OPT_HELPER: - xtables_param_act(XTF_ONLY_ONCE, "CT", "--helper", *flags & CT_OPT_HELPER); - strncpy(info->helper, optarg, sizeof(info->helper)); - info->helper[sizeof(info->helper) - 1] = '\0'; + case O_CTEVENTS: + info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), cb->arg); break; - case CT_OPT_CTEVENTS: - xtables_param_act(XTF_ONLY_ONCE, "CT", "--ctevents", *flags & CT_OPT_CTEVENTS); - info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), optarg); - break; - case CT_OPT_EXPEVENTS: - xtables_param_act(XTF_ONLY_ONCE, "CT", "--expevents", *flags & CT_OPT_EXPEVENTS); - info->exp_events = ct_parse_events(exp_event_tbl, ARRAY_SIZE(exp_event_tbl), optarg); - break; - case CT_OPT_ZONE: - xtables_param_act(XTF_ONLY_ONCE, "CT", "--zone", *flags & CT_OPT_ZONE); - if (!xtables_strtoui(optarg, NULL, &zone, 0, UINT16_MAX)) - xtables_error(PARAMETER_PROBLEM, "Bad zone value \"%s\"", optarg); - info->zone = zone; + case O_EXPEVENTS: + info->exp_events = ct_parse_events(exp_event_tbl, ARRAY_SIZE(exp_event_tbl), cb->arg); break; } - - *flags |= c; - return 1; } static void ct_print(const void *ip, const struct xt_entry_target *target, int numeric) @@ -178,10 +160,10 @@ static struct xtables_target ct_target = { .size = XT_ALIGN(sizeof(struct xt_ct_target_info)), .userspacesize = offsetof(struct xt_ct_target_info, ct), .help = ct_help, - .parse = ct_parse, .print = ct_print, .save = ct_save, - .extra_opts = ct_opts, + .x6_parse = ct_parse, + .x6_options = ct_opts, }; void _init(void) -- cgit v1.2.3 From 478be25c3b64e0f2ddbd2aa97ebe78df7ca00c0a Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 17:54:50 +0100 Subject: libxt_NFQUEUE: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_NFQUEUE.c | 139 +++++++++++++++------------------------------ 1 file changed, 47 insertions(+), 92 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_NFQUEUE.c b/extensions/libxt_NFQUEUE.c index 7f2aab16..a86c88a3 100644 --- a/extensions/libxt_NFQUEUE.c +++ b/extensions/libxt_NFQUEUE.c @@ -5,16 +5,16 @@ * This program is distributed under the terms of GNU GPL v2, 1991 * */ -#include #include -#include -#include -#include - #include -#include #include +enum { + O_QUEUE_NUM = 0, + O_QUEUE_BALANCE, + O_QUEUE_BYPASS, +}; + static void NFQUEUE_help(void) { printf( @@ -38,103 +38,58 @@ static void NFQUEUE_help_v2(void) " --queue-bypass Bypass Queueing if no queue instance exists.\n"); } -static const struct option NFQUEUE_opts[] = { - {.name = "queue-num", .has_arg = true, .val = 'F'}, - {.name = "queue-balance", .has_arg = true, .val = 'B'}, - {.name = "queue-bypass", .has_arg = false,.val = 'P'}, - XT_GETOPT_TABLEEND, +#define s struct xt_NFQ_info +static const struct xt_option_entry NFQUEUE_opts[] = { + {.name = "queue-num", .id = O_QUEUE_NUM, .type = XTTYPE_UINT16, + .flags = XTOPT_PUT, XTOPT_POINTER(s, queuenum)}, + {.name = "queue-balance", .id = O_QUEUE_BALANCE, + .type = XTTYPE_UINT16RC}, + {.name = "queue-bypass", .id = O_QUEUE_BYPASS, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, }; +#undef s -static void exit_badqueue(const char *s) -{ - xtables_error(PARAMETER_PROBLEM, "Invalid queue number `%s'\n", s); -} - -static void -parse_num(const char *s, struct xt_NFQ_info *tinfo) +static void NFQUEUE_parse(struct xt_option_call *cb) { - unsigned int num; - - if (!xtables_strtoui(s, NULL, &num, 0, UINT16_MAX)) - exit_badqueue(s); - - tinfo->queuenum = num; -} - -static int -NFQUEUE_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct xt_NFQ_info *tinfo - = (struct xt_NFQ_info *)(*target)->data; - - switch (c) { - case 'F': - if (*flags) - xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: " - "Only use --queue-num ONCE!"); - parse_num(optarg, tinfo); - break; - case 'B': + xtables_option_parse(cb); + if (cb->entry->id == O_QUEUE_BALANCE) xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: " "--queue-balance not supported (kernel too old?)"); - } - - return 1; } -static int -NFQUEUE_parse_v1(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void NFQUEUE_parse_v1(struct xt_option_call *cb) { - struct xt_NFQ_info_v1 *info = (void *)(*target)->data; - char *colon; - unsigned int firstqueue, lastqueue; - - switch (c) { - case 'F': /* fallthrough */ - case 'B': - if (*flags) - xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: " - "Only use --queue-num ONCE!"); - - if (!xtables_strtoui(optarg, &colon, &firstqueue, 0, UINT16_MAX)) - exit_badqueue(optarg); - - info->queuenum = firstqueue; - - if (c == 'F') { - if (*colon) - exit_badqueue(optarg); - break; - } + struct xt_NFQ_info_v1 *info = cb->data; + const uint16_t *r = cb->val.u16_range; - if (*colon != ':') - xtables_error(PARAMETER_PROBLEM, "Bad range \"%s\"", optarg); - - if (!xtables_strtoui(colon + 1, NULL, &lastqueue, 1, UINT16_MAX)) - exit_badqueue(optarg); - - if (firstqueue >= lastqueue) + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_QUEUE_BALANCE: + if (cb->nvals != 2) + xtables_error(PARAMETER_PROBLEM, + "Bad range \"%s\"", cb->arg); + if (r[0] >= r[1]) xtables_error(PARAMETER_PROBLEM, "%u should be less than %u", - firstqueue, lastqueue); - info->queues_total = lastqueue - firstqueue + 1; + r[0], r[1]); + info->queuenum = r[0]; + info->queues_total = r[1] - r[0] + 1; break; } - - return 1; } -static int -NFQUEUE_parse_v2(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void NFQUEUE_parse_v2(struct xt_option_call *cb) { - if (c == 'P') { - struct xt_NFQ_info_v2 *info = (void *)(*target)->data; + struct xt_NFQ_info_v2 *info = cb->data; + + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_QUEUE_BYPASS: info->bypass = 1; - return 1; + break; + default: + NFQUEUE_parse_v1(cb); + break; } - return NFQUEUE_parse_v1(c, argv, invert, flags, entry, target); } static void NFQUEUE_print(const void *ip, @@ -214,10 +169,10 @@ static struct xtables_target nfqueue_targets[] = { .size = XT_ALIGN(sizeof(struct xt_NFQ_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info)), .help = NFQUEUE_help, - .parse = NFQUEUE_parse, .print = NFQUEUE_print, .save = NFQUEUE_save, - .extra_opts = NFQUEUE_opts + .x6_parse = NFQUEUE_parse, + .x6_options = NFQUEUE_opts },{ .family = NFPROTO_UNSPEC, .revision = 1, @@ -227,10 +182,10 @@ static struct xtables_target nfqueue_targets[] = { .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info_v1)), .help = NFQUEUE_help_v1, .init = NFQUEUE_init_v1, - .parse = NFQUEUE_parse_v1, .print = NFQUEUE_print_v1, .save = NFQUEUE_save_v1, - .extra_opts = NFQUEUE_opts, + .x6_parse = NFQUEUE_parse_v1, + .x6_options = NFQUEUE_opts, },{ .family = NFPROTO_UNSPEC, .revision = 2, @@ -240,10 +195,10 @@ static struct xtables_target nfqueue_targets[] = { .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info_v2)), .help = NFQUEUE_help_v2, .init = NFQUEUE_init_v1, - .parse = NFQUEUE_parse_v2, .print = NFQUEUE_print_v2, .save = NFQUEUE_save_v2, - .extra_opts = NFQUEUE_opts, + .x6_parse = NFQUEUE_parse_v2, + .x6_options = NFQUEUE_opts, } }; -- cgit v1.2.3 From ea2a02f7e961011b2e226c25a5e8ff49e1f84278 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 18:00:05 +0100 Subject: libxt_TCPMSS: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_TCPMSS.c | 96 +++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 61 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_TCPMSS.c b/extensions/libxt_TCPMSS.c index e15e87a8..2266326d 100644 --- a/extensions/libxt_TCPMSS.c +++ b/extensions/libxt_TCPMSS.c @@ -2,16 +2,17 @@ * * Copyright (c) 2000 Marc Boucher */ -#include #include -#include -#include -#include - #include -#include +#include +#include #include +enum { + O_SET_MSS = 0, + O_CLAMP_MSS, +}; + struct mssinfo { struct xt_entry_target t; struct xt_tcpmss_info mss; @@ -28,69 +29,42 @@ hdrsize); static void TCPMSS_help(void) { - __TCPMSS_help(40); + __TCPMSS_help(sizeof(struct iphdr)); } static void TCPMSS_help6(void) { - __TCPMSS_help(60); + __TCPMSS_help(sizeof(struct ip6_hdr)); } -static const struct option TCPMSS_opts[] = { - {.name = "set-mss", .has_arg = true, .val = '1'}, - {.name = "clamp-mss-to-pmtu", .has_arg = false, .val = '2'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry TCPMSS4_opts[] = { + {.name = "set-mss", .id = O_SET_MSS, .type = XTTYPE_UINT16, + .min = 0, .max = UINT16_MAX - sizeof(struct iphdr), + .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_tcpmss_info, mss)}, + {.name = "clamp-mss-to-pmtu", .id = O_CLAMP_MSS, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, }; -static int __TCPMSS_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target, - int hdrsize) -{ - struct xt_tcpmss_info *mssinfo - = (struct xt_tcpmss_info *)(*target)->data; - - switch (c) { - unsigned int mssval; - - case '1': - if (*flags) - xtables_error(PARAMETER_PROBLEM, - "TCPMSS target: Only one option may be specified"); - if (!xtables_strtoui(optarg, NULL, &mssval, - 0, UINT16_MAX - hdrsize)) - xtables_error(PARAMETER_PROBLEM, "Bad TCPMSS value \"%s\"", optarg); - - mssinfo->mss = mssval; - *flags = 1; - break; - - case '2': - if (*flags) - xtables_error(PARAMETER_PROBLEM, - "TCPMSS target: Only one option may be specified"); - mssinfo->mss = XT_TCPMSS_CLAMP_PMTU; - *flags = 1; - break; - } - - return 1; -} +static const struct xt_option_entry TCPMSS6_opts[] = { + {.name = "set-mss", .id = O_SET_MSS, .type = XTTYPE_UINT16, + .min = 0, .max = UINT16_MAX - sizeof(struct ip6_hdr), + .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_tcpmss_info, mss)}, + {.name = "clamp-mss-to-pmtu", .id = O_CLAMP_MSS, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, +}; -static int TCPMSS_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void TCPMSS_parse(struct xt_option_call *cb) { - return __TCPMSS_parse(c, argv, invert, flags, entry, target, 40); -} + struct xt_tcpmss_info *mssinfo = cb->data; -static int TCPMSS_parse6(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - return __TCPMSS_parse(c, argv, invert, flags, entry, target, 60); + xtables_option_parse(cb); + if (cb->entry->id == O_CLAMP_MSS) + mssinfo->mss = XT_TCPMSS_CLAMP_PMTU; } -static void TCPMSS_check(unsigned int flags) +static void TCPMSS_check(struct xt_fcheck_call *cb) { - if (!flags) + if (cb->xflags == 0) xtables_error(PARAMETER_PROBLEM, "TCPMSS target: At least one parameter is required"); } @@ -124,11 +98,11 @@ static struct xtables_target tcpmss_target = { .size = XT_ALIGN(sizeof(struct xt_tcpmss_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_tcpmss_info)), .help = TCPMSS_help, - .parse = TCPMSS_parse, - .final_check = TCPMSS_check, .print = TCPMSS_print, .save = TCPMSS_save, - .extra_opts = TCPMSS_opts, + .x6_parse = TCPMSS_parse, + .x6_fcheck = TCPMSS_check, + .x6_options = TCPMSS4_opts, }; static struct xtables_target tcpmss_target6 = { @@ -138,11 +112,11 @@ static struct xtables_target tcpmss_target6 = { .size = XT_ALIGN(sizeof(struct xt_tcpmss_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_tcpmss_info)), .help = TCPMSS_help6, - .parse = TCPMSS_parse6, - .final_check = TCPMSS_check, .print = TCPMSS_print, .save = TCPMSS_save, - .extra_opts = TCPMSS_opts, + .x6_parse = TCPMSS_parse, + .x6_fcheck = TCPMSS_check, + .x6_options = TCPMSS6_opts, }; void _init(void) -- cgit v1.2.3 From c618a0b1d3696c30f7791a427da9ba60186dfe05 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 6 Mar 2011 18:12:04 +0100 Subject: libxt_string: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libxt_string.c | 138 ++++++++++++++++------------------------------ 1 file changed, 47 insertions(+), 91 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_string.c b/extensions/libxt_string.c index 1030d2e3..eef0b081 100644 --- a/extensions/libxt_string.c +++ b/extensions/libxt_string.c @@ -20,18 +20,25 @@ * updated to work with slightly modified * ipt_string_info. */ -#define _GNU_SOURCE 1 -#include #include -#include #include #include -#include #include #include -#include #include +enum { + O_FROM = 0, + O_TO, + O_ALGO, + O_ICASE, + O_STRING, + O_HEX_STRING, + F_STRING = 1 << O_STRING, + F_HEX_STRING = 1 << O_HEX_STRING, + F_OP_ANY = F_STRING | F_HEX_STRING, +}; + static void string_help(void) { printf( @@ -44,15 +51,22 @@ static void string_help(void) "[!] --hex-string string Match a hex string in a packet\n"); } -static const struct option string_opts[] = { - {.name = "from", .has_arg = true, .val = '1'}, - {.name = "to", .has_arg = true, .val = '2'}, - {.name = "algo", .has_arg = true, .val = '3'}, - {.name = "string", .has_arg = true, .val = '4'}, - {.name = "hex-string", .has_arg = true, .val = '5'}, - {.name = "icase", .has_arg = false, .val = '6'}, - XT_GETOPT_TABLEEND, +#define s struct xt_string_info +static const struct xt_option_entry string_opts[] = { + {.name = "from", .id = O_FROM, .type = XTTYPE_UINT16, + .flags = XTOPT_PUT, XTOPT_POINTER(s, from_offset)}, + {.name = "to", .id = O_TO, .type = XTTYPE_UINT16, + .flags = XTOPT_PUT, XTOPT_POINTER(s, to_offset)}, + {.name = "algo", .id = O_ALGO, .type = XTTYPE_STRING, + .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, algo)}, + {.name = "string", .id = O_STRING, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT, .excl = F_HEX_STRING}, + {.name = "hex-string", .id = O_HEX_STRING, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT, .excl = F_STRING}, + {.name = "icase", .id = O_ICASE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, }; +#undef s static void string_init(struct xt_entry_match *m) { @@ -73,17 +87,6 @@ parse_string(const char *s, struct xt_string_info *info) xtables_error(PARAMETER_PROBLEM, "STRING too long \"%s\"", s); } -static void -parse_algo(const char *s, struct xt_string_info *info) -{ - /* xt_string needs \0 for algo name */ - if (strlen(s) < XT_STRING_MAX_ALGO_NAME_SIZE) { - strncpy(info->algo, s, XT_STRING_MAX_ALGO_NAME_SIZE); - return; - } - xtables_error(PARAMETER_PROBLEM, "ALGO too long \"%s\"", s); -} - static void parse_hex_string(const char *s, struct xt_string_info *info) { @@ -162,94 +165,47 @@ parse_hex_string(const char *s, struct xt_string_info *info) info->patlen = sindex; } -#define STRING 0x1 -#define ALGO 0x2 -#define FROM 0x4 -#define TO 0x8 -#define ICASE 0x10 - -static int -string_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void string_parse(struct xt_option_call *cb) { - struct xt_string_info *stringinfo = - (struct xt_string_info *)(*match)->data; - const int revision = (*match)->u.user.revision; + struct xt_string_info *stringinfo = cb->data; + const unsigned int revision = (*cb->match)->u.user.revision; - switch (c) { - case '1': - if (*flags & FROM) - xtables_error(PARAMETER_PROBLEM, - "Can't specify multiple --from"); - stringinfo->from_offset = atoi(optarg); - *flags |= FROM; - break; - case '2': - if (*flags & TO) - xtables_error(PARAMETER_PROBLEM, - "Can't specify multiple --to"); - stringinfo->to_offset = atoi(optarg); - *flags |= TO; - break; - case '3': - if (*flags & ALGO) - xtables_error(PARAMETER_PROBLEM, - "Can't specify multiple --algo"); - parse_algo(optarg, stringinfo); - *flags |= ALGO; - break; - case '4': - if (*flags & STRING) - xtables_error(PARAMETER_PROBLEM, - "Can't specify multiple --string"); - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - parse_string(optarg, stringinfo); - if (invert) { + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_STRING: + parse_string(cb->arg, stringinfo); + if (cb->invert) { if (revision == 0) stringinfo->u.v0.invert = 1; else stringinfo->u.v1.flags |= XT_STRING_FLAG_INVERT; } - *flags |= STRING; break; - - case '5': - if (*flags & STRING) - xtables_error(PARAMETER_PROBLEM, - "Can't specify multiple --hex-string"); - - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - parse_hex_string(optarg, stringinfo); /* sets length */ - if (invert) { + case O_HEX_STRING: + parse_hex_string(cb->arg, stringinfo); /* sets length */ + if (cb->invert) { if (revision == 0) stringinfo->u.v0.invert = 1; else stringinfo->u.v1.flags |= XT_STRING_FLAG_INVERT; } - *flags |= STRING; break; - - case '6': + case O_ICASE: if (revision == 0) xtables_error(VERSION_PROBLEM, "Kernel doesn't support --icase"); stringinfo->u.v1.flags |= XT_STRING_FLAG_IGNORECASE; - *flags |= ICASE; break; } - return 1; } -static void string_check(unsigned int flags) +static void string_check(struct xt_fcheck_call *cb) { - if (!(flags & STRING)) + if (!(cb->xflags & F_OP_ANY)) xtables_error(PARAMETER_PROBLEM, "STRING match: You must specify `--string' or " "`--hex-string'"); - if (!(flags & ALGO)) - xtables_error(PARAMETER_PROBLEM, - "STRING match: You must specify `--algo'"); } /* Test to see if the string contains non-printable chars or quotes */ @@ -357,11 +313,11 @@ static struct xtables_match string_mt_reg[] = { .userspacesize = offsetof(struct xt_string_info, config), .help = string_help, .init = string_init, - .parse = string_parse, - .final_check = string_check, .print = string_print, .save = string_save, - .extra_opts = string_opts, + .x6_parse = string_parse, + .x6_fcheck = string_check, + .x6_options = string_opts, }, { .name = "string", @@ -372,11 +328,11 @@ static struct xtables_match string_mt_reg[] = { .userspacesize = offsetof(struct xt_string_info, config), .help = string_help, .init = string_init, - .parse = string_parse, - .final_check = string_check, .print = string_print, .save = string_save, - .extra_opts = string_opts, + .x6_parse = string_parse, + .x6_fcheck = string_check, + .x6_options = string_opts, }, }; -- cgit v1.2.3 From 0dd344a9bedc24feb6ad99d4620bdc7da171c72d Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 15 Feb 2011 12:05:12 +0100 Subject: libip[6]t_LOG: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libip6t_LOG.c | 174 +++++++++++------------------------------------ extensions/libipt_LOG.c | 174 +++++++++++------------------------------------ 2 files changed, 82 insertions(+), 266 deletions(-) (limited to 'extensions') diff --git a/extensions/libip6t_LOG.c b/extensions/libip6t_LOG.c index e9c738f1..a419ec91 100644 --- a/extensions/libip6t_LOG.c +++ b/extensions/libip6t_LOG.c @@ -1,11 +1,6 @@ -/* Shared library add-on to ip6tables to add LOG support. */ -#include #include -#include #include -#include #include -#include #include #include @@ -17,6 +12,16 @@ #define LOG_DEFAULT_LEVEL LOG_WARNING +enum { + O_LOG_LEVEL = 0, + O_LOG_PREFIX, + O_LOG_TCPSEQ, + O_LOG_TCPOPTS, + O_LOG_IPOPTS, + O_LOG_UID, + O_LOG_MAC, +}; + static void LOG_help(void) { printf( @@ -30,16 +35,20 @@ static void LOG_help(void) " --log-macdecode Decode MAC addresses and protocol.\n"); } -static const struct option LOG_opts[] = { - {.name = "log-level", .has_arg = true, .val = '!'}, - {.name = "log-prefix", .has_arg = true, .val = '#'}, - {.name = "log-tcp-sequence", .has_arg = false, .val = '1'}, - {.name = "log-tcp-options", .has_arg = false, .val = '2'}, - {.name = "log-ip-options", .has_arg = false, .val = '3'}, - {.name = "log-uid", .has_arg = false, .val = '4'}, - {.name = "log-macdecode", .has_arg = false, .val = '5'}, - XT_GETOPT_TABLEEND, +#define s struct ip6t_log_info +static const struct xt_option_entry LOG_opts[] = { + {.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL, + .flags = XTOPT_PUT, XTOPT_POINTER(s, level)}, + {.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING, + .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1}, + {.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE}, + {.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE}, + {.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE}, + {.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE}, + {.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, }; +#undef s static void LOG_init(struct xt_entry_target *t) { @@ -66,134 +75,33 @@ static const struct ip6t_log_names ip6t_log_names[] { .name = "warning", .level = LOG_WARNING } }; -static uint8_t -parse_level(const char *level) +static void LOG_parse(struct xt_option_call *cb) { - unsigned int lev = -1; - unsigned int set = 0; - - if (!xtables_strtoui(level, NULL, &lev, 0, 7)) { - unsigned int i = 0; - - for (i = 0; i < ARRAY_SIZE(ip6t_log_names); ++i) - if (strncasecmp(level, ip6t_log_names[i].name, - strlen(level)) == 0) { - if (set++) - xtables_error(PARAMETER_PROBLEM, - "log-level `%s' ambiguous", - level); - lev = ip6t_log_names[i].level; - } + struct ip6t_log_info *info = cb->data; - if (!set) - xtables_error(PARAMETER_PROBLEM, - "log-level `%s' unknown", level); - } - - return lev; -} - -#define IP6T_LOG_OPT_LEVEL 0x01 -#define IP6T_LOG_OPT_PREFIX 0x02 -#define IP6T_LOG_OPT_TCPSEQ 0x04 -#define IP6T_LOG_OPT_TCPOPT 0x08 -#define IP6T_LOG_OPT_IPOPT 0x10 -#define IP6T_LOG_OPT_UID 0x20 -#define IP6T_LOG_OPT_MACDECODE 0x40 - -static int LOG_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct ip6t_log_info *loginfo = (struct ip6t_log_info *)(*target)->data; - - switch (c) { - case '!': - if (*flags & IP6T_LOG_OPT_LEVEL) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-level twice"); - - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --log-level"); - - loginfo->level = parse_level(optarg); - *flags |= IP6T_LOG_OPT_LEVEL; - break; - - case '#': - if (*flags & IP6T_LOG_OPT_PREFIX) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-prefix twice"); - - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --log-prefix"); - - if (strlen(optarg) > sizeof(loginfo->prefix) - 1) - xtables_error(PARAMETER_PROBLEM, - "Maximum prefix length %u for --log-prefix", - (unsigned int)sizeof(loginfo->prefix) - 1); - - if (strlen(optarg) == 0) - xtables_error(PARAMETER_PROBLEM, - "No prefix specified for --log-prefix"); - - if (strlen(optarg) != strlen(strtok(optarg, "\n"))) + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_LOG_PREFIX: + if (strchr(cb->arg, '\n') != NULL) xtables_error(PARAMETER_PROBLEM, "Newlines not allowed in --log-prefix"); - - strcpy(loginfo->prefix, optarg); - *flags |= IP6T_LOG_OPT_PREFIX; break; - - case '1': - if (*flags & IP6T_LOG_OPT_TCPSEQ) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-tcp-sequence " - "twice"); - - loginfo->logflags |= IP6T_LOG_TCPSEQ; - *flags |= IP6T_LOG_OPT_TCPSEQ; + case O_LOG_TCPSEQ: + info->logflags = IP6T_LOG_TCPSEQ; break; - - case '2': - if (*flags & IP6T_LOG_OPT_TCPOPT) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-tcp-options twice"); - - loginfo->logflags |= IP6T_LOG_TCPOPT; - *flags |= IP6T_LOG_OPT_TCPOPT; + case O_LOG_TCPOPTS: + info->logflags = IP6T_LOG_TCPOPT; break; - - case '3': - if (*flags & IP6T_LOG_OPT_IPOPT) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-ip-options twice"); - - loginfo->logflags |= IP6T_LOG_IPOPT; - *flags |= IP6T_LOG_OPT_IPOPT; + case O_LOG_IPOPTS: + info->logflags = IP6T_LOG_IPOPT; break; - - case '4': - if (*flags & IP6T_LOG_OPT_UID) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-uid twice"); - - loginfo->logflags |= IP6T_LOG_UID; - *flags |= IP6T_LOG_OPT_UID; + case O_LOG_UID: + info->logflags = IP6T_LOG_UID; break; - - case '5': - if (*flags & IP6T_LOG_OPT_MACDECODE) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-macdecode twice"); - - loginfo->logflags |= IP6T_LOG_MACDECODE; - *flags |= IP6T_LOG_OPT_MACDECODE; + case O_LOG_MAC: + info->logflags = IP6T_LOG_MACDECODE; break; } - - return 1; } static void LOG_print(const void *ip, const struct xt_entry_target *target, @@ -264,10 +172,10 @@ static struct xtables_target log_tg6_reg = { .userspacesize = XT_ALIGN(sizeof(struct ip6t_log_info)), .help = LOG_help, .init = LOG_init, - .parse = LOG_parse, .print = LOG_print, .save = LOG_save, - .extra_opts = LOG_opts, + .x6_parse = LOG_parse, + .x6_options = LOG_opts, }; void _init(void) diff --git a/extensions/libipt_LOG.c b/extensions/libipt_LOG.c index ba6af044..b270bcf6 100644 --- a/extensions/libipt_LOG.c +++ b/extensions/libipt_LOG.c @@ -1,11 +1,6 @@ -/* Shared library add-on to iptables to add LOG support. */ -#include #include -#include #include -#include #include -#include #include #include @@ -17,6 +12,16 @@ #define IPT_LOG_MASK 0x0f #endif +enum { + O_LOG_LEVEL = 0, + O_LOG_PREFIX, + O_LOG_TCPSEQ, + O_LOG_TCPOPTS, + O_LOG_IPOPTS, + O_LOG_UID, + O_LOG_MAC, +}; + static void LOG_help(void) { printf( @@ -30,16 +35,20 @@ static void LOG_help(void) " --log-macdecode Decode MAC addresses and protocol.\n\n"); } -static const struct option LOG_opts[] = { - {.name = "log-level", .has_arg = true, .val = '!'}, - {.name = "log-prefix", .has_arg = true, .val = '#'}, - {.name = "log-tcp-sequence", .has_arg = false, .val = '1'}, - {.name = "log-tcp-options", .has_arg = false, .val = '2'}, - {.name = "log-ip-options", .has_arg = false, .val = '3'}, - {.name = "log-uid", .has_arg = false, .val = '4'}, - {.name = "log-macdecode", .has_arg = false, .val = '5'}, - XT_GETOPT_TABLEEND, +#define s struct ipt_log_info +static const struct xt_option_entry LOG_opts[] = { + {.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL, + .flags = XTOPT_PUT, XTOPT_POINTER(s, level)}, + {.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING, + .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1}, + {.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE}, + {.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE}, + {.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE}, + {.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE}, + {.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, }; +#undef s static void LOG_init(struct xt_entry_target *t) { @@ -66,134 +75,33 @@ static const struct ipt_log_names ipt_log_names[] { .name = "warning", .level = LOG_WARNING } }; -static uint8_t -parse_level(const char *level) +static void LOG_parse(struct xt_option_call *cb) { - unsigned int lev = -1; - unsigned int set = 0; - - if (!xtables_strtoui(level, NULL, &lev, 0, 7)) { - unsigned int i = 0; - - for (i = 0; i < ARRAY_SIZE(ipt_log_names); ++i) - if (strncasecmp(level, ipt_log_names[i].name, - strlen(level)) == 0) { - if (set++) - xtables_error(PARAMETER_PROBLEM, - "log-level `%s' ambiguous", - level); - lev = ipt_log_names[i].level; - } + struct ipt_log_info *info = cb->data; - if (!set) - xtables_error(PARAMETER_PROBLEM, - "log-level `%s' unknown", level); - } - - return lev; -} - -#define IPT_LOG_OPT_LEVEL 0x01 -#define IPT_LOG_OPT_PREFIX 0x02 -#define IPT_LOG_OPT_TCPSEQ 0x04 -#define IPT_LOG_OPT_TCPOPT 0x08 -#define IPT_LOG_OPT_IPOPT 0x10 -#define IPT_LOG_OPT_UID 0x20 -#define IPT_LOG_OPT_MACDECODE 0x40 - -static int LOG_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct ipt_log_info *loginfo = (struct ipt_log_info *)(*target)->data; - - switch (c) { - case '!': - if (*flags & IPT_LOG_OPT_LEVEL) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-level twice"); - - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --log-level"); - - loginfo->level = parse_level(optarg); - *flags |= IPT_LOG_OPT_LEVEL; - break; - - case '#': - if (*flags & IPT_LOG_OPT_PREFIX) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-prefix twice"); - - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --log-prefix"); - - if (strlen(optarg) > sizeof(loginfo->prefix) - 1) - xtables_error(PARAMETER_PROBLEM, - "Maximum prefix length %u for --log-prefix", - (unsigned int)sizeof(loginfo->prefix) - 1); - - if (strlen(optarg) == 0) - xtables_error(PARAMETER_PROBLEM, - "No prefix specified for --log-prefix"); - - if (strlen(optarg) != strlen(strtok(optarg, "\n"))) + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_LOG_PREFIX: + if (strchr(cb->arg, '\n') != NULL) xtables_error(PARAMETER_PROBLEM, "Newlines not allowed in --log-prefix"); - - strcpy(loginfo->prefix, optarg); - *flags |= IPT_LOG_OPT_PREFIX; break; - - case '1': - if (*flags & IPT_LOG_OPT_TCPSEQ) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-tcp-sequence " - "twice"); - - loginfo->logflags |= IPT_LOG_TCPSEQ; - *flags |= IPT_LOG_OPT_TCPSEQ; + case O_LOG_TCPSEQ: + info->logflags = IPT_LOG_TCPSEQ; break; - - case '2': - if (*flags & IPT_LOG_OPT_TCPOPT) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-tcp-options twice"); - - loginfo->logflags |= IPT_LOG_TCPOPT; - *flags |= IPT_LOG_OPT_TCPOPT; + case O_LOG_TCPOPTS: + info->logflags = IPT_LOG_TCPOPT; break; - - case '3': - if (*flags & IPT_LOG_OPT_IPOPT) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-ip-options twice"); - - loginfo->logflags |= IPT_LOG_IPOPT; - *flags |= IPT_LOG_OPT_IPOPT; + case O_LOG_IPOPTS: + info->logflags = IPT_LOG_IPOPT; break; - - case '4': - if (*flags & IPT_LOG_OPT_UID) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --log-uid twice"); - - loginfo->logflags |= IPT_LOG_UID; - *flags |= IPT_LOG_OPT_UID; + case O_LOG_UID: + info->logflags = IPT_LOG_UID; break; - - case '5': - if (*flags & IPT_LOG_OPT_MACDECODE) - xtables_error(PARAMETER_PROBLEM, - "Can't specifiy --log-macdecode twice"); - - loginfo->logflags |= IPT_LOG_MACDECODE; - *flags |= IPT_LOG_OPT_MACDECODE; + case O_LOG_MAC: + info->logflags = IPT_LOG_MACDECODE; break; } - - return 1; } static void LOG_print(const void *ip, const struct xt_entry_target *target, @@ -266,10 +174,10 @@ static struct xtables_target log_tg_reg = { .userspacesize = XT_ALIGN(sizeof(struct ipt_log_info)), .help = LOG_help, .init = LOG_init, - .parse = LOG_parse, .print = LOG_print, .save = LOG_save, - .extra_opts = LOG_opts, + .x6_parse = LOG_parse, + .x6_options = LOG_opts, }; void _init(void) -- cgit v1.2.3 From 64cb56e3e894f6b8b523ecb45f91abe43b07cf0c Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 9 Feb 2011 02:15:22 +0100 Subject: libxt_TPROXY: use guided option parser I am starting with a simple module here that does not require a final_check function. Signed-off-by: Jan Engelhardt --- extensions/libxt_TPROXY.c | 216 +++++++++++++--------------------------------- 1 file changed, 62 insertions(+), 154 deletions(-) (limited to 'extensions') diff --git a/extensions/libxt_TPROXY.c b/extensions/libxt_TPROXY.c index 890dd866..5264ea7d 100644 --- a/extensions/libxt_TPROXY.c +++ b/extensions/libxt_TPROXY.c @@ -1,32 +1,42 @@ /* - * Shared library add-on to iptables to add TPROXY target support. + * shared library add-on to iptables to add TPROXY target support. * * Copyright (C) 2002-2008 BalaBit IT Ltd. */ -#include -#include -#include #include -#include -#include #include - #include -#include #include +#include -static const struct option tproxy_tg_opts[] = { - {.name = "on-port", .has_arg = true, .val = '1'}, - {.name = "on-ip", .has_arg = true, .val = '2'}, - {.name = "tproxy-mark", .has_arg = true, .val = '3'}, - XT_GETOPT_TABLEEND, +enum { + P_PORT = 0, + P_ADDR, + P_MARK, + F_PORT = 1 << P_PORT, + F_ADDR = 1 << P_ADDR, + F_MARK = 1 << P_MARK, }; -enum { - PARAM_ONPORT = 1 << 0, - PARAM_ONIP = 1 << 1, - PARAM_MARK = 1 << 2, +#define s struct xt_tproxy_target_info +static const struct xt_option_entry tproxy_tg0_opts[] = { + {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT_NE, + .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, lport)}, + {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_ONEHOST}, + {.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32}, + XTOPT_TABLEEND, }; +#undef s +#define s struct xt_tproxy_target_info_v1 +static const struct xt_option_entry tproxy_tg1_opts[] = { + {.name = "on-port", .id = P_PORT, .type = XTTYPE_PORT_NE, + .flags = XTOPT_MAND | XTOPT_PUT, XTOPT_POINTER(s, lport)}, + {.name = "on-ip", .id = P_ADDR, .type = XTTYPE_ONEHOST, + .flags = XTOPT_PUT, XTOPT_POINTER(s, laddr)}, + {.name = "tproxy-mark", .id = P_MARK, .type = XTTYPE_MARKMASK32}, + XTOPT_TABLEEND, +}; +#undef s static void tproxy_tg_help(void) { @@ -37,134 +47,6 @@ static void tproxy_tg_help(void) " --tproxy-mark value[/mask] Mark packets with the given value/mask\n\n"); } -static void parse_tproxy_lport(const char *s, uint16_t *portp) -{ - unsigned int lport; - - if (xtables_strtoui(s, NULL, &lport, 0, UINT16_MAX)) - *portp = htons(lport); - else - xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-port", s); -} - -static void parse_tproxy_laddr(const char *s, union nf_inet_addr *addrp, - unsigned int nfproto) -{ - struct in6_addr *laddr6 = NULL; - struct in_addr *laddr4 = NULL; - - if (nfproto == NFPROTO_IPV6) { - laddr6 = xtables_numeric_to_ip6addr(s); - if (laddr6 == NULL) - goto out; - addrp->in6 = *laddr6; - } else if (nfproto == NFPROTO_IPV4) { - laddr4 = xtables_numeric_to_ipaddr(s); - if (laddr4 == NULL) - goto out; - addrp->in = *laddr4; - } - return; - out: - xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--on-ip", s); -} - -static void parse_tproxy_mark(char *s, uint32_t *markp, uint32_t *maskp) -{ - unsigned int value, mask = UINT32_MAX; - char *end; - - if (!xtables_strtoui(s, &end, &value, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s); - if (*end == '/') - if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) - xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s); - if (*end != '\0') - xtables_param_act(XTF_BAD_VALUE, "TPROXY", "--tproxy-mark", s); - - *markp = value; - *maskp = mask; -} - -static int tproxy_tg_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct xt_tproxy_target_info *info = (void *)(*target)->data; - - switch (c) { - case '1': - xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-port", *flags & PARAM_ONPORT); - xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-port", invert); - parse_tproxy_lport(optarg, &info->lport); - *flags |= PARAM_ONPORT; - return 1; - case '2': - xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-ip", *flags & PARAM_ONIP); - xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-ip", invert); - parse_tproxy_laddr(optarg, (void *)&info->laddr, NFPROTO_IPV4); - *flags |= PARAM_ONIP; - return 1; - case '3': - xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--tproxy-mark", *flags & PARAM_MARK); - xtables_param_act(XTF_NO_INVERT, "TPROXY", "--tproxy-mark", invert); - parse_tproxy_mark(optarg, &info->mark_value, &info->mark_mask); - *flags |= PARAM_MARK; - return 1; - } - - return 0; -} - -static int -tproxy_tg_parse1(int c, char **argv, int invert, unsigned int *flags, - struct xt_tproxy_target_info_v1 *info, unsigned int nfproto) -{ - switch (c) { - case '1': - xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-port", *flags & PARAM_ONPORT); - xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-port", invert); - parse_tproxy_lport(optarg, &info->lport); - *flags |= PARAM_ONPORT; - return true; - case '2': - xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--on-ip", *flags & PARAM_ONIP); - xtables_param_act(XTF_NO_INVERT, "TPROXY", "--on-ip", invert); - parse_tproxy_laddr(optarg, (void *)&info->laddr, nfproto); - *flags |= PARAM_ONIP; - return true; - case '3': - xtables_param_act(XTF_ONLY_ONCE, "TPROXY", "--tproxy-mark", *flags & PARAM_MARK); - xtables_param_act(XTF_NO_INVERT, "TPROXY", "--tproxy-mark", invert); - parse_tproxy_mark(optarg, &info->mark_value, &info->mark_mask); - *flags |= PARAM_MARK; - return true; - } - return false; -} - -static int -tproxy_tg_parse4(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct xt_tproxy_target_info_v1 *info = (void *)(*target)->data; - return tproxy_tg_parse1(c, argv, invert, flags, info, NFPROTO_IPV4); -} - -static int -tproxy_tg_parse6(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) -{ - struct xt_tproxy_target_info_v1 *info = (void *)(*target)->data; - return tproxy_tg_parse1(c, argv, invert, flags, info, NFPROTO_IPV6); -} - -static void tproxy_tg_check(unsigned int flags) -{ - if (!(flags & PARAM_ONPORT)) - xtables_error(PARAMETER_PROBLEM, - "TPROXY target: Parameter --on-port is required"); -} - static void tproxy_tg_print(const void *ip, const struct xt_entry_target *target, int numeric) { @@ -236,6 +118,35 @@ tproxy_tg_save6(const void *ip, const struct xt_entry_target *target) (unsigned int)info->mark_value, (unsigned int)info->mark_mask); } +static void tproxy_tg0_parse(struct xt_option_call *cb) +{ + struct xt_tproxy_target_info *info = cb->data; + + xtables_option_parse(cb); + switch (cb->entry->id) { + case P_MARK: + info->mark_value = cb->val.mark; + info->mark_mask = cb->val.mask; + break; + case P_ADDR: + info->laddr = cb->val.inetaddr.ip; + break; + } +} + +static void tproxy_tg1_parse(struct xt_option_call *cb) +{ + struct xt_tproxy_target_info_v1 *info = cb->data; + + xtables_option_parse(cb); + switch (cb->entry->id) { + case P_MARK: + info->mark_value = cb->val.mark; + info->mark_mask = cb->val.mask; + break; + } +} + static struct xtables_target tproxy_tg_reg[] = { { .name = "TPROXY", @@ -245,11 +156,10 @@ static struct xtables_target tproxy_tg_reg[] = { .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info)), .help = tproxy_tg_help, - .parse = tproxy_tg_parse, - .final_check = tproxy_tg_check, .print = tproxy_tg_print, .save = tproxy_tg_save, - .extra_opts = tproxy_tg_opts, + .x6_options = tproxy_tg0_opts, + .x6_parse = tproxy_tg0_parse, }, { .name = "TPROXY", @@ -259,11 +169,10 @@ static struct xtables_target tproxy_tg_reg[] = { .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)), .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)), .help = tproxy_tg_help, - .parse = tproxy_tg_parse4, - .final_check = tproxy_tg_check, .print = tproxy_tg_print4, .save = tproxy_tg_save4, - .extra_opts = tproxy_tg_opts, + .x6_options = tproxy_tg1_opts, + .x6_parse = tproxy_tg1_parse, }, { .name = "TPROXY", @@ -273,11 +182,10 @@ static struct xtables_target tproxy_tg_reg[] = { .size = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)), .userspacesize = XT_ALIGN(sizeof(struct xt_tproxy_target_info_v1)), .help = tproxy_tg_help, - .parse = tproxy_tg_parse6, - .final_check = tproxy_tg_check, .print = tproxy_tg_print6, .save = tproxy_tg_save6, - .extra_opts = tproxy_tg_opts, + .x6_options = tproxy_tg1_opts, + .x6_parse = tproxy_tg1_parse, }, }; -- cgit v1.2.3 From 1f2474ae5276e49005c8e234dec091b007e3fce2 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 8 Mar 2011 01:24:26 +0100 Subject: libipt_ULOG: use guided option parser Signed-off-by: Jan Engelhardt --- extensions/libipt_ULOG.c | 137 ++++++++++++----------------------------------- 1 file changed, 34 insertions(+), 103 deletions(-) (limited to 'extensions') diff --git a/extensions/libipt_ULOG.c b/extensions/libipt_ULOG.c index 8eeccf00..e08ae056 100644 --- a/extensions/libipt_ULOG.c +++ b/extensions/libipt_ULOG.c @@ -9,29 +9,18 @@ * * libipt_ULOG.c,v 1.7 2001/01/30 11:55:02 laforge Exp */ -#include #include -#include #include -#include -#include -#include #include /* For 64bit kernel / 32bit userspace */ #include - -static void print_groups(unsigned int gmask) -{ - int b; - unsigned int test; - - for (b = 31; b >= 0; b--) { - test = (1 << b); - if (gmask & test) - printf(" %d", b + 1); - } -} +enum { + O_ULOG_NLGROUP = 0, + O_ULOG_PREFIX, + O_ULOG_CPRANGE, + O_ULOG_QTHR, +}; static void ULOG_help(void) { @@ -42,12 +31,16 @@ static void ULOG_help(void) " --ulog-prefix prefix Prefix log messages with this prefix.\n"); } -static const struct option ULOG_opts[] = { - {.name = "ulog-nlgroup", .has_arg = true, .val = '!'}, - {.name = "ulog-prefix", .has_arg = true, .val = '#'}, - {.name = "ulog-cprange", .has_arg = true, .val = 'A'}, - {.name = "ulog-qthreshold", .has_arg = true, .val = 'B'}, - XT_GETOPT_TABLEEND, +static const struct xt_option_entry ULOG_opts[] = { + {.name = "ulog-nlgroup", .id = O_ULOG_NLGROUP, .type = XTTYPE_UINT8, + .min = 1, .max = 32}, + {.name = "ulog-prefix", .id = O_ULOG_PREFIX, .type = XTTYPE_STRING, + .flags = XTOPT_PUT, XTOPT_POINTER(struct ipt_ulog_info, prefix), + .min = 1}, + {.name = "ulog-cprange", .id = O_ULOG_CPRANGE, .type = XTTYPE_UINT64, + .min = 1, .max = ULOG_MAX_QLEN}, + {.name = "ulog-qthreshold", .id = O_ULOG_QTHR, .type = XTTYPE_UINT64}, + XTOPT_TABLEEND, }; static void ULOG_init(struct xt_entry_target *t) @@ -59,87 +52,27 @@ static void ULOG_init(struct xt_entry_target *t) } -#define IPT_LOG_OPT_NLGROUP 0x01 -#define IPT_LOG_OPT_PREFIX 0x02 -#define IPT_LOG_OPT_CPRANGE 0x04 -#define IPT_LOG_OPT_QTHRESHOLD 0x08 - -static int ULOG_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_target **target) +static void ULOG_parse(struct xt_option_call *cb) { - struct ipt_ulog_info *loginfo = - (struct ipt_ulog_info *) (*target)->data; - int group_d; + struct ipt_ulog_info *loginfo = cb->data; - switch (c) { - case '!': - if (*flags & IPT_LOG_OPT_NLGROUP) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --ulog-nlgroup twice"); - - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --ulog-nlgroup"); - group_d = atoi(optarg); - if (group_d > 32 || group_d < 1) - xtables_error(PARAMETER_PROBLEM, - "--ulog-nlgroup has to be between 1 and 32"); - - loginfo->nl_group = (1 << (group_d - 1)); - - *flags |= IPT_LOG_OPT_NLGROUP; + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_ULOG_NLGROUP: + loginfo->nl_group = 1 << (cb->val.u8 - 1); break; - - case '#': - if (*flags & IPT_LOG_OPT_PREFIX) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --ulog-prefix twice"); - - if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --ulog-prefix"); - - if (strlen(optarg) > sizeof(loginfo->prefix) - 1) - xtables_error(PARAMETER_PROBLEM, - "Maximum prefix length %u for --ulog-prefix", - (unsigned int)sizeof(loginfo->prefix) - 1); - - if (strlen(optarg) == 0) - xtables_error(PARAMETER_PROBLEM, - "No prefix specified for --ulog-prefix"); - - if (strlen(optarg) != strlen(strtok(optarg, "\n"))) + case O_ULOG_PREFIX: + if (strchr(cb->arg, '\n') != NULL) xtables_error(PARAMETER_PROBLEM, "Newlines not allowed in --ulog-prefix"); - - strcpy(loginfo->prefix, optarg); - *flags |= IPT_LOG_OPT_PREFIX; break; - case 'A': - if (*flags & IPT_LOG_OPT_CPRANGE) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --ulog-cprange twice"); - if (atoi(optarg) < 0) - xtables_error(PARAMETER_PROBLEM, - "Negative copy range?"); - loginfo->copy_range = atoi(optarg); - *flags |= IPT_LOG_OPT_CPRANGE; + case O_ULOG_CPRANGE: + loginfo->copy_range = cb->val.u64; break; - case 'B': - if (*flags & IPT_LOG_OPT_QTHRESHOLD) - xtables_error(PARAMETER_PROBLEM, - "Can't specify --ulog-qthreshold twice"); - if (atoi(optarg) < 1) - xtables_error(PARAMETER_PROBLEM, - "Negative or zero queue threshold ?"); - if (atoi(optarg) > ULOG_MAX_QLEN) - xtables_error(PARAMETER_PROBLEM, - "Maximum queue length exceeded"); - loginfo->qthreshold = atoi(optarg); - *flags |= IPT_LOG_OPT_QTHRESHOLD; + case O_ULOG_QTHR: + loginfo->qthreshold = cb->val.u64; break; } - return 1; } static void ULOG_save(const void *ip, const struct xt_entry_target *target) @@ -152,10 +85,8 @@ static void ULOG_save(const void *ip, const struct xt_entry_target *target) xtables_save_string(loginfo->prefix); } - if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) { - printf(" --ulog-nlgroup"); - print_groups(loginfo->nl_group); - } + if (loginfo->nl_group != ULOG_DEFAULT_NLGROUP) + printf(" --ulog-nlgroup %d", ffs(loginfo->nl_group)); if (loginfo->copy_range) printf(" --ulog-cprange %u", (unsigned int)loginfo->copy_range); @@ -170,8 +101,8 @@ static void ULOG_print(const void *ip, const struct xt_entry_target *target, = (const struct ipt_ulog_info *) target->data; printf(" ULOG "); - printf("copy_range %u nlgroup", (unsigned int)loginfo->copy_range); - print_groups(loginfo->nl_group); + printf("copy_range %u nlgroup %d", (unsigned int)loginfo->copy_range, + ffs(loginfo->nl_group)); if (strcmp(loginfo->prefix, "") != 0) printf(" prefix \"%s\"", loginfo->prefix); printf(" queue_threshold %u", (unsigned int)loginfo->qthreshold); @@ -185,10 +116,10 @@ static struct xtables_target ulog_tg_reg = { .userspacesize = XT_ALIGN(sizeof(struct ipt_ulog_info)), .help = ULOG_help, .init = ULOG_init, - .parse = ULOG_parse, .print = ULOG_print, .save = ULOG_save, - .extra_opts = ULOG_opts, + .x6_parse = ULOG_parse, + .x6_options = ULOG_opts, }; void _init(void) -- cgit v1.2.3