diff options
Diffstat (limited to 'extensions/libip6t_dst.c')
-rw-r--r-- | extensions/libip6t_dst.c | 113 |
1 files changed, 33 insertions, 80 deletions
diff --git a/extensions/libip6t_dst.c b/extensions/libip6t_dst.c index 72df6ad..3fd4c01 100644 --- a/extensions/libip6t_dst.c +++ b/extensions/libip6t_dst.c @@ -1,15 +1,14 @@ -/* Shared library add-on to ip6tables to add Dst header support. */ #include <stdio.h> -#include <netdb.h> #include <string.h> #include <stdlib.h> -#include <getopt.h> #include <errno.h> #include <xtables.h> #include <linux/netfilter_ipv6/ip6t_opts.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> + +enum { + O_DSTLEN = 0, + O_DSTOPTS, +}; static void dst_help(void) { @@ -21,14 +20,15 @@ static void dst_help(void) IP6T_OPTS_OPTSNR); } -static const struct option dst_opts[] = { - { .name = "dst-len", .has_arg = 1, .val = '1' }, - { .name = "dst-opts", .has_arg = 1, .val = '2' }, - { .name = "dst-not-strict", .has_arg = 1, .val = '3' }, - { .name = NULL } +static const struct xt_option_entry dst_opts[] = { + {.name = "dst-len", .id = O_DSTLEN, .type = XTTYPE_UINT32, + .flags = XTOPT_INVERT | XTOPT_PUT, + XTOPT_POINTER(struct ip6t_opts, hdrlen)}, + {.name = "dst-opts", .id = O_DSTOPTS, .type = XTTYPE_STRING}, + XTOPT_TABLEEND, }; -static u_int32_t +static uint32_t parse_opts_num(const char *idstr, const char *typestr) { unsigned long int id; @@ -53,7 +53,7 @@ parse_opts_num(const char *idstr, const char *typestr) } static int -parse_options(const char *optsstr, u_int16_t *opts) +parse_options(const char *optsstr, uint16_t *opts) { char *buffer, *cp, *next, *range; unsigned int i; @@ -105,68 +105,28 @@ parse_options(const char *optsstr, u_int16_t *opts) return i; } -static void dst_init(struct xt_entry_match *m) +static void dst_parse(struct xt_option_call *cb) { - struct ip6t_opts *optinfo = (struct ip6t_opts *)m->data; + struct ip6t_opts *optinfo = cb->data; - optinfo->hdrlen = 0; - optinfo->flags = 0; - optinfo->invflags = 0; - optinfo->optsnr = 0; -} - -static int dst_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - struct ip6t_opts *optinfo = (struct ip6t_opts *)(*match)->data; - - switch (c) { - case '1': - if (*flags & IP6T_OPTS_LEN) - xtables_error(PARAMETER_PROBLEM, - "Only one `--dst-len' allowed"); - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - optinfo->hdrlen = parse_opts_num(optarg, "length"); - if (invert) - optinfo->invflags |= IP6T_OPTS_INV_LEN; + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_DSTLEN: optinfo->flags |= IP6T_OPTS_LEN; - *flags |= IP6T_OPTS_LEN; break; - case '2': - if (*flags & IP6T_OPTS_OPTS) - xtables_error(PARAMETER_PROBLEM, - "Only one `--dst-opts' allowed"); - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - if (invert) - xtables_error(PARAMETER_PROBLEM, - " '!' not allowed with `--dst-opts'"); - optinfo->optsnr = parse_options(optarg, optinfo->opts); + case O_DSTOPTS: + optinfo->optsnr = parse_options(cb->arg, optinfo->opts); optinfo->flags |= IP6T_OPTS_OPTS; - *flags |= IP6T_OPTS_OPTS; break; - case '3': - if (*flags & IP6T_OPTS_NSTRICT) - xtables_error(PARAMETER_PROBLEM, - "Only one `--dst-not-strict' allowed"); - if ( !(*flags & IP6T_OPTS_OPTS) ) - xtables_error(PARAMETER_PROBLEM, - "`--dst-opts ...' required before " - "`--dst-not-strict'"); - optinfo->flags |= IP6T_OPTS_NSTRICT; - *flags |= IP6T_OPTS_NSTRICT; - break; - default: - return 0; } - - return 1; } static void -print_options(unsigned int optsnr, u_int16_t *optsp) +print_options(unsigned int optsnr, uint16_t *optsp) { unsigned int i; + printf(" "); for(i = 0; i < optsnr; i++) { printf("%d", (optsp[i] & 0xFF00) >> 8); @@ -182,22 +142,19 @@ static void dst_print(const void *ip, const struct xt_entry_match *match, { const struct ip6t_opts *optinfo = (struct ip6t_opts *)match->data; - printf("dst "); + printf(" dst"); if (optinfo->flags & IP6T_OPTS_LEN) - printf("length:%s%u ", + printf(" length:%s%u", optinfo->invflags & IP6T_OPTS_INV_LEN ? "!" : "", optinfo->hdrlen); if (optinfo->flags & IP6T_OPTS_OPTS) - printf("opts "); + printf(" opts"); - print_options(optinfo->optsnr, (u_int16_t *)optinfo->opts); - - if (optinfo->flags & IP6T_OPTS_NSTRICT) - printf("not-strict "); + print_options(optinfo->optsnr, (uint16_t *)optinfo->opts); if (optinfo->invflags & ~IP6T_OPTS_INV_MASK) - printf("Unknown invflags: 0x%X ", + printf(" Unknown invflags: 0x%X", optinfo->invflags & ~IP6T_OPTS_INV_MASK); } @@ -206,18 +163,15 @@ static void dst_save(const void *ip, const struct xt_entry_match *match) const struct ip6t_opts *optinfo = (struct ip6t_opts *)match->data; if (optinfo->flags & IP6T_OPTS_LEN) { - printf("%s--dst-len %u ", - (optinfo->invflags & IP6T_OPTS_INV_LEN) ? "! " : "", + printf("%s --dst-len %u", + (optinfo->invflags & IP6T_OPTS_INV_LEN) ? " !" : "", optinfo->hdrlen); } if (optinfo->flags & IP6T_OPTS_OPTS) - printf("--dst-opts "); - - print_options(optinfo->optsnr, (u_int16_t *)optinfo->opts); + printf(" --dst-opts"); - if (optinfo->flags & IP6T_OPTS_NSTRICT) - printf("--dst-not-strict "); + print_options(optinfo->optsnr, (uint16_t *)optinfo->opts); } static struct xtables_match dst_mt6_reg = { @@ -227,11 +181,10 @@ static struct xtables_match dst_mt6_reg = { .size = XT_ALIGN(sizeof(struct ip6t_opts)), .userspacesize = XT_ALIGN(sizeof(struct ip6t_opts)), .help = dst_help, - .init = dst_init, - .parse = dst_parse, .print = dst_print, .save = dst_save, - .extra_opts = dst_opts, + .x6_parse = dst_parse, + .x6_options = dst_opts, }; void |