X-Git-Url: http://git.ipfire.org/?p=ipfire-2.x.git;a=blobdiff_plain;f=html%2Fcgi-bin%2Fconnections.cgi;h=e9e9e335cfe4356b8509b5a79b1f482562e51e6c;hp=21f66d7b2c7a06315309f1bbefb0c35a133b2377;hb=727ac931479d2c67f50692d5ac3807b1bf9d5dee;hpb=b431bfce486adcccac747c21882a6f735583104e diff --git a/html/cgi-bin/connections.cgi b/html/cgi-bin/connections.cgi index 21f66d7b2c..e9e9e335cf 100644 --- a/html/cgi-bin/connections.cgi +++ b/html/cgi-bin/connections.cgi @@ -31,6 +31,34 @@ use Switch; require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; +require "${General::swroot}/geoip-functions.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(); @@ -41,12 +69,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); @@ -131,6 +187,11 @@ if ($netsettings{'BLUE_DEV'}) { } } +# Add Orange Firewall Interface +push(@network, $netsettings{'ORANGE_ADDRESS'}); +push(@masklen, "255.255.255.255" ); +push(@colour, ${Header::colourfw} ); + # Add Orange Network if ($netsettings{'ORANGE_DEV'}) { push(@network, $netsettings{'ORANGE_NETADDRESS'}); @@ -147,6 +208,11 @@ if ($netsettings{'ORANGE_DEV'}) { } } +# Highlight multicast connections. +push(@network, "224.0.0.0"); +push(@masklen, "239.0.0.0"); +push(@colour, $colour_multicast); + # Add OpenVPN net and RED/BLUE/ORANGE entry (when appropriate) if (-e "${General::swroot}/ovpn/settings") { my %ovpnsettings = (); @@ -173,21 +239,42 @@ if (-e "${General::swroot}/ovpn/settings") { } } -open(IPSEC, "${General::swroot}/var/ipfire/vpn/config"); +# Add OpenVPN net for custom OVPNs +if (-e "${General::swroot}/ovpn/ccd.conf") { + open(OVPNSUB, "${General::swroot}/ovpn/ccd.conf"); + my @ovpnsub = ; + close(OVPNSUB); + + foreach (@ovpnsub) { + my ($network, $mask) = split '/', (split ',', $_)[2]; + + $mask = ipv4_cidr2msk($mask) unless &General::validip($mask); + + push(@network, $network); + push(@masklen, $mask); + push(@colour, ${Header::colourovpn}); + } +} + +open(IPSEC, "${General::swroot}/vpn/config"); my @ipsec = ; close(IPSEC); foreach my $line (@ipsec) { my @vpn = split(',', $line); - my ($network, $mask) = split("/", $vpn[12]); - if (!&General::validip($mask)) { - $mask = ipv4_cidr2msk($mask); - } + my @subnets = split(/\|/, $vpn[12]); + for my $subnet (@subnets) { + my ($network, $mask) = split("/", $subnet); + + if (!&General::validip($mask)) { + $mask = ipv4_cidr2msk($mask); + } - push(@network, $network); - push(@masklen, $mask); - push(@colour, ${Header::colourvpn}); + push(@network, $network); + push(@masklen, $mask); + push(@colour, ${Header::colourvpn}); + } } if (-e "${General::swroot}/ovpn/n2nconf") { @@ -217,60 +304,131 @@ if (-e "${General::swroot}/ovpn/n2nconf") { # Print legend. print < + - + - - - - - - -
- $Lang::tr{'legend'} : + + $Lang::tr{'legend'} : + + $Lang::tr{'lan'} - $Lang::tr{'lan'} + + $Lang::tr{'internet'} - $Lang::tr{'internet'} + + $Lang::tr{'dmz'} - $Lang::tr{'dmz'} + + $Lang::tr{'wireless'} - $Lang::tr{'wireless'} + + IPFire - IPFire + + $Lang::tr{'vpn'} - $Lang::tr{'vpn'} + + $Lang::tr{'OpenVPN'} - $Lang::tr{'OpenVPN'} + + Multicast

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 < + + + + + + + + + + + - - - - + - - + - - @@ -316,9 +474,13 @@ foreach my $line (@conntrack) { # Source and destination. my $sip; + my $sip_ret; my $dip; + my $dip_ret; my $sport; + my $sport_ret; my $dport; + my $dport_ret; my @packets; my @bytes; @@ -334,16 +496,32 @@ foreach my $line (@conntrack) { switch ($key) { case "src" { - $sip = $val; + if ($sip == "") { + $sip = $val; + } else { + $dip_ret = $val; + } } case "dst" { - $dip = $val; + if ($dip == "") { + $dip = $val; + } else { + $sip_ret = $val; + } } case "sport" { - $sport = $val; + if ($sport == "") { + $sport = $val; + } else { + $dport_ret = $val; + } } case "dport" { - $dport = $val; + if ($dport == "") { + $dport = $val; + } else { + $sport_ret = $val; + } } case "packets" { push(@packets, $val); @@ -355,58 +533,112 @@ foreach my $line (@conntrack) { } my $sip_colour = ipcolour($sip); - my $dip_colour = ipcolour($dip); + # use colour of destination network for DNAT + my $dip_colour = $dip ne $dip_ret ? ipcolour($dip_ret) : ipcolour($dip); my $sserv = ''; if ($sport < 1024) { $sserv = uc(getservbyport($sport, lc($l4proto))); - if ($sserv ne '') { - $sserv = " ($sserv)"; - } } my $dserv = ''; if ($dport < 1024) { $dserv = uc(getservbyport($dport, lc($l4proto))); - if ($dserv ne '') { - $dserv = " ($dserv)"; - } } my $bytes_in = format_bytes($bytes[0]); my $bytes_out = format_bytes($bytes[1]); + # enumerate GeoIP information + my $srcccode = &GeoIP::lookup($sip_ret); + my $src_flag_icon = &GeoIP::get_flag_icon($srcccode); + my $dstccode = &GeoIP::lookup($dip_ret); + my $dst_flag_icon = &GeoIP::get_flag_icon($dstccode); + # Format TTL $ttl = format_time($ttl); + my $sip_extra; + if ($sip_ret && $sip ne $sip_ret) { + $sip_extra = "> "; + $sip_extra .= ""; + $sip_extra .= " $sip_ret"; + $sip_extra .= ""; + } + + my $dip_extra; + if ($dip_ret && $dip ne $dip_ret) { + $dip_extra = "> "; + $dip_extra .= ""; + $dip_extra .= " $dip_ret"; + $dip_extra .= ""; + } + + + my $sport_extra; + if ($sport ne $sport_ret) { + my $sserv_ret = ''; + if ($sport_ret < 1024) { + $sserv_ret = uc(getservbyport($sport_ret, lc($l4proto))); + } + + $sport_extra = "> "; + $sport_extra .= ""; + $sport_extra .= " $sport_ret"; + $sport_extra .= ""; + } + + my $dport_extra; + if ($dport ne $dport_ret) { + my $dserv_ret = ''; + if ($dport_ret < 1024) { + $dserv_ret = uc(getservbyport($dport_ret, lc($l4proto))); + } + + $dport_extra = "> "; + $dport_extra .= ""; + $dport_extra .= " $dport_ret"; + $dport_extra .= ""; + } + print < - - + - + - - - + - - + + END } @@ -454,15 +686,17 @@ sub ipcolour($) { 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]; + if ($ip) { + 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++; } - $id++; } }
+ + + + + +          + + +   + + +        + + +   + + +      + + + + + + + + +
+ $Lang::tr{'protocol'} + $Lang::tr{'source ip and port'}   + + $Lang::tr{'country'} + $Lang::tr{'dest ip and port'}   + + $Lang::tr{'country'} + $Lang::tr{'download'} /
$Lang::tr{'upload'}
+ $Lang::tr{'connection'}
$Lang::tr{'status'}
+ $Lang::tr{'expires'}
($Lang::tr{'seconds'})
$l4proto + $l4proto - $sip + $sip + $sip_extra - - $sport$sserv + + + $sport + $sport_extra + + $srcccode + - $dip + $dip + $dip_extra - - $dport$dserv + + + $dport + $dport_extra + + $dstccode + $bytes_in / $bytes_out $state$ttl$state$ttl