For 1.4.9 release
[monitoring-plugins.git] / plugins-scripts / check_rpc.pl
blob20c204dee7de93960a72d083bf7bdec6bc429e6f
1 #!/usr/local/bin/perl -w
3 # check_rpc plugin for nagios
5 # usage:
6 # check_rpc host service
8 # Check if an rpc serice is registered and running
9 # using rpcinfo - $proto $host $prognum 2>&1 |";
11 # Use these hosts.cfg entries as examples
13 # command[check_nfs]=/some/path/libexec/check_rpc $HOSTADDRESS$ nfs
14 # service[check_nfs]=NFS;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_rpc
16 # initial version: 3 May 2000 by Truongchinh Nguyen and Karl DeBisschop
17 # Modified May 2002 Subhendu Ghosh - support for ePN and patches
18 # current status: $Revision$
20 # Copyright Notice: GPL
21 # $Id$
24 use strict;
25 use lib utils.pm;
26 use utils qw($TIMEOUT %ERRORS &print_revision &support);
27 use vars qw($PROGNAME);
28 my ($verbose,@proto,%prognum,$host,$response,$prognum,$port,$cmd,$progver,$state);
29 my ($array_ref,$test,$element,@progkeys,$proto,$a,$b);
30 my ($opt_V,$opt_h,$opt_C,$opt_p,$opt_H,$opt_c,$opt_u,$opt_t);
31 my ($line, @progvers, $response2,$response3);
32 $opt_V = $opt_h = $opt_C = $opt_p = $opt_H = $opt_u = $opt_t ='';
33 $state = 'UNKNOWN';
34 $progver = $response=$response2= $response3 ='';
36 $PROGNAME = "check_rpc";
37 sub print_help ();
38 sub print_usage ();
39 sub in ($$);
41 $ENV{'BASH_ENV'}='';
42 $ENV{'ENV'}='';
43 $ENV{'PATH'}='';
44 $ENV{'LC_ALL'}='C';
46 #Initialise protocol for each progname number
47 # 'u' for UDP, 't' for TCP
48 $proto[10003]='u';
49 $proto[10004]='u';
50 $proto[10007]='u';
52 use Getopt::Long;
53 Getopt::Long::Configure('bundling');
54 GetOptions(
55 "V" => \$opt_V, "version" => \$opt_V,
56 "h" => \$opt_h, "help" => \$opt_h,
57 "C=s" => \$opt_C, "command=s" => \$opt_C,
58 "p=i" => \$opt_p, "port=i" => \$opt_p,
59 "H=s" => \$opt_H, "hostname=s" => \$opt_H,
60 "c=s" => \$opt_c, "progver=s" => \$opt_c,
61 "v+" => \$verbose, "verbose+" => \$verbose,
62 "u" => \$opt_u, "udp" => \$opt_u,
63 "t" => \$opt_t, "tcp" => \$opt_t
66 # -h means display verbose help screen
67 if ($opt_h) { print_help(); exit $ERRORS{'OK'}; }
69 # -V means display version number
70 if ($opt_V) {
71 print_revision($PROGNAME,'$Revision$ ');
72 exit $ERRORS{'OK'};
75 # Hash containing all RPC program names and numbers
76 # Add to the hash if support for new RPC program is required
78 %prognum = (
79 "portmapper" => 100000 ,
80 "portmap" => 100000 ,
81 "sunrpc" => 100000 ,
82 "rpcbind" => 100000 ,
83 "rstatd" => 100001 ,
84 "rstat" => 100001 ,
85 "rup" => 100001 ,
86 "perfmeter" => 100001 ,
87 "rstat_svc" => 100001 ,
88 "rusersd" => 100002 ,
89 "rusers" => 100002 ,
90 "nfs" => 100003 ,
91 "nfsprog" => 100003 ,
92 "ypserv" => 100004 ,
93 "ypprog" => 100004 ,
94 "mountd" => 100005 ,
95 "mount" => 100005 ,
96 "showmount" => 100005 ,
97 "ypbind" => 100007 ,
98 "walld" => 100008 ,
99 "rwall" => 100008 ,
100 "shutdown" => 100008 ,
101 "yppasswdd" => 100009 ,
102 "yppasswd" => 100009 ,
103 "etherstatd" => 100010 ,
104 "etherstat" => 100010 ,
105 "rquotad" => 100011 ,
106 "rquotaprog" => 100011 ,
107 "quota" => 100011 ,
108 "rquota" => 100011 ,
109 "sprayd" => 100012 ,
110 "spray" => 100012 ,
111 "3270_mapper" => 100013 ,
112 "rje_mapper" => 100014 ,
113 "selection_svc" => 100015 ,
114 "selnsvc" => 100015 ,
115 "database_svc" => 100016 ,
116 "rexd" => 100017 ,
117 "rex" => 100017 ,
118 "alis" => 100018 ,
119 "sched" => 100019 ,
120 "llockmgr" => 100020 ,
121 "nlockmgr" => 100021 ,
122 "x25_inr" => 100022 ,
123 "statmon" => 100023 ,
124 "status" => 100024 ,
125 "bootparam" => 100026 ,
126 "ypupdated" => 100028 ,
127 "ypupdate" => 100028 ,
128 "keyserv" => 100029 ,
129 "keyserver" => 100029 ,
130 "sunlink_mapper" => 100033 ,
131 "tfsd" => 100037 ,
132 "nsed" => 100038 ,
133 "nsemntd" => 100039 ,
134 "showfhd" => 100043 ,
135 "showfh" => 100043 ,
136 "ioadmd" => 100055 ,
137 "rpc.ioadmd" => 100055 ,
138 "NETlicense" => 100062 ,
139 "sunisamd" => 100065 ,
140 "debug_svc" => 100066 ,
141 "dbsrv" => 100066 ,
142 "ypxfrd" => 100069 ,
143 "rpc.ypxfrd" => 100069 ,
144 "bugtraqd" => 100071 ,
145 "kerbd" => 100078 ,
146 "event" => 100101 ,
147 "na.event" => 100101 ,
148 "logger" => 100102 ,
149 "na.logger" => 100102 ,
150 "sync" => 100104 ,
151 "na.sync" => 100104 ,
152 "hostperf" => 100107 ,
153 "na.hostperf" => 100107 ,
154 "activity" => 100109 ,
155 "na.activity" => 100109 ,
156 "hostmem" => 100112 ,
157 "na.hostmem" => 100112 ,
158 "sample" => 100113 ,
159 "na.sample" => 100113 ,
160 "x25" => 100114 ,
161 "na.x25" => 100114 ,
162 "ping" => 100115 ,
163 "na.ping" => 100115 ,
164 "rpcnfs" => 100116 ,
165 "na.rpcnfs" => 100116 ,
166 "hostif" => 100117 ,
167 "na.hostif" => 100117 ,
168 "etherif" => 100118 ,
169 "na.etherif" => 100118 ,
170 "iproutes" => 100120 ,
171 "na.iproutes" => 100120 ,
172 "layers" => 100121 ,
173 "na.layers" => 100121 ,
174 "snmp" => 100122 ,
175 "na.snmp" => 100122 ,
176 "snmp-cmc" => 100122 ,
177 "snmp-synoptics" => 100122 ,
178 "snmp-unisys" => 100122 ,
179 "snmp-utk" => 100122 ,
180 "traffic" => 100123 ,
181 "na.traffic" => 100123 ,
182 "nfs_acl" => 100227 ,
183 "sadmind" => 100232 ,
184 "nisd" => 100300 ,
185 "rpc.nisd" => 100300 ,
186 "nispasswd" => 100303 ,
187 "rpc.nispasswdd" => 100303 ,
188 "ufsd" => 100233 ,
189 "ufsd" => 100233 ,
190 "pcnfsd" => 150001 ,
191 "pcnfs" => 150001 ,
192 "amd" => 300019 ,
193 "amq" => 300019 ,
194 "bwnfsd" => 545580417 ,
195 "fypxfrd" => 600100069 ,
196 "freebsd-ypxfrd" => 600100069 ,
199 # -v means verbose, -v-v means verbose twice = print above hash
200 if (defined $verbose && ($verbose > 1) ){
201 my $key;
202 print "Supported programs:\n";
203 print " name\t=>\tnumber\n";
204 print " ===============================\n";
205 foreach $key (sort keys %prognum) {
206 print " $key \t=>\t$prognum{$key} \n";
208 print "\n\n";
209 print_usage();
210 exit $ERRORS{'OK'};
213 # -H means host name
214 unless ($opt_H) { print_usage(); exit $ERRORS{'UNKNOWN'}; }
216 if (! utils::is_hostname($opt_H)){
217 print "$opt_H is not a valid host name\n";
218 print_usage();
219 exit $ERRORS{"UNKNOWN"};
220 }else{
221 $host = $opt_H;
224 if ($opt_t && $opt_u) {
225 print "Cannot define tcp AND udp\n";
226 print_usage();
227 exit $ERRORS{'UNKNOWN'};
231 # -C means command name or number
232 $opt_C = shift unless ($opt_C);
233 unless ($opt_C) { print_usage(); exit -1; }
234 @progkeys = keys %prognum;
235 if ($opt_C =~ m/^([0-9]+)$/){
236 # $response = "RPC ok: program $opt_C (version ";
237 $prognum = $1;
238 } elsif ( in( \@progkeys, $opt_C)) {
239 # $response = "RPC ok: $opt_C (version ";
240 $prognum = $prognum{$opt_C};
241 } else {
242 print "Program $opt_C is not defined\n";
243 exit $ERRORS{'UNKNOWN'};
246 # -p means port number
247 if($opt_p =~ /^([0-9]+)$/){
248 $port = "-n $1";
249 } else {
250 $port = "";
253 $proto = 'u';
254 $proto = $proto[$prognum] if ($proto[$prognum]);
255 $proto = 't' if ($opt_t);
256 $proto = 'u' if ($opt_u);
259 # Just in case of problems, let's not hang Nagios
260 $SIG{'ALRM'} = sub {
261 print ("ERROR: No response from RPC server (alarm)\n");
262 exit $ERRORS{"UNKNOWN"};
264 alarm($TIMEOUT);
266 # -c is progver - if we need to check multiple specified versions.
267 if (defined $opt_c ) {
268 my $vers;
269 @progvers = split(/,/ ,$opt_c );
270 foreach $vers (sort @progvers) {
271 if($vers =~ /^([0-9]+)$/){
272 $progver = "$1";
273 print "Checking $opt_C version $progver proto $proto\n" if $verbose;
274 get_rpcinfo();
275 }else{
276 print "Version $vers is not an integer\n" if $verbose;
280 }else{
281 get_rpcinfo();
285 ## translate proto for output
286 if ($proto eq "u" ){
287 $proto = "udp";
288 }else{
289 $proto = "tcp";
292 if ($state eq 'OK') {
293 print "$state: RPC program $opt_C".$response." $proto running\n";
294 }else{
295 if($response){
296 print "$state: RPC program $opt_C".$response2." $proto is not running,".$response." $proto is running\n";
297 }else{
298 print "$state: RPC program $opt_C $response2 $proto is not running\n";
301 exit $ERRORS{$state};
304 ######## Subroutines ==========================
306 sub get_rpcinfo {
307 $cmd = "$utils::PATH_TO_RPCINFO $port -" . "$proto $host $prognum $progver 2>&1 |";
308 print "$cmd\n" if ($verbose);
309 open CMD, $cmd or die "Can't fork for rpcinfo: $!\n" ;
311 while ( $line = <CMD> ) {
312 printf "$line " if $verbose;
313 chomp $line;
315 if ( $line =~ /program $prognum version ([0-9]*) ready and waiting/ ) {
316 $response .= " version $1";
317 $state = 'OK' unless $state ne 'UNKNOWN';
318 print "1:$response \n" if $verbose;
321 if ( $line =~ /program $prognum version ([0-9]*) is not available/ ) {
322 $response2 .= " version $1";
323 $state = 'CRITICAL';
324 print "2:$response2 \n" if $verbose;
326 if ( $line =~ /program $prognum is not available/ ) {
327 $response3 = "";
328 $response3 = "tcp" if $opt_t;
329 $response3 = "udp" if $opt_u;
330 $state = 'CRITICAL';
331 print "3:$response3 \n" if $verbose;
334 close CMD;
338 sub print_help() {
339 print_revision($PROGNAME,'$Revision$ ');
340 print "Copyright (c) 2002 Karl DeBisschop/Truongchinh Nguyen/Subhendu Ghosh\n";
341 print "\n";
342 print "Check if a rpc service is registered and running using\n";
343 print " rpcinfo -H host -C rpc_command \n";
344 print "\n";
345 print_usage();
346 print "\n";
347 print " <host> The server providing the rpc service\n";
348 print " <rpc_command> The program name (or number).\n";
349 print " <program_version> The version you want to check for (one or more)\n";
350 print " Should prevent checks of unknown versions being syslogged\n";
351 print " e.g. 2,3,6 to check v2, v3, and v6\n";
352 print " [-u | -t] Test UDP or TCP\n";
353 print " [-v] Verbose \n";
354 print " [-v -v] Verbose - will print supported programs and numbers \n";
355 print "\n";
356 support();
359 sub print_usage () {
360 print "Usage: \n";
361 print " $PROGNAME -H host -C rpc_command [-p port] [-c program_version] [-u|-t] [-v]\n";
362 print " $PROGNAME [-h | --help]\n";
363 print " $PROGNAME [-V | --version]\n";
366 sub in ($$) {
367 $array_ref = shift;
368 $test = shift;
370 while ( $element = shift @{$array_ref} ) {
371 if ($test eq $element) {
372 return 1;
375 return 0;