Signed-off-by: Jan Engelhardt <jengelh@xxxxxxxxxx> --- extensions/libxt_conntrack.c | 670 ++++++++++++++---------------------------- 1 files changed, 219 insertions(+), 451 deletions(-) diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c index 8312d04..2fb3644 100644 --- a/extensions/libxt_conntrack.c +++ b/extensions/libxt_conntrack.c @@ -6,21 +6,14 @@ * Copyright © CC Computer Consultants GmbH, 2007 - 2008 * Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx> */ -#include <sys/socket.h> -#include <sys/types.h> -#include <ctype.h> -#include <getopt.h> -#include <netdb.h> #include <stdbool.h> -#include <stddef.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <xtables.h> -#include <linux/netfilter.h> #include <linux/netfilter/xt_conntrack.h> #include <linux/netfilter/nf_conntrack_common.h> -#include <arpa/inet.h> struct ip_conntrack_old_tuple { struct { @@ -55,6 +48,22 @@ struct xt_conntrack_info { uint8_t invflags; }; +enum { + O_CTSTATE = 0, + O_CTPROTO, + O_CTORIGSRC, + O_CTORIGDST, + O_CTREPLSRC, + O_CTREPLDST, + O_CTORIGSRCPORT, + O_CTORIGDSTPORT, + O_CTREPLSRCPORT, + O_CTREPLDSTPORT, + O_CTSTATUS, + O_CTEXPIRE, + O_CTDIR, +}; + static void conntrack_mt_help(void) { printf( @@ -79,34 +88,59 @@ static void conntrack_mt_help(void) " --ctdir {ORIGINAL|REPLY} Flow direction of packet\n"); } -static const struct option conntrack_mt_opts_v0[] = { - {.name = "ctstate", .has_arg = true, .val = '1'}, - {.name = "ctproto", .has_arg = true, .val = '2'}, - {.name = "ctorigsrc", .has_arg = true, .val = '3'}, - {.name = "ctorigdst", .has_arg = true, .val = '4'}, - {.name = "ctreplsrc", .has_arg = true, .val = '5'}, - {.name = "ctrepldst", .has_arg = true, .val = '6'}, - {.name = "ctstatus", .has_arg = true, .val = '7'}, - {.name = "ctexpire", .has_arg = true, .val = '8'}, - XT_GETOPT_TABLEEND, +#define s struct xt_conntrack_info /* for v0 */ +static const struct xt_option_entry conntrack_mt_opts_v0[] = { + {.name = "ctstate", .id = O_CTSTATE, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + {.name = "ctproto", .id = O_CTPROTO, .type = XTTYPE_PROTOCOL, + .flags = XTOPT_INVERT}, + {.name = "ctorigsrc", .id = O_CTORIGSRC, .type = XTTYPE_HOST, + .flags = XTOPT_INVERT}, + {.name = "ctorigdst", .id = O_CTORIGDST, .type = XTTYPE_HOST, + .flags = XTOPT_INVERT}, + {.name = "ctreplsrc", .id = O_CTREPLSRC, .type = XTTYPE_HOST, + .flags = XTOPT_INVERT}, + {.name = "ctrepldst", .id = O_CTREPLDST, .type = XTTYPE_HOST, + .flags = XTOPT_INVERT}, + {.name = "ctstatus", .id = O_CTSTATUS, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + {.name = "ctexpire", .id = O_CTEXPIRE, .type = XTTYPE_UINT32RC, + .flags = XTOPT_INVERT}, + XTOPT_TABLEEND, }; - -static const struct option conntrack_mt_opts[] = { - {.name = "ctstate", .has_arg = true, .val = '1'}, - {.name = "ctproto", .has_arg = true, .val = '2'}, - {.name = "ctorigsrc", .has_arg = true, .val = '3'}, - {.name = "ctorigdst", .has_arg = true, .val = '4'}, - {.name = "ctreplsrc", .has_arg = true, .val = '5'}, - {.name = "ctrepldst", .has_arg = true, .val = '6'}, - {.name = "ctstatus", .has_arg = true, .val = '7'}, - {.name = "ctexpire", .has_arg = true, .val = '8'}, - {.name = "ctorigsrcport", .has_arg = true, .val = 'a'}, - {.name = "ctorigdstport", .has_arg = true, .val = 'b'}, - {.name = "ctreplsrcport", .has_arg = true, .val = 'c'}, - {.name = "ctrepldstport", .has_arg = true, .val = 'd'}, - {.name = "ctdir", .has_arg = true, .val = 'e'}, - {.name = NULL}, +#undef s + +#define s struct xt_conntrack_mtinfo3 /* for v1-v3 */ +/* We exploit the fact that v1-v3 share the same layout */ +static const struct xt_option_entry conntrack_mt_opts[] = { + {.name = "ctstate", .id = O_CTSTATE, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + {.name = "ctproto", .id = O_CTPROTO, .type = XTTYPE_PROTOCOL, + .flags = XTOPT_INVERT}, + {.name = "ctorigsrc", .id = O_CTORIGSRC, .type = XTTYPE_HOSTMASK, + .flags = XTOPT_INVERT}, + {.name = "ctorigdst", .id = O_CTORIGDST, .type = XTTYPE_HOSTMASK, + .flags = XTOPT_INVERT}, + {.name = "ctreplsrc", .id = O_CTREPLSRC, .type = XTTYPE_HOSTMASK, + .flags = XTOPT_INVERT}, + {.name = "ctrepldst", .id = O_CTREPLDST, .type = XTTYPE_HOSTMASK, + .flags = XTOPT_INVERT}, + {.name = "ctstatus", .id = O_CTSTATUS, .type = XTTYPE_STRING, + .flags = XTOPT_INVERT}, + {.name = "ctexpire", .id = O_CTEXPIRE, .type = XTTYPE_UINT32RC, + .flags = XTOPT_INVERT}, + {.name = "ctorigsrcport", .id = O_CTORIGSRCPORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT}, + {.name = "ctorigdstport", .id = O_CTORIGDSTPORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT}, + {.name = "ctreplsrcport", .id = O_CTREPLSRCPORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT}, + {.name = "ctrepldstport", .id = O_CTREPLDSTPORT, .type = XTTYPE_PORTRC, + .flags = XTOPT_INVERT}, + {.name = "ctdir", .id = O_CTDIR, .type = XTTYPE_STRING}, + XTOPT_TABLEEND, }; +#undef s static int parse_state(const char *state, size_t len, struct xt_conntrack_info *sinfo) @@ -320,39 +354,21 @@ conntrack_ps_expires(struct xt_conntrack_mtinfo3 *info, const char *s) info->expires_max = max; } -static int conntrack_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void conntrack_parse(struct xt_option_call *cb) { - struct xt_conntrack_info *sinfo = (void *)(*match)->data; - char *protocol = NULL; - unsigned int naddrs = 0; - struct in_addr *addrs = NULL; + struct xt_conntrack_info *sinfo = cb->data; - - switch (c) { - case '1': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - - parse_states(optarg, sinfo); - if (invert) { + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_CTSTATE: + parse_states(cb->arg, sinfo); + if (cb->invert) sinfo->invflags |= XT_CONNTRACK_STATE; - } - sinfo->flags |= XT_CONNTRACK_STATE; break; - - case '2': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - - if(invert) + case O_CTPROTO: + if (cb->invert) sinfo->invflags |= XT_CONNTRACK_PROTO; - - /* Canonicalize into lower case */ - for (protocol = optarg; *protocol; protocol++) - *protocol = tolower(*protocol); - - protocol = optarg; - sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum = - xtables_parse_protocol(protocol); + sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum = cb->val.protocol; if (sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum == 0 && (sinfo->invflags & XT_INV_PROTO)) @@ -361,390 +377,151 @@ static int conntrack_parse(int c, char **argv, int invert, unsigned int *flags, sinfo->flags |= XT_CONNTRACK_PROTO; break; - - case '3': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - - if (invert) + case O_CTORIGSRC: + if (cb->invert) sinfo->invflags |= XT_CONNTRACK_ORIGSRC; - - xtables_ipparse_any(optarg, &addrs, - &sinfo->sipmsk[IP_CT_DIR_ORIGINAL], - &naddrs); - if(naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - - if(naddrs == 1) { - sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip = addrs[0].s_addr; - } - + sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip = cb->val.haddr.ip; sinfo->flags |= XT_CONNTRACK_ORIGSRC; break; - - case '4': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - - if (invert) + case O_CTORIGDST: + if (cb->invert) sinfo->invflags |= XT_CONNTRACK_ORIGDST; - - xtables_ipparse_any(optarg, &addrs, - &sinfo->dipmsk[IP_CT_DIR_ORIGINAL], - &naddrs); - if(naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - - if(naddrs == 1) { - sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip = addrs[0].s_addr; - } - + sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip = cb->val.haddr.ip; sinfo->flags |= XT_CONNTRACK_ORIGDST; break; - - case '5': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - - if (invert) + case O_CTREPLSRC: + if (cb->invert) sinfo->invflags |= XT_CONNTRACK_REPLSRC; - - xtables_ipparse_any(optarg, &addrs, - &sinfo->sipmsk[IP_CT_DIR_REPLY], - &naddrs); - if(naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - - if(naddrs == 1) { - sinfo->tuple[IP_CT_DIR_REPLY].src.ip = addrs[0].s_addr; - } - + sinfo->tuple[IP_CT_DIR_REPLY].src.ip = cb->val.haddr.ip; sinfo->flags |= XT_CONNTRACK_REPLSRC; break; - - case '6': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - - if (invert) + case O_CTREPLDST: + if (cb->invert) sinfo->invflags |= XT_CONNTRACK_REPLDST; - - xtables_ipparse_any(optarg, &addrs, - &sinfo->dipmsk[IP_CT_DIR_REPLY], - &naddrs); - if(naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - - if(naddrs == 1) { - sinfo->tuple[IP_CT_DIR_REPLY].dst.ip = addrs[0].s_addr; - } - + sinfo->tuple[IP_CT_DIR_REPLY].dst.ip = cb->val.haddr.ip; sinfo->flags |= XT_CONNTRACK_REPLDST; break; - - case '7': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - - parse_statuses(optarg, sinfo); - if (invert) { + case O_CTSTATUS: + parse_statuses(cb->arg, sinfo); + if (cb->invert) sinfo->invflags |= XT_CONNTRACK_STATUS; - } sinfo->flags |= XT_CONNTRACK_STATUS; break; - - case '8': - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - - parse_expires(optarg, sinfo); - if (invert) { + case O_CTEXPIRE: + parse_expires(cb->arg, sinfo); + if (cb->invert) sinfo->invflags |= XT_CONNTRACK_EXPIRES; - } sinfo->flags |= XT_CONNTRACK_EXPIRES; break; } - - *flags = sinfo->flags; - return 1; } -static void -ct_parse_ports(const char *param, const char *str, - u_int16_t *port_low, u_int16_t *port_high) +static void conntrack_mt_parse(struct xt_option_call *cb, uint8_t rev) { - unsigned int port; - char *buf, *cp; + struct xt_conntrack_mtinfo3 *info = cb->data; - buf = strdup(str); - cp = strchr(buf, ':'); - if (cp != NULL) - *cp = '\0'; - - if (!xtables_strtoui(buf, NULL, &port, 0, UINT16_MAX)) - xtables_param_act(XTF_BAD_VALUE, "conntrack", param, buf); - - if (port_high == NULL) { - /* revision 0-2 do not support ranges */ - if (cp != NULL) - xtables_error(PARAMETER_PROBLEM, "conntrack: " - "port ranges not supported"); - - *port_low = htons(port); - } else { - *port_low = port; - - if (cp != NULL) { - if (!xtables_strtoui(cp + 1, NULL, &port, 0, UINT16_MAX)) - xtables_param_act(XTF_BAD_VALUE, "conntrack", param, buf); - - *port_high = port; - if (*port_low > *port_high) - xtables_error(PARAMETER_PROBLEM, - "invalid portrange (min > max)"); - } else - *port_high = port; - } - - free(buf); -} - - -static int -conntrack_mt_parse(int c, bool invert, unsigned int *flags, - struct xt_conntrack_mtinfo3 *info, bool v3) -{ - char *p; - - switch (c) { - case '1': /* --ctstate */ - conntrack_ps_states(info, optarg); + xtables_option_parse(cb); + switch (cb->entry->id) { + case O_CTSTATE: + conntrack_ps_states(info, cb->arg); info->match_flags |= XT_CONNTRACK_STATE; - if (invert) + if (cb->invert) info->invert_flags |= XT_CONNTRACK_STATE; break; - - case '2': /* --ctproto */ - /* Canonicalize into lower case */ - for (p = optarg; *p != '\0'; ++p) - *p = tolower(*p); - info->l4proto = xtables_parse_protocol(optarg); - + case O_CTPROTO: + info->l4proto = cb->val.protocol; if (info->l4proto == 0 && (info->invert_flags & XT_INV_PROTO)) xtables_error(PARAMETER_PROBLEM, "conntrack: rule would " "never match protocol"); info->match_flags |= XT_CONNTRACK_PROTO; - if (invert) + if (cb->invert) info->invert_flags |= XT_CONNTRACK_PROTO; break; - - case '7': /* --ctstatus */ - conntrack_ps_statuses(info, optarg); + case O_CTORIGSRC: + info->origsrc_addr = cb->val.haddr; + info->origsrc_mask = cb->val.hmask; + info->match_flags |= XT_CONNTRACK_ORIGSRC; + if (cb->invert) + info->invert_flags |= XT_CONNTRACK_ORIGSRC; + break; + case O_CTORIGDST: + info->origdst_addr = cb->val.haddr; + info->origdst_mask = cb->val.hmask; + info->match_flags |= XT_CONNTRACK_ORIGDST; + if (cb->invert) + info->invert_flags |= XT_CONNTRACK_ORIGDST; + break; + case O_CTREPLSRC: + info->replsrc_addr = cb->val.haddr; + info->replsrc_mask = cb->val.hmask; + info->match_flags |= XT_CONNTRACK_REPLSRC; + if (cb->invert) + info->invert_flags |= XT_CONNTRACK_REPLSRC; + break; + case O_CTREPLDST: + info->repldst_addr = cb->val.haddr; + info->repldst_mask = cb->val.hmask; + info->match_flags |= XT_CONNTRACK_REPLDST; + if (cb->invert) + info->invert_flags |= XT_CONNTRACK_REPLDST; + break; + case O_CTSTATUS: + conntrack_ps_statuses(info, cb->arg); info->match_flags |= XT_CONNTRACK_STATUS; - if (invert) + if (cb->invert) info->invert_flags |= XT_CONNTRACK_STATUS; break; - - case '8': /* --ctexpire */ - conntrack_ps_expires(info, optarg); + case O_CTEXPIRE: + conntrack_ps_expires(info, cb->arg); info->match_flags |= XT_CONNTRACK_EXPIRES; - if (invert) + if (cb->invert) info->invert_flags |= XT_CONNTRACK_EXPIRES; break; - - case 'a': /* --ctorigsrcport */ - ct_parse_ports("--ctorigsrcport", optarg, - &info->origsrc_port, - v3 ? &info->origsrc_port_high : NULL); - + case O_CTORIGSRCPORT: + info->origsrc_port = cb->val.port_range[0]; + info->origsrc_port = (cb->nvals == 2) ? cb->val.port_range[1] : + cb->val.port_range[0]; info->match_flags |= XT_CONNTRACK_ORIGSRC_PORT; - if (invert) + if (cb->invert) info->invert_flags |= XT_CONNTRACK_ORIGSRC_PORT; break; - - case 'b': /* --ctorigdstport */ - ct_parse_ports("--ctorigdstport", optarg, - &info->origdst_port, - v3 ? &info->origdst_port_high : NULL); - + case O_CTORIGDSTPORT: + info->origdst_port = cb->val.port_range[0]; + info->origdst_port = (cb->nvals == 2) ? cb->val.port_range[1] : + cb->val.port_range[0]; info->match_flags |= XT_CONNTRACK_ORIGDST_PORT; - if (invert) + if (cb->invert) info->invert_flags |= XT_CONNTRACK_ORIGDST_PORT; break; - - case 'c': /* --ctreplsrcport */ - ct_parse_ports("--ctreplsrcport", optarg, - &info->replsrc_port, - v3 ? &info->replsrc_port_high : NULL); - + case O_CTREPLSRCPORT: + info->replsrc_port = cb->val.port_range[0]; + info->replsrc_port = (cb->nvals == 2) ? cb->val.port_range[1] : + cb->val.port_range[0]; info->match_flags |= XT_CONNTRACK_REPLSRC_PORT; - if (invert) + if (cb->invert) info->invert_flags |= XT_CONNTRACK_REPLSRC_PORT; break; - - case 'd': /* --ctrepldstport */ - ct_parse_ports("--ctrepldstport", optarg, - &info->repldst_port, - v3 ? &info->repldst_port_high : NULL); - + case O_CTREPLDSTPORT: + info->repldst_port = cb->val.port_range[0]; + info->repldst_port = (cb->nvals == 2) ? cb->val.port_range[1] : + cb->val.port_range[0]; info->match_flags |= XT_CONNTRACK_REPLDST_PORT; - if (invert) + if (cb->invert) info->invert_flags |= XT_CONNTRACK_REPLDST_PORT; break; - - case 'e': /* --ctdir */ - xtables_param_act(XTF_NO_INVERT, "conntrack", "--ctdir", invert); - if (strcasecmp(optarg, "ORIGINAL") == 0) { + case O_CTDIR: + if (strcasecmp(cb->arg, "ORIGINAL") == 0) { info->match_flags |= XT_CONNTRACK_DIRECTION; info->invert_flags &= ~XT_CONNTRACK_DIRECTION; - } else if (strcasecmp(optarg, "REPLY") == 0) { + } else if (strcasecmp(cb->arg, "REPLY") == 0) { info->match_flags |= XT_CONNTRACK_DIRECTION; info->invert_flags |= XT_CONNTRACK_DIRECTION; } else { - xtables_param_act(XTF_BAD_VALUE, "conntrack", "--ctdir", optarg); + xtables_param_act(XTF_BAD_VALUE, "conntrack", "--ctdir", cb->arg); } break; } - - *flags = info->match_flags; - return true; -} - -static int -conntrack_mt4_parse(int c, bool invert, unsigned int *flags, - struct xt_conntrack_mtinfo3 *info, bool v3) -{ - struct in_addr *addr = NULL; - unsigned int naddrs = 0; - - switch (c) { - case '3': /* --ctorigsrc */ - xtables_ipparse_any(optarg, &addr, &info->origsrc_mask.in, - &naddrs); - if (naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - if (naddrs == 1) - memcpy(&info->origsrc_addr.in, addr, sizeof(*addr)); - info->match_flags |= XT_CONNTRACK_ORIGSRC; - if (invert) - info->invert_flags |= XT_CONNTRACK_ORIGSRC; - break; - - case '4': /* --ctorigdst */ - xtables_ipparse_any(optarg, &addr, &info->origdst_mask.in, - &naddrs); - if (naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - if (naddrs == 1) - memcpy(&info->origdst_addr.in, addr, sizeof(*addr)); - info->match_flags |= XT_CONNTRACK_ORIGDST; - if (invert) - info->invert_flags |= XT_CONNTRACK_ORIGDST; - break; - - case '5': /* --ctreplsrc */ - xtables_ipparse_any(optarg, &addr, &info->replsrc_mask.in, - &naddrs); - if (naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - if (naddrs == 1) - memcpy(&info->replsrc_addr.in, addr, sizeof(*addr)); - info->match_flags |= XT_CONNTRACK_REPLSRC; - if (invert) - info->invert_flags |= XT_CONNTRACK_REPLSRC; - break; - - case '6': /* --ctrepldst */ - xtables_ipparse_any(optarg, &addr, &info->repldst_mask.in, - &naddrs); - if (naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - if (naddrs == 1) - memcpy(&info->repldst_addr.in, addr, sizeof(*addr)); - info->match_flags |= XT_CONNTRACK_REPLDST; - if (invert) - info->invert_flags |= XT_CONNTRACK_REPLDST; - break; - - - default: - return conntrack_mt_parse(c, invert, flags, info, v3); - } - - *flags = info->match_flags; - return true; -} - -static int -conntrack_mt6_parse(int c, bool invert, unsigned int *flags, - struct xt_conntrack_mtinfo3 *info, bool v3) -{ - struct in6_addr *addr = NULL; - unsigned int naddrs = 0; - - switch (c) { - case '3': /* --ctorigsrc */ - xtables_ip6parse_any(optarg, &addr, - &info->origsrc_mask.in6, &naddrs); - if (naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - if (naddrs == 1) - memcpy(&info->origsrc_addr.in6, addr, sizeof(*addr)); - info->match_flags |= XT_CONNTRACK_ORIGSRC; - if (invert) - info->invert_flags |= XT_CONNTRACK_ORIGSRC; - break; - - case '4': /* --ctorigdst */ - xtables_ip6parse_any(optarg, &addr, - &info->origdst_mask.in6, &naddrs); - if (naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - if (naddrs == 1) - memcpy(&info->origdst_addr.in, addr, sizeof(*addr)); - info->match_flags |= XT_CONNTRACK_ORIGDST; - if (invert) - info->invert_flags |= XT_CONNTRACK_ORIGDST; - break; - - case '5': /* --ctreplsrc */ - xtables_ip6parse_any(optarg, &addr, - &info->replsrc_mask.in6, &naddrs); - if (naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - if (naddrs == 1) - memcpy(&info->replsrc_addr.in, addr, sizeof(*addr)); - info->match_flags |= XT_CONNTRACK_REPLSRC; - if (invert) - info->invert_flags |= XT_CONNTRACK_REPLSRC; - break; - - case '6': /* --ctrepldst */ - xtables_ip6parse_any(optarg, &addr, - &info->repldst_mask.in6, &naddrs); - if (naddrs > 1) - xtables_error(PARAMETER_PROBLEM, - "multiple IP addresses not allowed"); - if (naddrs == 1) - memcpy(&info->repldst_addr.in, addr, sizeof(*addr)); - info->match_flags |= XT_CONNTRACK_REPLDST; - if (invert) - info->invert_flags |= XT_CONNTRACK_REPLDST; - break; - - - default: - return conntrack_mt_parse(c, invert, flags, info, v3); - } - - *flags = info->match_flags; - return true; } #define cinfo_transform(r, l) \ @@ -754,65 +531,56 @@ conntrack_mt6_parse(int c, bool invert, unsigned int *flags, (r)->status_mask = (l)->status_mask; \ } while (false); -static int -conntrack1_mt4_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void conntrack1_mt_parse(struct xt_option_call *cb) { - struct xt_conntrack_mtinfo1 *info = (void *)(*match)->data; + struct xt_conntrack_mtinfo1 *info = cb->data; struct xt_conntrack_mtinfo3 up; + memset(&up, 0, sizeof(up)); cinfo_transform(&up, info); - if (!conntrack_mt4_parse(c, invert, flags, &up, false)) - return false; - cinfo_transform(info, &up); - return true; -} - -static int -conntrack1_mt6_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - struct xt_conntrack_mtinfo1 *info = (void *)(*match)->data; - struct xt_conntrack_mtinfo3 up; - - cinfo_transform(&up, info); - if (!conntrack_mt6_parse(c, invert, flags, &up, false)) - return false; + cb->data = &up; + conntrack_mt_parse(cb, 3); + if (up.origsrc_port != up.origsrc_port_high || + up.origdst_port != up.origdst_port_high || + up.replsrc_port != up.replsrc_port_high || + up.repldst_port != up.repldst_port_high) + xtables_error(PARAMETER_PROBLEM, + "connlimit rev 1 does not support port ranges"); cinfo_transform(info, &up); - return true; + cb->data = info; } -static int -conntrack2_mt4_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void conntrack2_mt_parse(struct xt_option_call *cb) { - return conntrack_mt4_parse(c, invert, flags, (void *)(*match)->data, false); -} +#define cinfo2_transform(r, l) \ + memcpy((r), (l), offsetof(typeof(*(l)), sizeof(*info)); -static int -conntrack2_mt6_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - return conntrack_mt6_parse(c, invert, flags, (void *)(*match)->data, false); -} + struct xt_conntrack_mtinfo2 *info = cb->data; + struct xt_conntrack_mtinfo3 up; -static int -conntrack3_mt4_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - return conntrack_mt4_parse(c, invert, flags, (void *)(*match)->data, true); + memset(&up, 0, sizeof(up)); + memcpy(&up, info, sizeof(*info)); + cb->data = &up; + conntrack_mt_parse(cb, 3); + if (up.origsrc_port != up.origsrc_port_high || + up.origdst_port != up.origdst_port_high || + up.replsrc_port != up.replsrc_port_high || + up.repldst_port != up.repldst_port_high) + xtables_error(PARAMETER_PROBLEM, + "connlimit rev 2 does not support port ranges"); + memcpy(info, &up, sizeof(*info)); + cb->data = info; +#undef cinfo2_transform } -static int -conntrack3_mt6_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) +static void conntrack3_mt_parse(struct xt_option_call *cb) { - return conntrack_mt6_parse(c, invert, flags, (void *)(*match)->data, true); + conntrack_mt_parse(cb, 3); } -static void conntrack_mt_check(unsigned int flags) +static void conntrack_mt_check(struct xt_fcheck_call *cb) { - if (flags == 0) + if (cb->xflags == 0) xtables_error(PARAMETER_PROBLEM, "conntrack: At least one option " "is required"); } @@ -1259,11 +1027,11 @@ static struct xtables_match conntrack_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_conntrack_info)), .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_info)), .help = conntrack_mt_help, - .parse = conntrack_parse, - .final_check = conntrack_mt_check, + .x6_parse = conntrack_parse, + .x6_fcheck = conntrack_mt_check, .print = conntrack_print, .save = conntrack_save, - .extra_opts = conntrack_mt_opts_v0, + .x6_options = conntrack_mt_opts_v0, }, { .version = XTABLES_VERSION, @@ -1273,11 +1041,11 @@ static struct xtables_match conntrack_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)), .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)), .help = conntrack_mt_help, - .parse = conntrack1_mt4_parse, - .final_check = conntrack_mt_check, + .x6_parse = conntrack1_mt_parse, + .x6_fcheck = conntrack_mt_check, .print = conntrack1_mt4_print, .save = conntrack1_mt4_save, - .extra_opts = conntrack_mt_opts, + .x6_options = conntrack_mt_opts, }, { .version = XTABLES_VERSION, @@ -1287,11 +1055,11 @@ static struct xtables_match conntrack_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)), .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)), .help = conntrack_mt_help, - .parse = conntrack1_mt6_parse, - .final_check = conntrack_mt_check, + .x6_parse = conntrack1_mt_parse, + .x6_fcheck = conntrack_mt_check, .print = conntrack1_mt6_print, .save = conntrack1_mt6_save, - .extra_opts = conntrack_mt_opts, + .x6_options = conntrack_mt_opts, }, { .version = XTABLES_VERSION, @@ -1301,11 +1069,11 @@ static struct xtables_match conntrack_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo2)), .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo2)), .help = conntrack_mt_help, - .parse = conntrack2_mt4_parse, - .final_check = conntrack_mt_check, + .x6_parse = conntrack2_mt_parse, + .x6_fcheck = conntrack_mt_check, .print = conntrack2_mt_print, .save = conntrack2_mt_save, - .extra_opts = conntrack_mt_opts, + .x6_options = conntrack_mt_opts, }, { .version = XTABLES_VERSION, @@ -1315,11 +1083,11 @@ static struct xtables_match conntrack_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo2)), .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo2)), .help = conntrack_mt_help, - .parse = conntrack2_mt6_parse, - .final_check = conntrack_mt_check, + .x6_parse = conntrack2_mt_parse, + .x6_fcheck = conntrack_mt_check, .print = conntrack2_mt6_print, .save = conntrack2_mt6_save, - .extra_opts = conntrack_mt_opts, + .x6_options = conntrack_mt_opts, }, { .version = XTABLES_VERSION, @@ -1329,11 +1097,11 @@ static struct xtables_match conntrack_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo3)), .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo3)), .help = conntrack_mt_help, - .parse = conntrack3_mt4_parse, - .final_check = conntrack_mt_check, + .x6_parse = conntrack3_mt_parse, + .x6_fcheck = conntrack_mt_check, .print = conntrack3_mt_print, .save = conntrack3_mt_save, - .extra_opts = conntrack_mt_opts, + .x6_options = conntrack_mt_opts, }, { .version = XTABLES_VERSION, @@ -1343,11 +1111,11 @@ static struct xtables_match conntrack_mt_reg[] = { .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo3)), .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo3)), .help = conntrack_mt_help, - .parse = conntrack3_mt6_parse, - .final_check = conntrack_mt_check, + .x6_parse = conntrack3_mt_parse, + .x6_fcheck = conntrack_mt_check, .print = conntrack3_mt6_print, .save = conntrack3_mt6_save, - .extra_opts = conntrack_mt_opts, + .x6_options = conntrack_mt_opts, }, }; -- 1.7.1 -- 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