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