Code

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