summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--iptables-restore.813
-rw-r--r--iptables-restore.c114
-rw-r--r--iptables-save.813
-rw-r--r--iptables-save.c20
4 files changed, 74 insertions, 86 deletions
diff --git a/iptables-restore.8 b/iptables-restore.8
index 4e4e1504..2ca6973a 100644
--- a/iptables-restore.8
+++ b/iptables-restore.8
@@ -38,18 +38,7 @@ don't flush the previous contents of the table. If not specified,
.B iptables-restore
flushes (deletes) all previous contents of the respective IP Table.
.SH BUGS
-.B iptables-save
-doesn't order user-defined chains and builtin chains in any specific manner.
-This raises some dependency problems when using the unmodified output of
-.B iptables-restore
-as input for
-.B iptables-restore.
-.PP
-Expect this to be fixed in the next iptables release.
-.PP
-To make it work, reorder the output in a way that in every table, all
-user-defined chains are created before any other chain uses this chain
-as target.
+None known as of iptables-1.2.1 release
.SH AUTHOR
Harald Welte <laforge@gnumonks.org>
.SH SEE ALSO
diff --git a/iptables-restore.c b/iptables-restore.c
index b4a81353..936c6667 100644
--- a/iptables-restore.c
+++ b/iptables-restore.c
@@ -4,7 +4,7 @@
*
* This coude is distributed under the terms of GNU GPL
*
- * $Id: iptables-restore.c,v 1.8 2001/01/23 22:54:34 laforge Exp $
+ * $Id: iptables-restore.c,v 1.9 2001/02/26 17:31:20 laforge Exp $
*/
#include <getopt.h>
@@ -65,6 +65,21 @@ int parse_counters(char *string, struct ipt_counters *ctr)
return (sscanf(string, "[%llu:%llu]", &ctr->pcnt, &ctr->bcnt) == 2);
}
+/* global new argv and argc */
+static char* newargv[1024];
+static int newargc;
+
+/* function adding one argument to newargv, updating newargc
+ * returns true if argument added, false otherwise */
+static int add_argv(char *what) {
+ if (what && ((newargc + 1) < sizeof(newargv)/sizeof(char *))) {
+ newargv[newargc] = what;
+ newargc++;
+ return 1;
+ } else
+ return 0;
+}
+
int main(int argc, char *argv[])
{
iptc_handle_t handle;
@@ -72,7 +87,6 @@ int main(int argc, char *argv[])
unsigned int line = 0;
int c;
char curtable[IPT_TABLE_MAXNAMELEN + 1];
- char curchain[IPT_FUNCTION_MAXNAMELEN + 1];
FILE *in;
program_name = "iptables-restore";
@@ -109,17 +123,7 @@ int main(int argc, char *argv[])
exit(1);
}
else in = stdin;
-/*
- handle = iptc_init("filter");
- if (!handle)
- exit_error(VERSION_PROBLEM,
- "can't initialize iptables-restore: %s",
- iptc_strerror(errno));
-
- if (!clean_slate(&handle))
- exit_error(OTHER_PROBLEM, "Deleting old chains: %s",
- iptc_strerror(errno));
-*/
+
/* Grab standard input. */
while (fgets(buffer, sizeof(buffer), in)) {
int ret;
@@ -173,16 +177,14 @@ int main(int argc, char *argv[])
program_name, line);
exit(1);
}
- strncpy(curchain, chain, IPT_FUNCTION_MAXNAMELEN);
- /* why the f... does iptc_builtin not work here ? */
/* FIXME: abort if chain creation fails --RR */
-// if (!iptc_builtin(curchain, &handle)) {
- DEBUGP("Creating new chain '%s'\n", curchain);
- if (!iptc_create_chain(curchain, &handle))
- DEBUGP("unable to create chain '%s':%s\n", curchain,
+ if (!iptc_builtin(chain, handle)) {
+ DEBUGP("Creating new chain '%s'\n", chain);
+ if (!iptc_create_chain(chain, &handle))
+ DEBUGP("unable to create chain '%s':%s\n", chain,
strerror(errno));
-// }
+ }
policy = strtok(NULL, " \t\n");
DEBUGP("line %u, policy '%s'\n", line, policy);
@@ -222,66 +224,64 @@ int main(int argc, char *argv[])
ret = 1;
} else {
- char *newargv[1024];
- int i,a, argvsize;
+ int a;
char *ptr = buffer;
char *pcnt = NULL;
char *bcnt = NULL;
+ char *parsestart;
+
+ /* 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, ":");
- bcnt = strtok(NULL, "]");
- }
+ if (!pcnt)
+ exit_error(PARAMETER_PROBLEM,
+ "Bad line %u: need :\n",
+ line);
- newargv[0] = argv[0];
- newargv[1] = "-t";
- newargv[2] = (char *) &curtable;
- newargv[3] = "-A";
- newargv[4] = (char *) &curchain;
- argvsize = 5;
+ bcnt = strtok(NULL, "]");
+ if (!bcnt)
+ exit_error(PARAMETER_PROBLEM,
+ "Bad line %u: need ]\n",
+ line);
- if (counters && pcnt && bcnt) {
- newargv[5] = "--set-counters";
- newargv[6] = (char *) pcnt;
- newargv[7] = (char *) bcnt;
- argvsize = 8;
+ /* start command parsing after counter */
+ parsestart = ptr + 1;
+ } else {
+ /* start command parsing at start of line */
+ parsestart = buffer;
}
- // strtok initcialize!
- if ( buffer[0]!='[' )
- {
- if (!(newargv[argvsize] = strtok(buffer, " \t\n")))
- goto ImLaMeR;
- //break;
- argvsize++;
+ 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);
}
- /* strtok: a function only a coder could love */
- for (i = argvsize; i < sizeof(newargv)/sizeof(char *);
- i++) {
- if (!(newargv[i] = strtok(NULL, " \t\n")))
- break;
- ptr = NULL;
- }
-ImLaMeR: if (i == sizeof(newargv)/sizeof(char *)) {
- fprintf(stderr,
- "%s: line %u too many arguments\n",
- program_name, line);
- exit(1);
+ /* parse till end of line */
+ if (add_argv(strtok(parsestart, " \t\n"))) {
+ while (add_argv(strtok(NULL, " \t\n")));
}
DEBUGP("===>calling do_command(%u, argv, &%s, handle):\n",
- i, curtable);
+ newargc, curtable);
- for (a = 0; a <= i; a++)
+ for (a = 0; a <= newargc; a++)
DEBUGP("argv[%u]: %s\n", a, newargv[a]);
- ret = do_command(i, newargv, &newargv[2], &handle);
+ ret = do_command(newargc, newargv, &newargv[2], &handle);
}
if (!ret) {
fprintf(stderr, "%s: line %u failed\n",
diff --git a/iptables-save.8 b/iptables-save.8
index 32b70ef2..71a957da 100644
--- a/iptables-save.8
+++ b/iptables-save.8
@@ -37,18 +37,7 @@ include the current values of all packet and byte counters in the output
restrict output to only one table. If not specified, output includes all
available tables.
.SH BUGS
-.B iptables-save
-doesn't order user-defined chains and builtin chains in any specific manner.
-This raises some dependency problems when using the unmodified output of
-.B iptables-save
-as input for
-.B iptables-restore.
-.PP
-Expect this to be fixed in the next iptables release.
-.PP
-To make it work, reorder the output in a way that in every table, all
-user-defined chains are created before any other chain uses this chain
-as target.
+None known as of iptables-1.2.1 release
.SH AUTHOR
Harald Welte <laforge@gnumonks.org>
.SH SEE ALSO
diff --git a/iptables-save.c b/iptables-save.c
index f648efae..282ca7f8 100644
--- a/iptables-save.c
+++ b/iptables-save.c
@@ -145,7 +145,7 @@ static void print_ip(char *prefix, u_int32_t ip, u_int32_t mask, int invert)
/* We want this to be readable, so only print out neccessary fields.
* Because that's the kind of world I want to live in. */
static void print_rule(const struct ipt_entry *e,
- iptc_handle_t *h, int counters)
+ iptc_handle_t *h, const char *chain, int counters)
{
struct ipt_entry_target *t;
@@ -153,6 +153,9 @@ static void print_rule(const struct ipt_entry *e,
if (counters)
printf("[%llu:%llu] ", e->counters.pcnt, e->counters.bcnt);
+ /* print chain name */
+ printf("-A %s ", chain);
+
/* Print IP part. */
print_ip("-s", e->ip.src.s_addr,e->ip.smsk.s_addr,
e->ip.invflags & IPT_INV_SRCIP);
@@ -246,12 +249,12 @@ static int do_output(const char *tablename)
NETFILTER_VERSION, ctime(&now));
printf("*%s\n", tablename);
- /* Dump out chain names */
+ /* Dump out chain names first,
+ * thereby preventing dependency conflicts */
for (chain = iptc_first_chain(&h);
chain;
chain = iptc_next_chain(&h)) {
- const struct ipt_entry *e;
-
+
printf(":%s ", chain);
if (iptc_builtin(chain, h)) {
struct ipt_counters count;
@@ -261,11 +264,18 @@ static int do_output(const char *tablename)
} else {
printf("- [0:0]\n");
}
+ }
+
+
+ for (chain = iptc_first_chain(&h);
+ chain;
+ chain = iptc_next_chain(&h)) {
+ const struct ipt_entry *e;
/* Dump out rules */
e = iptc_first_rule(chain, &h);
while(e) {
- print_rule(e, &h, counters);
+ print_rule(e, &h, chain, counters);
e = iptc_next_rule(e, &h);
}
}