You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
568 lines
15 KiB
568 lines
15 KiB
From fc87d26b0343a5fbe661acc967f7a7c316531ca5 Mon Sep 17 00:00:00 2001 |
|
From: Phil Sutter <psutter@redhat.com> |
|
Date: Wed, 3 Apr 2019 20:16:49 +0200 |
|
Subject: [PATCH] xshared: Consolidate argv construction routines |
|
|
|
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1668475 |
|
Upstream Status: iptables commit a2ed880a19d08 |
|
Conflicts: |
|
* Context change due to missing commit 2963a8df2175b |
|
("iptables: Remove explicit static variables initalization."). |
|
* Context change due to missing commit 1cc09188079a6 |
|
("xshared: Consolidate parse_counters()"). |
|
* Context change due to previously backported commit 8da04ffdca193 |
|
("Share print_ipv{4,6}_addr() from xtables"). |
|
* Dropped changes to non-existing file iptables/xtables-restore.c. |
|
|
|
commit a2ed880a19d0861342b3515721804b18d698bf44 |
|
Author: Phil Sutter <phil@nwl.cc> |
|
Date: Thu Aug 2 17:05:17 2018 +0200 |
|
|
|
xshared: Consolidate argv construction routines |
|
|
|
Implementations were equal in {ip,ip6,x}tables-restore.c. The one in |
|
iptables-xml.c differed slightly. For now, collect all features |
|
together. Maybe it would make sense to migrate iptables-xml.c to using |
|
add_param_to_argv() at some point and therefore extend the latter to |
|
store whether a given parameter was quoted or not. |
|
|
|
While being at it, a few improvements were done: |
|
|
|
* free_argv() now also resets 'newargc' variable, so users don't have to |
|
do that anymore. |
|
* Indenting level in add_param_to_argv() was reduced a bit. |
|
* That long error message is put into a single line to aid in grepping |
|
for it. |
|
* Explicit call to exit() after xtables_error() is removed since the |
|
latter does not return anyway. |
|
|
|
Signed-off-by: Phil Sutter <phil@nwl.cc> |
|
Signed-off-by: Florian Westphal <fw@strlen.de> |
|
|
|
Signed-off-by: Phil Sutter <psutter@redhat.com> |
|
--- |
|
iptables/ip6tables-restore.c | 107 ++---------------------------- |
|
iptables/iptables-restore.c | 107 ++---------------------------- |
|
iptables/iptables-xml.c | 63 ------------------ |
|
iptables/xshared.c | 123 +++++++++++++++++++++++++++++++++++ |
|
iptables/xshared.h | 13 ++++ |
|
5 files changed, 150 insertions(+), 263 deletions(-) |
|
|
|
diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c |
|
index 611430d930eda..1f8cb43286f03 100644 |
|
--- a/iptables/ip6tables-restore.c |
|
+++ b/iptables/ip6tables-restore.c |
|
@@ -91,96 +91,6 @@ static int parse_counters(char *string, struct xt_counters *ctr) |
|
return ret == 2; |
|
} |
|
|
|
-/* global new argv and argc */ |
|
-static char *newargv[255]; |
|
-static int newargc; |
|
- |
|
-/* function adding one argument to newargv, updating newargc |
|
- * returns true if argument added, false otherwise */ |
|
-static int add_argv(char *what) { |
|
- DEBUGP("add_argv: %s\n", what); |
|
- if (what && newargc + 1 < ARRAY_SIZE(newargv)) { |
|
- newargv[newargc] = strdup(what); |
|
- newargv[++newargc] = NULL; |
|
- return 1; |
|
- } else { |
|
- xtables_error(PARAMETER_PROBLEM, |
|
- "Parser cannot handle more arguments\n"); |
|
- return 0; |
|
- } |
|
-} |
|
- |
|
-static void free_argv(void) { |
|
- int i; |
|
- |
|
- for (i = 0; i < newargc; i++) |
|
- free(newargv[i]); |
|
-} |
|
- |
|
-static void add_param_to_argv(char *parsestart) |
|
-{ |
|
- int quote_open = 0, escaped = 0, param_len = 0; |
|
- char param_buffer[1024], *curchar; |
|
- |
|
- /* After fighting with strtok enough, here's now |
|
- * a 'real' parser. According to Rusty I'm now no |
|
- * longer a real hacker, but I can live with that */ |
|
- |
|
- for (curchar = parsestart; *curchar; curchar++) { |
|
- if (quote_open) { |
|
- if (escaped) { |
|
- param_buffer[param_len++] = *curchar; |
|
- escaped = 0; |
|
- continue; |
|
- } else if (*curchar == '\\') { |
|
- escaped = 1; |
|
- continue; |
|
- } else if (*curchar == '"') { |
|
- quote_open = 0; |
|
- *curchar = ' '; |
|
- } else { |
|
- param_buffer[param_len++] = *curchar; |
|
- continue; |
|
- } |
|
- } else { |
|
- if (*curchar == '"') { |
|
- quote_open = 1; |
|
- continue; |
|
- } |
|
- } |
|
- |
|
- if (*curchar == ' ' |
|
- || *curchar == '\t' |
|
- || * curchar == '\n') { |
|
- if (!param_len) { |
|
- /* two spaces? */ |
|
- continue; |
|
- } |
|
- |
|
- param_buffer[param_len] = '\0'; |
|
- |
|
- /* check if table name specified */ |
|
- if (!strncmp(param_buffer, "-t", 2) |
|
- || !strncmp(param_buffer, "--table", 8)) { |
|
- xtables_error(PARAMETER_PROBLEM, |
|
- "The -t option (seen in line %u) cannot be " |
|
- "used in ip6tables-restore.\n", line); |
|
- exit(1); |
|
- } |
|
- |
|
- add_argv(param_buffer); |
|
- param_len = 0; |
|
- } else { |
|
- /* regular character, copy to buffer */ |
|
- param_buffer[param_len++] = *curchar; |
|
- |
|
- if (param_len >= sizeof(param_buffer)) |
|
- xtables_error(PARAMETER_PROBLEM, |
|
- "Parameter too long!"); |
|
- } |
|
- } |
|
-} |
|
- |
|
int ip6tables_restore_main(int argc, char *argv[]) |
|
{ |
|
struct xtc_handle *handle = NULL; |
|
@@ -425,9 +335,6 @@ int ip6tables_restore_main(int argc, char *argv[]) |
|
char *bcnt = NULL; |
|
char *parsestart; |
|
|
|
- /* reset the newargv */ |
|
- newargc = 0; |
|
- |
|
if (buffer[0] == '[') { |
|
/* we have counters in our input */ |
|
char *ptr = strchr(buffer, ']'); |
|
@@ -456,17 +363,17 @@ int ip6tables_restore_main(int argc, char *argv[]) |
|
parsestart = buffer; |
|
} |
|
|
|
- add_argv(argv[0]); |
|
- add_argv("-t"); |
|
- add_argv(curtable); |
|
+ add_argv(argv[0], 0); |
|
+ add_argv("-t", 0); |
|
+ add_argv(curtable, 0); |
|
|
|
if (counters && pcnt && bcnt) { |
|
- add_argv("--set-counters"); |
|
- add_argv((char *) pcnt); |
|
- add_argv((char *) bcnt); |
|
+ add_argv("--set-counters", 0); |
|
+ add_argv((char *) pcnt, 0); |
|
+ add_argv((char *) bcnt, 0); |
|
} |
|
|
|
- add_param_to_argv(parsestart); |
|
+ add_param_to_argv(parsestart, line); |
|
|
|
DEBUGP("calling do_command6(%u, argv, &%s, handle):\n", |
|
newargc, curtable); |
|
diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c |
|
index b0da96d45d297..615e38a6625e0 100644 |
|
--- a/iptables/iptables-restore.c |
|
+++ b/iptables/iptables-restore.c |
|
@@ -89,96 +89,6 @@ static int parse_counters(char *string, struct xt_counters *ctr) |
|
return ret == 2; |
|
} |
|
|
|
-/* global new argv and argc */ |
|
-static char *newargv[255]; |
|
-static int newargc; |
|
- |
|
-/* function adding one argument to newargv, updating newargc |
|
- * returns true if argument added, false otherwise */ |
|
-static int add_argv(char *what) { |
|
- DEBUGP("add_argv: %s\n", what); |
|
- if (what && newargc + 1 < ARRAY_SIZE(newargv)) { |
|
- newargv[newargc] = strdup(what); |
|
- newargv[++newargc] = NULL; |
|
- return 1; |
|
- } else { |
|
- xtables_error(PARAMETER_PROBLEM, |
|
- "Parser cannot handle more arguments\n"); |
|
- return 0; |
|
- } |
|
-} |
|
- |
|
-static void free_argv(void) { |
|
- int i; |
|
- |
|
- for (i = 0; i < newargc; i++) |
|
- free(newargv[i]); |
|
-} |
|
- |
|
-static void add_param_to_argv(char *parsestart) |
|
-{ |
|
- int quote_open = 0, escaped = 0, param_len = 0; |
|
- char param_buffer[1024], *curchar; |
|
- |
|
- /* After fighting with strtok enough, here's now |
|
- * a 'real' parser. According to Rusty I'm now no |
|
- * longer a real hacker, but I can live with that */ |
|
- |
|
- for (curchar = parsestart; *curchar; curchar++) { |
|
- if (quote_open) { |
|
- if (escaped) { |
|
- param_buffer[param_len++] = *curchar; |
|
- escaped = 0; |
|
- continue; |
|
- } else if (*curchar == '\\') { |
|
- escaped = 1; |
|
- continue; |
|
- } else if (*curchar == '"') { |
|
- quote_open = 0; |
|
- *curchar = ' '; |
|
- } else { |
|
- param_buffer[param_len++] = *curchar; |
|
- continue; |
|
- } |
|
- } else { |
|
- if (*curchar == '"') { |
|
- quote_open = 1; |
|
- continue; |
|
- } |
|
- } |
|
- |
|
- if (*curchar == ' ' |
|
- || *curchar == '\t' |
|
- || * curchar == '\n') { |
|
- if (!param_len) { |
|
- /* two spaces? */ |
|
- continue; |
|
- } |
|
- |
|
- param_buffer[param_len] = '\0'; |
|
- |
|
- /* check if table name specified */ |
|
- if (!strncmp(param_buffer, "-t", 2) |
|
- || !strncmp(param_buffer, "--table", 8)) { |
|
- xtables_error(PARAMETER_PROBLEM, |
|
- "The -t option (seen in line %u) cannot be " |
|
- "used in iptables-restore.\n", line); |
|
- exit(1); |
|
- } |
|
- |
|
- add_argv(param_buffer); |
|
- param_len = 0; |
|
- } else { |
|
- /* regular character, copy to buffer */ |
|
- param_buffer[param_len++] = *curchar; |
|
- |
|
- if (param_len >= sizeof(param_buffer)) |
|
- xtables_error(PARAMETER_PROBLEM, |
|
- "Parameter too long!"); |
|
- } |
|
- } |
|
-} |
|
- |
|
int |
|
iptables_restore_main(int argc, char *argv[]) |
|
{ |
|
@@ -424,9 +334,6 @@ iptables_restore_main(int argc, char *argv[]) |
|
char *bcnt = NULL; |
|
char *parsestart; |
|
|
|
- /* reset the newargv */ |
|
- newargc = 0; |
|
- |
|
if (buffer[0] == '[') { |
|
/* we have counters in our input */ |
|
char *ptr = strchr(buffer, ']'); |
|
@@ -455,17 +362,17 @@ iptables_restore_main(int argc, char *argv[]) |
|
parsestart = buffer; |
|
} |
|
|
|
- add_argv(argv[0]); |
|
- add_argv("-t"); |
|
- add_argv(curtable); |
|
+ add_argv(argv[0], 0); |
|
+ add_argv("-t", 0); |
|
+ add_argv(curtable, 0); |
|
|
|
if (counters && pcnt && bcnt) { |
|
- add_argv("--set-counters"); |
|
- add_argv((char *) pcnt); |
|
- add_argv((char *) bcnt); |
|
+ add_argv("--set-counters", 0); |
|
+ add_argv((char *) pcnt, 0); |
|
+ add_argv((char *) bcnt, 0); |
|
} |
|
|
|
- add_param_to_argv(parsestart); |
|
+ add_param_to_argv(parsestart, line); |
|
|
|
DEBUGP("calling do_command4(%u, argv, &%s, handle):\n", |
|
newargc, curtable); |
|
diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c |
|
index c523a132b2240..49f8ea2826181 100644 |
|
--- a/iptables/iptables-xml.c |
|
+++ b/iptables/iptables-xml.c |
|
@@ -66,16 +66,6 @@ parse_counters(char *string, struct xt_counters *ctr) |
|
return (0 == 2); |
|
} |
|
|
|
-/* global new argv and argc */ |
|
-static char *newargv[255]; |
|
-static unsigned int newargc = 0; |
|
- |
|
-static char *oldargv[255]; |
|
-static unsigned int oldargc = 0; |
|
- |
|
-/* arg meta data, were they quoted, frinstance */ |
|
-static int newargvattr[255]; |
|
- |
|
#define XT_CHAIN_MAXNAMELEN XT_TABLE_MAXNAMELEN |
|
static char closeActionTag[XT_TABLE_MAXNAMELEN + 1]; |
|
static char closeRuleTag[XT_TABLE_MAXNAMELEN + 1]; |
|
@@ -93,56 +83,6 @@ struct chain { |
|
static struct chain chains[maxChains]; |
|
static int nextChain = 0; |
|
|
|
-/* funCtion adding one argument to newargv, updating newargc |
|
- * returns true if argument added, false otherwise */ |
|
-static int |
|
-add_argv(char *what, int quoted) |
|
-{ |
|
- DEBUGP("add_argv: %d %s\n", newargc, what); |
|
- if (what && newargc + 1 < ARRAY_SIZE(newargv)) { |
|
- newargv[newargc] = strdup(what); |
|
- newargvattr[newargc] = quoted; |
|
- newargc++; |
|
- return 1; |
|
- } else |
|
- return 0; |
|
-} |
|
- |
|
-static void |
|
-free_argv(void) |
|
-{ |
|
- unsigned int i; |
|
- |
|
- for (i = 0; i < newargc; i++) { |
|
- free(newargv[i]); |
|
- newargv[i] = NULL; |
|
- } |
|
- newargc = 0; |
|
- |
|
- for (i = 0; i < oldargc; i++) { |
|
- free(oldargv[i]); |
|
- oldargv[i] = NULL; |
|
- } |
|
- oldargc = 0; |
|
-} |
|
- |
|
-/* save parsed rule for comparison with next rule |
|
- to perform action agregation on duplicate conditions */ |
|
-static void |
|
-save_argv(void) |
|
-{ |
|
- unsigned int i; |
|
- |
|
- for (i = 0; i < oldargc; i++) |
|
- free(oldargv[i]); |
|
- oldargc = newargc; |
|
- newargc = 0; |
|
- for (i = 0; i < oldargc; i++) { |
|
- oldargv[i] = newargv[i]; |
|
- newargv[i] = NULL; |
|
- } |
|
-} |
|
- |
|
/* like puts but with xml encoding */ |
|
static void |
|
xmlEncode(char *text) |
|
@@ -736,9 +676,6 @@ iptables_xml_main(int argc, char *argv[]) |
|
int quote_open, quoted; |
|
char param_buffer[1024]; |
|
|
|
- /* reset the newargv */ |
|
- newargc = 0; |
|
- |
|
if (buffer[0] == '[') { |
|
/* we have counters in our input */ |
|
char *ptr = strchr(buffer, ']'); |
|
diff --git a/iptables/xshared.c b/iptables/xshared.c |
|
index 742502154aa55..84dbea562576e 100644 |
|
--- a/iptables/xshared.c |
|
+++ b/iptables/xshared.c |
|
@@ -406,3 +406,126 @@ void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format) |
|
ipv6_addr_to_string(&fw6->ipv6.dst, |
|
&fw6->ipv6.dmsk, format)); |
|
} |
|
+ |
|
+/* global new argv and argc */ |
|
+char *newargv[255]; |
|
+int newargc = 0; |
|
+ |
|
+/* saved newargv and newargc from save_argv() */ |
|
+char *oldargv[255]; |
|
+int oldargc = 0; |
|
+ |
|
+/* arg meta data, were they quoted, frinstance */ |
|
+int newargvattr[255]; |
|
+ |
|
+/* function adding one argument to newargv, updating newargc |
|
+ * returns true if argument added, false otherwise */ |
|
+int add_argv(const char *what, int quoted) |
|
+{ |
|
+ DEBUGP("add_argv: %s\n", what); |
|
+ if (what && newargc + 1 < ARRAY_SIZE(newargv)) { |
|
+ newargv[newargc] = strdup(what); |
|
+ newargvattr[newargc] = quoted; |
|
+ newargv[++newargc] = NULL; |
|
+ return 1; |
|
+ } else { |
|
+ xtables_error(PARAMETER_PROBLEM, |
|
+ "Parser cannot handle more arguments\n"); |
|
+ } |
|
+} |
|
+ |
|
+void free_argv(void) |
|
+{ |
|
+ while (newargc) |
|
+ free(newargv[--newargc]); |
|
+ while (oldargc) |
|
+ free(oldargv[--oldargc]); |
|
+} |
|
+ |
|
+/* Save parsed rule for comparison with next rule to perform action aggregation |
|
+ * on duplicate conditions. |
|
+ */ |
|
+void save_argv(void) |
|
+{ |
|
+ unsigned int i; |
|
+ |
|
+ while (oldargc) |
|
+ free(oldargv[--oldargc]); |
|
+ |
|
+ oldargc = newargc; |
|
+ newargc = 0; |
|
+ for (i = 0; i < oldargc; i++) { |
|
+ oldargv[i] = newargv[i]; |
|
+ } |
|
+} |
|
+ |
|
+void add_param_to_argv(char *parsestart, int line) |
|
+{ |
|
+ int quote_open = 0, escaped = 0, param_len = 0; |
|
+ char param_buffer[1024], *curchar; |
|
+ |
|
+ /* After fighting with strtok enough, here's now |
|
+ * a 'real' parser. According to Rusty I'm now no |
|
+ * longer a real hacker, but I can live with that */ |
|
+ |
|
+ for (curchar = parsestart; *curchar; curchar++) { |
|
+ if (quote_open) { |
|
+ if (escaped) { |
|
+ param_buffer[param_len++] = *curchar; |
|
+ escaped = 0; |
|
+ continue; |
|
+ } else if (*curchar == '\\') { |
|
+ escaped = 1; |
|
+ continue; |
|
+ } else if (*curchar == '"') { |
|
+ quote_open = 0; |
|
+ *curchar = '"'; |
|
+ } else { |
|
+ param_buffer[param_len++] = *curchar; |
|
+ continue; |
|
+ } |
|
+ } else { |
|
+ if (*curchar == '"') { |
|
+ quote_open = 1; |
|
+ continue; |
|
+ } |
|
+ } |
|
+ |
|
+ switch (*curchar) { |
|
+ case '"': |
|
+ break; |
|
+ case ' ': |
|
+ case '\t': |
|
+ case '\n': |
|
+ if (!param_len) { |
|
+ /* two spaces? */ |
|
+ continue; |
|
+ } |
|
+ break; |
|
+ default: |
|
+ /* regular character, copy to buffer */ |
|
+ param_buffer[param_len++] = *curchar; |
|
+ |
|
+ if (param_len >= sizeof(param_buffer)) |
|
+ xtables_error(PARAMETER_PROBLEM, |
|
+ "Parameter too long!"); |
|
+ continue; |
|
+ } |
|
+ |
|
+ param_buffer[param_len] = '\0'; |
|
+ |
|
+ /* check if table name specified */ |
|
+ if ((param_buffer[0] == '-' && |
|
+ param_buffer[1] != '-' && |
|
+ strchr(param_buffer, 't')) || |
|
+ (!strncmp(param_buffer, "--t", 3) && |
|
+ !strncmp(param_buffer, "--table", strlen(param_buffer)))) { |
|
+ xtables_error(PARAMETER_PROBLEM, |
|
+ "The -t option (seen in line %u) cannot be used in %s.\n", |
|
+ line, xt_params->program_name); |
|
+ } |
|
+ |
|
+ add_argv(param_buffer, 0); |
|
+ param_len = 0; |
|
+ } |
|
+} |
|
diff --git a/iptables/xshared.h b/iptables/xshared.h |
|
index bfdb10b2701e5..4f567db9f410b 100644 |
|
--- a/iptables/xshared.h |
|
+++ b/iptables/xshared.h |
|
@@ -119,6 +119,19 @@ bool xs_has_arg(int argc, char *argv[]); |
|
|
|
extern const struct xtables_afinfo *afinfo; |
|
|
|
+extern char *newargv[]; |
|
+extern int newargc; |
|
+ |
|
+extern char *oldargv[]; |
|
+extern int oldargc; |
|
+ |
|
+extern int newargvattr[]; |
|
+ |
|
+int add_argv(const char *what, int quoted); |
|
+void free_argv(void); |
|
+void save_argv(void); |
|
+void add_param_to_argv(char *parsestart, int line); |
|
+ |
|
void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format); |
|
void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format); |
|
|
|
-- |
|
2.21.0 |
|
|
|
|