#!/usr/bin/perl # check_cisco_command - telnet's to a Cisco router to run a command # License Information: # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # ############################################################################ use strict; use Getopt::Long; use vars qw($opt_d $opt_u $opt_p $opt_P $opt_h $opt_H $opt_V $opt_v $debug $username $password $hostname $state $error $PROGNAME @command_output $session $command $opt_r $tmp_var_loss $tmp_var_latency $opt_c $opt_w $info $answer $opt_m $metric $warning_rta $warning_pl $timeout $router $critical_rta $critical_pl $opt_t $vrf $stats); use lib "utils.pm"; use utils qw(%ERRORS &print_revision &support &usage ); use Net::Telnet::Cisco; sub print_help (); sub print_usage (); $ENV{'PATH'}=''; $ENV{'BASH_ENV'}=''; $ENV{'ENV'}=''; # defaults my $debug = 0; my $state = $ERRORS{'UNKNOWN'}; my $packets = 5; my $command = "ping"; my $timeout = $packets * 4; # seconds my $router = ""; my $username = ""; my $password = ""; my $warning_rta = ""; my $critical_rta = ""; my $warning_pl = ""; my $critical_pl = ""; Getopt::Long::Configure('bundling'); GetOptions( "d" => \$opt_d, "debug" => \$opt_d, "V" => \$opt_V, "version" => \$opt_V, "u=s" => \$opt_u, "username=s" => \$opt_u, "p=s" => \$opt_p, "password=s" => \$opt_p, "r=s" => \$opt_r, "router=s" => \$opt_r, "v=s" => \$opt_v, "vrf=s" => \$opt_v, "P=i" => \$opt_P, "packets=i" => \$opt_P, "w=s" => \$opt_w, "warning=s" => \$opt_w, "c=s" => \$opt_c, "critical=s" => \$opt_c, "h" => \$opt_h, "help" => \$opt_h, "t=i" => \$opt_t, "timeout=i" => \$opt_t, "H=s" => \$opt_H, "hostname=s" => \$opt_H); $PROGNAME = "check_cisco_ping"; if ($opt_d) { $debug = 1; } if ($opt_V) { print_revision($PROGNAME,'$Revision: 1.1 $'); exit $ERRORS{'OK'}; } if ($opt_h) {print_help(); exit $ERRORS{'OK'};} unless (defined $opt_H) { print("No target hostname specified\n"); print_usage(); exit $ERRORS{"UNKNOWN"}; } $hostname = $opt_H; if (! utils::is_hostname($hostname)){ print("$hostname did not match pattern\n"); print_usage(); exit $ERRORS{"UNKNOWN"}; } unless (defined $opt_u) { print("So who exactly do I login as ?\n"); print_usage(); exit $ERRORS{"UNKNOWN"}; } $username = $opt_u; unless (defined $opt_p) { print("So how exactly do I prove my identity ?\n"); print_usage(); exit $ERRORS{"UNKOWN"}; } $password = $opt_p; unless (defined $opt_r) { print("I need to know what router to login to\n"); print_usage(); exit $ERRORS{"UNKNOWN"}; } if (! utils::is_hostname($opt_r)) { print("Invalid target hostname/IP address\n"); pring_usage(); exit $ERRORS{"UNKNOWN"}; } $router = $opt_r; if (defined $opt_P) { if ($opt_P > 0) { if ($opt_P > $packets) { $timeout = $opt_P * 4; } $packets = $opt_P; } else { print("Invalid packet count (try >= 1)\n"); print_usage(); exit $ERRORS{'UNKNOWN'}; } } if (defined $opt_v) { $vrf = $opt_v; } if (defined $opt_t) { $timeout = $opt_t; } if (defined $opt_w) { if ($opt_w =~ /[0-9]+,[0-9]+\%/) { $opt_w =~ s/\%$//; ($warning_rta, $warning_pl) = split(/,/, $opt_w); } else { print("Invalid threshold pair\n"); print_usage(); exit $ERRORS{'UNKNOWN'}; } } if (defined $opt_c) { if ($opt_c =~ /[0-9]+,[0-9]+\%/) { $opt_c =~ s/\%$//; ($critical_rta, $critical_pl) = split(/,/, $opt_c); } else { print("Invalid threshold pair\n"); print_usage(); exit $ERRORS{'UNKNOWN'}; } } if ($debug == 1) { print "debug = $debug username = '$username' password = '$password' router = '$router' hostname = '$hostname' vrf = '$vrf', packets = '$packets', warning rta = '$warning_rta', critical rta = '$critical_rta', warning pl = '$warning_pl', critical pl = '$critical_pl'\n"; } ### main logic #eag123-lv08-rt01.bne#ping ? # WORD Ping destination address or hostname # appletalk Appletalk echo # atm ATM echo # clns CLNS echo # decnet DECnet echo # ip IP echo # ipv6 IPv6 echo # ipx Novell/IPX echo # srb srb echo # tag Tag encapsulated IP echo # vrf Select VPN routing instance # # #eag123-lv08-rt01.bne#ping ip ns1.intrapower.com.au ? # data specify data pattern # df-bit enable do not fragment bit in IP header # repeat specify repeat count # size specify datagram size # source specify source address or name # timeout specify timeout interval # validate validate reply data # # $session = Net::Telnet::Cisco->new(Host => "$router"); $session->login("$username", "$password"); $session->cmd('terminal length 0'); # TODO: Verify router has configuration with VRF tag if (defined $vrf) { $command = "$command vrf $vrf ip $hostname repeat $packets"; } else { $command = "$command ip $hostname repeat $packets"; } if ($debug == 1) { print "command = '$command'\n"; } @command_output = $session->cmd(String => "$command", Timeout => $timeout); $session->close; $info = 'UNKNOWN ERROR'; $answer = 'UNKNOWN: $info'; $state = $ERRORS{'UNKNOWN'}; $stats = "PL=NULL,RTA=NULL"; foreach $info (@command_output) { chomp($info); if ($info =~ /Success\ rate/) { if ($debug == 1) { print "Information string found: '$info'\n"; } $tmp_var_loss = $tmp_var_latency = $info; $tmp_var_loss =~ s/(^Success\ rate\ is\ |\ percent.*$)//g; if ($tmp_var_loss > 0) { $tmp_var_loss -= 100; } else { $tmp_var_loss = 100; } $state = 'OK'; $stats = "Packet loss = $tmp_var_loss%"; if ($debug == 1) { print "Percentage loss: $tmp_var_loss%\n"; } if ($critical_pl =~ /[0-9]+/ && $tmp_var_loss >= $critical_pl) { $state = 'CRITICAL'; } elsif ($warning_pl =~ /[0-9]+/ && $tmp_var_loss >= $warning_pl) { $state = 'WARNING'; } elsif ($tmp_var_loss != 100) { $tmp_var_latency =~ s/(^.*max\ \=\ [0-9]+\/|\/[0-9]+\ ms$)//g; if ($debug == 1) { print "Average Latency: $tmp_var_latency ms\n"; } $stats = "$stats, RTA = $tmp_var_latency ms"; if ($critical_rta =~ /[0-9]+/ && $tmp_var_latency >= $critical_rta) { $state = 'CRITICAL'; } elsif ($warning_rta =~ /[0-9]+/ && $tmp_var_latency >= $warning_rta) { $state = 'WARNING'; } } } $answer = "PING $state - $stats|$info"; } print "$answer\n"; exit $ERRORS{$state}; #### subroutines sub print_usage () { print "Usage: $PROGNAME -H -u -p -r -w % -c % [--vrf ] [-P ] [-h ] [-V]\n"; } sub print_help () { print_revision($PROGNAME,'$Revision: 1.0 $'); print "Copyright (c) 2005 Colin Stubbs This plugin runs commands on a Cisco device via telnet "; print_usage(); print " -r, --router=HOST Name or IP address of Cisco device to run ping on -H, --hostname=HOST Name or IP address to ping -u --username=USERNAME Username to login with -p --password=PASSWORD Password to login with -v --vrf=VRF VRF routing target -P --packets=$packets Number of ICMP ECHO packets to send (Default: 5) -w --warning=THRESHOLD Warning threshold pair -c --critical=THRESHOLD Critical threshold pair -h --help This screen -V --version Plugin version THRESHOLD is ,% where is the round trip average travel time (ms) which triggers a WARNING or CRITICAL state, and is the percentage of packet loss to trigger an alarm state. "; support(); }