check_rpc.pl 9.4 KB

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