summaryrefslogtreecommitdiffstats
path: root/iptables/xshared.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2018-08-02 17:05:17 +0200
committerFlorian Westphal <fw@strlen.de>2018-08-04 14:29:21 +0200
commita2ed880a19d0861342b3515721804b18d698bf44 (patch)
tree22fc03a1b1db3e30f594f292b166a86a92de7e19 /iptables/xshared.c
parent1cc09188079a64dc8b733f198c959cfb441e6e20 (diff)
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>
Diffstat (limited to 'iptables/xshared.c')
-rw-r--r--iptables/xshared.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/iptables/xshared.c b/iptables/xshared.c
index ec5c4955..492e0087 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -379,3 +379,126 @@ inline bool xs_has_arg(int argc, char *argv[])
argv[optind][0] != '-' &&
argv[optind][0] != '!';
}
+
+/* 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;
+ }
+}