Code

check_pgsql: Determine connection time in µs-resolution.
[nagiosplug.git] / plugins-scripts / check_rpc.pl
index 2e25f4140bdd38029b2d76d8d178fbca92e74e9e..d2701e95075db6c2af19f676614b34b1148a10b5 100755 (executable)
@@ -1,4 +1,4 @@
-#! /usr/bin/perl -wT
+#!/usr/local/bin/perl -w
 #
 # check_rpc plugin for nagios
 #
 # service[check_nfs]=NFS;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_rpc
 #
 # initial version: 3 May 2000 by Truongchinh Nguyen and Karl DeBisschop
-# current status: $Revision$
+# Modified May 2002 Subhendu Ghosh - support for ePN and patches
 #
 # Copyright Notice: GPL
 #
 
-
 use strict;
-use FindBin;
-use lib "$FindBin::Bin";
+use lib utils.pm;
 use utils qw($TIMEOUT %ERRORS &print_revision &support);
 use vars qw($PROGNAME);
-my ($verbose,@proto,%prognum,$host,$response,$prognum,$port,$cmd);
+my ($verbose,@proto,%prognum,$host,$response,$prognum,$port,$cmd,$progver,$state);
 my ($array_ref,$test,$element,@progkeys,$proto,$a,$b);
-my ($opt_V,$opt_h,$opt_C,$opt_p,$opt_H);
-$opt_V = $opt_h = $opt_C = $opt_p = $opt_H = '';
+my ($opt_V,$opt_h,$opt_C,$opt_p,$opt_H,$opt_c,$opt_u,$opt_t);
+my ($line, @progvers, $response2,$response3);
+$opt_V = $opt_h = $opt_C = $opt_p = $opt_H =  $opt_u = $opt_t ='';
+$state = 'UNKNOWN';
+$progver = $response=$response2= $response3 ='';
 
+$PROGNAME = "check_rpc";
 sub print_help ();
 sub print_usage ();
 sub in ($$);
 
-$ENV{'BASH_ENV'}=''; 
+$ENV{'BASH_ENV'}='';
 $ENV{'ENV'}='';
 $ENV{'PATH'}='';
+$ENV{'LC_ALL'}='C';
 
 #Initialise protocol for each progname number
-# 'u' for UDP, 't' for TCP 
+# 'u' for UDP, 't' for TCP
 $proto[10003]='u';
 $proto[10004]='u';
 $proto[10007]='u';
 
 use Getopt::Long;
 Getopt::Long::Configure('bundling');
-GetOptions
-               ("V"   => \$opt_V, "version"    => \$opt_V,
-          "h"   => \$opt_h, "help"       => \$opt_h,
-          "C=s" => \$opt_C, "command=s"  => \$opt_C,
-          "p=i" => \$opt_p, "port=i"     => \$opt_p,
-          "H=s" => \$opt_H, "hostname=s" => \$opt_H);
+GetOptions(
+       "V"   => \$opt_V,   "version"    => \$opt_V,
+       "h"   => \$opt_h,   "help"       => \$opt_h,
+       "C=s" => \$opt_C,   "command=s"  => \$opt_C,
+       "p=i" => \$opt_p,   "port=i"     => \$opt_p,
+       "H=s" => \$opt_H,   "hostname=s" => \$opt_H,
+       "c=s" => \$opt_c,   "progver=s"  => \$opt_c,
+       "v+"  => \$verbose, "verbose+"   => \$verbose,
+       "u"   => \$opt_u,   "udp"        => \$opt_u,
+       "t"   => \$opt_t,   "tcp"        => \$opt_t
+);
 
 # -h means display verbose help screen
-if ($opt_h) { print_help(); exit 0; }
+if ($opt_h) { print_help(); exit $ERRORS{'OK'}; }
 
 # -V means display version number
-if ($opt_V) { print_revision($PROGNAME,'$Revision$ '); exit 0; }
+if ($opt_V) {
+       print_revision($PROGNAME,'@NP_VERSION@');
+       exit $ERRORS{'OK'};
+}
+
+# Hash containing all RPC program names and numbers
+# Add to the hash if support for new RPC program is required
+
+%prognum  = (
+       "portmapper"  => 100000 ,
+       "portmap"  => 100000 ,
+       "sunrpc"  => 100000 ,
+       "rpcbind"  => 100000 ,
+       "rstatd"  => 100001 ,
+       "rstat"  => 100001 ,
+       "rup"  => 100001 ,
+       "perfmeter"  => 100001 ,
+       "rstat_svc"  => 100001 ,
+       "rusersd"  => 100002 ,
+       "rusers"  => 100002 ,
+       "nfs"  => 100003 ,
+       "nfsprog"  => 100003 ,
+       "ypserv"  => 100004 ,
+       "ypprog"  => 100004 ,
+       "mountd"  => 100005 ,
+       "mount"  => 100005 ,
+       "showmount"  => 100005 ,
+       "ypbind"  => 100007 ,
+       "walld"  => 100008 ,
+       "rwall"  => 100008 ,
+       "shutdown"  => 100008 ,
+       "yppasswdd"  => 100009 ,
+       "yppasswd"  => 100009 ,
+       "etherstatd"  => 100010 ,
+       "etherstat"  => 100010 ,
+       "rquotad"  => 100011 ,
+       "rquotaprog"  => 100011 ,
+       "quota"  => 100011 ,
+       "rquota"  => 100011 ,
+       "sprayd"  => 100012 ,
+       "spray"  => 100012 ,
+       "3270_mapper"  => 100013 ,
+       "rje_mapper"  => 100014 ,
+       "selection_svc"  => 100015 ,
+       "selnsvc"  => 100015 ,
+       "database_svc"  => 100016 ,
+       "rexd"  => 100017 ,
+       "rex"  => 100017 ,
+       "alis"  => 100018 ,
+       "sched"  => 100019 ,
+       "llockmgr"  => 100020 ,
+       "nlockmgr"  => 100021 ,
+       "x25_inr"  => 100022 ,
+       "statmon"  => 100023 ,
+       "status"  => 100024 ,
+       "bootparam"  => 100026 ,
+       "ypupdated"  => 100028 ,
+       "ypupdate"  => 100028 ,
+       "keyserv"  => 100029 ,
+       "keyserver"  => 100029 ,
+       "sunlink_mapper"  => 100033 ,
+       "tfsd"  => 100037 ,
+       "nsed"  => 100038 ,
+       "nsemntd"  => 100039 ,
+       "showfhd"  => 100043 ,
+       "showfh"  => 100043 ,
+       "ioadmd"  => 100055 ,
+       "rpc.ioadmd"  => 100055 ,
+       "NETlicense"  => 100062 ,
+       "sunisamd"  => 100065 ,
+       "debug_svc"  => 100066 ,
+       "dbsrv"  => 100066 ,
+       "ypxfrd"  => 100069 ,
+       "rpc.ypxfrd"  => 100069 ,
+       "bugtraqd"  => 100071 ,
+       "kerbd"  => 100078 ,
+       "event"  => 100101 ,
+       "na.event"  => 100101 ,
+       "logger"  => 100102 ,
+       "na.logger"  => 100102 ,
+       "sync"  => 100104 ,
+       "na.sync"  => 100104 ,
+       "hostperf"  => 100107 ,
+       "na.hostperf"  => 100107 ,
+       "activity"  => 100109 ,
+       "na.activity"  => 100109 ,
+       "hostmem"  => 100112 ,
+       "na.hostmem"  => 100112 ,
+       "sample"  => 100113 ,
+       "na.sample"  => 100113 ,
+       "x25"  => 100114 ,
+       "na.x25"  => 100114 ,
+       "ping"  => 100115 ,
+       "na.ping"  => 100115 ,
+       "rpcnfs"  => 100116 ,
+       "na.rpcnfs"  => 100116 ,
+       "hostif"  => 100117 ,
+       "na.hostif"  => 100117 ,
+       "etherif"  => 100118 ,
+       "na.etherif"  => 100118 ,
+       "iproutes"  => 100120 ,
+       "na.iproutes"  => 100120 ,
+       "layers"  => 100121 ,
+       "na.layers"  => 100121 ,
+       "snmp"  => 100122 ,
+       "na.snmp"  => 100122 ,
+       "snmp-cmc"  => 100122 ,
+       "snmp-synoptics"  => 100122 ,
+       "snmp-unisys"  => 100122 ,
+       "snmp-utk"  => 100122 ,
+       "traffic"  => 100123 ,
+       "na.traffic"  => 100123 ,
+       "nfs_acl"  => 100227 ,
+       "sadmind"  => 100232 ,
+       "nisd"  => 100300 ,
+       "rpc.nisd"  => 100300 ,
+       "nispasswd"  => 100303 ,
+       "rpc.nispasswdd"  => 100303 ,
+       "ufsd"  => 100233 ,
+       "ufsd"  => 100233 ,
+       "pcnfsd"  => 150001 ,
+       "pcnfs"  => 150001 ,
+       "amd"  => 300019 ,
+       "amq"  => 300019 ,
+       "bwnfsd"  => 545580417 ,
+       "fypxfrd"  => 600100069 ,
+       "freebsd-ypxfrd"  => 600100069 ,
+);
+
+# -v means verbose, -v-v means verbose twice = print above hash
+if (defined $verbose && ($verbose > 1) ){
+       my $key;
+       print "Supported programs:\n";
+       print "    name\t=>\tnumber\n";
+       print " ===============================\n";
+       foreach $key (sort keys %prognum) {
+               print "   $key \t=>\t$prognum{$key} \n";
+       }
+       print "\n\n";
+       print_usage();
+       exit $ERRORS{'OK'};
+}
 
 # -H means host name
-$opt_H = shift unless ($opt_H);
-unless ($opt_H) { print_usage(); exit -1; }
-if($opt_H && $opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0-9]+(\.[a-zA-Z][-a-zA-Z0-9]+)*)$/) {
-    $host = $1;
-} else {
-    print "$opt_H is not a valid host name\n";
-    exit -1;
+unless ($opt_H) { print_usage(); exit $ERRORS{'UNKNOWN'}; }
+
+if (! utils::is_hostname($opt_H)){
+       print "$opt_H is not a valid host name\n";
+       print_usage();
+       exit $ERRORS{"UNKNOWN"};
+}else{
+       $host = $opt_H;
 }
 
-while (<DATA>) {
-       ($a,$b) = split;
-       $prognum{$a} = $b;
+if ($opt_t && $opt_u) {
+       print "Cannot define tcp AND udp\n";
+       print_usage();
+       exit $ERRORS{'UNKNOWN'};
 }
-close DATA;
+
 
 # -C means command name or number
 $opt_C = shift unless ($opt_C);
 unless ($opt_C) { print_usage(); exit -1; }
 @progkeys = keys %prognum;
 if ($opt_C =~ m/^([0-9]+)$/){
-    $response = "RPC ok: program $opt_p (version ";
+#    $response = "RPC ok: program $opt_C (version ";
     $prognum = $1;
 } elsif ( in( \@progkeys, $opt_C)) {
-    $response = "RPC ok: $opt_C (version ";
+#    $response = "RPC ok: $opt_C (version ";
     $prognum = $prognum{$opt_C};
 } else {
     print "Program $opt_C is not defined\n";
-    exit -1;
+    exit $ERRORS{'UNKNOWN'};
 }
 
 # -p means port number
@@ -99,42 +250,115 @@ if($opt_p =~ /^([0-9]+)$/){
 
 $proto = 'u';
 $proto = $proto[$prognum] if ($proto[$prognum]);
-$cmd = "/usr/sbin/rpcinfo $port -" . "$proto $host $prognum 2>&1 |";
-print "$cmd\n" if ($verbose);
-open CMD, $cmd;
-
-while ( <CMD> ) {
-    chomp;
-    if ( /program $prognum version ([0-9]*) ready and waiting/ ) {
-       $response .= "$1) is running";
-        print "$response\n";
-        exit 0;
-    }
+$proto = 't' if ($opt_t);
+$proto = 'u' if ($opt_u);
+
+
+# Just in case of problems, let's not hang Nagios
+$SIG{'ALRM'} = sub {
+        print ("ERROR: No response from RPC server (alarm)\n");
+        exit $ERRORS{"UNKNOWN"};
+};
+alarm($TIMEOUT);
+
+# -c is progver  - if we need to check multiple specified versions.
+if (defined $opt_c ) {
+       my $vers;
+       @progvers = split(/,/ ,$opt_c );
+       foreach $vers (sort @progvers) {
+               if($vers =~ /^([0-9]+)$/){
+                       $progver = "$1";
+                       print "Checking $opt_C version $progver proto $proto\n" if $verbose;
+                       get_rpcinfo();
+               }else{
+                       print "Version $vers is not an integer\n" if $verbose;
+               }
+
+       }
+}else{
+       get_rpcinfo();
+}
+
+
+## translate proto for output
+if ($proto eq "u" ){
+       $proto = "udp";
+}else{
+       $proto = "tcp";
 }
 
-print "RPC CRITICAL: Program $opt_C not registered\n";
-exit 2;
+if ($state eq 'OK') {
+       print "$state: RPC program $opt_C".$response." $proto running\n";
+}else{
+       if($response){
+               print "$state: RPC program $opt_C".$response2." $proto is not running,".$response." $proto is running\n";
+       }else{
+               print "$state: RPC program $opt_C $response2 $proto is not running\n";
+       }
+}
+exit $ERRORS{$state};
+
+
+########  Subroutines ==========================
 
+sub get_rpcinfo {
+       $cmd = "$utils::PATH_TO_RPCINFO $port -" . "$proto $host $prognum $progver 2>&1 |";
+       print "$cmd\n" if ($verbose);
+       open CMD, $cmd or die "Can't fork for rpcinfo: $!\n" ;
+
+       while ( $line = <CMD> ) {
+               printf "$line " if $verbose;
+               chomp $line;
+
+       if ( $line =~ /program $prognum version ([0-9]*) ready and waiting/ ) {
+                       $response .= " version $1";
+                       $state = 'OK' unless $state ne 'UNKNOWN';
+                       print "1:$response \n" if $verbose;
+       }
+
+               if ( $line =~ /program $prognum version ([0-9]*) is not available/ ) {
+                       $response2 .= " version $1";
+                       $state = 'CRITICAL';
+                       print "2:$response2 \n" if $verbose;
+               }
+               if ( $line =~ /program $prognum is not available/ ) {
+                       $response3 = "";
+                       $response3 = "tcp" if $opt_t;
+                       $response3 = "udp" if $opt_u;
+                       $state = 'CRITICAL';
+                       print "3:$response3 \n" if $verbose;
+               }
+       }
+       close CMD;
+}
 
 
 sub print_help() {
-       print_revision($PROGNAME,'$Revision$ ');
-       print "Copyright (c) 2000 Karl DeBisschop/Truongchinh Nguyen\n";
+       print_revision($PROGNAME,'@NP_VERSION@');
+       print "Copyright (c) 2002 Karl DeBisschop/Truongchinh Nguyen/Subhendu Ghosh\n";
        print "\n";
        print "Check if a rpc service is registered and running using\n";
-       print "      rpcinfo -<protocol> <host> <program number>\n";
+       print "      rpcinfo -H host -C rpc_command \n";
        print "\n";
        print_usage();
        print "\n";
-       print "<host>    The server providing the rpc service\n";
-       print "<program> The program name (or number).\n\n";
+       print "  <host>          The server providing the rpc service\n";
+       print "  <rpc_command>   The program name (or number).\n";
+       print "  <program_version> The version you want to check for (one or more)\n";
+       print "                    Should prevent checks of unknown versions being syslogged\n";
+       print "                    e.g. 2,3,6 to check v2, v3, and v6\n";
+       print "  [-u | -t]       Test UDP or TCP\n";
+       print "  [-v]            Verbose \n";
+       print "  [-v -v]         Verbose - will print supported programs and numbers \n";
+       print "\n";
        support();
 }
 
 sub print_usage () {
-       print "$PROGNAME -H host -C rpc_command [-p port]\n";
-       print "$PROGNAME [-h | --help]\n";
-       print "$PROGNAME [-V | --version]\n";
+       print "Usage: \n";
+       print " $PROGNAME -H host -C rpc_command [-p port] [-c program_version] [-u|-t] [-v]\n";
+       print " $PROGNAME [-h | --help]\n";
+       print " $PROGNAME [-V | --version]\n";
 }
 
 sub in ($$) {
@@ -149,122 +373,3 @@ sub in ($$) {
        return 0;
 }
 
-__DATA__
-portmapper 100000
-portmap 100000
-sunrpc 100000
-rpcbind 100000
-rstatd 100001
-rstat 100001
-rup 100001
-perfmeter 100001
-rstat_svc 100001
-rusersd 100002
-rusers 100002
-nfs 100003
-nfsprog 100003
-ypserv 100004
-ypprog 100004
-mountd 100005
-mount 100005
-showmount 100005
-ypbind 100007
-walld 100008
-rwall 100008
-shutdown 100008
-yppasswdd 100009
-yppasswd 100009
-etherstatd 100010
-etherstat 100010
-rquotad 100011
-rquotaprog 100011
-quota 100011
-rquota 100011 
-sprayd 100012
-spray 100012
-3270_mapper 100013
-rje_mapper 100014
-selection_svc 100015
-selnsvc 100015
-database_svc 100016
-rexd 100017
-rex 100017
-alis 100018
-sched 100019
-llockmgr 100020
-nlockmgr 100021
-x25_inr 100022
-statmon 100023
-status 100024
-bootparam 100026
-ypupdated 100028
-ypupdate 100028
-keyserv 100029
-keyserver 100029 
-sunlink_mapper 100033
-tfsd 100037
-nsed 100038
-nsemntd 100039
-showfhd 100043
-showfh 100043
-ioadmd 100055
-rpc.ioadmd 100055
-NETlicense 100062
-sunisamd 100065
-debug_svc 100066
-dbsrv 100066
-ypxfrd 100069
-rpc.ypxfrd 100069
-bugtraqd 100071
-kerbd 100078
-event 100101
-na.event 100101
-logger 100102
-na.logger 100102
-sync 100104
-na.sync 100104
-hostperf 100107
-na.hostperf 100107
-activity 100109
-na.activity 100109
-hostmem 100112
-na.hostmem 100112
-sample 100113
-na.sample 100113
-x25 100114
-na.x25 100114
-ping 100115
-na.ping 100115
-rpcnfs 100116
-na.rpcnfs 100116
-hostif 100117
-na.hostif 100117
-etherif 100118
-na.etherif 100118
-iproutes 100120
-na.iproutes 100120
-layers 100121
-na.layers 100121
-snmp 100122
-na.snmp 100122
-snmp-cmc 100122
-snmp-synoptics 100122
-snmp-unisys 100122
-snmp-utk 100122
-traffic 100123
-na.traffic 100123
-nfs_acl 100227
-sadmind 100232
-nisd 100300
-rpc.nisd 100300
-nispasswd 100303
-rpc.nispasswdd 100303
-ufsd 100233
-ufsd 100233
-pcnfsd 150001
-pcnfs 150001
-amd 300019
-amq 300019
-bwnfsd 545580417
-fypxfrd 600100069
-freebsd-ypxfrd 600100069