diff options
author | Daniil Baturin <daniil@baturin.org> | 2014-11-29 15:40:51 +0600 |
---|---|---|
committer | Daniil Baturin <daniil@baturin.org> | 2014-11-29 15:40:51 +0600 |
commit | 164e703b1c1089fdf687e0e8449495821abf6d78 (patch) | |
tree | 6f5ee433e5c968c1a5e3e4b4304d2509a3f92cfb /lib | |
parent | 5eae6d9b155e1fbdf02d950e829a89437835ca93 (diff) | |
parent | ae70480c3a0def9dcb28e9e33e225e1e22273b0e (diff) | |
download | vyatta-op-vpn-164e703b1c1089fdf687e0e8449495821abf6d78.tar.gz vyatta-op-vpn-164e703b1c1089fdf687e0e8449495821abf6d78.zip |
Merge pull request #5 from jhendryUK/show_ikev2_sa
Bug #388: Add IKEv2 SA info to "show vpn ipsec *" options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/OPMode.pm | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/lib/OPMode.pm b/lib/OPMode.pm index 9d83941..f46fb28 100644 --- a/lib/OPMode.pm +++ b/lib/OPMode.pm @@ -201,6 +201,7 @@ sub get_tunnel_info_peer { sub process_tunnels{ my @ipsecstatus = @{pop(@_)}; my %tunnel_hash = (); + my %esp_hash = (); foreach my $line (@ipsecstatus) { if (($line =~ /\"(peer-.*-tunnel-.*?)\"/)){ my $connectid = $1; @@ -500,10 +501,155 @@ sub process_tunnels{ } } } + } elsif ($line =~ /^(peer-.*-tunnel-.*?)[{\[].*:\s+/) { + my $connectid = $1; + $connectid .= $2 if ($line =~ /(peer-.*-tunnel-.*?):(\[\d*\])/); + $connectid =~ /peer-(.*)-tunnel-(.*)/; + + my ($peer, $tunid) = ($1, $2); + $peer = conv_id($peer); + + if (not exists $tunnel_hash{$connectid}){ + $tunnel_hash{$connectid} = { + _peerid => $peer, + _tunnelnum => $tunid, + _lip => 'n/a', + _rip => 'n/a', + _lid => 'n/a', + _rid => 'n/a', + _lsnet => 'n/a', + _rsnet => 'n/a', + _lproto => 'all', + _rproto => 'all', + _lport => 'all', + _rport => 'all', + _lca => undef, + _rca => undef, + _newestspi => 'n/a', + _newestike => 'n/a', + _encryption => 'n/a', + _hash => 'n/a', + _inspi => 'n/a', + _outspi => 'n/a', + _pfsgrp => 'n/a', + _ikeencrypt => 'n/a', + _ikehash => 'n/a', + _natt => 'n/a', + _natsrc => 'n/a', + _natdst => 'n/a', + _ikestate => "down", + _dhgrp => 'n/a', + _state => "down", + _inbytes => 'n/a', + _outbytes => 'n/a', + _ikelife => 'n/a', + _ikeexpire => 'n/a', + _lifetime => 'n/a', + _expire => 'n/a' }; + } + + $line =~ s/---.*\.\.\./.../g; # remove the next hop router for local-ip 0.0.0.0 case + + if ($line =~ /:\s+ESTABLISHED (.*), (.*?)\[(.*?)\]\.\.\.(.*?)\[(.*?)\]/) { + my $lip = $2; + my $lid = $3; + my $rip = $4; + my $rid = $5; + ($lip, my $natt, my $natsrc, $rip, my $natdst) = nat_detect($lip, $rip); + + $tunnel_hash{$connectid}->{_lid} = conv_id($lid); + $tunnel_hash{$connectid}->{_lip} = $lip; + $tunnel_hash{$connectid}->{_rid} = conv_id($rid); + $tunnel_hash{$connectid}->{_rip} = $rip; + $tunnel_hash{$connectid}->{_natt} = $natt; + $tunnel_hash{$connectid}->{_natsrc} = $natsrc; + $tunnel_hash{$connectid}->{_natdst} = $natdst; + + # Pull stuff from running config (IKE/ESP lifetime, PFS group) + my $vpncfg = new Vyatta::Config(); + $vpncfg->setLevel('vpn ipsec'); + my $esp_path = "default-esp-group"; + my $peer_path = "site-to-site peer $tunnel_hash{$connectid}->{_peerid}"; + if ($vpncfg->existsOrig("$peer_path tunnel $tunid esp-group")) { + $esp_path = "tunnel $tunid esp-group"; + } + my $esp_group = $vpncfg->returnEffectiveValue("$peer_path $esp_path"); + my $ike_group = $vpncfg->returnEffectiveValue("site-to-site peer $tunnel_hash{$connectid}->{_peerid} ike-group"); + my $pfs_group = $vpncfg->returnEffectiveValue("esp-group $esp_group pfs"); + $pfs_group = "default" if ($pfs_group eq 'enable'); + my $lifetime = $vpncfg->returnEffectiveValue("esp-group $esp_group lifetime"); + my $ikelife = $vpncfg->returnEffectiveValue("ike-group $ike_group lifetime"); + + $tunnel_hash{$connectid}->{_lifetime} = $lifetime; + $tunnel_hash{$connectid}->{_ikelife} = $ikelife; + $tunnel_hash{$connectid}->{_pfsgrp} = $pfs_group; + + } elsif ($line =~ /\]:\s+IKE SPIs: .* reauthentication in (.*)/) { + $tunnel_hash{$connectid}->{_ikeexpire} = conv_time($1); + my $atime = $tunnel_hash{$connectid}->{_ikelife} - $tunnel_hash{$connectid}->{_ikeexpire}; + + $tunnel_hash{$connectid}->{_ikestate} = "up" if ($atime >= 0); + + } elsif ($line =~ /\]:\s+IKE.proposal:(.*?)\/(.*?)\/(.*)/) { + $tunnel_hash{$connectid}->{_ikeencrypt} = $1; + $tunnel_hash{$connectid}->{_ikehash} = $2; + $tunnel_hash{$connectid}->{_dhgrp} = $3; + + } elsif ($line =~ /{(\d+)}:\s+INSTALLED.*ESP.*SPIs: (.*)_i (.*)_o/) { + $esp_hash{$connectid}{$1}->{_inspi} = $2; + $esp_hash{$connectid}{$1}->{_outspi} = $3; + + } elsif ($line =~ /{(\d+)}:\s+(.*?)\/(.*?), (\d+) bytes_i.* (\d+) bytes_o.*rekeying in (.*)/) { + my $esp_id = $1; + $esp_hash{$connectid}{$esp_id}->{_encryption} = $2; + $esp_hash{$connectid}{$esp_id}->{_hash} = $3; + $esp_hash{$connectid}{$esp_id}->{_inbytes} = $4; + $esp_hash{$connectid}{$esp_id}->{_outbytes} = $5; + $esp_hash{$connectid}{$esp_id}->{_expire} = conv_time($6); + + my $last_used = 1000; + $last_used = $1 if ($line =~ /\((\d+)s ago\)/); + $esp_hash{$connectid}{$esp_id}->{last_used} = $last_used; + + } elsif ($line =~ /{(\d+)}:\s+(.*?)\[(.*?)\] === (.*)\[(.*)\]/) { + $esp_hash{$connectid}{$1}->{_lsnet} = $2; + $esp_hash{$connectid}{$1}->{_lproto} = $3; + $esp_hash{$connectid}{$1}->{_rsnet} = $4; + $esp_hash{$connectid}{$1}->{_rproto} = $5; + } } } + + # For each tunnel, loop through all ESP SA's and extract data from one most recently used + foreach my $connectid (keys %esp_hash) { + foreach my $esp_sa (reverse sort {$esp_hash{$a}{last_used} <=> $esp_hash{$b}{last_used}} keys %{$esp_hash{$connectid}}) { + foreach my $data (keys %{$esp_hash{$connectid}{$esp_sa}}) { + $tunnel_hash{$connectid}->{$data} = $esp_hash{$connectid}{$esp_sa}{$data} if ($data =~ /^_/); + } + my $atime = $tunnel_hash{$connectid}->{_lifetime} - $tunnel_hash{$connectid}->{_expire}; + $tunnel_hash{$connectid}->{_state} = "up" if ($atime >= 0); + last; + } + } + return %tunnel_hash; } + +sub conv_time { + my @time = split(/\s+/, $_[0]); + my $multiply = 1; + + if ($time[1] =~ /minute/i) { + $multiply = 60; + } elsif ($time[1] =~ /hour/i) { + $multiply = 3600; + } elsif ($time[1] =~ /day/i) { + $multiply = 86400; + } + + return $time[0] * $multiply; +} + sub get_conns { my $cmd = "sudo cat /etc/ipsec.conf"; |