check_rpc.pl 9.4 KB

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