]> git.ipfire.org Git - ipfire-2.x.git/commitdiff
Update connections.cgi: Show byte counters.
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 18 Jul 2012 10:21:23 +0000 (12:21 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 18 Jul 2012 10:21:23 +0000 (12:21 +0200)
The connections.cgi file has been rewritten to read
the needed information directly from the kernel.

Byte counters have been added which show how much data
has been transmitted over one connection in each
direction.

config/rootfiles/common/misc-progs
config/rootfiles/core/61/filelists/files
html/cgi-bin/connections.cgi
src/misc-progs/Makefile
src/misc-progs/getconntracktable.c [new file with mode: 0644]

index adab51bc1eea62f39c70c0e8101a43476534b5ed..3c0b398d3aaf3270193dae2d9299103c12f14bb1 100644 (file)
@@ -5,6 +5,7 @@ usr/local/bin/backupctrl
 usr/local/bin/dhcpctrl
 usr/local/bin/extrahdctrl
 usr/local/bin/fireinfoctrl
+usr/local/bin/getconntracktable
 usr/local/bin/getipstat
 usr/local/bin/getiptstate
 #usr/local/bin/iowrap
index 1624d83b54cff03f690c77b9e490c4ee9c1cda36..9d4c2cc98e3a3ae325abef331fa643abde14039c 100644 (file)
@@ -7,4 +7,5 @@ srv/web/ipfire/cgi-bin/ovpnmain.cgi
 srv/web/ipfire/cgi-bin/proxy.cgi
 var/ipfire/general-functions.pl
 var/ipfire/langs
+usr/local/bin/getconntracktable
 usr/sbin/redirect_wrapper
index 14ee20910509b0e9633e6b5d586039d7cda7d12e..54089d0bbc6ebd6b684957a07ea8f46dbbf3a03e 100644 (file)
@@ -2,7 +2,7 @@
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2007-2011  IPFire Team  <info@ipfire.org>                     #
+# Copyright (C) 2007-2012  IPFire Team  <info@ipfire.org>                     #
 #                                                                             #
 # 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        #
 #                                                                             #
 ###############################################################################
 
-my @network=();
-my @masklen=();
-my @colour=();
+use strict;
 
 use Net::IPv4Addr qw( :all );
-
-use strict;
+use Switch;
 
 # enable only the following on debugging purpose
 #use warnings;
@@ -35,42 +32,62 @@ require '/var/ipfire/general-functions.pl';
 require "${General::swroot}/lang.pl";
 require "${General::swroot}/header.pl";
 
+&Header::showhttpheaders();
+
+my @network=();
+my @masklen=();
+my @colour=();
+
+my %netsettings=();
+&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
+
 #workaround to suppress a warning when a variable is used only once
 my @dummy = ( ${Header::table1colour} );
 undef (@dummy);
 
-# Read various files
+# 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";
+my @conntrack = <CONNTRACK>;
+close(CONNTRACK);
 
-my %netsettings=();
-&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
+# Collect data for the @network array.
 
-open (ACTIVE, '/usr/local/bin/getiptstate |') or die 'Unable to open ip_conntrack';
-my @active = <ACTIVE>;
-close (ACTIVE);
+# Add Firewall Localhost 127.0.0.1
+push(@network, '127.0.0.1');
+push(@masklen, '255.255.255.255');
+push(@colour, ${Header::colourfw});
 
 if (open(IP, "${General::swroot}/red/local-ipaddress")) {
-        my $redip = <IP>;
-        close(IP);
-        chomp $redip;
-        push(@network, $redip);
-        push(@masklen, '255.255.255.255' );
-        push(@colour, ${Header::colourfw} );
+       my $redip = <IP>;
+       close(IP);
+
+       chomp $redip;
+       push(@network, $redip);
+       push(@masklen, '255.255.255.255');
+       push(@colour, ${Header::colourfw});
 }
 
-my @vpn = `/usr/local/bin/ipsecctrl I 2>/dev/null|grep erouted|cut -d"]" -f3|cut -d"=" -f4|cut -d";" -f1| sed "s|/| |g"`;
-  foreach my $route (@vpn) {
-                chomp($route);
-                my @temp = split(/[\t ]+/, $route);
-                if ( $temp[0] eq '$redip' ){next;}
-                push(@network, $temp[0]);
-                push(@masklen, $temp[1]);
-                push(@colour, ${Header::colourvpn} );
-        }
-
-my $aliasfile = "${General::swroot}/ethernet/aliases";
-open(ALIASES, $aliasfile) or die 'Unable to open aliases file.';
-my @aliases = <ALIASES>;
-close(ALIASES);
+# Add STATIC RED aliases
+if ($netsettings{'RED_DEV'}) {
+       my $aliasfile = "${General::swroot}/ethernet/aliases";
+       open(ALIASES, $aliasfile) or die 'Unable to open aliases file.';
+       my @aliases = <ALIASES>;
+       close(ALIASES);
+
+       # We have a RED eth iface
+       if ($netsettings{'RED_TYPE'} eq 'STATIC') {
+               # We have a STATIC RED eth iface
+               foreach my $line (@aliases) {
+                       chomp($line);
+                       my @temp = split(/\,/,$line);
+                       if ($temp[0]) {
+                               push(@network, $temp[0]);
+                               push(@masklen, $netsettings{'RED_NETMASK'} );
+                               push(@colour, ${Header::colourfw} );
+                       }
+               }
+       }
+}
 
 # Add Green Firewall Interface
 push(@network, $netsettings{'GREEN_ADDRESS'});
@@ -85,32 +102,11 @@ push(@colour, ${Header::colourgreen} );
 # Add Green Routes to Array
 my @routes = `/sbin/route -n | /bin/grep $netsettings{'GREEN_DEV'}`;
 foreach my $route (@routes) {
-        chomp($route);
-        my @temp = split(/[\t ]+/, $route);
-        push(@network, $temp[0]);
-        push(@masklen, $temp[2]);
-        push(@colour, ${Header::colourgreen} );
-}
-
-# Add Firewall Localhost 127.0.0.1
-push(@network, '127.0.0.1');
-push(@masklen, '255.255.255.255' );
-push(@colour, ${Header::colourfw} );
-
-# Add Orange Network
-if ($netsettings{'ORANGE_DEV'}) {
-        push(@network, $netsettings{'ORANGE_NETADDRESS'});
-        push(@masklen, $netsettings{'ORANGE_NETMASK'} );
-        push(@colour, ${Header::colourorange} );
-        # Add Orange Routes to Array
-        @routes = `/sbin/route -n | /bin/grep $netsettings{'ORANGE_DEV'}`;
-        foreach my $route (@routes) {
-                  chomp($route);
-                my @temp = split(/[\t ]+/, $route);
-                push(@network, $temp[0]);
-                push(@masklen, $temp[2]);
-                push(@colour, ${Header::colourorange} );
-        }
+       chomp($route);
+       my @temp = split(/[\t ]+/, $route);
+       push(@network, $temp[0]);
+       push(@masklen, $temp[2]);
+       push(@colour, ${Header::colourgreen} );
 }
 
 # Add Blue Firewall Interface
@@ -120,304 +116,317 @@ push(@colour, ${Header::colourfw} );
 
 # Add Blue Network
 if ($netsettings{'BLUE_DEV'}) {
-        push(@network, $netsettings{'BLUE_NETADDRESS'});
-        push(@masklen, $netsettings{'BLUE_NETMASK'} );
-        push(@colour, ${Header::colourblue} );
-        # Add Blue Routes to Array
-        @routes = `/sbin/route -n | /bin/grep $netsettings{'BLUE_DEV'}`;
-        foreach my $route (@routes) {
-                  chomp($route);
-                my @temp = split(/[\t ]+/, $route);
-                push(@network, $temp[0]);
-                push(@masklen, $temp[2]);
-                push(@colour, ${Header::colourblue} );
-        }
+       push(@network, $netsettings{'BLUE_NETADDRESS'});
+       push(@masklen, $netsettings{'BLUE_NETMASK'} );
+       push(@colour, ${Header::colourblue} );
+
+       # Add Blue Routes to Array
+       @routes = `/sbin/route -n | /bin/grep $netsettings{'BLUE_DEV'}`;
+       foreach my $route (@routes) {
+               chomp($route);
+               my @temp = split(/[\t ]+/, $route);
+               push(@network, $temp[0]);
+               push(@masklen, $temp[2]);
+               push(@colour, ${Header::colourblue} );
+       }
+}
+
+# Add Orange Network
+if ($netsettings{'ORANGE_DEV'}) {
+       push(@network, $netsettings{'ORANGE_NETADDRESS'});
+       push(@masklen, $netsettings{'ORANGE_NETMASK'} );
+       push(@colour, ${Header::colourorange} );
+       # Add Orange Routes to Array
+       @routes = `/sbin/route -n | /bin/grep $netsettings{'ORANGE_DEV'}`;
+       foreach my $route (@routes) {
+               chomp($route);
+               my @temp = split(/[\t ]+/, $route);
+               push(@network, $temp[0]);
+               push(@masklen, $temp[2]);
+               push(@colour, ${Header::colourorange} );
+       }
 }
 
 # Add OpenVPN net and RED/BLUE/ORANGE entry (when appropriate)
 if (-e "${General::swroot}/ovpn/settings") {
-    my %ovpnsettings = ();    
-    &General::readhash("${General::swroot}/ovpn/settings", \%ovpnsettings);
-    my @tempovpnsubnet = split("\/",$ovpnsettings{'DOVPN_SUBNET'});
+       my %ovpnsettings = ();
+       &General::readhash("${General::swroot}/ovpn/settings", \%ovpnsettings);
+       my @tempovpnsubnet = split("\/",$ovpnsettings{'DOVPN_SUBNET'});
+
+       # add OpenVPN net
+       push(@network, $tempovpnsubnet[0]);
+       push(@masklen, $tempovpnsubnet[1]);
+       push(@colour, ${Header::colourovpn} );
+
+       # add BLUE:port / proto
+       if (($ovpnsettings{'ENABLED_BLUE'} eq 'on') && $netsettings{'BLUE_DEV'}) {
+               push(@network, $netsettings{'BLUE_ADDRESS'} );
+               push(@masklen, '255.255.255.255' );
+               push(@colour, ${Header::colourovpn});
+       }
 
-    # add OpenVPN net
-                push(@network, $tempovpnsubnet[0]);
-                push(@masklen, $tempovpnsubnet[1]);
-                push(@colour, ${Header::colourovpn} );
+       # add ORANGE:port / proto
+       if (($ovpnsettings{'ENABLED_ORANGE'} eq 'on') && $netsettings{'ORANGE_DEV'}) {
+               push(@network, $netsettings{'ORANGE_ADDRESS'} );
+               push(@masklen, '255.255.255.255' );
+               push(@colour, ${Header::colourovpn} );
+       }
+}
 
+open(IPSEC, "/var/ipfire/vpn/config");
+my @ipsec = <IPSEC>;
+close(IPSEC);
 
-    if ( ($ovpnsettings{'ENABLED_BLUE'} eq 'on') && $netsettings{'BLUE_DEV'} ) {
-      # add BLUE:port / proto
-            push(@network, $netsettings{'BLUE_ADDRESS'} );
-            push(@masklen, '255.255.255.255' );
-                  push(@colour, ${Header::colourovpn} );
-    }
-    if ( ($ovpnsettings{'ENABLED_ORANGE'} eq 'on') && $netsettings{'ORANGE_DEV'} ) {
-      # add ORANGE:port / proto
-            push(@network, $netsettings{'ORANGE_ADDRESS'} );
-            push(@masklen, '255.255.255.255' );
-                  push(@colour, ${Header::colourovpn} );
-    }
-}
+foreach my $line (@ipsec) {
+       my @vpn = split(',', $line);
+       my ($network, $mask) = split("/", $vpn[12]);
 
-# Add STATIC RED aliases
-if ($netsettings{'RED_DEV'}) {
-        # We have a RED eth iface
-        if ($netsettings{'RED_TYPE'} eq 'STATIC') {
-                # We have a STATIC RED eth iface
-                foreach my $line (@aliases)
-                {
-                        chomp($line);
-                        my @temp = split(/\,/,$line);
-                        if ( $temp[0] ) {
-                                push(@network, $temp[0]);
-                                push(@masklen, $netsettings{'RED_NETMASK'} );
-                                push(@colour, ${Header::colourfw} );
-                        }
-                }
-        }
-}
+       if (!&General::validip($mask)) {
+               $mask = ipv4_cidr2msk($mask);
+       }
 
-# Add VPNs
-if ( $vpn[0] ne 'none' ) {
-        foreach my $line (@vpn) {
-                my @temp = split(/[\t ]+/,$line);
-                my @temp1 = split(/[\/:]+/,$temp[3]);
-                push(@network, $temp1[0]);
-                push(@masklen, ipv4_cidr2msk($temp1[1]));
-                push(@colour, ${Header::colourvpn} );
-        }
+       push(@network, $network);
+       push(@masklen, $mask);
+       push(@colour, ${Header::colourvpn});
 }
 
-#Establish simple filtering&sorting boxes on top of table
+# Show the page.
+&Header::openpage($Lang::tr{'connections'}, 1, '');
+&Header::openbigbox('100%', 'left');
+&Header::openbox('100%', 'left', $Lang::tr{'connection tracking'});
 
-our %cgiparams;
-&Header::getcgihash(\%cgiparams);
+# Print legend.
+print <<END;
+       <table width='100%'>
+               <tr>
+                       <td align='center'>
+                               <b>$Lang::tr{'legend'} : </b>
+                       </td>
+                       <td align='center' bgcolor='${Header::colourgreen}'>
+                               <b><font color='#FFFFFF'>$Lang::tr{'lan'}</font></b>
+                       </td>
+                       <td align='center' bgcolor='${Header::colourred}'>
+                               <b><font color='#FFFFFF'>$Lang::tr{'internet'}</font></b>
+                       </td>
+                       <td align='center' bgcolor='${Header::colourorange}'>
+                               <b><font color='#FFFFFF'>$Lang::tr{'dmz'}</font></b>
+                       </td>
+                       <td align='center' bgcolor='${Header::colourblue}'>
+                               <b><font color='#FFFFFF'>$Lang::tr{'wireless'}</font></b>
+                       </td>
+                       <td align='center' bgcolor='${Header::colourfw}'>
+                               <b><font color='#FFFFFF'>IPFire</font></b>
+                       </td>
+                       <td align='center' bgcolor='${Header::colourvpn}'>
+                               <b><font color='#FFFFFF'>$Lang::tr{'vpn'}</font></b>
+                       </td>
+                       <td align='center' bgcolor='${Header::colourovpn}'>
+                               <b><font color='#FFFFFF'>$Lang::tr{'OpenVPN'}</font></b>
+                       </td>
+               </tr>
+       </table>
+       <br>
+END
 
-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');
+# Print table header.
+print <<END;
+       <table width='100%'>
+               <tr>
+                       <th align='center'>
+                               $Lang::tr{'protocol'}
+                       </th>
+                       <th align='center'>
+                               $Lang::tr{'source ip and port'}
+                       </th>
+                       <th>&nbsp;</th>
+                       <th align='center'>
+                               $Lang::tr{'dest ip and port'}
+                       </th>
+                       <th>&nbsp;</th>
+                       <th align='center'>
+                               $Lang::tr{'download'} /
+                               <br>$Lang::tr{'upload'}
+                       </th>
+                       <th align='center'>
+                               $Lang::tr{'connection'}<br>$Lang::tr{'status'}
+                       </th>
+                       <th align='center'>
+                               $Lang::tr{'expires'}<br>($Lang::tr{'seconds'})
+                       </th>
+               </tr>
+END
 
-# init or silently correct unknown value...
-if ( ! grep ( /^$cgiparams{'SEE_PROTO'}$/ , @list_proto )) { $cgiparams{'SEE_PROTO'} = $list_proto[0] };
-if ( ! grep ( /^$cgiparams{'SEE_STATE'}$/ , @list_state )) { $cgiparams{'SEE_STATE'} = $list_state[0] };
-if ( ($cgiparams{'SEE_MARK'} ne $Lang::tr{'all'}) &&   # ok the grep should work but it doesn't because of
-     ($cgiparams{'SEE_MARK'} ne '[ASSURED]') &&                # the '[' & ']' interpreted as list separator.
-     ($cgiparams{'SEE_MARK'} ne '[UNREPLIED]')         # So, explicitly enumerate items.
-   )  { $cgiparams{'SEE_MARK'}  = $list_mark[0] };
-if ( ! grep ( /^$cgiparams{'SEE_SORT'}$/  , @list_sort ))  { $cgiparams{'SEE_SORT'}  = $list_sort[0] };
-# *.*.*.* or a valid IP
-if ( $cgiparams{'SEE_SRC'}  !~ /^(\*\.\*\.\*\.\*\.|\d+\.\d+\.\d+\.\d+)$/) {  $cgiparams{'SEE_SRC'} = '*.*.*.*' };
-if ( $cgiparams{'SEE_DEST'} !~ /^(\*\.\*\.\*\.\*\.|\d+\.\d+\.\d+\.\d+)$/) {  $cgiparams{'SEE_DEST'} = '*.*.*.*' };
+foreach my $line (@conntrack) {
+       my @conn = split(' ', $line);
 
+       # The first bit is the l3 protocol.
+       my $l3proto = $conn[0];
 
-our %entries = ();     # will hold the lines analyzed correctly
-my $unknownlines = ''; # should be empty all the time...
-my $index = 0;         # just a counter to make unique entryies in entries
+       # Skip everything that is not IPv4.
+       if ($l3proto ne 'ipv4') {
+               next;
+       }
 
-&Header::showhttpheaders();
-&Header::openpage($Lang::tr{'connections'}, 1, '');
-&Header::openbigbox('100%', 'left');
-&Header::openbox('100%', 'left', $Lang::tr{'connection tracking'});
+       # L4 protocol (tcp, udp, ...).
+       my $l4proto = $conn[2];
 
-# Build listbox objects
-my $menu_proto = &make_select ('SEE_PROTO', $cgiparams{'SEE_PROTO'}, @list_proto);
-my $menu_state = &make_select ('SEE_STATE', $cgiparams{'SEE_STATE'}, @list_state);
-
-print <<END
-<form method='post' action='$ENV{'SCRIPT_NAME'}'>
-<table width='100%'>
-<tr><td align='center'><b>$Lang::tr{'legend'} : </b></td>
-    <td align='center' bgcolor='${Header::colourgreen}'><b><font color='#FFFFFF'>$Lang::tr{'lan'}</font></b></td>
-    <td align='center' bgcolor='${Header::colourred}'><b><font color='#FFFFFF'>$Lang::tr{'internet'}</font></b></td>
-    <td align='center' bgcolor='${Header::colourorange}'><b><font color='#FFFFFF'>$Lang::tr{'dmz'}</font></b></td>
-    <td align='center' bgcolor='${Header::colourblue}'><b><font color='#FFFFFF'>$Lang::tr{'wireless'}</font></b></td>
-    <td align='center' bgcolor='${Header::colourfw}'><b><font color='#FFFFFF'>IPFire</font></b></td>
-    <td align='center' bgcolor='${Header::colourvpn}'><b><font color='#FFFFFF'>$Lang::tr{'vpn'}</font></b></td>
-    <td align='center' bgcolor='${Header::colourovpn}'><b><font color='#FFFFFF'>$Lang::tr{'OpenVPN'}</font></b></td>
-</tr>
-</table>
-<br />
-<table width='100%'>
-<tr><td align='center'><font size=2>$Lang::tr{'source ip and port'}</font></td>
-               <td>&nbsp;</td>
-               <td align='center'><font size=2>$Lang::tr{'dest ip and port'}</font></td>
-               <td>&nbsp;</td>
-               <td align='center'><font size=2>$Lang::tr{'protocol'}</font></td>
-               <td align='center'><font size=2>$Lang::tr{'connection'}<br></br>$Lang::tr{'status'}</font></td>
-    <td align='center'><font size=2>$Lang::tr{'expires'}<br></br>($Lang::tr{'seconds'})</font></td>
-    
-</tr>
-<tr><td colspan='4'>&nbsp;</td>
-               <td align='center'>$menu_proto</td>
-    <td align='center'>$menu_state</td>
-    <td>&nbsp;</td>
-</tr>
-<tr>
-    <td align='center' colspan='7'></td>
-</tr>
-<tr>
-    <td align='center' colspan='7'><input type='submit' value="$Lang::tr{'update'}" /></td>
-</tr>
+       if ($l4proto eq 'unknown') {
+               $l4proto = '';
+       }
 
-END
-;
+       # Source and destination.
+       my $sip;
+       my $dip;
+       my $sport;
+       my $dport;
+       my @packets;
+       my @bytes;
+
+       my $ttl = $conn[4];
+       my $state;
+       if ($l4proto eq 'tcp') {
+               $state = $conn[5];
+       }
 
-my $i=0;
-foreach my $line (@active) {
-    $i++;
-    if ($i < 3) {
-                       next;
-    }
-    chomp($line);
-    my @temp = split(' ',$line);
-
-    my ($sip, $sport) = split(':', $temp[0]);
-    my ($dip, $dport) = split(':', $temp[1]);
-    my $proto = $temp[2];
-    my $state; my $ttl;
-    if ( $proto eq "esp" ){$state = "";$ttl = $temp[3];}
-    elsif ( $proto eq "icmp" ){$state = "";$ttl = $temp[4];}
-    else{$state = $temp[3];$ttl = $temp[4];}
-    
-    next if( !(
-                       (($cgiparams{'SEE_PROTO'}  eq $Lang::tr{'all'}) || ($proto  eq $cgiparams{'SEE_PROTO'} ))
-                && (($cgiparams{'SEE_STATE'}  eq $Lang::tr{'all'}) || ($state  eq $cgiparams{'SEE_STATE'} ))
-               && (($cgiparams{'SEE_SRC'}    eq "*.*.*.*")        || ($sip    eq $cgiparams{'SEE_SRC'}   ))
-               && (($cgiparams{'SEE_DEST'}   eq "*.*.*.*")       || ($dip    eq $cgiparams{'SEE_DEST'}  ))
-              ));
-
-    if (($proto eq 'udp') && ($ttl eq '')) {
-                       $ttl = $state;
-                       $state = '&nbsp;';      
-    }
+       # Kick out everything that is not IPv4.
+       foreach my $item (@conn) {
+               my ($key, $val) = split('=', $item);
+
+               switch ($key) {
+                       case "src" {
+                               $sip = $val;
+                       }
+                       case "dst" {
+                               $dip = $val;
+                       }
+                       case "sport" {
+                               $sport = $val;
+                       }
+                       case "dport" {
+                               $dport = $val;
+                       }
+                       case "packets" {
+                               push(@packets, $val);
+                       }
+                       case "bytes" {
+                               push(@bytes, $val);
+                       }
+               }
+       }
 
-    my $sipcol = ipcolour($sip);
-    my $dipcol = ipcolour($dip);
+       my $sip_colour = ipcolour($sip);
+       my $dip_colour = ipcolour($dip);
 
     my $sserv = '';
     if ($sport < 1024) {
-       $sserv = uc(getservbyport($sport, lc($proto)));
-       if ($sserv ne '') {
-           $sserv = "&nbsp;($sserv)";
-       }
+               $sserv = uc(getservbyport($sport, lc($l4proto)));
+               if ($sserv ne '') {
+                       $sserv = "&nbsp;($sserv)";
+               }
     }
 
     my $dserv = '';
     if ($dport < 1024) {
-       $dserv = uc(getservbyport($dport, lc($proto)));
-       if ($dserv ne '') {
-           $dserv = "&nbsp;($dserv)";
-       }
+               $dserv = uc(getservbyport($dport, lc($l4proto)));
+               if ($dserv ne '') {
+                       $dserv = "&nbsp;($dserv)";
+               }
     }
 
-    print <<END
-    <tr >
-      <td align='center' bgcolor='$sipcol'>
-        <a href='/cgi-bin/ipinfo.cgi?ip=$sip'>
-          <font color='#FFFFFF'>$sip</font>
-        </a>
-      </td>
-      <td align='center' bgcolor='$sipcol'>
-        <a href='http://isc.sans.org/port_details.php?port=$sport' target='top'>
-          <font color='#FFFFFF'>$sport$sserv</font>
-        </a>
-      </td>
-      <td align='center' bgcolor='$dipcol'>
-        <a href='/cgi-bin/ipinfo.cgi?ip=$dip'>
-          <font color='#FFFFFF'>$dip</font>
-        </a>
-      </td>
-      <td align='center' bgcolor='$dipcol'>
-        <a href='http://isc.sans.org/port_details.php?port=$dport' target='top'>
-          <font color='#FFFFFF'>$dport$dserv</font>
-        </a>
-      </td>
-      <td align='center'>$proto</td>
-      <td align='center'>$state</td>
-      <td align='center'>$ttl</td>
-    </tr>
+       my $bytes_in = format_bytes($bytes[0]);
+       my $bytes_out = format_bytes($bytes[1]);
+
+       # Format TTL
+       $ttl = format_time($ttl);
+
+       print <<END;
+       <tr>
+               <td align='center'>$l4proto</td>
+               <td align='center' bgcolor='$sip_colour'>
+                       <a href='/cgi-bin/ipinfo.cgi?ip=$sip'>
+                               <font color='#FFFFFF'>$sip</font>
+                       </a>
+               </td>
+               <td align='center' bgcolor='$sip_colour'>
+                       <a href='http://isc.sans.org/port_details.php?port=$sport' target='top'>
+                               <font color='#FFFFFF'>$sport$sserv</font>
+                       </a>
+               </td>
+               <td align='center' bgcolor='$dip_colour'>
+                       <a href='/cgi-bin/ipinfo.cgi?ip=$dip'>
+                               <font color='#FFFFFF'>$dip</font>
+                       </a>
+               </td>
+               <td align='center' bgcolor='$dip_colour'>
+                       <a href='http://isc.sans.org/port_details.php?port=$dport' target='top'>
+                               <font color='#FFFFFF'>$dport$dserv</font>
+                       </a>
+               </td>
+               <td align='center'>
+                       $bytes_in / $bytes_out
+               </td>
+               <td align='center'>$state</td>
+               <td align='center'>$ttl</td>
+       </tr>
 END
-;
 }
 
-print "</table></form>";
+# Close the main table.
+print "</table>";
 
 &Header::closebox();
 &Header::closebigbox();
 &Header::closepage();
 
-sub ipcolour($) {
-        my $id = 0;
-        my $line;
-        my $colour = ${Header::colourred};
-        my ($ip) = $_[0];
-        my $found = 0;
-        foreach $line (@network) {
-                                       if ($network[$id] eq '') {
-                                               $id++;
-                                       } else {
-                                               if (!$found && ipv4_in_network( $network[$id] , $masklen[$id], $ip) ) {
-                                                       $found = 1;
-                                                       $colour = $colour[$id];
-                                               }
-                                               $id++;
-                                       }
-        }
-        return $colour
-}
+sub format_bytes($) {
+       my $bytes = shift;
+       my @units = ("B", "k", "M", "G", "T");
+
+       foreach my $unit (@units) {
+               if ($bytes < 1024) {
+                       return sprintf("%d%s", $bytes, $unit);
+               }
 
-# Create a string containing a complete SELECT html object 
-# param1: name
-# param2: current value selected
-# param3: field list
-sub make_select ($,$,$) {
-        my $select_name = shift;
-        my $selected    = shift;
-        my $select = "<select name='$select_name'>";
-
-        foreach my $value (@_) {
-                    my $check = $selected eq $value ? "selected='selected'" : '';
-                    $select .= "<option $check value='$value'>$value</option>";
-        }
-        $select .= "</select>";
-        return $select;
+               $bytes /= 1024;
+       }
+
+       return sprintf("%d%s", $bytes, $units[$#units]);
 }
 
-# Build a list of IP obtained from the %entries hash
-# param1: IP field name
-sub get_known_ips ($) {
-        my $field = shift;
-        my $qs = $cgiparams{'SEE_SORT'};       # switch the sort order
-        $cgiparams{'SEE_SORT'} = $field;
+sub format_time($) {
+       my $time = shift;
 
-        my @liste=('*.*.*.*');
-        foreach my $entry ( sort sort_entries keys %entries) {
-                    push (@liste, $entries{$entry}->{$field}) if (! grep (/^$entries{$entry}->{$field}$/,@liste) );
-        }
+       my $seconds = $time % 60;
+       my $minutes = $time / 60;
 
-        $cgiparams{'SEE_SORT'} = $qs;  #restore sort order
-        return @liste;
+       my $hours = 0;
+       if ($minutes >= 60) {
+               $hours = $minutes / 60;
+               $minutes %= 60;
+       }
+
+       return sprintf("%3d:%02d:%02d", $hours, $minutes, $seconds);
 }
 
-# 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/) {
-                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/) {
-                    $entries{$a}->{$qs} <=> $entries{$b}->{$qs};
-        } else {
-                    $entries{$a}->{$qs} cmp $entries{$b}->{$qs};
-        }
+sub ipcolour($) {
+       my $id = 0;
+       my $colour = ${Header::colourred};
+       my ($ip) = $_[0];
+       my $found = 0;
+
+       foreach my $line (@network) {
+               if ($network[$id] eq '') {
+                       $id++;
+               } else {
+                       if (!$found && ipv4_in_network($network[$id], $masklen[$id], $ip) ) {
+                               $found = 1;
+                               $colour = $colour[$id];
+                       }
+                       $id++;
+               }
+       }
+
+       return $colour;
 }
 
 1;
index 9f1e3f0006d16b3dac3ac93e8bc95af8fbd2c191..300e9ecbb244caabd7fb447a82259b92d764d6e8 100644 (file)
@@ -32,7 +32,8 @@ SUID_PROGS = setdmzholes setportfw setxtaccess \
        wirelessctrl getipstat getiptstate qosctrl launch-ether-wake \
        redctrl syslogdctrl extrahdctrl sambactrl upnpctrl tripwirectrl \
        smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \
-       setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes
+       setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes \
+       getconntracktable
 SUID_UPDX = updxsetperms
 
 install : all
@@ -160,3 +161,6 @@ fireinfoctrl: fireinfoctrl.c setuid.o ../install+setup/libsmooth/varval.o
 
 rebuildroutes: rebuildroutes.c setuid.o ../install+setup/libsmooth/varval.o
        $(COMPILE) -I../install+setup/libsmooth/ rebuildroutes.c setuid.o ../install+setup/libsmooth/varval.o -o $@
+
+getconntracktable: getconntracktable.c setuid.o ../install+setup/libsmooth/varval.o
+       $(COMPILE) -I../install+setup/libsmooth/ getconntracktable.c setuid.o ../install+setup/libsmooth/varval.o -o $@
diff --git a/src/misc-progs/getconntracktable.c b/src/misc-progs/getconntracktable.c
new file mode 100644 (file)
index 0000000..674b211
--- /dev/null
@@ -0,0 +1,31 @@
+/* IPFire helper program - getconntracktable\r
+ *\r
+ * This program is distributed under the terms of the GNU General Public\r
+ * Licence.  See the file COPYING for details.\r
+ *\r
+ * The kernel's connection tracking table is not readable by\r
+ * non-root users. So this helper will just read and output it.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include "setuid.h"\r
+\r
+int main(void) {\r
+       if (!(initsetuid()))\r
+               exit(1);\r
+\r
+       FILE *fp = fopen("/proc/net/nf_conntrack", "r");\r
+       if (fp == NULL) {\r
+               exit(1);\r
+       }\r
+\r
+       /* Read content line by line and write it to stdout. */\r
+       char linebuf[STRING_SIZE];\r
+       while (fgets(linebuf, STRING_SIZE, fp)) {\r
+               printf("%s", linebuf);\r
+       }\r
+\r
+       fclose(fp);\r
+       return 0;\r
+}\r