package probes::SshFPing; =head1 NAME probes::SshFPing - SshFPing Probe for SmokePing =head1 SYNOPSIS *** Probes *** + SshFPing binary = /usr/local/sbin/fping ssh_bin = /usr/local/OpenSSH/bin/ssh ssh_host = localhost pre_pings = 0 =head1 DESCRIPTION Integrates a remote call from FPing using Ssh as a probe into smokeping. The variable B must point to your copy of the FPing program. If it is not installed on your system yet, you can get it from http://www.fping.com/. The variable B should contain the hostname where the FPing command should be executed via the Ssh program. The variable B should point to your copy of the Ssh program. The variable B may contain the number of extra pre pings that will not be counted. When unspecified, no pre pings will be used. =head1 AUTHOR Tobias Oetiker Hans Blom =cut use strict; use base qw(probes::basefork); use IPC::Open3; use Symbol; use Carp; sub new($$$) { my $proto = shift; my $class = ref($proto) || $proto; my $self = $class->SUPER::new(@_); my $binary = $self->{properties}{binary}; my $ssh_bin = $self->{properties}{ssh_bin}; croak "ERROR: SshFPing 'binary' not defined in SshFPing probe definition" unless defined $binary; croak "ERROR: SshFPing 'ssh_bin' not defined in SshFPing probe definition" unless defined $ssh_bin; croak "ERROR: SshFPing 'ssh_bin' does not point to an executable" unless -f $ssh_bin and -x $ssh_bin; $_ = `$binary -C 1 localhost 2>&1`; if (m/bytes, ([0-9.]+)\sms\s+.*\n.*\n.*:\s+([0-9.]+)/){ $self->{pingfactor} = 1000 * $2/$1; print "### fping seems to report in ", $1/$2, " miliseconds\n" unless $ENV{SERVER_SOFTWARE}; } else { $self->{pingfactor} = 1000; # Gives us a good-guess default print "### assuming you are using an fping copy reporting in miliseconds\n" unless $ENV{SERVER_SOFTWARE}; }; return $self; } sub ProbeDesc($){ my $self = shift; my $desc = "ICMP Echo Pings"; my $pre_pings = $self->{properties}->{pre_pings}; if (!defined $pre_pings) { $pre_pings = 0; } if ($pre_pings > 0) { $desc .= " (with $pre_pings pre pings)"; } return $desc; } sub pingone ($$){ my $self = shift; my $target = shift; # do NOT call superclass ... the pingone method MUST be overwriten my $host = $target->{addr}; my $ssh_host = $self->{properties}->{ssh_host}; if (!defined $ssh_host) { $ssh_host = $target->{vars}->{ssh_host}; } croak "ERROR: SshFPing 'ssh_host' not defined in SshFPing probe definition" unless defined $ssh_host; my $pre_pings = $self->{properties}->{pre_pings}; if (!defined $pre_pings) { $pre_pings = $target->{vars}->{pre_pings}; } if (!defined $pre_pings) { $pre_pings = 0; } my $all_pings = $self->{cfg}{Database}{pings} + $pre_pings; my $inh = gensym; my $outh = gensym; my $errh = gensym; my $pid = open3($inh,$outh,$errh, $self->{properties}{ssh_bin}, $ssh_host, $self->{properties}{binary}, '-C', $all_pings, '-q', $host); $self->{rtts}={}; my @times = (); while (<$errh>){ chomp; @times = split /\s+/; my $ip = shift @times; next unless ':' eq shift @times; #drop the colon splice @times, 0, $pre_pings; #drop the pre pings, if any @times = map {sprintf "%.10e", $_ / $self->{pingfactor}} sort {$a <=> $b} grep {$_ ne "-"} @times; } waitpid $pid,0; close $inh; close $outh; close $errh; return @times; } 1;