From 9280d5f455dc7bdf963bd1ebb74d20b151643f59 Mon Sep 17 00:00:00 2001
From: Subhendu Ghosh <sghosh@users.sourceforge.net>
Date: Fri, 10 May 2002 03:51:17 +0000
Subject: updates for ePN, patch for multiple version check

git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@32 f882894a-f735-0410-b71e-b25c423dba1c

diff --git a/plugins-scripts/check_rpc.pl b/plugins-scripts/check_rpc.pl
index 2e25f41..623d6ab 100755
--- a/plugins-scripts/check_rpc.pl
+++ b/plugins-scripts/check_rpc.pl
@@ -1,4 +1,4 @@
-#! /usr/bin/perl -wT
+#! /usr/local/bin/perl -w
 #
 # check_rpc plugin for nagios
 #
@@ -14,22 +14,26 @@
 # 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
+# Modified May 2002 Subhendu Ghosh - support for ePN and patches
 # current status: $Revision$
 #
 # Copyright Notice: GPL
+# $Id$
 #
 
-
 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_c = $opt_u = $opt_t ='';
+$state = 'OK';
+$progver = $response=$response2= $response3 ='';
 
+$PROGNAME = "check_rpc";
 sub print_help ();
 sub print_usage ();
 sub in ($$);
@@ -46,48 +50,196 @@ $proto[10007]='u';
 
 use Getopt::Long;
 Getopt::Long::Configure('bundling');
-GetOptions
-		("V"   => \$opt_V, "version"    => \$opt_V,
+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);
+	   "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,'$Revision$ '); 
+	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 +251,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";
+}
+
+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};
 
-print "RPC CRITICAL: Program $opt_C not registered\n";
-exit 2;
 
+########  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 'OK';
+			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 "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 +374,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
-- 
cgit v0.10-9-g596f

