Skip to contentSkip to conversation

iptables-edit: source out iptables-restore and iptables-save functionality to iptables-dump.c

PATCH Applied Peter Warasin 2 participants 2 messages Nov 5, 2007 – Nov 6, 2007 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 2/3 iptables-edit: source out iptables-restore and iptables-save functionality to iptables-dump.c

Signature · 6 lines
-- 
:: e n d i a n
:: open source - open minds

:: peter warasin
:: http://www.endian.com   :: [email protected]

source out iptables-restore and iptables-save functionality to iptables-dump.c which renames do_output() to create_dump(), extends it and introduces restore_dump() in order to allow reuse.

---
 Makefile                |    9 
 include/iptables-dump.h |   24 +
 iptables-dump.c         |  686 ++++++++++++++++++++++++++++++++++++++++++++++++
 iptables-restore.c      |  360 -------------------------
 iptables-save.c         |  312 ---------------------
 5 files changed, 725 insertions(+), 666 deletions(-)
iptables-restore.c renamed from iptables-restore.c.orig +5 -355
Index: iptables-restore.c
===================================================================
@@ -8,13 +8,9 @@
  */
 
 #include <getopt.h>
-#include <sys/errno.h>
-#include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include "iptables.h"
-#include "xtables.h"
-#include "libiptc/libiptc.h"
+#include "iptables-dump.h"
 
 #ifdef DEBUG
 #define DEBUGP(x, args...) fprintf(stderr, x, ## args)
@@ -22,8 +18,6 @@
 #define DEBUGP(x, args...) 
 #endif
 
-static int binary = 0, counters = 0, verbose = 0, noflush = 0;
-
 /* Keeping track of external matches and targets.  */
 static struct option options[] = {
 	{ "binary", 0, 0, 'b' },
@@ -54,62 +48,6 @@
 	exit(1);
 }
 
-iptc_handle_t create_handle(const char *tablename, const char* modprobe )
-{
-	iptc_handle_t handle;
-
-	handle = iptc_init(tablename);
-
-	if (!handle) {
-		/* try to insmod the module if iptc_init failed */
-		load_xtables_ko(modprobe, 0);
-		handle = iptc_init(tablename);
-	}
-
-	if (!handle) {
-		exit_error(PARAMETER_PROBLEM, "%s: unable to initialize "
-			"table '%s'\n", program_name, tablename);
-		exit(1);
-	}
-	return handle;
-}
-
-static int parse_counters(char *string, struct ipt_counters *ctr)
-{
-	unsigned long long pcnt, bcnt;
-	int ret;
-
-	ret = sscanf(string, "[%llu:%llu]",
-		     (unsigned long long *)&pcnt,
-		     (unsigned long long *)&bcnt);
-	ctr->pcnt = pcnt;
-	ctr->bcnt = bcnt;
-	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) < sizeof(newargv)/sizeof(char *))) {
-		newargv[newargc] = strdup(what);
-		newargc++;
-		return 1;
-	} else 
-		return 0;
-}
-
-static void free_argv(void) {
-	int i;
-
-	for (i = 0; i < newargc; i++)
-		free(newargv[i]);
-}
-
 #ifdef IPTABLES_MULTI
 int
 iptables_restore_main(int argc, char *argv[])
@@ -118,18 +56,14 @@
 main(int argc, char *argv[])
 #endif
 {
-	iptc_handle_t handle = NULL;
-	char buffer[10240];
+	int binary = 0, counters = 0, verbose = 0, noflush = 0, testing = 0;
 	int c;
-	char curtable[IPT_TABLE_MAXNAMELEN + 1];
-	FILE *in;
 	const char *modprobe = 0;
-	int in_table = 0, testing = 0;
+	const char *filename = 0;
 	const char *tablename = 0;
 
 	program_name = "iptables-restore";
 	program_version = IPTABLES_VERSION;
-	line = 0;
 
 	lib_dir = getenv("IPTABLES_LIB_DIR");
 	if (!lib_dir)
@@ -170,295 +104,11 @@
 	}
 	
 	if (optind == argc - 1) {
-		in = fopen(argv[optind], "r");
-		if (!in) {
-			fprintf(stderr, "Can't open %s: %s\n", argv[optind],
-				strerror(errno));
-			exit(1);
-		}
+		filename = argv[optind];
 	}
 	else if (optind < argc) {
 		fprintf(stderr, "Unknown arguments found on commandline\n");
 		exit(1);
 	}
-	else in = stdin;
-	
-	/* Grab standard input. */
-	while (fgets(buffer, sizeof(buffer), in)) {
-		int ret = 0;
-
-		line++;
-		if (buffer[0] == '\n')
-			continue;
-		else if (buffer[0] == '#') {
-			if (verbose)
-				fputs(buffer, stdout);
-			continue;
-		} else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) {
-			if (!testing) {
-				DEBUGP("Calling commit\n");
-				ret = iptc_commit(&handle);
-			} else {
-				DEBUGP("Not calling commit, testing\n");
-				ret = 1;
-			}
-			in_table = 0;
-		} else if ((buffer[0] == '*') && (!in_table)) {
-			/* New table */
-			char *table;
-
-			table = strtok(buffer+1, " \t\n");
-			DEBUGP("line %u, table '%s'\n", line, table);
-			if (!table) {
-				exit_error(PARAMETER_PROBLEM, 
-					"%s: line %u table name invalid\n",
-					program_name, line);
-				exit(1);
-			}
-			strncpy(curtable, table, IPT_TABLE_MAXNAMELEN);
-			curtable[IPT_TABLE_MAXNAMELEN] = '\0';
-
-			if (tablename && (strcmp(tablename, table) != 0))
-				continue;
-			if (handle)
-				iptc_free(&handle);
-
-			handle = create_handle(table, modprobe);
-			if (noflush == 0) {
-				DEBUGP("Cleaning all chains of table '%s'\n",
-					table);
-				for_each_chain(flush_entries, verbose, 1, 
-						&handle);
-	
-				DEBUGP("Deleting all user-defined chains "
-				       "of table '%s'\n", table);
-				for_each_chain(delete_chain, verbose, 0, 
-						&handle) ;
-			}
-
-			ret = 1;
-			in_table = 1;
-
-		} else if ((buffer[0] == ':') && (in_table)) {
-			/* New chain. */
-			char *policy, *chain;
-
-			chain = strtok(buffer+1, " \t\n");
-			DEBUGP("line %u, chain '%s'\n", line, chain);
-			if (!chain) {
-				exit_error(PARAMETER_PROBLEM,
-					   "%s: line %u chain name invalid\n",
-					   program_name, line);
-				exit(1);
-			}
-
-			if (iptc_builtin(chain, handle) <= 0) {
-				if (noflush && iptc_is_chain(chain, handle)) {
-					DEBUGP("Flushing existing user defined chain '%s'\n", chain);
-					if (!iptc_flush_entries(chain, &handle))
-						exit_error(PARAMETER_PROBLEM,
-							   "error flushing chain "
-							   "'%s':%s\n", chain,
-							   strerror(errno));
-				} else {
-					DEBUGP("Creating new chain '%s'\n", chain);
-					if (!iptc_create_chain(chain, &handle))
-						exit_error(PARAMETER_PROBLEM,
-							   "error creating chain "
-							   "'%s':%s\n", chain,
-							   strerror(errno));
-				}
-			}
-
-			policy = strtok(NULL, " \t\n");
-			DEBUGP("line %u, policy '%s'\n", line, policy);
-			if (!policy) {
-				exit_error(PARAMETER_PROBLEM,
-					   "%s: line %u policy invalid\n",
-					   program_name, line);
-				exit(1);
-			}
-
-			if (strcmp(policy, "-") != 0) {
-				struct ipt_counters count;
-
-				if (counters) {
-					char *ctrs;
-					ctrs = strtok(NULL, " \t\n");
-
-					if (!ctrs || !parse_counters(ctrs, &count))
-						exit_error(PARAMETER_PROBLEM,
-							   "invalid policy counters "
-							   "for chain '%s'\n", chain);
-
-				} else {
-					memset(&count, 0, 
-					       sizeof(struct ipt_counters));
-				}
-
-				DEBUGP("Setting policy of chain %s to %s\n",
-					chain, policy);
-
-				if (!iptc_set_policy(chain, policy, &count,
-						     &handle))
-					exit_error(OTHER_PROBLEM,
-						"Can't set policy `%s'"
-						" on `%s' line %u: %s\n",
-						chain, policy, line,
-						iptc_strerror(errno));
-			}
-
-			ret = 1;
-
-		} else if (in_table) {
-			int a;
-			char *ptr = buffer;
-			char *pcnt = NULL;
-			char *bcnt = NULL;
-			char *parsestart;
-
-			/* the parser */
-			char *curchar;
-			int quote_open;
-			int param_len;
-
-			/* reset the newargv */
-			newargc = 0;
-
-			if (buffer[0] == '[') {
-				/* we have counters in our input */
-				ptr = strchr(buffer, ']');
-				if (!ptr)
-					exit_error(PARAMETER_PROBLEM,
-						   "Bad line %u: need ]\n",
-						   line);
-
-				pcnt = strtok(buffer+1, ":");
-				if (!pcnt)
-					exit_error(PARAMETER_PROBLEM,
-						   "Bad line %u: need :\n",
-						   line);
-
-				bcnt = strtok(NULL, "]");
-				if (!bcnt)
-					exit_error(PARAMETER_PROBLEM,
-						   "Bad line %u: need ]\n",
-						   line);
-
-				/* start command parsing after counter */
-				parsestart = ptr + 1;
-			} else {
-				/* start command parsing at start of line */
-				parsestart = buffer;
-			}
-
-			add_argv(argv[0]);
-			add_argv("-t");
-			add_argv((char *) &curtable);
-			
-			if (counters && pcnt && bcnt) {
-				add_argv("--set-counters");
-				add_argv((char *) pcnt);
-				add_argv((char *) bcnt);
-			}
-
-			/* 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 */
-
-			quote_open = 0;
-			param_len = 0;
-			
-			for (curchar = parsestart; *curchar; curchar++) {
-				char param_buffer[1024];
-
-				if (*curchar == '"') {
-					/* quote_open cannot be true if there
-					 * was no previous character.  Thus, 
-					 * curchar-1 has to be within bounds */
-					if (quote_open && 
-					    *(curchar-1) != '\\') {
-						quote_open = 0;
-						*curchar = ' ';
-					} else if (!quote_open) {
-						quote_open = 1;
-						continue;
-					}
-				} 
-				if (*curchar == ' '
-				    || *curchar == '\t'
-				    || * curchar == '\n') {
-
-					if (quote_open) {
-						param_buffer[param_len++] = 
-								*curchar;
-						continue;
-					}
-
-					if (!param_len) {
-						/* two spaces? */
-						continue;
-					}
-
-					param_buffer[param_len] = '\0';
-
-					/* check if table name specified */
-					if (!strncmp(param_buffer, "-t", 3)
-                                            || !strncmp(param_buffer, "--table", 8)) {
-						exit_error(PARAMETER_PROBLEM, 
-						   "Line %u seems to have a "
-						   "-t table option.\n", line);
-						exit(1);
-					}
-
-					add_argv(param_buffer);
-					param_len = 0;
-				} else {
-					/* Skip backslash that escapes quote: 
-					 * the standard input does not require
-					 * escaping. However, the output
-					 * generated by iptables-save
-					 * introduces bashlash to keep
-					 * consistent with iptables
-					 */
-					if (quote_open &&
-					    *curchar == '\\' &&
-					    *(curchar+1) == '"')
-						continue;
-
-					/* regular character, copy to buffer */
-					param_buffer[param_len++] = *curchar;
-
-					if (param_len >= sizeof(param_buffer))
-						exit_error(PARAMETER_PROBLEM, 
-						   "Parameter too long!");
-				}
-			}
-
-			DEBUGP("calling do_command(%u, argv, &%s, handle):\n",
-				newargc, curtable);
-
-			for (a = 0; a < newargc; a++)
-				DEBUGP("argv[%u]: %s\n", a, newargv[a]);
-
-			ret = do_command(newargc, newargv, 
-					 &newargv[2], &handle);
-
-			free_argv();
-		}
-		if (tablename && (strcmp(tablename, curtable) != 0))
-			continue;
-		if (!ret) {
-			fprintf(stderr, "%s: line %u failed\n",
-					program_name, line);
-			exit(1);
-		}
-	}
-	if (in_table) {
-		fprintf(stderr, "%s: COMMIT expected at line %u\n",
-				program_name, line + 1);
-		exit(1);
-	}
-
-	return 0;
+	return restore_dump(tablename, NULL, modprobe, filename, binary, counters, verbose, noflush, testing);
 }
iptables-dump.h new file +24 -0
Index: include/iptables-dump.h
===================================================================
@@ -0,0 +1,24 @@
+/* Code to save or restore the iptables state, in human readable-form. */
+/* (C) 1999 by Paul 'Rusty' Russell <[email protected]> and
+ * (C) 2000-2002 by Harald Welte <[email protected]>
+ *
+ * This code is distributed under the terms of GNU GPL v2
+ *
+ * $Id$
+ */
+
+#ifndef _IPTABLES_DUMP_H
+#define _IPTABLES_DUMP_H
+
+#include "iptables.h"
+
+extern const char *program_name;
+extern const char *program_version;
+
+int create_dump(const char *tablename, iptc_handle_t h, int binary, int counters);
+
+int restore_dump(const char *tablename, iptc_handle_t storehandle,
+		  const char *modprobe, const char *filename, int binary,
+		  int counters, int verbose, int noflush, int testing);
+
+#endif /*_IPTABLES_DUMP_H*/
iptables-dump.c new file +686 -0

686 lines not on this page · raw message

iptables-save.c renamed from iptables-save.c.orig +4 -308

342 lines not on this page · raw message

Makefile renamed from Makefile.orig +6 -3
Index: Makefile
===================================================================
@@ -105,8 +105,11 @@
 iptables.o: iptables.c
 	$(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -c -o $@ $<
 
+iptables-dump.o: iptables-dump.c include/iptables-dump.h
+	$(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" -c -o $@ $<
+
 ifeq ($(DO_MULTI), 1)
-iptables: iptables-multi.c iptables-save.c iptables-restore.c iptables-xml.c iptables-standalone.c iptables.o xtables.o $(STATIC_LIBS) libiptc/libiptc.a
+iptables: iptables-multi.c iptables-save.c iptables-restore.c iptables-xml.c iptables-standalone.c iptables.o xtables.o iptables-dump.o $(STATIC_LIBS) libiptc/libiptc.a
 	$(CC) $(CFLAGS) -DIPTABLES_MULTI -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" $(LDFLAGS) -o $@ $^ $(LDLIBS)
 else
 iptables: iptables-standalone.c iptables.o xtables.o $(STATIC_LIBS) libiptc/libiptc.a
@@ -117,7 +120,7 @@
 	@[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
 	cp $< $@
 
-iptables-save: iptables-save.c iptables.o xtables.o $(STATIC_LIBS) libiptc/libiptc.a
+iptables-save: iptables-save.c iptables.o xtables.o iptables-dump.o $(STATIC_LIBS) libiptc/libiptc.a
 	$(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" $(LDFLAGS) -o $@ $^ $(LDLIBS)
 
 ifeq ($(DO_MULTI), 1)
@@ -130,7 +133,7 @@
 	cp $< $@
 endif
 
-iptables-restore: iptables-restore.c iptables.o xtables.o $(STATIC_LIBS) libiptc/libiptc.a
+iptables-restore: iptables-restore.c iptables.o xtables.o iptables-dump.o $(STATIC_LIBS) libiptc/libiptc.a
 	$(CC) $(CFLAGS) -DIPT_LIB_DIR=\"$(IPT_LIBDIR)\" $(LDFLAGS) -o $@ $^ $(LDLIBS)
 
 ifeq ($(DO_MULTI), 1)

begin:vcard
fn:Peter Warasin
n:;Peter Warasin
org:Endian GmbH/Srl
adr:;;Pillhof 47;Frangart/Frangarto;BZ;I-39010;Italien/Italia email;internet:[email protected]
tel;work:+39 0471 631763
tel;fax:+39 0471 631764
x-mozilla-html:FALSE
url:http://www.endian.com
version:2.1
end:vcard

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw
Quoted 4 lines · Patrick McHardy

Peter Warasin wrote:

Looks fine, but I'm going delay applying this until we get the 1.4.0 release out.