summaryrefslogtreecommitdiffstats
path: root/lib/Smokeping/probes/AnotherSSH.pm
diff options
context:
space:
mode:
authorNiko Tyni <ntyni@iki.fi>2005-02-13 20:23:04 +0100
committerNiko Tyni <ntyni@iki.fi>2005-02-13 20:23:04 +0100
commit6d76521656e91daa160bc8019828f1b68d7aa5dc (patch)
treeaaa27615a0702942fa1606d9a5c89f0a3547467c /lib/Smokeping/probes/AnotherSSH.pm
parent6dba1afbe4b475a7d34f5ef867b7b37291cd1484 (diff)
downloadsmokeping-6d76521656e91daa160bc8019828f1b68d7aa5dc.tar.gz
smokeping-6d76521656e91daa160bc8019828f1b68d7aa5dc.tar.xz
Moved probes, matchers and ciscoRttMonMIB modules to lib/Smokeping.
Diffstat (limited to 'lib/Smokeping/probes/AnotherSSH.pm')
-rw-r--r--lib/Smokeping/probes/AnotherSSH.pm238
1 files changed, 238 insertions, 0 deletions
diff --git a/lib/Smokeping/probes/AnotherSSH.pm b/lib/Smokeping/probes/AnotherSSH.pm
new file mode 100644
index 0000000..c708de9
--- /dev/null
+++ b/lib/Smokeping/probes/AnotherSSH.pm
@@ -0,0 +1,238 @@
+package Smokeping::probes::AnotherSSH;
+
+=head1 301 Moved Permanently
+
+This is a Smokeping probe module. Please use the command
+
+C<smokeping -man Smokeping::probes::AnotherSSH>
+
+to view the documentation or the command
+
+C<smokeping -makepod Smokeping::probes::AnotherSSH>
+
+to generate the POD document.
+
+=cut
+
+use strict;
+use base qw(Smokeping::probes::basefork);
+use Carp;
+use Time::HiRes qw(sleep ualarm gettimeofday tv_interval);
+use IO::Select;
+use Socket;
+use Fcntl;
+
+sub pod_hash {
+ return {
+ name => <<DOC,
+Smokeping::probes::AnotherSSH - Another SSH probe
+DOC
+ description => <<DOC,
+Latency measurement using SSH. This generates Logfile messages on the other
+Host, so get permission from the owner first!
+DOC
+ authors => <<'DOC',
+Christoph Heine <Christoph.Heine@HaDiKo.DE>
+DOC
+ }
+}
+
+sub new($$$) {
+ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my $self = $class->SUPER::new(@_);
+ return $self;
+}
+
+sub ProbeDesc($) {
+ my $self = shift;
+ return "SSH connections";
+}
+
+sub pingone ($) {
+ my $self = shift;
+ my $target = shift;
+
+ my $host = $target->{addr};
+
+ # Time
+ my $mininterval = $target->{vars}{mininterval};
+
+ # Our greeting string.
+ my $greeting = $target->{vars}{greeting};
+
+ # Interval to measure
+ my $interval = $target->{vars}{interval};
+
+ # Connect to this port.
+ my $port = $target->{vars}{port};
+
+ #Timeout for the select() calls.
+ my $timeout = $target->{vars}{timeout};
+
+ my @times; # Result times
+
+ my $t0;
+ for ( my $run = 0 ; $run < $self->pings($target) ; $run++ ) {
+ if (defined $t0) {
+ my $elapsed = tv_interval($t0, [gettimeofday]);
+ my $timeleft = $mininterval - $elapsed;
+ sleep $timeleft if $timeleft > 0;
+ }
+ my ($t1,$t2,$t3); # Timestamps.
+
+ #Temporary variables to play with.
+ my $ready;
+ my $buf;
+ my $nbytes;
+
+ my $proto = getprotobyname('tcp');
+ my $iaddr = gethostbyname($host);
+ my $sin = sockaddr_in( $port, $iaddr );
+ socket( Socket_Handle, PF_INET, SOCK_STREAM, $proto );
+
+ # Make the Socket non-blocking
+ my $flags = fcntl( Socket_Handle, F_GETFL, 0 ) or do {
+ $self->do_debug("Can't get flags for socket: $!");
+ close(Socket_Handle);
+ next;
+ };
+
+ fcntl( Socket_Handle, F_SETFL, $flags | O_NONBLOCK ) or do {
+ $self->do_debug("Can't make socket nonblocking: $!");
+ close(Socket_Handle); next;
+ };
+
+ my $sel = IO::Select->new( \*Socket_Handle );
+
+ # connect () and measure the Time.
+ $t0 = [gettimeofday];
+ connect( Socket_Handle, $sin );
+ ($ready) = $sel->can_read($timeout);
+ $t1 = [gettimeofday];
+
+ if(not defined $ready) {
+ $self->do_debug("Timeout!");
+ close(Socket_Handle); next;
+ }
+ $nbytes = sysread( Socket_Handle, $buf, 1500 );
+ if (not defined $nbytes or $nbytes <= 0) {
+ $self->do_debug("Read nothing and Connection closed!");
+ close(Socket_Handle); next;
+ }
+ # $self->do_debug("Got '$buf' from remote Server");
+ if (not $buf =~ m/^SSH/) {
+ $self->do_debug("Not an SSH Server");
+ close(Socket_Handle); next;
+ }
+
+ ($ready) = $sel->can_write($timeout);
+ if (not defined($ready)) {
+ $self->do_debug("Huh? Can't write.");
+ close(Socket_Handle); next;
+ }
+ $t2 = [gettimeofday];
+ syswrite( Socket_Handle, $greeting . "\n" );
+ ($ready) = $sel->can_read($timeout);
+ $t3 = [gettimeofday];
+ if(not defined $ready) {
+ $self->do_debug("Timeout!");
+ close(Socket_Handle); next;
+ }
+ close(Socket_Handle);
+
+ # We made it! Yeah!
+
+ if( $interval eq "connect") {
+ push @times, tv_interval( $t0, $t1 );
+ } elsif ( $interval eq "established") {
+ push @times, tv_interval($t2,$t3);
+ } elsif ($interval eq "complete") {
+ push @times, tv_interval($t0,$t3);
+ } else {
+ $self->do_debug("You should never see this message.\n The universe will now collapse. Goodbye!\n");
+ }
+
+
+ }
+ @times =
+ map { sprintf "%.10e", $_ } sort { $a <=> $b } grep { $_ ne "-" } @times;
+
+ return @times;
+}
+
+sub probevars {
+ my $class = shift;
+ my $h = $class->SUPER::probevars;
+ delete $h->{timeout};
+ return $h;
+}
+
+sub targetvars {
+ my $class = shift;
+ my $e = "=";
+ return $class->_makevars($class->SUPER::targetvars, {
+ greeting => {
+ _doc => <<DOC,
+Greeting string to send to the SSH Server. This will appear in the Logfile.
+Use this to make clear, who you are and what you are doing to avoid confusion.
+
+Also, don't use something that is a valid version string. This probe assumes
+that the connection gets terminated because of protocol mismatch.
+DOC
+ _default => "SSH-Latency-Measurement-Sorry-for-this-logmessage" ,
+ },
+ mininterval => {
+ _doc => "Minimum interval between the start of two connection attempts in (possibly fractional) seconds.",
+ _default => 0.5,
+ _re => '(\d*\.)?\d+',
+ },
+ interval => {
+ _doc => <<DOC,
+The interval to be measured. One of:
+
+${e}over
+
+${e}item connect
+
+Interval between connect() and the greeting string from the host.
+
+${e}item established
+
+Interval between our greeting message and the end of the connection
+because of Protocol mismatch. This is the default.
+
+${e}item complete
+
+From connect() to the end of the connection.
+
+${e}back
+
+DOC
+
+ _sub => sub {
+ my $interval = shift;
+ if(not ( $interval eq "connect"
+ or $interval eq "established"
+ or $interval eq "complete")) {
+ return "ERROR: Invalid interval parameter";
+ }
+ return undef;
+ },
+ _default => 'established',
+ },
+ timeout => {
+ _doc => 'Timeout for the connection.',
+ _re => '\d+',
+ _default => 5,
+ },
+ port => {
+ _doc => 'Connect to this port.',
+ _re => '\d+',
+ _default => 22,
+ },
+ });
+}
+
+1;
+