From: Florian Westphal <fwestphal@xxxxxxxxxx> Fairly straightforward from userspace view. Use XT_ADDRTYE_UNSPEC etc. instead of relying on RTN_* values from rtnetlink.h. XT_ADDRTYPE_ values .. match the shifted RTN_ ones, so this change is compatible. Signed-off-by: Florian Westphal <fwestphal@xxxxxxxxxx> --- extensions/libxt_addrtype.c | 195 ++++++++++++++++++++++++++----------------- 1 files changed, 118 insertions(+), 77 deletions(-) diff --git a/extensions/libxt_addrtype.c b/extensions/libxt_addrtype.c index a592f0d..14be638 100644 --- a/extensions/libxt_addrtype.c +++ b/extensions/libxt_addrtype.c @@ -8,31 +8,38 @@ #include <getopt.h> #include <xtables.h> -#include <linux/netfilter_ipv4/ipt_addrtype.h> - -/* from linux/rtnetlink.h, must match order of enumeration */ -static const char *const rtn_names[] = { - "UNSPEC", - "UNICAST", - "LOCAL", - "BROADCAST", - "ANYCAST", - "MULTICAST", - "BLACKHOLE", - "UNREACHABLE", - "PROHIBIT", - "THROW", - "NAT", - "XRESOLVE", - NULL +#include <linux/netfilter/xt_addrtype.h> + +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) +#define NAME_MASK(x) { __stringify(x), XT_ADDRTYPE_ ## x, } + +static struct { + const char *name; + uint32_t maskbit; +} rtn_names[] = { + NAME_MASK(UNSPEC), + NAME_MASK(UNICAST), + NAME_MASK(LOCAL), + NAME_MASK(BROADCAST), + NAME_MASK(ANYCAST), + NAME_MASK(MULTICAST), + NAME_MASK(BLACKHOLE), + NAME_MASK(UNREACHABLE), + NAME_MASK(PROHIBIT), + NAME_MASK(THROW), + NAME_MASK(NAT), + NAME_MASK(XRESOLVE), + + { NULL, 0 } }; static void addrtype_help_types(void) { int i; - for (i = 0; rtn_names[i]; i++) - printf(" %s\n", rtn_names[i]); + for (i = 0; rtn_names[i].name; i++) + printf(" %s\n", rtn_names[i].name); } static void addrtype_help_v0(void) @@ -56,18 +63,38 @@ static void addrtype_help_v1(void) " --limit-iface-out Match only on the packet's incoming device\n" "\n" "Valid types: \n"); +} + +static void addrtype_help4_v1(void) +{ + addrtype_help_v1(); addrtype_help_types(); } +static void addrtype_help6_v1(void) +{ + int i; + addrtype_help_v1(); + + for (i = 0; rtn_names[i].name ; i++) { + if (rtn_names[i].maskbit == XT_ADDRTYPE_BROADCAST || + rtn_names[i].maskbit == XT_ADDRTYPE_BLACKHOLE) + continue; + if (rtn_names[i].maskbit == XT_ADDRTYPE_PROHIBIT) + break; + + printf(" %s\n", rtn_names[i].name); + } +} + static int parse_type(const char *name, size_t len, uint16_t *mask) { int i; - for (i = 0; rtn_names[i]; i++) - if (strncasecmp(name, rtn_names[i], len) == 0) { - /* build up bitmask for kernel module */ - *mask |= (1 << i); + for (i = 0; rtn_names[i].name; i++) + if (strncasecmp(name, rtn_names[i].name, len) == 0) { + *mask |= rtn_names[i].maskbit; return 1; } @@ -88,42 +115,42 @@ static void parse_types(const char *arg, uint16_t *mask) if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask)) xtables_error(PARAMETER_PROBLEM, "addrtype: bad type \"%s\"", arg); } - -#define IPT_ADDRTYPE_OPT_SRCTYPE 0x1 -#define IPT_ADDRTYPE_OPT_DSTTYPE 0x2 -#define IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN 0x4 -#define IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT 0x8 + +#define XT_ADDRTYPE_OPT_SRCTYPE 0x1 +#define XT_ADDRTYPE_OPT_DSTTYPE 0x2 +#define XT_ADDRTYPE_OPT_LIMIT_IFACE_IN 0x4 +#define XT_ADDRTYPE_OPT_LIMIT_IFACE_OUT 0x8 static int addrtype_parse_v0(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { - struct ipt_addrtype_info *info = - (struct ipt_addrtype_info *) (*match)->data; + struct xt_addrtype_info *info = + (struct xt_addrtype_info *) (*match)->data; switch (c) { case '1': - if (*flags&IPT_ADDRTYPE_OPT_SRCTYPE) + if (*flags&XT_ADDRTYPE_OPT_SRCTYPE) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify src-type twice"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_types(optarg, &info->source); if (invert) info->invert_source = 1; - *flags |= IPT_ADDRTYPE_OPT_SRCTYPE; + *flags |= XT_ADDRTYPE_OPT_SRCTYPE; break; case '2': - if (*flags&IPT_ADDRTYPE_OPT_DSTTYPE) + if (*flags&XT_ADDRTYPE_OPT_DSTTYPE) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify dst-type twice"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_types(optarg, &info->dest); if (invert) info->invert_dest = 1; - *flags |= IPT_ADDRTYPE_OPT_DSTTYPE; + *flags |= XT_ADDRTYPE_OPT_DSTTYPE; break; } - + return 1; } @@ -131,43 +158,43 @@ static int addrtype_parse_v1(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) { - struct ipt_addrtype_info_v1 *info = - (struct ipt_addrtype_info_v1 *) (*match)->data; + struct xt_addrtype_info_v1 *info = + (struct xt_addrtype_info_v1 *) (*match)->data; switch (c) { case '1': - if (*flags & IPT_ADDRTYPE_OPT_SRCTYPE) + if (*flags & XT_ADDRTYPE_OPT_SRCTYPE) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify src-type twice"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_types(optarg, &info->source); if (invert) - info->flags |= IPT_ADDRTYPE_INVERT_SOURCE; - *flags |= IPT_ADDRTYPE_OPT_SRCTYPE; + info->flags |= XT_ADDRTYPE_INVERT_SOURCE; + *flags |= XT_ADDRTYPE_OPT_SRCTYPE; break; case '2': - if (*flags & IPT_ADDRTYPE_OPT_DSTTYPE) + if (*flags & XT_ADDRTYPE_OPT_DSTTYPE) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify dst-type twice"); xtables_check_inverse(optarg, &invert, &optind, 0, argv); parse_types(optarg, &info->dest); if (invert) - info->flags |= IPT_ADDRTYPE_INVERT_DEST; - *flags |= IPT_ADDRTYPE_OPT_DSTTYPE; + info->flags |= XT_ADDRTYPE_INVERT_DEST; + *flags |= XT_ADDRTYPE_OPT_DSTTYPE; break; case '3': - if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN) + if (*flags & XT_ADDRTYPE_OPT_LIMIT_IFACE_IN) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify limit-iface-in twice"); - info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_IN; - *flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN; + info->flags |= XT_ADDRTYPE_LIMIT_IFACE_IN; + *flags |= XT_ADDRTYPE_OPT_LIMIT_IFACE_IN; break; case '4': - if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT) + if (*flags & XT_ADDRTYPE_OPT_LIMIT_IFACE_OUT) xtables_error(PARAMETER_PROBLEM, "addrtype: can't specify limit-iface-out twice"); - info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_OUT; - *flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT; + info->flags |= XT_ADDRTYPE_LIMIT_IFACE_OUT; + *flags |= XT_ADDRTYPE_OPT_LIMIT_IFACE_OUT; break; } @@ -176,18 +203,18 @@ addrtype_parse_v1(int c, char **argv, int invert, unsigned int *flags, static void addrtype_check_v0(unsigned int flags) { - if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE))) + if (!(flags & (XT_ADDRTYPE_OPT_SRCTYPE|XT_ADDRTYPE_OPT_DSTTYPE))) xtables_error(PARAMETER_PROBLEM, "addrtype: you must specify --src-type or --dst-type"); } static void addrtype_check_v1(unsigned int flags) { - if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE))) + if (!(flags & (XT_ADDRTYPE_OPT_SRCTYPE|XT_ADDRTYPE_OPT_DSTTYPE))) xtables_error(PARAMETER_PROBLEM, "addrtype: you must specify --src-type or --dst-type"); - if (flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN && - flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT) + if (flags & XT_ADDRTYPE_OPT_LIMIT_IFACE_IN && + flags & XT_ADDRTYPE_OPT_LIMIT_IFACE_OUT) xtables_error(PARAMETER_PROBLEM, "addrtype: you can't specify both --limit-iface-in " "and --limit-iface-out"); @@ -198,9 +225,9 @@ static void print_types(uint16_t mask) const char *sep = ""; int i; - for (i = 0; rtn_names[i]; i++) - if (mask & (1 << i)) { - printf("%s%s", sep, rtn_names[i]); + for (i = 0; rtn_names[i].name; i++) + if (mask & rtn_names[i].maskbit) { + printf("%s%s", sep, rtn_names[i].name); sep = ","; } } @@ -208,8 +235,8 @@ static void print_types(uint16_t mask) static void addrtype_print_v0(const void *ip, const struct xt_entry_match *match, int numeric) { - const struct ipt_addrtype_info *info = - (struct ipt_addrtype_info *) match->data; + const struct xt_addrtype_info *info = + (struct xt_addrtype_info *) match->data; printf(" ADDRTYPE match"); if (info->source) { @@ -229,34 +256,34 @@ static void addrtype_print_v0(const void *ip, const struct xt_entry_match *match static void addrtype_print_v1(const void *ip, const struct xt_entry_match *match, int numeric) { - const struct ipt_addrtype_info_v1 *info = - (struct ipt_addrtype_info_v1 *) match->data; + const struct xt_addrtype_info_v1 *info = + (struct xt_addrtype_info_v1 *) match->data; printf(" ADDRTYPE match"); if (info->source) { printf(" src-type "); - if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE) + if (info->flags & XT_ADDRTYPE_INVERT_SOURCE) printf("!"); print_types(info->source); } if (info->dest) { printf(" dst-type "); - if (info->flags & IPT_ADDRTYPE_INVERT_DEST) + if (info->flags & XT_ADDRTYPE_INVERT_DEST) printf("!"); print_types(info->dest); } - if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { + if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) { printf(" limit-in"); } - if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { + if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) { printf(" limit-out"); } } static void addrtype_save_v0(const void *ip, const struct xt_entry_match *match) { - const struct ipt_addrtype_info *info = - (struct ipt_addrtype_info *) match->data; + const struct xt_addrtype_info *info = + (struct xt_addrtype_info *) match->data; if (info->source) { if (info->invert_source) @@ -274,25 +301,25 @@ static void addrtype_save_v0(const void *ip, const struct xt_entry_match *match) static void addrtype_save_v1(const void *ip, const struct xt_entry_match *match) { - const struct ipt_addrtype_info_v1 *info = - (struct ipt_addrtype_info_v1 *) match->data; + const struct xt_addrtype_info_v1 *info = + (struct xt_addrtype_info_v1 *) match->data; if (info->source) { - if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE) + if (info->flags & XT_ADDRTYPE_INVERT_SOURCE) printf(" !"); printf(" --src-type "); print_types(info->source); } if (info->dest) { - if (info->flags & IPT_ADDRTYPE_INVERT_DEST) + if (info->flags & XT_ADDRTYPE_INVERT_DEST) printf(" !"); printf(" --dst-type "); print_types(info->dest); } - if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { + if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN) { printf(" --limit-iface-in"); } - if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { + if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT) { printf(" --limit-iface-out"); } } @@ -322,8 +349,8 @@ static struct xtables_match addrtype_mt_reg[] = { .name = "addrtype", .version = XTABLES_VERSION, .family = NFPROTO_IPV4, - .size = XT_ALIGN(sizeof(struct ipt_addrtype_info)), - .userspacesize = XT_ALIGN(sizeof(struct ipt_addrtype_info)), + .size = XT_ALIGN(sizeof(struct xt_addrtype_info)), + .userspacesize = XT_ALIGN(sizeof(struct xt_addrtype_info)), .help = addrtype_help_v0, .parse = addrtype_parse_v0, .final_check = addrtype_check_v0, @@ -336,9 +363,23 @@ static struct xtables_match addrtype_mt_reg[] = { .revision = 1, .version = XTABLES_VERSION, .family = NFPROTO_IPV4, - .size = XT_ALIGN(sizeof(struct ipt_addrtype_info_v1)), - .userspacesize = XT_ALIGN(sizeof(struct ipt_addrtype_info_v1)), - .help = addrtype_help_v1, + .size = XT_ALIGN(sizeof(struct xt_addrtype_info_v1)), + .userspacesize = XT_ALIGN(sizeof(struct xt_addrtype_info_v1)), + .help = addrtype_help4_v1, + .parse = addrtype_parse_v1, + .final_check = addrtype_check_v1, + .print = addrtype_print_v1, + .save = addrtype_save_v1, + .extra_opts = addrtype_opts_v1, + }, + { + .name = "addrtype", + .revision = 1, + .version = XTABLES_VERSION, + .family = NFPROTO_IPV6, + .size = XT_ALIGN(sizeof(struct xt_addrtype_info_v1)), + .userspacesize = XT_ALIGN(sizeof(struct xt_addrtype_info_v1)), + .help = addrtype_help6_v1, .parse = addrtype_parse_v1, .final_check = addrtype_check_v1, .print = addrtype_print_v1, -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html