From: <ow...@us...> - 2008-07-31 20:19:52
|
Revision: 1620 http://ipcop.svn.sourceforge.net/ipcop/?rev=1620&view=rev Author: owes Date: 2008-07-31 20:19:58 +0000 (Thu, 31 Jul 2008) Log Message: ----------- Use XML output from connection tracking. connections.cgi now shows traffic (packets and bytes) or status (1.4 style info). Modified Paths: -------------- ipcop/trunk/doc/Configuration-Files ipcop/trunk/html/cgi-bin/connections.cgi ipcop/trunk/src/misc-progs/conntrack_helper.c Modified: ipcop/trunk/doc/Configuration-Files =================================================================== --- ipcop/trunk/doc/Configuration-Files 2008-07-31 16:17:03 UTC (rev 1619) +++ ipcop/trunk/doc/Configuration-Files 2008-07-31 20:19:58 UTC (rev 1620) @@ -16,6 +16,7 @@ KEYMAP used keyboard map, for example /usr/share/kbd/keymaps/i386/qwertz/de.map.gz LANGUAGE short language name, for example de TIMEZONE used timezone, for example /usr/share/zoneinfo/posix/Europe/Berlin + DISPLAY_CONNECTIONS display style for connections.cgi, TRAFFIC or STATUS ================================================================================ Modified: ipcop/trunk/html/cgi-bin/connections.cgi =================================================================== --- ipcop/trunk/html/cgi-bin/connections.cgi 2008-07-31 16:17:03 UTC (rev 1619) +++ ipcop/trunk/html/cgi-bin/connections.cgi 2008-07-31 20:19:58 UTC (rev 1620) @@ -22,6 +22,8 @@ # # (c) 2006 Franck - add sorting+filtering capability # +# (c) 2008 Olaf for the IPCop team - use conntrack with XML output from conntrack-tools +# # $Id$ # @@ -32,30 +34,42 @@ my @routes=(); my @colour=(); -use Net::IPv4Addr qw( :all ); - use strict; # enable only the following on debugging purpose -#use warnings; -#use CGI::Carp 'fatalsToBrowser'; +use warnings; no warnings 'once'; +use CGI::Carp 'fatalsToBrowser'; +use Net::IPv4Addr qw( :all ); +use XML::Simple; +use XML::Parser::Style::Tree; + require '/var/ipcop/general-functions.pl'; require '/var/ipcop/lang.pl'; require '/var/ipcop/header.pl'; -#workaround to suppress a warning when a variable is used only once -my @dummy = ( ${Header::table1colour} ); -undef (@dummy); - my $icount = 0; # Read various files my %netsettings=(); &General::readhash('/var/ipcop/ethernet/settings', \%netsettings); +my %mainsettings=(); +$mainsettings{'DISPLAY_CONNECTIONS'} = 'TRAFFIC'; +&General::readhash('/var/ipcop/main/settings',\%mainsettings); +my %cgiparams=(); +$cgiparams{'ACTION'} = ''; +&General::getcgihash(\%cgiparams); +# Fetch connection tracking info in XML format my @active = `/usr/local/bin/conntrack_helper`; + +if ( $cgiparams{'ACTION'} eq 'SAVE' ) { + $mainsettings{'DISPLAY_CONNECTIONS'} = $cgiparams{'DISPLAY_CONNECTIONS'}; + &General::writehash('/var/ipcop/main/settings', \%mainsettings); +} + + my $aliasfile = '/var/ipcop/ethernet/aliases'; open(ALIASES, $aliasfile) or die 'Unable to open aliases file.'; my @aliases = <ALIASES>; @@ -184,12 +198,16 @@ $cgiparams{'SEE_SORT'} = ''; &General::getcgihash(\%cgiparams); +&Header::showhttpheaders(); +&Header::openpage($Lang::tr{'connections'}, 1, ''); +&Header::openbigbox('100%', 'left'); + my @list_proto = ($Lang::tr{'all'}, 'icmp', 'udp', 'tcp'); my @list_state = ($Lang::tr{'all'}, 'SYN_SENT', 'SYN_RECV', 'ESTABLISHED', 'FIN_WAIT', 'CLOSE_WAIT', 'LAST_ACK', 'TIME_WAIT', 'CLOSE', 'LISTEN'); my @list_mark = ($Lang::tr{'all'}, '[ASSURED]', '[UNREPLIED]'); my @list_sort = ('orgsip','protocol', 'expires', 'status', 'orgdip', 'orgsp', - 'orgdp', 'exsip', 'exdip', 'exsp', 'exdp', 'marked'); + 'orgdp', 'repsip', 'repdip', 'repsp', 'repdp', 'marked'); # init or silently correct unknown value... if ( ! grep ( /^$cgiparams{'SEE_PROTO'}$/ , @list_proto )) { $cgiparams{'SEE_PROTO'} = $list_proto[0] }; @@ -208,107 +226,59 @@ my $unknownlines = ''; # should be empty all the time... my $index = 0; # just a counter to make unique entryies in entries -foreach my $line (@active) { - my $protocol=''; - my $expires=''; - my $status=''; - my $orgsip=''; - my $orgdip=''; - my $orgsp=''; - my $orgdp=''; - my $exsip=''; - my $exdip=''; - my $exsp=''; - my $exdp=''; - my $marked=''; - my $use=''; - my $extraline=''; - +foreach my $line (@active) +{ chomp($line); - my @temp = split(' ',$line); + my $xml = new XML::Simple; + my $data = $xml->XMLin($line); - - if ( ($temp[0] eq 'ipv4') && ($temp[2] eq 'udp') ) { - my $offset = 0; - $marked = ''; - $protocol = $temp[2]; - $expires = $temp[4]; - $status = ' '; - $orgsip = substr $temp[5], 4; - $orgdip = substr $temp[6], 4; - $orgsp = substr $temp[7], 6; - $orgdp = substr $temp[8], 6; - if ($temp[11] eq '[UNREPLIED]') { - $offset = 1; - $marked = $temp[11]; - $use = substr $temp[19], 4; - } else { - if ((substr $temp[17], 0, 3) eq 'use' ) { - $marked = ''; - $use = substr $temp[17], 4; - } else { - $marked = $temp[17]; - $use = substr $temp[18], 4; - } + foreach my $elt ( @{$data->{meta}} ) + { + if ( $elt->{direction} eq 'original' ) + { + $entries{$index}->{protocol} = $elt->{layer4}->{protoname}; + $entries{$index}->{orgsip} = $elt->{layer3}->{src}; + $entries{$index}->{orgdip} = $elt->{layer3}->{dst}; + $entries{$index}->{orgsp} = $elt->{layer4}->{sport}; + $entries{$index}->{orgdp} = $elt->{layer4}->{dport}; + $entries{$index}->{orgtraf} = $elt->{counters}->{packets}." / ".$elt->{counters}->{bytes}; } - $exsip = substr $temp[11 + $offset], 4; - $exdip = substr $temp[12 + $offset], 4; - $exsp = substr $temp[13 + $offset], 6; - $exdp = substr $temp[14 + $offset], 6; - - $extraline = "$temp[9] $temp[10] , $temp[15+$offset] $temp[16+$offset]"; - } - elsif ( ($temp[0] eq 'ipv4') && ($temp[2] eq 'tcp') ) { - my $offset = 0; - $protocol = $temp[2]; - $expires = $temp[4]; - $status = $temp[5]; - $orgsip = substr $temp[6], 4; - $orgdip = substr $temp[7], 4; - $orgsp = substr $temp[8], 6; - $orgdp = substr $temp[9], 6; - if ($temp[12] eq '[UNREPLIED]') { - $marked = $temp[0]; - $offset = 1; - } else { - $marked = $temp[18]; + elsif ( $elt->{direction} eq 'reply' ) + { + $entries{$index}->{repsip} = $elt->{layer3}->{src}; + $entries{$index}->{repdip} = $elt->{layer3}->{dst}; + $entries{$index}->{repsp} = $elt->{layer4}->{sport}; + $entries{$index}->{repdp} = $elt->{layer4}->{dport}; + $entries{$index}->{reptraf} = $elt->{counters}->{packets}." / ".$elt->{counters}->{bytes}; } - $exsip = substr $temp[12 + $offset], 4; - $exdip = substr $temp[13 + $offset], 4; - $exsp = substr $temp[14 + $offset], 6; - $exdp = substr $temp[15 + $offset], 6; - $use = substr $temp[20], 4; - - $extraline = "$temp[10] $temp[11] , $temp[16+$offset] $temp[17+$offset]"; + elsif ( $elt->{direction} eq 'independent' ) + { + for my $key ( keys %{$elt} ) + { + if ( $key eq 'timeout' ) + { + $entries{$index}->{expires} = ${$elt}{$key}; + } + elsif ( $key eq 'mark' ) + { + $entries{$index}->{marked} = ${$elt}{$key}; + } + elsif ( $key eq 'use' ) + { + $entries{$index}->{use} = ${$elt}{$key}; + } + elsif ( ($key eq 'id') || ($key eq 'direction') ) + { + } + else + { + $entries{$index}->{status} = $key; + } + } + } } - # Only from this point, lines have the same known format/field - # The floating fields [UNREPLIED] [ASSURED] etc are ok. - - # Store the line in a hash array for sorting - if ( $protocol ) { # line is decoded ? - my @record = ( 'index', $index++, - 'extra', $extraline, - 'protocol', $protocol, - 'expires', $expires, - 'status', $status, - 'orgsip', $orgsip, - 'orgdip', $orgdip, - 'orgsp', $orgsp, - 'orgdp', $orgdp, - 'exsip', $exsip, - 'exdip', $exdip, - 'exsp', $exsp, - 'exdp', $exdp, - 'marked', $marked, - 'use', $use); - my $record = {}; # create a reference to empty hash - %{$record} = @record; # populate that hash with @record - $entries{$record->{index}} = $record; # add this to a hash of hashes - } else { # it was not a known line - $unknownlines .= "<tr bgcolor='${Header::table1colour}'>"; - $unknownlines .= "<td colspan='9'> unknown:$line</td></tr>"; - } + $index++; } # Build listbox objects @@ -319,33 +289,90 @@ my $menu_mark = &make_select ('SEE_MARK', $cgiparams{'SEE_MARK'}, @list_mark); my $menu_sort = &make_select ('SEE_SORT', $cgiparams{'SEE_SORT'}, @list_sort); -&Header::showhttpheaders(); -&Header::openpage($Lang::tr{'connections'}, 1, ''); -&Header::openbigbox('100%', 'left'); &Header::openbox('100%', 'left', $Lang::tr{'connection tracking'}); +my %selected = (); +$selected{'TRAFFIC'} = ''; +$selected{'STATUS'} = ''; +$selected{$mainsettings{'DISPLAY_CONNECTIONS'}} = "selected='selected'"; + print <<END <form method='post' action='$ENV{'SCRIPT_NAME'}'> -<table width='60%'> -<tr><td align='center'><b>$Lang::tr{'legend'} : </b></td> - <td align='center' class='ipcop_iface_bg_green'><b>$Lang::tr{'lan'}</b></td> - <td align='center' class='ipcop_iface_bg_red'><b>$Lang::tr{'internet'}</b></td> - <td align='center' class='ipcop_iface_bg_blue'><b>$Lang::tr{'wireless'}</b></td> - <td align='center' class='ipcop_iface_bg_orange'><b>$Lang::tr{'dmz'}</b></td> - <td align='center' class='ipcop_iface_bg_fw'><b>IPCop</b></td> - <td align='center' class='ipcop_iface_bg_ipsec'><b>IPsec</b></td> - <td align='center' class='ipcop_iface_bg_ovpn'><b>OpenVPN</b></td> +<table width='100%'><tr> + <td width='25%' class='base'>$Lang::tr{'display'}:</td> + <td width='25%'><select name='DISPLAY_CONNECTIONS'><option value='TRAFFIC' $selected{'TRAFFIC'}>$Lang::tr{'traffic'}</option><option value='STATUS' $selected{'STATUS'}>$Lang::tr{'status'}</option></select></td> + <td width='25%'> </td> + <td width='25%'> </td> +</tr></table><table width='100%'><tr> + <td class='base' width='55%'> </td> + <td width='40%' align='center'><input type='hidden' name='ACTION' value='SAVE' /><input type='submit' name='SUBMIT' value='$Lang::tr{'save'}' /></td> + <td width='5%' align='right'> + <a href='${General::adminmanualurl}/status.html#connections' target='_blank'> + <img src='/images/web-support.png' alt='$Lang::tr{'online help en'}' title='$Lang::tr{'online help en'}' /></a></td> +</tr></table> +</form> +<hr /> +END +; + + +if ( $mainsettings{'DISPLAY_CONNECTIONS'} eq 'TRAFFIC' ) +{ +print <<END +<table cellpadding='2'> +<tr><td align='center'><b>$Lang::tr{'protocol'}</b></td> + <td align='center'><b>$Lang::tr{'original'}<br />$Lang::tr{'source ip and port'}</b></td> + <td align='center'><b>$Lang::tr{'original'}<br />$Lang::tr{'dest ip and port'}</b></td> + <td align='center'><b>$Lang::tr{'packets'} / $Lang::tr{'bytes'}</b></td> + <td align='center'><b>$Lang::tr{'reply'}<br />$Lang::tr{'source ip and port'}</b></td> + <td align='center'><b>$Lang::tr{'reply'}<br />$Lang::tr{'dest ip and port'}</b></td> + <td align='center'><b>$Lang::tr{'packets'} / $Lang::tr{'bytes'}</b></td> </tr> -</table> -<br /> +END +; + +foreach my $entry (sort sort_entries keys %entries) { + my $orgsipcolour = &ipcolour( $entries{$entry}->{orgsip} ); + my $orgdipcolour = &ipcolour( $entries{$entry}->{orgdip} ); + my $repsipcolour = &ipcolour( $entries{$entry}->{repsip} ); + my $repdipcolour = &ipcolour( $entries{$entry}->{repdip} ); + print <<END + <tr class='table1colour'> + <td align='center'>$entries{$entry}->{protocol}</td> + <td align='center' class='$orgsipcolour'> + <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{orgsip}' class='$orgsipcolour'> + $entries{$entry}->{orgsip} + </a>:$entries{$entry}->{orgsp}</td> + <td align='center' class='$orgdipcolour'> + <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{orgdip}' class='$orgdipcolour'> + $entries{$entry}->{orgdip} + </a>:$entries{$entry}->{orgdp}</td> + <td align='center'>$entries{$entry}->{orgtraf}</td> + <td align='center' class='$repsipcolour'> + <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{repsip}' class='$repsipcolour'> + $entries{$entry}->{repsip} + </a>:$entries{$entry}->{repsp}</td> + <td align='center' class='$repdipcolour'> + <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{repdip}' class='$repdipcolour'> + $entries{$entry}->{repdip} + </a>:$entries{$entry}->{repdp}</td> + <td align='center'>$entries{$entry}->{reptraf}</td> + </tr> +END +; +} +} +else +{ +print <<END <table cellpadding='2'> <tr><td align='center'><b>$Lang::tr{'protocol'}</b></td> + <td align='center'><b>$Lang::tr{'original'}<br />$Lang::tr{'source ip and port'}</b></td> + <td align='center'><b>$Lang::tr{'original'}<br />$Lang::tr{'dest ip and port'}</b></td> + <td align='center'><b>$Lang::tr{'reply'}<br />$Lang::tr{'source ip and port'}</b></td> + <td align='center'><b>$Lang::tr{'reply'}<br />$Lang::tr{'dest ip and port'}</b></td> <td align='center'><b>$Lang::tr{'expires'}<br />($Lang::tr{'seconds'})</b></td> <td align='center'><b>$Lang::tr{'connection'}<br />$Lang::tr{'status'}</b></td> - <td align='center'><b>$Lang::tr{'original'}<br />$Lang::tr{'source ip and port'}</b></td> - <td align='center'><b>$Lang::tr{'original'}<br />$Lang::tr{'dest ip and port'}</b></td> - <td align='center'><b>$Lang::tr{'expected'}<br />$Lang::tr{'source ip and port'}</b></td> - <td align='center'><b>$Lang::tr{'expected'}<br />$Lang::tr{'dest ip and port'}</b></td> <td align='center'><b>$Lang::tr{'marked'}</b></td> <td align='center'><b>$Lang::tr{'use'}</b></td> </tr> @@ -355,13 +382,11 @@ foreach my $entry (sort sort_entries keys %entries) { my $orgsipcolour = &ipcolour( $entries{$entry}->{orgsip} ); my $orgdipcolour = &ipcolour( $entries{$entry}->{orgdip} ); - my $exsipcolour = &ipcolour( $entries{$entry}->{exsip} ); - my $exdipcolour = &ipcolour( $entries{$entry}->{exdip} ); + my $repsipcolour = &ipcolour( $entries{$entry}->{repsip} ); + my $repdipcolour = &ipcolour( $entries{$entry}->{repdip} ); print <<END <tr class='table1colour'> <td align='center'>$entries{$entry}->{protocol}</td> - <td align='center'>$entries{$entry}->{expires}</td> - <td align='center'>$entries{$entry}->{status}</td> <td align='center' class='$orgsipcolour'> <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{orgsip}' class='$orgsipcolour'> $entries{$entry}->{orgsip} @@ -370,26 +395,39 @@ <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{orgdip}' class='$orgdipcolour'> $entries{$entry}->{orgdip} </a>:$entries{$entry}->{orgdp}</td> - <td align='center' class='$exsipcolour'> - <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{exsip}' class='$exsipcolour'> - $entries{$entry}->{exsip} - </a>:$entries{$entry}->{exsp}</td> - <td align='center' class='$exdipcolour'> - <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{exdip}' class='$exdipcolour'> - $entries{$entry}->{exdip} - </a>:$entries{$entry}->{exdp}</td> + <td align='center' class='$repsipcolour'> + <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{repsip}' class='$repsipcolour'> + $entries{$entry}->{repsip} + </a>:$entries{$entry}->{repsp}</td> + <td align='center' class='$repdipcolour'> + <a href='/cgi-bin/ipinfo.cgi?ip=$entries{$entry}->{repdip}' class='$repdipcolour'> + $entries{$entry}->{repdip} + </a>:$entries{$entry}->{repdp}</td> + <td align='center'>$entries{$entry}->{expires}</td> + <td align='center'>$entries{$entry}->{status}</td> <td align='center'>$entries{$entry}->{marked}</td> <td align='center'>$entries{$entry}->{use}</td> </tr> END ; - if ( $entries{$entry}->{extra} ne '' ) - { - print "<tr><td colspan='9'>$entries{$entry}->{extra}</td></tr>"; - } } +} -print "$unknownlines</table></form>"; +print <<END +</table> +<hr /> +<table width='60%'><tr> + <td align='center'><b>$Lang::tr{'legend'}: </b></td> + <td align='center' class='ipcop_iface_bg_green'><b>$Lang::tr{'lan'}</b></td> + <td align='center' class='ipcop_iface_bg_red'><b>$Lang::tr{'internet'}</b></td> + <td align='center' class='ipcop_iface_bg_blue'><b>$Lang::tr{'wireless'}</b></td> + <td align='center' class='ipcop_iface_bg_orange'><b>$Lang::tr{'dmz'}</b></td> + <td align='center' class='ipcop_iface_bg_fw'><b>IPCop</b></td> + <td align='center' class='ipcop_iface_bg_ipsec'><b>IPsec</b></td> + <td align='center' class='ipcop_iface_bg_ovpn'><b>OpenVPN</b></td> +</tr></table> +END +; &Header::closebox(); &Header::closebigbox(); @@ -413,7 +451,7 @@ # param1: name # param2: current value selected # param3: field list -sub make_select ($,$,$) { +sub make_select () { my $select_name = shift; my $selected = shift; my $select = "<select name='$select_name'>"; @@ -445,14 +483,14 @@ # Used to sort the table containing the lines displayed. sub sort_entries { #Reverse is not implemented my $qs=$cgiparams{'SEE_SORT'}; - if ($qs =~ /orgsip|orgdip|exsip|exdip/) { + if ($qs =~ /orgsip|orgdip|repsip|repdip/) { my @a = split(/\./,$entries{$a}->{$qs}); my @b = split(/\./,$entries{$b}->{$qs}); ($a[0]<=>$b[0]) || ($a[1]<=>$b[1]) || ($a[2]<=>$b[2]) || ($a[3]<=>$b[3]); - } elsif ($qs =~ /expire|orgsp|orgdp|exsp|exdp/) { + } elsif ($qs =~ /expire|orgsp|orgdp|repsp|repdp/) { $entries{$a}->{$qs} <=> $entries{$b}->{$qs}; } else { $entries{$a}->{$qs} cmp $entries{$b}->{$qs}; Modified: ipcop/trunk/src/misc-progs/conntrack_helper.c =================================================================== --- ipcop/trunk/src/misc-progs/conntrack_helper.c 2008-07-31 16:17:03 UTC (rev 1619) +++ ipcop/trunk/src/misc-progs/conntrack_helper.c 2008-07-31 20:19:58 UTC (rev 1620) @@ -29,7 +29,7 @@ if ( !(initsetuid()) ) exit(1); - safe_system("/usr/sbin/conntrack -L -o extended"); + safe_system("/usr/sbin/conntrack -L -o xml 2>/dev/null"); return(0); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |