[PATCH 17/17] libxt_conntrack: use guided option parser

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux