From b34c87cfa20f9c9dc75d341430baddb70ba1fb5f Mon Sep 17 00:00:00 2001 From: laforge Date: Tue, 23 Jan 2001 22:54:34 +0000 Subject: added 'iptables --set-counters' and fixed counter-restore in iptables-restore --- iptables-restore.8 | 5 ----- iptables-restore.c | 29 +++++++++++++++++------------ iptables.8 | 8 ++++++++ iptables.c | 36 +++++++++++++++++++++++++++++++++--- 4 files changed, 58 insertions(+), 20 deletions(-) diff --git a/iptables-restore.8 b/iptables-restore.8 index 590015e..4e4e150 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 .SH SEE ALSO diff --git a/iptables-restore.c b/iptables-restore.c index 95b6d8a..475f345 100644 --- a/iptables-restore.c +++ b/iptables-restore.c @@ -3,6 +3,8 @@ * based on previous code from Rusty Russell * * This coude is distributed under the terms of GNU GPL + * + * $Id$ */ #include @@ -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 1b437ca..1a7f810 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 02c5c7a..c570d3a 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= 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) -- cgit v1.2.3