#!/usr/bin/perl -w # copyright 2005 alexeyt(at)freeshell.org, GPL 2.0 or later. # # run this from inetd like so: # http stream tcp nowait nobody /usr/sbin/tcpd /usr/local/bin/swanwebstat # use strict; use warnings; $_ = ; chomp; unless ( /^GET.+HTTP\/1.[01]\r?$/ ) { while ( ) { chomp; last if /^\r?$/; } print "HTTP/1.1 400 Bad Request\r\nContent-Type: text/html\r\n\r\n"; print "400 Bad Request\n"; print "

Bad Request

Request no good.

\n"; exit ( 1 ); } while ( ) { chomp; last if /^\r?$/; } close ( STDIN ); print "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n", "IPSEC Status

\n", "
Name:State:", "Our Net:Their Net:Gateway:\n"; my $ips = []; my $conn = undef; my $conns = []; my $destinations = []; open ( STDIN, "/sbin/ip -4 -o addr ls |" ) or die "could not run ip"; while ( ) { ( push @$ips, $1 ) if ( /inet ([0-9.]+)\// ); } close ( STDIN ); open ( STDIN, "/etc/ipsec.conf" ) or die "could not read ipsec.conf"; while ( ) { if ( /^conn ([\w-]+)/ ) { $conn = { 'name' => "$1" }; } if ( /^\s*#/ or /^\s*$/ ) { ( push @$conns, $conn ) if ( $conn ); $conn = undef; } if ( /^\s+(left|leftsubnet|right|rightsubnet)\s*=\s*([0-9.\/]+)/ ) { ( $conn->{"$1"} = "$2" ) if ( $conn ); } } ( push @$conns, $conn ) if ( $conn ); close ( STDIN ); foreach $conn ( @$conns ) { if ( $conn->{'name'} and $conn->{'left'} and $conn->{'leftsubnet'} and $conn->{'right'} and $conn->{'rightsubnet'} ) { if ( grep ( ( $_ eq $conn->{'left'} ), @$ips ) ) { push @$destinations, { 'name' => $conn->{'name'}, 'them' => $conn->{'right'}, 'ournet' => $conn->{'leftsubnet'}, 'theirnet' => $conn->{'rightsubnet'}, }; } elsif ( grep ( ( $_ eq $conn->{'right'} ), @$ips ) ) { push @$destinations, { 'name' => $conn->{'name'}, 'them' => $conn->{'left'}, 'ournet' => $conn->{'rightsubnet'}, 'theirnet' => $conn->{'leftsubnet'}, }; } } } open ( STDIN, "/usr/sbin/ipsec look |" ) or die "could not run ipsec"; while ( ) { if ( /([0-9.\/]+)\s+->\s+([0-9.\/]+)\s+=>\s+(.*)/ ) { my ( $dest ) = grep ( ( ( $1 eq $_->{'ournet'} ) and ( $2 eq $_->{'theirnet'} ) ), @$destinations ); if ( $dest ) { print "
$dest->{'name'}"; if ( $3 =~ /(trap|hold)/ ) { print "DOWN"; } else { print "up"; } print "$dest->{'ournet'}$dest->{'theirnet'}", "$dest->{'them'}\n"; } else { print $_; } } } close ( STDIN ); print "
\n"; 1;