From: Kay-Michael Köhler Date: Fri, 26 Apr 2013 10:21:08 +0000 (+0200) Subject: Make connection tracking list sortable. X-Git-Url: http://git.ipfire.org/?p=people%2Fteissler%2Fipfire-2.x.git;a=commitdiff_plain;h=9b37e91ef6dfd93a257bf1ee802b1919e30d0f74 Make connection tracking list sortable. --- diff --git a/config/rootfiles/common/stage2 b/config/rootfiles/common/stage2 index e10c649b1..1e91b3743 100644 --- a/config/rootfiles/common/stage2 +++ b/config/rootfiles/common/stage2 @@ -71,6 +71,7 @@ usr/lib/libstdc++.so.6 #usr/local/bin/archive.files usr/local/bin/backupiso usr/local/bin/connscheduler +usr/local/bin/consort.sh usr/local/bin/dialctrl.pl usr/local/bin/hddshutdown usr/local/bin/httpscert diff --git a/html/cgi-bin/connections.cgi b/html/cgi-bin/connections.cgi index 1edf3e5d4..d566cf7eb 100644 --- a/html/cgi-bin/connections.cgi +++ b/html/cgi-bin/connections.cgi @@ -34,6 +34,31 @@ require "${General::swroot}/header.pl"; my $colour_multicast = "#A0A0A0"; +# sort arguments for connection tracking table +# the sort field. eg. 1=src IP, 2=dst IP, 3=src port, 4=dst port +my $SORT_FIELD = 0; +# the sort order. (a)scending orr (d)escending +my $SORT_ORDER = 0; +# cgi query arguments +my %cgiin; +# debug mode +my $debug = 0; + +# retrieve query arguments +# note: let a-z A-Z and 0-9 pass as value only +if (length ($ENV{'QUERY_STRING'}) > 0){ + my $name; + my $value; + my $buffer = $ENV{'QUERY_STRING'}; + my @pairs = split(/&/, $buffer); + foreach my $pair (@pairs){ + ($name, $value) = split(/=/, $pair); + $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # e.g. "%20" => " " + $value =~ s/[^a-zA-Z0-9]*//g; # a-Z 0-9 will pass + $cgiin{$name} = $value; + } +} + &Header::showhttpheaders(); my @network=(); @@ -43,12 +68,40 @@ my @colour=(); my %netsettings=(); &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); +# output cgi query arrguments to browser on debug +if ( $debug ){ + &Header::openbox('100%', 'center', 'DEBUG'); + my $debugCount = 0; + foreach my $line (sort keys %cgiin) { + print "$line = '$cgiin{$line}'
\n"; + $debugCount++; + } + print " Count: $debugCount\n"; + &Header::closebox(); +} + #workaround to suppress a warning when a variable is used only once my @dummy = ( ${Header::table1colour} ); undef (@dummy); -# Read the connection tracking table. -open(CONNTRACK, "/usr/local/bin/getconntracktable | sort -k 5,5 --numeric-sort --reverse |") or die "Unable to read conntrack table"; +# check sorting arguments +if ( $cgiin{'sort_field'} ~~ [ '1','2','3','4','5','6','7','8','9' ] ) { + $SORT_FIELD = $cgiin{'sort_field'}; + + if ( $cgiin{'sort_order'} ~~ [ 'a','d','A','D' ] ) { + $SORT_ORDER = lc($cgiin{'sort_order'}); + } +} + +# Read and sort the connection tracking table +# do sorting +if ($SORT_FIELD and $SORT_ORDER) { + # field sorting when sorting arguments are sane + open(CONNTRACK, "/usr/local/bin/getconntracktable | /usr/local/bin/consort.sh $SORT_FIELD $SORT_ORDER |") or die "Unable to read conntrack table"; +} else { + # default sorting with no query arguments + open(CONNTRACK, "/usr/local/bin/getconntracktable | sort -k 5,5 --numeric-sort --reverse |") or die "Unable to read conntrack table"; +} my @conntrack = ; close(CONNTRACK); @@ -263,21 +316,81 @@ print < END +if ($SORT_FIELD and $SORT_ORDER) { + my @sort_field_name = ( + $Lang::tr{'source ip'}, + $Lang::tr{'destination ip'}, + $Lang::tr{'source port'}, + $Lang::tr{'destination port'}, + $Lang::tr{'protocol'}, + $Lang::tr{'connection'}.' '.$Lang::tr{'status'}, + $Lang::tr{'expires'}.' ('.$Lang::tr{'seconds'}.')', + $Lang::tr{'download'}, + $Lang::tr{'upload'} + ); + my $sort_order_name; + if (lc($SORT_ORDER) eq "a") { + $sort_order_name = $Lang::tr{'sort ascending'}; + } else { + $sort_order_name = $Lang::tr{'sort descending'}; + } + +print < + $sort_order_name: $sort_field_name[$SORT_FIELD-1] + +END +; +} + # Print table header. print < - + - $Lang::tr{'protocol'} + + + + + + +          + + + + + + +        + + - $Lang::tr{'source ip and port'} + + +      + + + + + + -   + + + + + + + $Lang::tr{'protocol'} + + + $Lang::tr{'source ip and port'} + + $Lang::tr{'dest ip and port'} -   $Lang::tr{'download'} /
$Lang::tr{'upload'} diff --git a/src/scripts/consort.sh b/src/scripts/consort.sh new file mode 100644 index 000000000..1682f7ac4 --- /dev/null +++ b/src/scripts/consort.sh @@ -0,0 +1,158 @@ +#/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007-2013 IPFire Team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +# sort conntrack table entries based on ip addresses +# @parm sort field +do_ip_sort() { + sed \ + -r \ + 's/.*src=([0-9\.]+).*dst=([0-9\.]+).*src=.*/\'$1'#\0/' $FILE_NAME \ + | sort \ + -t. \ + -k 1,1n$SORT_ORDER -k 2,2n$SORT_ORDER -k 3,3n$SORT_ORDER -k 4,4n$SORT_ORDER \ + | sed \ + -r \ + 's/.*#(.*)/\1/' +} + +# sort conntrack table entries based on port addresses +# @parm sort field +do_port_sort() { + sed \ + -r \ + 's/.*sport=([0-9]+).*dport=([0-9]+).*src=.*/\'$1'#\0/' $FILE_NAME \ + | sort \ + -t# \ + -k 1,1n$SORT_ORDER \ + | sed \ + -r \ + 's/.*#(.*)/\1/' +} + +# sort conntrack table entries based on protocol +do_protocol_sort() { + sed \ + -r \ + 's/^[0-9a-zA-Z]+[ ]+[0-9]+[ ]+([a-zA-Z0-9]+)/\1#\0/' $FILE_NAME \ + | sort \ + -t# \ + -k 1,1$SORT_ORDER \ + | sed \ + -r \ + 's/.*#(.*)/\1/' +} + +# sort conntrack table entries based on connection status +do_status_sort() { + sed \ + -r \ + 's/^[0-9a-zA-Z]+[ ]+[0-9]+[ ]+[a-zA-Z0-9]+[ ]+[0-9]+[ ]+[0-9]+[ ]+([a-zA-Z_0-9]+)[ ]+|^[0-9a-zA-Z]+[ ]+[0-9]+[ ]+[a-zA-Z0-9]+[ ]+[0-9]+[ ]+[0-9]+([ ]+)/\1#\0/' $FILE_NAME \ + | sort \ + -t# \ + -k 1,1$SORT_ORDER \ + | sed \ + -r \ + 's/.*#(.*)/\1/' +} + +# sort conntrack table entries based on connection time to life +do_ttl_sort() { + sed \ + -r \ + 's/^[0-9a-zA-Z]+[ ]+[0-9]+[ ]+[a-zA-Z0-9]+[ ]+[0-9]+[ ]+([0-9]+)[ ]+/\1#\0/' $FILE_NAME \ + | sort \ + -t# \ + -k 1,1n$SORT_ORDER \ + | sed \ + -r \ + 's/.*#(.*)/\1/' +} + +# sort conntrack table entries based on downloaded bytes +do_downloaded_bytes_sort() { + sed \ + -r \ + 's/.*src=.*bytes=([0-9]+).*src=/\1#\0/' $FILE_NAME \ + | sort \ + -t# \ + -k 1,1n$SORT_ORDER \ + | sed \ + -r \ + 's/.*#(.*)/\1/' +} + +# sort conntrack table entries based on uploaded bytes +do_uploaded_bytes_sort() { + sed \ + -r \ + 's/.*src=.*bytes=([0-9]+).*/\1#\0/' $FILE_NAME \ + | sort \ + -t# \ + -k 1,1n$SORT_ORDER \ + | sed \ + -r \ + 's/.*#(.*)/\1/' +} + +SORT_ORDER= +FILE_NAME= + +if [ $# -lt 2 ]; then + echo "Usage: consort [input file]" + echo " consort.sh 1 a a.txt" + echo " cat a.txt | consort 1 d" + exit; +fi + +if [[ 'a d A D' =~ $2 ]]; then + if [[ 'd D' =~ $2 ]]; then + SORT_ORDER=r + fi +else + echo "Unknown sort order \"$2\"" + exit; +fi + +if [ $# == 3 ]; then + if [ ! -f $3 ]; then + echo "File not found." + exit; + fi + FILE_NAME=$3 +fi + +if [[ '1 2' =~ $1 ]]; then + do_ip_sort $1 +elif [[ '3 4' =~ $1 ]]; then + do_port_sort $(($1-2)) +elif [[ '5' =~ $1 ]]; then + do_protocol_sort +elif [[ '6' =~ $1 ]]; then + do_status_sort +elif [[ '7' =~ $1 ]]; then + do_ttl_sort +elif [[ '8' =~ $1 ]]; then + do_downloaded_bytes_sort +elif [[ '9' =~ $1 ]]; then + do_uploaded_bytes_sort +else + echo "Unknown sort criteria \"$1\"" +fi