[iptables PATCH 4/6] Combine parse_target() and command_jump() implementations

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

 



Merge these two functions from xtables, iptables, ip6tables and
arptables. Both functions were basically identical in the first three,
only the last one required a bit more attention.

To eliminate access to 'invflags' in variant-specific location, move the
call to set_option() into callers. This is actually consistent with
parsing of other options in them.

As with command_match(), use xt_params instead of the different
*_globals objects to refer to 'opts' and 'orig_opts'.

It was necessary to rename parse_target() as it otherwise clashes with a
static function of same name in libxt_SET.

In arptables, the maximum allowed target name is a bit larger, so
introduce xtables_globals.target_maxnamelen defining the value. It is
used in the shared xt_parse_target() implementation.

Implementation of command_jump() in arptables diverted from the others
for no obvious reason. The call to parse_target() was done outside of it
and a pointer to cs->arp was passed but not used inside.

Signed-off-by: Phil Sutter <phil@xxxxxx>
---
 include/xtables.h      |  1 +
 iptables/ip6tables.c   | 66 +++-------------------------------------
 iptables/iptables.c    | 69 +++---------------------------------------
 iptables/xshared.c     | 63 ++++++++++++++++++++++++++++++++++++++
 iptables/xshared.h     |  2 ++
 iptables/xtables-arp.c | 60 ++----------------------------------
 iptables/xtables.c     | 68 +++--------------------------------------
 7 files changed, 80 insertions(+), 249 deletions(-)

diff --git a/include/xtables.h b/include/xtables.h
index bf169b08186f5..fd9e6c33516bc 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -424,6 +424,7 @@ struct xtables_globals
 	struct option *opts;
 	void (*exit_err)(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
 	int (*compat_rev)(const char *name, uint8_t rev, int opt);
+	size_t target_maxnamelen;
 };
 
 #define XT_GETOPT_TABLEEND {.name = NULL, .has_arg = false}
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index 1137256a259ca..7a9cd643f8e76 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -125,6 +125,7 @@ struct xtables_globals ip6tables_globals = {
 	.orig_opts = original_opts,
 	.exit_err = ip6tables_exit_error,
 	.compat_rev = xtables_compatible_revision,
+	.target_maxnamelen = XT_EXTENSION_MAXNAMELEN,
 };
 
 /* Table of legal combinations of commands and options.  If any of the
@@ -420,27 +421,6 @@ parse_chain(const char *chainname)
 				   "Invalid chain name `%s'", chainname);
 }
 
-static const char *
-parse_target(const char *targetname)
-{
-	const char *ptr;
-
-	if (strlen(targetname) < 1)
-		xtables_error(PARAMETER_PROBLEM,
-			   "Invalid target name (too short)");
-
-	if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
-		xtables_error(PARAMETER_PROBLEM,
-			   "Invalid target name `%s' (%u chars max)",
-			   targetname, XT_EXTENSION_MAXNAMELEN - 1);
-
-	for (ptr = targetname; *ptr; ptr++)
-		if (isspace(*ptr))
-			xtables_error(PARAMETER_PROBLEM,
-				   "Invalid target name `%s'", targetname);
-	return targetname;
-}
-
 static void
 set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
 	   int invert)
@@ -1221,46 +1201,6 @@ generate_entry(const struct ip6t_entry *fw,
 	return e;
 }
 
-static void command_jump(struct iptables_command_state *cs)
-{
-	size_t size;
-
-	set_option(&cs->options, OPT_JUMP, &cs->fw6.ipv6.invflags, cs->invert);
-	cs->jumpto = parse_target(optarg);
-	/* TRY_LOAD (may be chain name) */
-	cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
-
-	if (cs->target == NULL)
-		return;
-
-	size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
-
-	cs->target->t = xtables_calloc(1, size);
-	cs->target->t->u.target_size = size;
-	if (cs->target->real_name == NULL) {
-		strcpy(cs->target->t->u.user.name, cs->jumpto);
-	} else {
-		strcpy(cs->target->t->u.user.name, cs->target->real_name);
-		if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
-			fprintf(stderr, "Notice: The %s target is converted into %s target "
-			        "in rule listing and saving.\n",
-			        cs->jumpto, cs->target->real_name);
-	}
-	cs->target->t->u.user.revision = cs->target->revision;
-
-	xs_init_target(cs->target);
-	if (cs->target->x6_options != NULL)
-		opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts,
-					    cs->target->x6_options,
-					    &cs->target->option_offset);
-	else
-		opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
-					     cs->target->extra_opts,
-					     &cs->target->option_offset);
-	if (opts == NULL)
-		xtables_error(OTHER_PROBLEM, "can't alloc memory!");
-}
-
 int do_command6(int argc, char *argv[], char **table,
 		struct xtc_handle **handle, bool restore)
 {
@@ -1495,11 +1435,13 @@ int do_command6(int argc, char *argv[], char **table,
 			set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
 					cs.invert);
 			cs.fw6.ipv6.flags |= IP6T_F_GOTO;
-			cs.jumpto = parse_target(optarg);
+			cs.jumpto = xt_parse_target(optarg);
 			break;
 #endif
 
 		case 'j':
+			set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
+					cs.invert);
 			command_jump(&cs);
 			break;
 
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 70ba67c9a9701..b9ce64e6b32a6 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -124,6 +124,7 @@ struct xtables_globals iptables_globals = {
 	.orig_opts = original_opts,
 	.exit_err = iptables_exit_error,
 	.compat_rev = xtables_compatible_revision,
+	.target_maxnamelen = XT_EXTENSION_MAXNAMELEN,
 };
 
 /* Table of legal combinations of commands and options.  If any of the
@@ -405,27 +406,6 @@ parse_chain(const char *chainname)
 				   "Invalid chain name `%s'", chainname);
 }
 
-static const char *
-parse_target(const char *targetname)
-{
-	const char *ptr;
-
-	if (strlen(targetname) < 1)
-		xtables_error(PARAMETER_PROBLEM,
-			   "Invalid target name (too short)");
-
-	if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
-		xtables_error(PARAMETER_PROBLEM,
-			   "Invalid target name `%s' (%u chars max)",
-			   targetname, XT_EXTENSION_MAXNAMELEN - 1);
-
-	for (ptr = targetname; *ptr; ptr++)
-		if (isspace(*ptr))
-			xtables_error(PARAMETER_PROBLEM,
-				   "Invalid target name `%s'", targetname);
-	return targetname;
-}
-
 static void
 set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
 	   int invert)
@@ -1211,49 +1191,6 @@ generate_entry(const struct ipt_entry *fw,
 	return e;
 }
 
-static void command_jump(struct iptables_command_state *cs)
-{
-	size_t size;
-
-	set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags, cs->invert);
-	cs->jumpto = parse_target(optarg);
-	/* TRY_LOAD (may be chain name) */
-	cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
-
-	if (cs->target == NULL)
-		return;
-
-	size = XT_ALIGN(sizeof(struct xt_entry_target))
-		+ cs->target->size;
-
-	cs->target->t = xtables_calloc(1, size);
-	cs->target->t->u.target_size = size;
-	if (cs->target->real_name == NULL) {
-		strcpy(cs->target->t->u.user.name, cs->jumpto);
-	} else {
-		/* Alias support for userspace side */
-		strcpy(cs->target->t->u.user.name, cs->target->real_name);
-		if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
-			fprintf(stderr, "Notice: The %s target is converted into %s target "
-			        "in rule listing and saving.\n",
-			        cs->jumpto, cs->target->real_name);
-	}
-	cs->target->t->u.user.revision = cs->target->revision;
-
-	xs_init_target(cs->target);
-
-	if (cs->target->x6_options != NULL)
-		opts = xtables_options_xfrm(iptables_globals.orig_opts, opts,
-					    cs->target->x6_options,
-					    &cs->target->option_offset);
-	else
-		opts = xtables_merge_options(iptables_globals.orig_opts, opts,
-					     cs->target->extra_opts,
-					     &cs->target->option_offset);
-	if (opts == NULL)
-		xtables_error(OTHER_PROBLEM, "can't alloc memory!");
-}
-
 int do_command4(int argc, char *argv[], char **table,
 		struct xtc_handle **handle, bool restore)
 {
@@ -1478,11 +1415,13 @@ int do_command4(int argc, char *argv[], char **table,
 			set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
 				   cs.invert);
 			cs.fw.ip.flags |= IPT_F_GOTO;
-			cs.jumpto = parse_target(optarg);
+			cs.jumpto = xt_parse_target(optarg);
 			break;
 #endif
 
 		case 'j':
+			set_option(&cs.options, OPT_JUMP, &cs.fw.ip.invflags,
+				   cs.invert);
 			command_jump(&cs);
 			break;
 
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 860373cb2db84..d5365d9398e90 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1,4 +1,5 @@
 #include <config.h>
+#include <ctype.h>
 #include <getopt.h>
 #include <errno.h>
 #include <libgen.h>
@@ -631,3 +632,65 @@ void command_match(struct iptables_command_state *cs)
 		xtables_error(OTHER_PROBLEM, "can't alloc memory!");
 	xt_params->opts = opts;
 }
+
+const char *xt_parse_target(const char *targetname)
+{
+	const char *ptr;
+
+	if (strlen(targetname) < 1)
+		xtables_error(PARAMETER_PROBLEM,
+			   "Invalid target name (too short)");
+
+	if (strlen(targetname) >= xt_params->target_maxnamelen)
+		xtables_error(PARAMETER_PROBLEM,
+			   "Invalid target name `%s' (%zu chars max)",
+			   targetname, xt_params->target_maxnamelen - 1);
+
+	for (ptr = targetname; *ptr; ptr++)
+		if (isspace(*ptr))
+			xtables_error(PARAMETER_PROBLEM,
+				   "Invalid target name `%s'", targetname);
+	return targetname;
+}
+
+void command_jump(struct iptables_command_state *cs)
+{
+	struct option *opts = xt_params->opts;
+	size_t size;
+
+	cs->jumpto = xt_parse_target(optarg);
+	/* TRY_LOAD (may be chain name) */
+	cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
+
+	if (cs->target == NULL)
+		return;
+
+	size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
+
+	cs->target->t = xtables_calloc(1, size);
+	cs->target->t->u.target_size = size;
+	if (cs->target->real_name == NULL) {
+		strcpy(cs->target->t->u.user.name, cs->jumpto);
+	} else {
+		/* Alias support for userspace side */
+		strcpy(cs->target->t->u.user.name, cs->target->real_name);
+		if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
+			fprintf(stderr, "Notice: The %s target is converted into %s target "
+				"in rule listing and saving.\n",
+				cs->jumpto, cs->target->real_name);
+	}
+	cs->target->t->u.user.revision = cs->target->revision;
+	xs_init_target(cs->target);
+
+	if (cs->target->x6_options != NULL)
+		opts = xtables_options_xfrm(xt_params->orig_opts, opts,
+					    cs->target->x6_options,
+					    &cs->target->option_offset);
+	else
+		opts = xtables_merge_options(xt_params->orig_opts, opts,
+					     cs->target->extra_opts,
+					     &cs->target->option_offset);
+	if (opts == NULL)
+		xtables_error(OTHER_PROBLEM, "can't alloc memory!");
+	xt_params->opts = opts;
+}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 9039a24ba75e6..db499f29236ed 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -175,5 +175,7 @@ void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
 		  unsigned int format);
 
 void command_match(struct iptables_command_state *cs);
+const char *xt_parse_target(const char *targetname);
+void command_jump(struct iptables_command_state *cs);
 
 #endif /* IPTABLES_XSHARED_H */
diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c
index a457ea30ad685..4a782148d0f6a 100644
--- a/iptables/xtables-arp.c
+++ b/iptables/xtables-arp.c
@@ -158,6 +158,7 @@ struct xtables_globals arptables_globals = {
 	.orig_opts		= original_opts,
 	.exit_err		= xtables_exit_error,
 	.compat_rev		= nft_compatible_revision,
+	.target_maxnamelen	= sizeof(arpt_chainlabel),
 };
 
 /* Table of legal combinations of commands and options.  If any of the
@@ -755,27 +756,6 @@ parse_rulenumber(const char *rule)
 	return rulenum;
 }
 
-static const char *
-parse_target(const char *targetname)
-{
-	const char *ptr;
-
-	if (strlen(targetname) < 1)
-		xtables_error(PARAMETER_PROBLEM,
-			      "Invalid target name (too short)");
-
-	if (strlen(targetname)+1 > sizeof(arpt_chainlabel))
-		xtables_error(PARAMETER_PROBLEM,
-			      "Invalid target name `%s' (%zu chars max)",
-			      targetname, sizeof(arpt_chainlabel)-1);
-
-	for (ptr = targetname; *ptr; ptr++)
-		if (isspace(*ptr))
-			xtables_error(PARAMETER_PROBLEM,
-				      "Invalid target name `%s'", targetname);
-	return targetname;
-}
-
 static void
 set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
 	   int invert)
@@ -822,41 +802,6 @@ list_entries(struct nft_handle *h, const char *chain, const char *table,
 	return nft_rule_list(h, chain, table, rulenum, format);
 }
 
-static struct xtables_target *command_jump(struct arpt_entry *fw,
-					   const char *jumpto)
-{
-	struct xtables_target *target;
-	size_t size;
-
-	/* XTF_TRY_LOAD (may be chain name) */
-	target = xtables_find_target(jumpto, XTF_TRY_LOAD);
-
-	if (!target)
-		return NULL;
-
-	size = XT_ALIGN(sizeof(struct xt_entry_target))
-		+ target->size;
-
-	target->t = xtables_calloc(1, size);
-	target->t->u.target_size = size;
-	strncpy(target->t->u.user.name, jumpto, sizeof(target->t->u.user.name) - 1);
-	target->t->u.user.name[sizeof(target->t->u.user.name)-1] = '\0';
-	target->t->u.user.revision = target->revision;
-
-	xs_init_target(target);
-
-	if (target->x6_options != NULL)
-		opts = xtables_options_xfrm(arptables_globals.orig_opts,
-					    opts, target->x6_options,
-					    &target->option_offset);
-	else
-		opts = xtables_merge_options(arptables_globals.orig_opts,
-					     opts, target->extra_opts,
-					     &target->option_offset);
-
-	return target;
-}
-
 static int
 append_entry(struct nft_handle *h,
 	     const char *chain,
@@ -1216,8 +1161,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
 		case 'j':
 			set_option(&options, OPT_JUMP, &cs.arp.arp.invflags,
 				   invert);
-			cs.jumpto = parse_target(optarg);
-			cs.target = command_jump(&cs.arp, cs.jumpto);
+			command_jump(&cs);
 			break;
 
 		case 'i':
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 423be37f51fbc..c17e66f1a805f 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -108,6 +108,7 @@ struct xtables_globals xtables_globals = {
 	.orig_opts = original_opts,
 	.exit_err = xtables_exit_error,
 	.compat_rev = nft_compatible_revision,
+	.target_maxnamelen = XT_EXTENSION_MAXNAMELEN,
 };
 
 /* Table of legal combinations of commands and options.  If any of the
@@ -363,27 +364,6 @@ parse_rulenumber(const char *rule)
 	return rulenum;
 }
 
-static const char *
-parse_target(const char *targetname)
-{
-	const char *ptr;
-
-	if (strlen(targetname) < 1)
-		xtables_error(PARAMETER_PROBLEM,
-			   "Invalid target name (too short)");
-
-	if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
-		xtables_error(PARAMETER_PROBLEM,
-			   "Invalid target name `%s' (%u chars max)",
-			   targetname, XT_EXTENSION_MAXNAMELEN - 1);
-
-	for (ptr = targetname; *ptr; ptr++)
-		if (isspace(*ptr))
-			xtables_error(PARAMETER_PROBLEM,
-				   "Invalid target name `%s'", targetname);
-	return targetname;
-}
-
 static void
 set_option(unsigned int *options, unsigned int option, uint8_t *invflg,
 	   int invert)
@@ -602,48 +582,6 @@ list_rules(struct nft_handle *h, const char *chain, const char *table,
 	return nft_rule_list_save(h, chain, table, rulenum, counters);
 }
 
-static void command_jump(struct iptables_command_state *cs)
-{
-	size_t size;
-
-	set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags, cs->invert);
-	cs->jumpto = parse_target(optarg);
-	/* TRY_LOAD (may be chain name) */
-	cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
-
-	if (cs->target == NULL)
-		return;
-
-	size = XT_ALIGN(sizeof(struct xt_entry_target))
-		+ cs->target->size;
-
-	cs->target->t = xtables_calloc(1, size);
-	cs->target->t->u.target_size = size;
-	if (cs->target->real_name == NULL) {
-		strcpy(cs->target->t->u.user.name, cs->jumpto);
-	} else {
-		/* Alias support for userspace side */
-		strcpy(cs->target->t->u.user.name, cs->target->real_name);
-		if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
-			fprintf(stderr, "Notice: The %s target is converted into %s target "
-				"in rule listing and saving.\n",
-				cs->jumpto, cs->target->real_name);
-	}
-	cs->target->t->u.user.revision = cs->target->revision;
-	xs_init_target(cs->target);
-
-	if (cs->target->x6_options != NULL)
-		opts = xtables_options_xfrm(xtables_globals.orig_opts, opts,
-					    cs->target->x6_options,
-					    &cs->target->option_offset);
-	else
-		opts = xtables_merge_options(xtables_globals.orig_opts, opts,
-					     cs->target->extra_opts,
-					     &cs->target->option_offset);
-	if (opts == NULL)
-		xtables_error(OTHER_PROBLEM, "can't alloc memory!");
-}
-
 void do_parse(struct nft_handle *h, int argc, char *argv[],
 	      struct nft_xt_cmd_parse *p, struct iptables_command_state *cs,
 	      struct xtables_args *args)
@@ -876,11 +814,13 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
 			set_option(&cs->options, OPT_JUMP, &args->invflags,
 				   cs->invert);
 			args->goto_set = true;
-			cs->jumpto = parse_target(optarg);
+			cs->jumpto = xt_parse_target(optarg);
 			break;
 #endif
 
 		case 'j':
+			set_option(&cs->options, OPT_JUMP, &cs->fw.ip.invflags,
+				   cs->invert);
 			command_jump(cs);
 			break;
 
-- 
2.19.0




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

  Powered by Linux