From a49002efbdc5813ee193aa8fde3da3e35ff0d38f Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 28 Aug 2011 14:10:19 +0200 Subject: libxt_addrtype: rename from libipt_addrtype Signed-off-by: Jan Engelhardt --- extensions/libxt_addrtype.c | 308 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 extensions/libxt_addrtype.c (limited to 'extensions/libxt_addrtype.c') diff --git a/extensions/libxt_addrtype.c b/extensions/libxt_addrtype.c new file mode 100644 index 00000000..3dec626b --- /dev/null +++ b/extensions/libxt_addrtype.c @@ -0,0 +1,308 @@ +/* Shared library add-on to iptables to add addrtype matching support + * + * This program is released under the terms of GNU GPL */ +#include +#include +#include +#include + +enum { + O_SRC_TYPE = 0, + O_DST_TYPE, + O_LIMIT_IFACE_IN, + O_LIMIT_IFACE_OUT, + F_SRC_TYPE = 1 << O_SRC_TYPE, + F_DST_TYPE = 1 << O_DST_TYPE, + F_LIMIT_IFACE_IN = 1 << O_LIMIT_IFACE_IN, + F_LIMIT_IFACE_OUT = 1 << O_LIMIT_IFACE_OUT, +}; + +/* 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 +}; + +static void addrtype_help_types(void) +{ + int i; + + for (i = 0; rtn_names[i]; i++) + printf(" %s\n", rtn_names[i]); +} + +static void addrtype_help_v0(void) +{ + printf( +"Address type match options:\n" +" [!] --src-type type[,...] Match source address type\n" +" [!] --dst-type type[,...] Match destination address type\n" +"\n" +"Valid types: \n"); + addrtype_help_types(); +} + +static void addrtype_help_v1(void) +{ + printf( +"Address type match options:\n" +" [!] --src-type type[,...] Match source address type\n" +" [!] --dst-type type[,...] Match destination address type\n" +" --limit-iface-in Match only on the packet's incoming device\n" +" --limit-iface-out Match only on the packet's incoming device\n" +"\n" +"Valid types: \n"); + addrtype_help_types(); +} + +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); + return 1; + } + + return 0; +} + +static void parse_types(const char *arg, uint16_t *mask) +{ + const char *comma; + + while ((comma = strchr(arg, ',')) != NULL) { + if (comma == arg || !parse_type(arg, comma-arg, mask)) + xtables_error(PARAMETER_PROBLEM, + "addrtype: bad type `%s'", arg); + arg = comma + 1; + } + + if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask)) + xtables_error(PARAMETER_PROBLEM, "addrtype: bad type \"%s\"", arg); +} + +static void addrtype_parse_v0(struct xt_option_call *cb) +{ + struct ipt_addrtype_info *info = cb->data; + + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SRC_TYPE: + parse_types(cb->arg, &info->source); + if (cb->invert) + info->invert_source = 1; + break; + case O_DST_TYPE: + parse_types(cb->arg, &info->dest); + if (cb->invert) + info->invert_dest = 1; + break; + } +} + +static void addrtype_parse_v1(struct xt_option_call *cb) +{ + struct ipt_addrtype_info_v1 *info = cb->data; + + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_SRC_TYPE: + parse_types(cb->arg, &info->source); + if (cb->invert) + info->flags |= IPT_ADDRTYPE_INVERT_SOURCE; + break; + case O_DST_TYPE: + parse_types(cb->arg, &info->dest); + if (cb->invert) + info->flags |= IPT_ADDRTYPE_INVERT_DEST; + break; + case O_LIMIT_IFACE_IN: + info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_IN; + break; + case O_LIMIT_IFACE_OUT: + info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_OUT; + break; + } +} + +static void addrtype_check(struct xt_fcheck_call *cb) +{ + if (!(cb->xflags & (F_SRC_TYPE | F_DST_TYPE))) + xtables_error(PARAMETER_PROBLEM, + "addrtype: you must specify --src-type or --dst-type"); +} + +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]); + sep = ","; + } +} + +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; + + printf(" ADDRTYPE match"); + if (info->source) { + printf(" src-type "); + if (info->invert_source) + printf("!"); + print_types(info->source); + } + if (info->dest) { + printf(" dst-type"); + if (info->invert_dest) + printf("!"); + print_types(info->dest); + } +} + +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; + + printf(" ADDRTYPE match"); + if (info->source) { + printf(" src-type "); + if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE) + printf("!"); + print_types(info->source); + } + if (info->dest) { + printf(" dst-type "); + if (info->flags & IPT_ADDRTYPE_INVERT_DEST) + printf("!"); + print_types(info->dest); + } + if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { + printf(" limit-in"); + } + if (info->flags & IPT_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; + + if (info->source) { + if (info->invert_source) + printf(" !"); + printf(" --src-type "); + print_types(info->source); + } + if (info->dest) { + if (info->invert_dest) + printf(" !"); + printf(" --dst-type "); + print_types(info->dest); + } +} + +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; + + if (info->source) { + if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE) + printf(" !"); + printf(" --src-type "); + print_types(info->source); + } + if (info->dest) { + if (info->flags & IPT_ADDRTYPE_INVERT_DEST) + printf(" !"); + printf(" --dst-type "); + print_types(info->dest); + } + if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { + printf(" --limit-iface-in"); + } + if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { + printf(" --limit-iface-out"); + } +} + +static const struct xt_option_entry addrtype_opts_v0[] = { + {.name = "src-type", .id = O_SRC_TYPE, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + {.name = "dst-type", .id = O_DST_TYPE, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + XTOPT_TABLEEND, +}; + +static const struct xt_option_entry addrtype_opts_v1[] = { + {.name = "src-type", .id = O_SRC_TYPE, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + {.name = "dst-type", .id = O_DST_TYPE, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + {.name = "limit-iface-in", .id = O_LIMIT_IFACE_IN, + .type = XTTYPE_NONE, .excl = F_LIMIT_IFACE_OUT}, + {.name = "limit-iface-out", .id = O_LIMIT_IFACE_OUT, + .type = XTTYPE_NONE, .excl = F_LIMIT_IFACE_IN}, + XTOPT_TABLEEND, +}; + +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)), + .help = addrtype_help_v0, + .print = addrtype_print_v0, + .save = addrtype_save_v0, + .x6_parse = addrtype_parse_v0, + .x6_fcheck = addrtype_check, + .x6_options = addrtype_opts_v0, + }, + { + .name = "addrtype", + .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, + .print = addrtype_print_v1, + .save = addrtype_save_v1, + .x6_parse = addrtype_parse_v1, + .x6_fcheck = addrtype_check, + .x6_options = addrtype_opts_v1, + }, +}; + + +void _init(void) +{ + xtables_register_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg)); +} -- cgit v1.2.3 From 3775fb69f63b76191bc3571bfa8538c18173d90f Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 28 Aug 2011 14:16:14 +0200 Subject: libxt_addrtype: add support for revision 1 Rev 1 was added to the kernel in commit v2.6.39-rc1~468^2~10^2~1 but there was no corresponding iptables patch so far. Cc: Florian Westphal Signed-off-by: Jan Engelhardt --- extensions/libxt_addrtype.c | 56 +++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 32 deletions(-) (limited to 'extensions/libxt_addrtype.c') diff --git a/extensions/libxt_addrtype.c b/extensions/libxt_addrtype.c index 3dec626b..59072b35 100644 --- a/extensions/libxt_addrtype.c +++ b/extensions/libxt_addrtype.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include enum { O_SRC_TYPE = 0, @@ -98,7 +98,7 @@ static void parse_types(const char *arg, uint16_t *mask) static void addrtype_parse_v0(struct xt_option_call *cb) { - struct ipt_addrtype_info *info = cb->data; + struct xt_addrtype_info *info = cb->data; xtables_option_parse(cb); switch (cb->entry->id) { @@ -117,25 +117,25 @@ static void addrtype_parse_v0(struct xt_option_call *cb) static void addrtype_parse_v1(struct xt_option_call *cb) { - struct ipt_addrtype_info_v1 *info = cb->data; + struct xt_addrtype_info_v1 *info = cb->data; xtables_option_parse(cb); switch (cb->entry->id) { case O_SRC_TYPE: parse_types(cb->arg, &info->source); if (cb->invert) - info->flags |= IPT_ADDRTYPE_INVERT_SOURCE; + info->flags |= XT_ADDRTYPE_INVERT_SOURCE; break; case O_DST_TYPE: parse_types(cb->arg, &info->dest); if (cb->invert) - info->flags |= IPT_ADDRTYPE_INVERT_DEST; + info->flags |= XT_ADDRTYPE_INVERT_DEST; break; case O_LIMIT_IFACE_IN: - info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_IN; + info->flags |= XT_ADDRTYPE_LIMIT_IFACE_IN; break; case O_LIMIT_IFACE_OUT: - info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_OUT; + info->flags |= XT_ADDRTYPE_LIMIT_IFACE_OUT; break; } } @@ -162,8 +162,7 @@ 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 = (const void *)match->data; printf(" ADDRTYPE match"); if (info->source) { @@ -183,34 +182,30 @@ 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 = (const void *)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 = (const void *)match->data; if (info->source) { if (info->invert_source) @@ -228,27 +223,24 @@ 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 = (const void *)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"); - } } static const struct xt_option_entry addrtype_opts_v0[] = { @@ -276,8 +268,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, .print = addrtype_print_v0, .save = addrtype_save_v0, @@ -289,9 +281,9 @@ static struct xtables_match addrtype_mt_reg[] = { .name = "addrtype", .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)), + .family = NFPROTO_UNSPEC, + .size = XT_ALIGN(sizeof(struct xt_addrtype_info_v1)), + .userspacesize = XT_ALIGN(sizeof(struct xt_addrtype_info_v1)), .help = addrtype_help_v1, .print = addrtype_print_v1, .save = addrtype_save_v1, -- cgit v1.2.3