summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--iptables-restore.85
-rw-r--r--iptables-restore.c29
-rw-r--r--iptables.88
-rw-r--r--iptables.c36
4 files changed, 58 insertions, 20 deletions
diff --git a/iptables-restore.8 b/iptables-restore.8
index 590015e3..4e4e1504 100644
--- a/iptables-restore.8
+++ b/iptables-restore.8
@@ -50,11 +50,6 @@ Expect this to be fixed in the next iptables release.
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.
-.PP
-.B iptables-restore
-does only restore the counter values of the builtin chains, and
-.B NOT
-the individual counters of each rule.
.SH AUTHOR
Harald Welte <laforge@gnumonks.org>
.SH SEE ALSO
diff --git a/iptables-restore.c b/iptables-restore.c
index 95b6d8ab..475f345b 100644
--- a/iptables-restore.c
+++ b/iptables-restore.c
@@ -3,6 +3,8 @@
* based on previous code from Rusty Russell <rusty@linuxcare.com.au>
*
* This coude is distributed under the terms of GNU GPL
+ *
+ * $Id$
*/
#include <getopt.h>
@@ -221,10 +223,10 @@ int main(int argc, char *argv[])
} else {
char *newargv[1024];
- int i,a;
+ int i,a, argvsize;
char *ptr = buffer;
- char *ctrs = NULL;
- struct ipt_counters count;
+ char *pcnt = NULL;
+ char *bcnt = NULL;
if (buffer[0] == '[') {
ptr = strchr(buffer, ']');
@@ -232,24 +234,27 @@ int main(int argc, char *argv[])
exit_error(PARAMETER_PROBLEM,
"Bad line %u: need ]\n",
line);
- ctrs = strtok(ptr, " \t\n");
- }
-
- if (counters && ctrs) {
-
- parse_counters(ctrs, &count);
+ pcnt = strtok(buffer+1, ":");
+ bcnt = strtok(NULL, "]");
}
- /* FIXME: Don't ignore counters. */
-
newargv[0] = argv[0];
newargv[1] = "-t";
newargv[2] = (char *) &curtable;
newargv[3] = "-A";
newargv[4] = (char *) &curchain;
+ argvsize = 5;
+
+ if (counters && pcnt && bcnt) {
+ newargv[5] = "--set-counters";
+ newargv[6] = (char *) pcnt;
+ newargv[7] = (char *) bcnt;
+ argvsize = 8;
+ }
/* strtok: a function only a coder could love */
- for (i = 5; i < sizeof(newargv)/sizeof(char *); i++) {
+ for (i = argvsize; i < sizeof(newargv)/sizeof(char *);
+ i++) {
if (!(newargv[i] = strtok(NULL, " \t\n")))
break;
ptr = NULL;
diff --git a/iptables.8 b/iptables.8
index 1b437ca4..1a7f8102 100644
--- a/iptables.8
+++ b/iptables.8
@@ -267,6 +267,14 @@ destination ports of such a packet (or ICMP type), such a packet will
not match any rules which specify them. When the "!" argument
precedes the "-f" flag, the rule will only match head fragments, or
unfragmented packets.
+.TP
+.B "-c, --set-counters " "PKTS BYTES"
+This enables the administrater to initialize the packet and byte
+counters of a rule (during
+.B INSERT,
+.B APPEND,
+.B REPLACE
+operations)
.SS "OTHER OPTIONS"
The following additional options can be specified:
.TP
diff --git a/iptables.c b/iptables.c
index 02c5c7af..c570d3af 100644
--- a/iptables.c
+++ b/iptables.c
@@ -95,9 +95,10 @@ static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
#define OPT_VIANAMEOUT 0x00100U
#define OPT_FRAGMENT 0x00200U
#define OPT_LINENUMBERS 0x00400U
-#define NUMBER_OF_OPT 11
+#define OPT_COUNTERS 0x00800U
+#define NUMBER_OF_OPT 12
static const char optflags[NUMBER_OF_OPT]
-= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', 'f', '3'};
+= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', 'f', '3', 'c'};
static struct option original_opts[] = {
{ "append", 1, 0, 'A' },
@@ -130,6 +131,7 @@ static struct option original_opts[] = {
{ "help", 2, 0, 'h' },
{ "line-numbers", 0, 0, '0' },
{ "modprobe", 1, 0, 'M' },
+ { "set-counters", 1, 0, 'c' },
{ 0 }
};
@@ -387,6 +389,7 @@ exit_printhelp(void)
" --exact -x expand numbers (display exact values)\n"
"[!] --fragment -f match second or further fragments only\n"
" --modprobe=<command> try to insert modules using this command\n"
+" --set-counters PKTS BYTES set the counter during insert/append\n"
"[!] --version -V print package version.\n");
/* Print out any special helps. A user might like to be able
@@ -1615,6 +1618,7 @@ int do_command(int argc, char *argv[], char **table, iptc_handle_t *handle)
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
unsigned int rulenum = 0, options = 0, command = 0;
+ const char *pcnt = NULL, *bcnt = NULL;
int ret = 1;
struct iptables_match *m;
struct iptables_target *target = NULL;
@@ -1646,7 +1650,7 @@ int do_command(int argc, char *argv[], char **table, iptc_handle_t *handle)
opterr = 0;
while ((c = getopt_long(argc, argv,
- "-A:C:D:R:I:L::F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:x",
+ "-A:C:D:R:I:L::F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:",
opts, NULL)) != -1) {
switch (c) {
/*
@@ -1926,6 +1930,32 @@ int do_command(int argc, char *argv[], char **table, iptc_handle_t *handle)
modprobe = optarg;
break;
+ case 'c':
+
+ set_option(&options, OPT_COUNTERS, &fw.ip.invflags,
+ invert);
+ pcnt = optarg;
+ if (optind < argc && argv[optind][0] != '-'
+ && argv[optind][0] != '!')
+ bcnt = argv[optind++];
+ else
+ exit_error(PARAMETER_PROBLEM,
+ "-%c requires packet and byte counter",
+ opt2char(OPT_COUNTERS));
+
+ if (sscanf(pcnt, "%llu", &fw.counters.pcnt) != 1)
+ exit_error(PARAMETER_PROBLEM,
+ "-%c packet counter not numeric",
+ opt2char(OPT_COUNTERS));
+
+ if (sscanf(bcnt, "%llu", &fw.counters.bcnt) != 1)
+ exit_error(PARAMETER_PROBLEM,
+ "-%c byte counter not numeric",
+ opt2char(OPT_COUNTERS));
+
+ break;
+
+
case 1: /* non option */
if (optarg[0] == '!' && optarg[1] == '\0') {
if (invert)