# # Module Vyatta::vpnprof::OpMode.pm # package Vyatta::vpnprof::OPMode; use lib "/opt/vyatta/share/perl5/"; use Vyatta::VPN::Util; use Vyatta::Config; use strict; sub conv_id { my $peer = pop(@_); if ( $peer =~ /\d+\.\d+\.\d+\.\d+/ ) { $peer = $peer; } elsif ( $peer =~ /\d+\:\d+\:\d+\:\d+\:\d+\:\d+\:\d+\:\d+/ ) { $peer = $peer; } elsif ( $peer =~ /\%any/ ) { $peer = "any"; } else { $peer = "\@$peer"; } return $peer; } sub conv_dh_group { my $dhgrp = pop(@_); my $dh_group = ''; if ( $dhgrp eq "MODP_768" ) { $dh_group = 1; } elsif ( $dhgrp eq "MODP_1024" ) { $dh_group = 2; } elsif ( $dhgrp eq "MODP_1536" ) { $dh_group = 5; } elsif ( $dhgrp eq "MODP_2048" ) { $dh_group = 7; } elsif ( $dhgrp eq "" ) { $dh_group = "n/a"; } else { $dh_group = $dhgrp; } return $dh_group; } sub conv_hash { my $hash = pop(@_); if ( $hash =~ /.*_(.*)/ ) { $hash = lc($1); } return $hash; } sub conv_enc { my $enc = pop(@_); if ( $enc =~ /(.*?)_.*?_(.*)/ ) { $enc = lc($1) . $2; $enc =~ s/^ //g; } elsif ( $enc =~ /3DES/ ) { $enc = "3des"; } return $enc; } sub conv_natt { my $natt = pop(@_); if ( $natt == 0 ) { $natt = "no"; } else { $natt = "yes"; } return $natt; } sub conv_id_rev { my $peerid = pop(@_); if ( $peerid =~ /@(.*)/ ) { $peerid = $1; } return $peerid; } sub conv_bytes { my $bytes = pop(@_); my $suffix = ''; $bytes =~ s/\s+$//; if ( $bytes > 1024 && $bytes < 1048576 ) { $bytes = $bytes / 1024; $suffix = "K"; } elsif ( $bytes >= 1048576 && $bytes < 1073741824 ) { $bytes = $bytes / 1048576; $suffix = "M"; } elsif ( $bytes >= 1073741824 ) { $bytes = $bytes / 1073741824; $suffix = "G"; } $bytes = sprintf( "%.1f", $bytes ); $bytes = "$bytes$suffix"; } sub conv_ip { my $peerip = pop(@_); if ( $peerip =~ /\@.*/ ) { $peerip = "0.0.0.0"; } elsif ( $peerip =~ /\%any/ ) { $peerip = "0.0.0.0"; } return $peerip; } sub nat_detect { ( my $lip, my $rip ) = @_; my @values; if ( $lip =~ /(\d+\.\d+\.\d+\.\d+):(\d+)/ ) { push( @values, $1 ); push( @values, 1 ); push( @values, $2 ); } else { push( @values, $lip ); push( @values, 0 ); push( @values, 'n/a' ); } if ( $rip =~ /(\d+\.\d+\.\d+\.\d+):(\d+)/ ) { push( @values, $1 ); push( @values, $2 ); } else { push( @values, $rip ); push( @values, 'n/a' ); } return @values; } sub get_tunnel_info { my $cmd = "sudo ipsec statusall"; open( my $IPSECSTATUS,, '-|', $cmd ); my @ipsecstatus = []; while (<$IPSECSTATUS>) { push( @ipsecstatus, $_ ); } process_tunnels( \@ipsecstatus ); } sub get_tunnel_info_profile { my $profile = pop(@_); my @tunnels = split( ' ', `cli-shell-api listActiveNodes vpn ipsec profile $profile bind tunnel` ); my $static_conn_str = "vpnprof-tunnel-\\("; my $first_tun = 1; for my $tun (@tunnels) { if ($first_tun) { } else { $static_conn_str .= "\\|"; } $static_conn_str .= substr $tun, 1, -1; $first_tun = 0; } $static_conn_str .= "\\)"; my $dyn_conn_str = "\\("; my $first_addr = 1; for my $tun (@tunnels) { my @addresses = split( ' ', `cli-shell-api returnActiveValues interfaces tunnel $tun address` ); for my $addr (@addresses) { if ($first_addr) { } else { $dyn_conn_str .= "\\|"; } $dyn_conn_str .= substr $addr, 1, -4; $first_addr = 0; } } $dyn_conn_str .= "\\)-to-"; my $search_str = "\\($static_conn_str\\)\\|\\($dyn_conn_str\\)"; my $cmd = "sudo ipsec statusall | grep \"$search_str\""; open( my $IPSECSTATUS,, '-|', $cmd ); my @ipsecstatus = []; while (<$IPSECSTATUS>) { push( @ipsecstatus, $_ ); } process_tunnels( \@ipsecstatus ); } sub process_tunnels { my @ipsecstatus = @{ pop(@_) }; my %tunnel_hash = (); foreach my $line (@ipsecstatus) { if ( ( $line =~ /\"(vpnprof-tunnel-.*?)\"/ ) || ( $line =~ /\"(.*-to-.*)\"/ ) ) { my $connectid = $1; if ( ( $line =~ /\"(vpnprof-tunnel-.*?)\"(\[\d*\])/ ) ) { $connectid .= $2; } my $tunid = ""; if ( ( $connectid =~ /vpnprof-tunnel-(.*)/ ) ) { $tunid = $1; } else { # this is for whack connection, we are to find tunid for it. $line =~ /\"(.*)-to-(.*)\"/; my $lip = $1; my @tunnels = split( ' ', `cli-shell-api listActiveNodes interfaces tunnel` ); for my $tun (@tunnels) { my @addresses = split( ' ', `cli-shell-api returnActiveValues interfaces tunnel $tun address` ); for my $addr (@addresses) { my $tst = index $addr, $lip; if ( $tst > -1 ) { $tunid = substr $tun, 1, -1; } } } } if ( not exists $tunnel_hash{$connectid} ) { $tunnel_hash{$connectid} = { _peerid => undef, _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 =~ /IKE.proposal:(.*?)\/(.*?)\/(.*)/ ) { $tunnel_hash{$connectid}->{_ikeencrypt} = $1; $tunnel_hash{$connectid}->{_ikehash} = $2; $tunnel_hash{$connectid}->{_dhgrp} = $3; } # both subnets elsif ( $line =~ /: (.*?)===(.*?)\[(.*?)\]\.\.\.(.*?)\[(.*?)\]===(.*?);/ ) { my $lsnet = $1; my $lip = $2; my $lid = $3; my $rip = $4; my $rid = $5; my $rsnet = $6; ( $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}->{_lsnet} = $lsnet; $tunnel_hash{$connectid}->{_rid} = conv_id($rid); $tunnel_hash{$connectid}->{_rip} = $rip; $tunnel_hash{$connectid}->{_rsnet} = $rsnet; $tunnel_hash{$connectid}->{_natt} = $natt; $tunnel_hash{$connectid}->{_natsrc} = $natsrc; $tunnel_hash{$connectid}->{_natdst} = $natdst; } #left subnet elsif ( $line =~ /: (.*?)\[(.*?)\]\.\.\.(.*?)\[(.*?)\];/ ) { my $lip = $1; my $lid = $2; my $rip = $3; my $rid = $4; my $lsnet; if ( $lip =~ /(.*?)===(.*)/ ) { $lsnet = $1; $lip = $2; } ( $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; $tunnel_hash{$connectid}->{_lsnet} = $lsnet if ( defined($lsnet) ); } #left subnet with protocols elsif ( $line =~ /: (.*?)\[(.*?)\]:(\d+)\/(\d+)\.\.\.(.*?)\[(.*?)\]:(\d+)\/(\d+);/ ) { my $lip = $1; my $lsnet; my $lid = $2; my $lproto = conv_protocol($3); my $lport = $4; my $rip = $5; my $rid = $6; my $rproto = conv_protocol($7); my $rport = $8; if ( $lip =~ /(.*?)===(.*)/ ) { $lsnet = $1; $lip = $2; } ( $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}->{_lsnet} = $lsnet if ( defined($lsnet) ); $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; $tunnel_hash{$connectid}->{_lproto} = "$lproto"; $tunnel_hash{$connectid}->{_rproto} = "$rproto"; $tunnel_hash{$connectid}->{_lport} = "$lport"; $tunnel_hash{$connectid}->{_rport} = "$rport"; } # both proto/port and subnets elsif ( $line =~ /: (.*)===(.*?)\[(.*?)\]:(\d+)\/(\d+)\.\.\.(.*?)\[(.*?)\]:(\d+)\/(\d+)===(.*?);/ ) { my $lsnet = $1; my $lip = $2; my $lid = $3; my $lproto = conv_protocol($4); my $lport = $5; my $rip = $6; my $rid = $7; my $rproto = conv_protocol($8); my $rport = $9; my $rsnet = $10; my $lprotoport; my $rprotoport; $lprotoport = $lproto if ( $lport == 0 ); $lprotoport = "$lproto/$lport" if ( $lport != 0 ); $rprotoport = $rproto if ( $rport == 0 ); $rprotoport = "$rproto/$rport" if ( $rport != 0 ); ( $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}->{_lsnet} = $lsnet; $tunnel_hash{$connectid}->{_rid} = conv_id($rid); $tunnel_hash{$connectid}->{_rip} = $rip; $tunnel_hash{$connectid}->{_rsnet} = $rsnet; $tunnel_hash{$connectid}->{_lproto} = "$lproto"; $tunnel_hash{$connectid}->{_rproto} = "$rproto"; $tunnel_hash{$connectid}->{_lport} = "$lport"; $tunnel_hash{$connectid}->{_rport} = "$rport"; $tunnel_hash{$connectid}->{_natt} = $natt; $tunnel_hash{$connectid}->{_natsrc} = $natsrc; $tunnel_hash{$connectid}->{_natdst} = $natdst; } # right proto/port only with subnet elsif ( $line =~ /: (.*)===(.*?)\[(.*?)\]\.\.\.(.*?)\[(.*?)\]:(\d+)\/(\d+)===(.*?);/ ) { my $lsnet = $1; my $lip = $2; my $lid = $3; my $rip = $4; my $rid = $5; my $rproto = conv_protocol($6); my $rport = $7; my $rsnet = $8; my $lprotoport; my $rprotoport; $rprotoport = $rproto if ( $rport == 0 ); $rprotoport = "$rproto/$rport" if ( $rport != 0 ); ( $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}->{_lsnet} = $lsnet; $tunnel_hash{$connectid}->{_rid} = conv_id($rid); $tunnel_hash{$connectid}->{_rip} = $rip; $tunnel_hash{$connectid}->{_rsnet} = $rsnet; $tunnel_hash{$connectid}->{_rproto} = "$rproto"; $tunnel_hash{$connectid}->{_rport} = "$rport"; $tunnel_hash{$connectid}->{_natt} = $natt; $tunnel_hash{$connectid}->{_natsrc} = $natsrc; $tunnel_hash{$connectid}->{_natdst} = $natdst; } # left proto/port only with subnet elsif ( $line =~ /: (.*)===(.*?)\[(.*?)\]:(\d+)\/(\d+)\.\.\.(.*?)\[(.*?)\]===(.*?);/ ) { my $lsnet = $1; my $lip = $2; my $lid = $3; my $lproto = conv_protocol($4); my $lport = $5; my $rip = $6; my $rid = $7; my $rsnet = $8; my $lprotoport; my $rprotoport; $lprotoport = $lproto if ( $lport == 0 ); $lprotoport = "$lproto/$lport" if ( $lport != 0 ); ( $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}->{_lsnet} = $lsnet; $tunnel_hash{$connectid}->{_rid} = conv_id($rid); $tunnel_hash{$connectid}->{_rip} = $rip; $tunnel_hash{$connectid}->{_rsnet} = $rsnet; $tunnel_hash{$connectid}->{_lproto} = "$lproto"; $tunnel_hash{$connectid}->{_lport} = "$lport"; $tunnel_hash{$connectid}->{_natt} = $natt; $tunnel_hash{$connectid}->{_natsrc} = $natsrc; $tunnel_hash{$connectid}->{_natdst} = $natdst; } elsif ( $line =~ /ESP.proposal:(.*?)\/(.*?)\/(.*)/ ) { $tunnel_hash{$connectid}->{_encryption} = $1; $tunnel_hash{$connectid}->{_hash} = $2; $tunnel_hash{$connectid}->{_pfsgrp} = $3; } elsif ( $line =~ /STATE_MAIN_I1/ ) { $tunnel_hash{$connectid}->{_ikestate} = "init"; } elsif ( $line =~ /newest ISAKMP SA: (.*); newest IPsec SA: (.*);/ ) { if ( $tunnel_hash{$connectid}->{_newestike} ne 'n/a' ) { if ( $tunnel_hash{$connectid}->{_newestike} lt $1 ) { $tunnel_hash{$connectid}->{_newestike} = $1; } } else { $tunnel_hash{$connectid}->{_newestike} = $1; } if ( $tunnel_hash{$connectid}->{_newestspi} ne 'n/a' ) { if ( $tunnel_hash{$connectid}->{newestspi} lt $2 ) { $tunnel_hash{$connectid}->{_newestspi} = $2; } } else { $tunnel_hash{$connectid}->{_newestspi} = $2; } } elsif ( $line =~ /ike_life: (.*?)s; ipsec_life: (.*?)s;/ ) { $tunnel_hash{$connectid}->{_ikelife} = $1; $tunnel_hash{$connectid}->{_lifetime} = $2; } elsif ( $line =~ /CAs: (.*?)\.\.\.(.*)/ ) { $tunnel_hash{$connectid}->{_lca} = $1; $tunnel_hash{$connectid}->{_rca} = $2; } my $ike = $tunnel_hash{$connectid}->{_newestike}; if ( $ike ne 'n/a' ) { if ( $line =~ /$ike:.*ISAKMP.SA.established.*EVENT_SA_REPLACE.in.(.*?)s;/ ) { $tunnel_hash{$connectid}->{_ikeexpire} = $1; my $atime = $tunnel_hash{$connectid}->{_ikelife} - $tunnel_hash{$connectid}->{_ikeexpire}; if ( $atime >= 0 ) { $tunnel_hash{$connectid}->{_ikestate} = "up"; } } if ( $line =~ /$ike:.*ISAKMP.SA.established.*EVENT_SA_EXPIRE.in.(.*?)s;/ ) { $tunnel_hash{$connectid}->{_ikeexpire} = $1; my $atime = $tunnel_hash{$connectid}->{_ikelife} - $tunnel_hash{$connectid}->{_ikeexpire}; if ( $atime >= 0 ) { $tunnel_hash{$connectid}->{_ikestate} = "up"; } } } my $spi = $tunnel_hash{$connectid}->{_newestspi}; if ( $spi ne 'n/a' ) { if ( $line =~ /$spi:.*esp.(.*)\@.*\((.*)bytes.*esp.(.*)\@.*/ ) { $tunnel_hash{$connectid}->{_outspi} = $1; $tunnel_hash{$connectid}->{_outbytes} = $2; $tunnel_hash{$connectid}->{_inspi} = $3; } if ( $line =~ /$spi:.*esp.(.*)\@.*esp.(.*)\@.*\((.*)bytes/ ) { $tunnel_hash{$connectid}->{_outspi} = $1; $tunnel_hash{$connectid}->{_inspi} = $2; $tunnel_hash{$connectid}->{_inbytes} = $3; } if ( $line =~ /$spi:.*esp.(.*)\@.*\((.*)bytes.*esp.(.*)\@.*\((.*)bytes/ ) { $tunnel_hash{$connectid}->{_outspi} = $1; $tunnel_hash{$connectid}->{_outbytes} = $2; $tunnel_hash{$connectid}->{_inspi} = $3; $tunnel_hash{$connectid}->{_inbytes} = $4; } if ( $line =~ /$spi:.*?EVENT_SA_REPLACE.*? in (.*?)s;/ ) { $tunnel_hash{$connectid}->{_expire} = $1; my $atime = $tunnel_hash{$connectid}->{_lifetime} - $tunnel_hash{$connectid}->{_expire}; if ( $atime >= 0 ) { $tunnel_hash{$connectid}->{_state} = "up"; } } if ( $line =~ /$spi:.*?EVENT_SA_EXPIRE in (.*?)s;/ ) { $tunnel_hash{$connectid}->{_expire} = $1; my $atime = $tunnel_hash{$connectid}->{_lifetime} - $tunnel_hash{$connectid}->{_expire}; if ( $atime >= 0 ) { $tunnel_hash{$connectid}->{_state} = "up"; } } } } } return %tunnel_hash; } sub get_conns { my $cmd = "sudo cat /etc/dmvpn.conf"; open( my $IPSECCONF, '-|', $cmd ); my @ipsecconf = []; while (<$IPSECCONF>) { push( @ipsecconf, $_ ); } my %th = (); for my $line (@ipsecconf) { next if ( $line =~ /^\#/ ); if ( $line =~ /vpnprof-tunnel-(.*)/ ) { my $tun = $1; if ( not exists $th{$tun} ) { $th{$tun} = { _conns => [$tun], _tunid => $tun }; } else { push( @{ $th{$tun}->{_conns} }, $tun ); } } } return %th; } sub get_profiles_for_cli { my @profiles = split( ' ', `cli-shell-api listActiveNodes vpn ipsec profile` ); for my $prof (@profiles) { print substr $prof, 1, -1; print "\n"; } } sub get_conn_for_cli { my $profileid = pop(@_); my %th = get_conns(); for my $tun ( keys %th ) { for my $conn ( @{ $th{$tun}->{_conns} } ) { print "$conn\n"; } } } sub profileSort { #TODO: It's not used now. Should implement smth meaningfull or delete this sub sort { $a->[0] <=> $b->[0]; } @_; } sub tunSort { #TODO: not used now. Early it was sorting tun ids as numbers, but now we have 'tunX' as tunid. sort { $a->[0] <=> $b->[0]; } @_; } sub show_ipsec_sa { my %tunnel_hash = get_tunnel_info(); display_ipsec_sa_brief( \%tunnel_hash ); } sub show_ipsec_sa_detail { my %tunnel_hash = get_tunnel_info(); display_ipsec_sa_detail( \%tunnel_hash ); } sub show_ipsec_sa_stats { my %tunnel_hash = get_tunnel_info(); display_ipsec_sa_stats( \%tunnel_hash ); } sub show_ipsec_sa_profile { my $profile = pop(@_); my %tunnel_hash = get_tunnel_info_profile($profile); display_ipsec_sa_brief( \%tunnel_hash ); } sub show_ipsec_sa_stats_profile { my $profile = pop(@_); my %tunnel_hash = get_tunnel_info_profile($profile); display_ipsec_sa_stats( \%tunnel_hash ); } sub show_ipsec_sa_stats_conn { my %tmphash = (); ( my $profileid, my $tun ) = @_; my %th = get_tunnel_info_profile($profileid); for my $profile ( keys %th ) { if ( $th{$profile}->{_tunnelnum} eq $tun ) { $tmphash{$profile} = \%{ $th{$profile} }; } } display_ipsec_sa_stats( \%tmphash ); } sub show_ipsec_sa_profile_detail { my $profileid = pop(@_); my %tunnel_hash = get_tunnel_info_profile($profileid); display_ipsec_sa_detail( \%tunnel_hash ); } sub show_ipsec_sa_conn_detail { my %tmphash = (); ( my $profileid, my $tun ) = @_; my %th = get_tunnel_info_profile($profileid); for my $profile ( keys %th ) { if ( $th{$profile}->{_tunnelnum} eq $tun ) { $tmphash{$profile} = \%{ $th{$profile} }; } } display_ipsec_sa_detail( \%tmphash ); } sub show_ipsec_sa_conn { my %tmphash = (); ( my $profileid, my $tun ) = @_; my %th = get_tunnel_info_profile($profileid); for my $profile ( keys %th ) { if ( $th{$profile}->{_tunnelnum} eq $tun ) { $tmphash{$profile} = \%{ $th{$profile} }; } } display_ipsec_sa_brief( \%tmphash ); } sub display_ipsec_sa_brief { my %th = %{ pop(@_) }; my $listref = []; my %tunhash = (); my $myid = undef; my $peerid = undef; for my $connectid ( keys %th ) { $peerid = conv_ip( $th{$connectid}->{_rip} ); my $lip = conv_ip( $th{$connectid}->{_lip} ); my $tunnel = "$peerid-$lip"; my $peer_configured = conv_id_rev( $th{$connectid}->{_peerid} ); if ( not exists $tunhash{$tunnel} ) { $tunhash{$tunnel} = { _outspi => $th{$connectid}->{_outspi}, _natt => $th{$connectid}->{_natt}, _lip => $lip, _peerid => $peer_configured, _tunnels => [] }; } my @tmp = ( $th{$connectid}->{_tunnelnum}, $th{$connectid}->{_state}, $th{$connectid}->{_inbytes}, $th{$connectid}->{_outbytes}, $th{$connectid}->{_encryption}, $th{$connectid}->{_hash}, $th{$connectid}->{_lifetime}, $th{$connectid}->{_lproto}, $th{$connectid}->{_expire} ); push( @{ $tunhash{"$tunnel"}->{_tunnels} }, [@tmp] ); } for my $connid ( keys %tunhash ) { print <{_tunnels} } ) { ( my $tunnum, my $state, my $inbytes, my $outbytes, my $enc, my $hash, my $life, my $proto, my $expire ) = @{$tunnel}; my $lip = $tunhash{$connid}->{_lip}; my $peerip = conv_ip($peerid); my $natt = $tunhash{$connid}->{_natt}; my $bytesp = 'n/a'; $enc = conv_enc($enc); $hash = conv_hash($hash); $natt = conv_natt($natt); if ( !( $inbytes eq 'n/a' && $outbytes eq 'n/a' ) ) { $outbytes = conv_bytes($outbytes); $inbytes = conv_bytes($inbytes); $bytesp = "$outbytes/$inbytes"; } my $atime = $life - $expire; $atime = 0 if ( $atime == $life ); printf " %-7s %-6s %-14s %-8s %-5s %-6s %-7s %-7s %-2s\n", $tunnum, $state, $bytesp, $enc, $hash, $natt, $atime, $life, $proto; } print "\n \n"; } } sub display_ipsec_sa_detail { my %th = %{ pop(@_) }; my $listref = []; my %tunhash = (); my $myid = undef; my $peerid = undef; for my $connectid ( keys %th ) { my $lip = conv_ip( $th{$connectid}->{_lip} ); $peerid = conv_ip( $th{$connectid}->{_rip} ); my $tunnel = "$peerid-$lip"; if ( not exists $tunhash{$tunnel} ) { $tunhash{$tunnel} = { _peerip => $th{$connectid}->{_rip}, _peerid => $th{$connectid}->{_rid}, _configpeer => conv_id_rev( $th{$connectid}->{_peerid} ), _localip => $th{$connectid}->{_lip}, _localid => $th{$connectid}->{_lid}, _dhgrp => $th{$connectid}->{_dhgrp}, _natt => $th{$connectid}->{_natt}, _natsrc => $th{$connectid}->{_natsrc}, _natdst => $th{$connectid}->{_natdst}, _tunnels => [] }; } my @tmp = ( $th{$connectid}->{_tunnelnum}, $th{$connectid}->{_state}, $th{$connectid}->{_inspi}, $th{$connectid}->{_outspi}, $th{$connectid}->{_encryption}, $th{$connectid}->{_hash}, $th{$connectid}->{_pfsgrp}, $th{$connectid}->{_lsnet}, $th{$connectid}->{_rsnet}, $th{$connectid}->{_inbytes}, $th{$connectid}->{_outbytes}, $th{$connectid}->{_lifetime}, $th{$connectid}->{_expire}, $th{$connectid}->{_lca}, $th{$connectid}->{_rca}, $th{$connectid}->{_lproto}, $th{$connectid}->{_rproto}, $th{$connectid}->{_lport}, $th{$connectid}->{_rport} ); push( @{ $tunhash{$tunnel}->{_tunnels} }, [@tmp] ); } for my $connid ( keys %tunhash ) { my $natt = conv_natt( $tunhash{$connid}->{_natt} ); my $peerip = conv_ip( $tunhash{$connid}->{_peerip} ); my $localid = $tunhash{$connid}->{_localid}; if ( $localid =~ /CN=(.*?),/ ) { $localid = $1; } my $peerid = $tunhash{$connid}->{_peerid}; if ( $peerid =~ /CN=(.*?),/ ) { $peerid = $1; } print "------------------------------------------------------------------\n"; print "Peer IP:\t\t$peerip\n"; print "Peer ID:\t\t$peerid\n"; print "Local IP:\t\t$tunhash{$connid}->{_localip}\n"; print "Local ID:\t\t$localid\n"; print "NAT Traversal:\t\t$natt\n"; print "NAT Source Port:\t$tunhash{$connid}->{_natsrc}\n"; print "NAT Dest Port:\t\t$tunhash{$connid}->{_natdst}\n"; print "\n"; for my $tunnel ( tunSort( @{ $tunhash{$connid}->{_tunnels} } ) ) { ( my $tunnum, my $state, my $inspi, my $outspi, my $enc, my $hash, my $pfsgrp, my $srcnet, my $dstnet, my $inbytes, my $outbytes, my $life, my $expire, my $lca, my $rca, my $lproto, my $rproto, my $lport, my $rport ) = @{$tunnel}; $enc = conv_enc($enc); $hash = conv_hash($hash); $lport = 'all' if ( $lport eq '0' ); $rport = 'all' if ( $rport eq '0' ); $pfsgrp = conv_dh_group($pfsgrp); my $atime = $life - $expire; $atime = 0 if ( $atime == $life ); $inbytes = conv_bytes($inbytes); $outbytes = conv_bytes($outbytes); print " Tunnel $tunnum:\n"; print " State:\t\t\t$state\n"; print " Inbound SPI:\t\t$inspi\n"; print " Outbound SPI:\t\t$outspi\n"; print " Encryption:\t\t$enc\n"; print " Hash:\t\t\t$hash\n"; print " PFS Group:\t\t$pfsgrp\n"; if ( defined $lca ) { print " \n"; print " CA:\n"; foreach my $field ( split( ', ', $lca ) ) { $field =~ s/\"//g; print " $field\n"; } } #print " Local CA:\t\t$lca\n" if defined($lca); #print " Right CA:\t\t$rca\n" if defined($rca); print " \n"; print " Local Net:\t\t$srcnet\n"; print " Local Protocol:\t\t$lproto\n"; print " Local Port: \t\t$lport\n"; print " \n"; print " Remote Net:\t\t$dstnet\n"; print " Remote Protocol:\t$rproto\n"; print " Remote Port: \t\t$rport\n"; print " \n"; print " Inbound Bytes:\t\t$inbytes\n"; print " Outbound Bytes:\t\t$outbytes\n"; print " Active Time (s):\t$atime\n"; print " Lifetime (s):\t\t$life\n"; print " \n"; } print "\n"; } } sub display_ipsec_sa_stats { my %th = %{ pop(@_) }; my $listref = []; my %tunhash = (); my $myid = undef; my $peerid = undef; for my $connectid ( keys %th ) { my $lip = conv_ip( $th{$connectid}->{_lip} ); $peerid = conv_ip( $th{$connectid}->{_rip} ); my $tunnel = "$peerid-$lip"; if ( not exists $tunhash{$tunnel} ) { $tunhash{$tunnel} = { _configpeer => conv_id_rev( $th{$connectid}->{_peerid} ), _tunnels => [] }; } my @tmp = ( $th{$connectid}->{_tunnelnum}, $th{$connectid}->{_lsnet}, $th{$connectid}->{_rsnet}, $th{$connectid}->{_inbytes}, $th{$connectid}->{_outbytes} ); push( @{ $tunhash{$tunnel}->{_tunnels} }, [@tmp] ); } for my $connid ( keys %tunhash ) { print <{_tunnels} } ) ) { ( my $tunnum, my $srcnet, my $dstnet, my $inbytes, my $outbytes ) = @{$tunnel}; printf " %-6s %-3s %-28s %-28s %-8s\n", $tunnum, 'in', $dstnet, $srcnet, $inbytes; printf " %-6s %-3s %-28s %-28s %-8s\n", $tunnum, 'out', $srcnet, $dstnet, $outbytes; } print "\n \n"; } } 1;