From 8b68ed1226c6dd9b352bb157a6a1c5ce7cb7ef82 Mon Sep 17 00:00:00 2001 From: Robin Roevens Date: Tue, 27 Apr 2021 22:07:32 +0200 Subject: [PATCH] misc-progs: getipstat: Refactor + extend * 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 Signed-off-by: Michael Tremer --- 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 fb16be00e9..552c672111 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 () { 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 b52d74fcfb..f900562d9e 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 <){ $iplines[$lines] = $_; @@ -206,11 +204,11 @@ print <){ $ipmlines[$manlines] = $_; @@ -333,11 +331,11 @@ print <){ $ipnatlines[$natlines] = $_; @@ -433,7 +431,3 @@ print "
"; &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 c806d54a9b..99d053bbf8 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 @@ -9,20 +18,60 @@ #include #include #include -#include #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); } -- 2.39.2