#!/usr/bin/perl -w # copyright 2005 alexeyt(at)freeshell.org, GPL 2.0 or later. use strict; use warnings; my $ips = []; my $conn = undef; my $conns = []; my $destinations = []; my $debug = 0; if ( scalar @ARGV ) { if ( $ARGV[0] =~ /^-v+$/ ) { $debug = length ( $ARGV[0] ) - 1; } else { print "Usage: $0 [-v[v]]\nPrints {free|open}swan status\n"; exit ( 1 ); } } 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 ) { if ( $3 =~ /(trap|hold)/ ) { printf "%-13s DOWN %18s -> %-18s via %-15s\n", $dest->{'name'}, $dest->{'ournet'}, $dest->{'theirnet'}, $dest->{'them'}; } elsif ( $debug ) { printf "%-13s up %18s -> %-18s via %-15s\n", $dest->{'name'}, $dest->{'ournet'}, $dest->{'theirnet'}, $dest->{'them'}; } } else { print $_; } } } close ( STDIN ); 1;