* Return output of iptables directly instead of writing it to files. * Make iptables wait for 5s if xtables is locked by another iptables process. (--wait 5 argument) * Add optional parameter "-x" to have iptables report exact numbers. * Add optional parameter "-f" to display the filter table (default). * Add optional parameter "-n" to display the nat table. * Add optional parameter "-m" to display the mangle table. * Adapt iptables.cgi and guardian.cgi to catch getipstat output instead of reading temp-files.
Signed-off-by: Robin Roevens robin.roevens@disroot.org --- html/cgi-bin/guardian.cgi | 12 ++----- html/cgi-bin/iptables.cgi | 18 ++++------ src/misc-progs/getipstat.c | 67 +++++++++++++++++++++++++++++++++----- 3 files changed, 66 insertions(+), 31 deletions(-)
diff --git a/html/cgi-bin/guardian.cgi b/html/cgi-bin/guardian.cgi index fb16be00e..552c67211 100644 --- a/html/cgi-bin/guardian.cgi +++ b/html/cgi-bin/guardian.cgi @@ -829,12 +829,9 @@ sub GetBlockedHosts() { my @hosts;
# Launch helper to get chains from iptables. - system('/usr/local/bin/getipstat'); + open (FILE, '/usr/local/bin/getipstat | ');
- # Open temporary file which contains the chains and rules. - open (FILE, '/var/tmp/iptables.txt'); - - # Loop through the entire file. + # Loop through the entire output. while (<FILE>) { my $line = $_;
@@ -864,11 +861,6 @@ sub GetBlockedHosts() { # Close filehandle. close(FILE);
- # Remove recently created temporary files of the "getipstat" binary. - system("rm -f /var/tmp/iptables.txt"); - system("rm -f /var/tmp/iptablesmangle.txt"); - system("rm -f /var/tmp/iptablesnat.txt"); - # Convert entries, sort them, write back and store the sorted entries into new array. my @sorted = map { $_->[0] } sort { $a->[1] <=> $b->[1] } diff --git a/html/cgi-bin/iptables.cgi b/html/cgi-bin/iptables.cgi index b52d74fcf..f900562d9 100644 --- a/html/cgi-bin/iptables.cgi +++ b/html/cgi-bin/iptables.cgi @@ -44,8 +44,6 @@ my %cgiparams=();
&Header::getcgihash(%cgiparams);
-system('/usr/local/bin/getipstat'); - &Header::showhttpheaders(); &Header::openpage($Lang::tr{'ipts'}, 1, ''); &Header::openbigbox('100%', 'LEFT'); @@ -84,11 +82,11 @@ print <<END END ;
-# We´ll open the txt files and extract each line, if the line +# We´ll get iptables output and examine each line, if the line # start with an Chain the the name, start- and endline of the # chain is extracted into a hash
- open (FILE, '/var/tmp/iptables.txt'); + open (FILE, '/usr/local/bin/getipstat | '); while (<FILE>){
$iplines[$lines] = $_; @@ -206,11 +204,11 @@ print <<END END ;
-# We´ll open the txt files and extract each line, if the line +# We´ll get iptables output and examine each line, if the line # start with an Chain the the name, start- and endline of the # chain is extracted into a hash
- open (FILE, '/var/tmp/iptablesmangle.txt'); + open (FILE, '/usr/local/bin/getipstat -m | '); while (<FILE>){
$ipmlines[$manlines] = $_; @@ -333,11 +331,11 @@ print <<END END ;
-# We´ll open the txt files and extract each line, if the line +# We´ll get iptables output and examine each line, if the line # start with an Chain the the name, start- and endline of the # chain is extracted into a hash
- open (FILE, '/var/tmp/iptablesnat.txt'); + open (FILE, '/usr/local/bin/getipstat -n | '); while (<FILE>){
$ipnatlines[$natlines] = $_; @@ -433,7 +431,3 @@ print "</table></div><br />"; &Header::closebox(); &Header::closebigbox(); &Header::closepage(); - -system("rm -f /var/tmp/iptables.txt"); -system("rm -f /var/tmp/iptablesmangle.txt"); -system("rm -f /var/tmp/iptablesnat.txt"); diff --git a/src/misc-progs/getipstat.c b/src/misc-progs/getipstat.c index c806d54a9..99d053bbf 100644 --- a/src/misc-progs/getipstat.c +++ b/src/misc-progs/getipstat.c @@ -2,6 +2,15 @@ * * Get the list from IPTABLES -L * + * Optional commandline parameters: + * -x + * instruct iptables to expand numbers + * -f + * display filter table + * -n + * display nat table + * -m + * display mangle table */
#include <stdio.h> @@ -9,20 +18,60 @@ #include <unistd.h> #include <stdlib.h> #include <sys/types.h> -#include <fcntl.h> #include "setuid.h"
- -int main(void) +int main(int argc, char** argv) { + // Set defaults + // first argument has to be "iptables" since execve executes the program pointed to by filename + // but /sbin/iptables is actually a symlink to /sbin/xtables-legacy-multi hence that program is executed + // however without the notion that it was called as "iptables". So we have to pass "iptables" as first + // argument. + char *args[10] = {"iptables", "--list", "--verbose", "--numeric", "--wait", "5", NULL, NULL, NULL, NULL}; + char *usage = "getipstat [-x][-f|-n|-m]"; + unsigned int pcount = 6; + unsigned int table_set = 0; + + int opt; + if (!(initsetuid())) exit(1);
- safe_system("/sbin/iptables -L -v -n > /var/tmp/iptables.txt"); - safe_system("/sbin/iptables -L -v -n -t nat > /var/tmp/iptablesnat.txt"); - safe_system("/sbin/iptables -t mangle -L -v -n > /var/tmp/iptablesmangle.txt"); - safe_system("chown nobody.nobody /var/tmp/iptables.txt /var/tmp/iptablesnat.txt /var/tmp/iptablesmangle.txt"); - - return 0; + // Parse command line arguments + if (argc > 1) { + while ((opt = getopt(argc, argv, "xfnm")) != -1) { + switch(opt) { + case 'x': + args[pcount++] = "--exact"; + break; + case 'f': + table_set++; + break; + case 'n': + if (table_set == 0) { + args[pcount++] = "--table"; + args[pcount++] = "nat"; + } + table_set++; + break; + case 'm': + if (table_set == 0) { + args[pcount++] = "--table"; + args[pcount++] = "mangle"; + } + table_set++; + break; + default: + fprintf(stderr, "\nBad argument given.\n\n%s\n", usage); + exit(1); + } + } + if (table_set > 1) { + fprintf(stderr, "\nArguments -f/-n/-m are mutualy exclusive.\n\n%s\n", usage); + exit(1); + } + } + + return run("/sbin/iptables", args); }