Code

Fix incorrectly labelled units in output (1025905, Jason Martin)
[nagiosplug.git] / plugins-scripts / check_rpc.pl
1 #!/usr/local/bin/perl -w
2 #
3 # check_rpc plugin for nagios
4 #
5 # usage:
6 #    check_rpc host service
7 #
8 # Check if an rpc serice is registered and running
9 # using rpcinfo - $proto $host $prognum 2>&1 |";
10 #
11 # Use these hosts.cfg entries as examples
12 #
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
15 #
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$
19 #
20 # Copyright Notice: GPL
21 # $Id$
22 #
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
64 );
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'}; 
73 }
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 ,
197 );
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";
207         }
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"};
263 };
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;
277                 }
278         
279         }
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";
299         }
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;
314         
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;
319         }
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;
325                 }
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;
332                 }
333         }
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;
373                 }
374         }
375         return 0;