From fdb038790a0d79438f22205844dd4851112c6230 Mon Sep 17 00:00:00 2001 From: Jan Wagner Date: Tue, 26 Nov 2013 21:26:43 +0100 Subject: [PATCH 1/2] Initial upstream branch. From 05f86278bc6a5969b86f09bea04c6b4fba92ef27 Mon Sep 17 00:00:00 2001 From: Jan Wagner Date: Tue, 26 Nov 2013 21:27:10 +0100 Subject: [PATCH 2/2] Imported Upstream version 1.1 --- LICENSE | 280 +++++++++++++ README | 58 +++ check_snmp_boostedge.pl | 320 ++++++++++++++ check_snmp_cpfw.pl | 536 +++++++++++++++++++++++ check_snmp_css.pl | 480 +++++++++++++++++++++ check_snmp_css_main.pl | 266 ++++++++++++ check_snmp_env.pl | 816 ++++++++++++++++++++++++++++++++++++ check_snmp_int.pl | 612 +++++++++++++++++++++++++++ check_snmp_linkproof_nhr.pl | 319 ++++++++++++++ check_snmp_load.pl | 726 ++++++++++++++++++++++++++++++++ check_snmp_mem.pl | 525 +++++++++++++++++++++++ check_snmp_nsbox.pl | 351 ++++++++++++++++ check_snmp_process.pl | 610 +++++++++++++++++++++++++++ check_snmp_storage.pl | 615 +++++++++++++++++++++++++++ check_snmp_vrrp.pl | 451 ++++++++++++++++++++ check_snmp_win.pl | 381 +++++++++++++++++ install.sh | 211 ++++++++++ 17 files changed, 7557 insertions(+) create mode 100644 LICENSE create mode 100644 README create mode 100755 check_snmp_boostedge.pl create mode 100755 check_snmp_cpfw.pl create mode 100755 check_snmp_css.pl create mode 100755 check_snmp_css_main.pl create mode 100755 check_snmp_env.pl create mode 100755 check_snmp_int.pl create mode 100755 check_snmp_linkproof_nhr.pl create mode 100755 check_snmp_load.pl create mode 100755 check_snmp_mem.pl create mode 100755 check_snmp_nsbox.pl create mode 100755 check_snmp_process.pl create mode 100755 check_snmp_storage.pl create mode 100755 check_snmp_vrrp.pl create mode 100755 check_snmp_win.pl create mode 100755 install.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8420802 --- /dev/null +++ b/LICENSE @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/README b/README new file mode 100644 index 0000000..7429550 --- /dev/null +++ b/README @@ -0,0 +1,58 @@ +Nagios SNMP plugins 1.0 README +------------------------------ + + +Nagios SNMP plugins is a set of Nagios plugins to check hosts/devices using snmp protocol. +http://www.manubulon.com/nagios for more details. + + +Requirements: +------------- +- perl +- Net::SNMP and Getopt::Long +- File utils.pm in Nagios plugin directory (default /usr/local/nagios/libexec) + +Installation: +------------- + +You can simply copy the files to the Nagios Plugin directory if it is in /usr/local/nagios/libexec. + +You can also use the "install.sh" script provided in this directory to install the plugins. +Type : "./install.sh" to install all the plugins or "./install.sh " for a specific one. + +The script will check for dependencies and ask for Nagios and temp directories. +It will modify the scripts dependding on these answers and install the scripts. + +By default, the scripts will consider : +- perl is in /usr/bin/perl +- Net::SNMP and Getopt::Long +- Nagios plugins (and file utils.pm) are in /usr/local/nagios/libexec +- Temp files will be written in /tmp + +Help and support: +----------------- + +Help files, examples and manual : http://www.manubulon.com/nagios/ +FAQ : http://www.manubulon.com/nagios/faq.html +Mailling list, forum : https://sourceforge.net/projects/nagios-snmp/ + + +Legal stuff: +------------ + + Nagios SNMP plugins version 1.0, Copyright (C) 2004-2006 Patrick Proy (nagios at proy.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + Nagios and the Nagios logo are registered trademarks of Ethan Galstad. diff --git a/check_snmp_boostedge.pl b/check_snmp_boostedge.pl new file mode 100755 index 0000000..580c722 --- /dev/null +++ b/check_snmp_boostedge.pl @@ -0,0 +1,320 @@ +#!/usr/bin/perl -w +############################## check_snmp_boostedge.pl ################# +# Version : 1.0 +# Date : 27 Aug 2006 +# Author : Patrick Proy ( patrick at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Changelog : +# Contributors : +################################################################# +# +# Help : ./check_snmp_boostedge.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas + +my $be_global_status= "1.3.6.1.4.1.4185.12.1.1.3.0"; # boostedge global status (stop(0), start(1)) + +my $be_service_number= "1.3.6.1.4.1.4185.12.1.5.1.0"; # beServiceNumber + +my $be_service_table= "1.3.6.1.4.1.4185.12.1.5"; # beServices +my $be_service_name= "1.3.6.1.4.1.4185.12.1.5.2.1.2"; # beServiceName +my $be_service_status= "1.3.6.1.4.1.4185.12.1.5.2.1.4"; # status ("RUNNING") +my $be_service_mode= "1.3.6.1.4.1.4185.12.1.5.2.1.5"; # beServiceMode (disabled(0), enabled(1)) +my $be_service_datain= "1.3.6.1.4.1.4185.12.1.5.2.1.6"; # beServiceDataIn (Not populated for now : HTTP/S - V5.2.16.0) +my $be_service_dataout= "1.3.6.1.4.1.4185.12.1.5.2.1.7"; # beServiceDataOut (Not populated for now : HTTP/S - V5.2.16.0) +my $be_service_connect= "1.3.6.1.4.1.4185.12.1.5.2.1.8"; # beServiceConnect (Not populated for now : HTTP/S - V5.2.16.0) + + +# Globals + +my $Version='1.0'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_timeout= undef; # Timeout (Default 5) +my $o_perf= undef; # Output performance data +my $o_version2= undef; # use snmp v2c +# Specific +my $o_service= undef; # service regexp selection +my $o_nservice= undef; # service number expected + +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_boostedge version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) -s -n [-p ] [-f] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub set_status { # return worst status with this order : OK, unknwonw, warning, critical + my $new_status=shift; + my $cur_status=shift; + if (($cur_status == 0)|| ($new_status==$cur_status)){ return $new_status; } + if ($new_status==3) { return $cur_status; } + if ($new_status > $cur_status) {return $new_status;} + return $cur_status; +} + +sub is_pattern_valid { # Test for things like "" or "+5-i" + my $pat = shift; + if (!defined($pat)) { $pat=" ";} # Just to get rid of compilation time warnings + return eval { "" =~ /$pat/; 1 } || 0; +} + +sub help { + print "\nSNMP Boostedge service monitor for Nagios version ",$Version,"\n"; + print "(c)2004-2006 Patrick Proy\n\n"; + print_usage(); + print < + Regexp of service to select +-n, --number= + Number of services selected that must be in running & enabled state +-2, --v2c + Use snmp v2c +-l, --login=LOGIN ; -x, --passwd=PASSWD + Login and auth password for snmpv3 authentication + If no priv password exists, implies AuthNoPriv +-X, --privpass=PASSWD + Priv password for snmpv3 (AuthPriv protocol) +-L, --protocols=, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-f, --perfparse + Perfparse compatible output +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'f' => \$o_perf, 'perfparse' => \$o_perf, + 's:s' => \$o_service, 'service:s' => \$o_service, + 'n:i' => \$o_nservice, 'number:i' => \$o_nservice + ); + # Basic checks + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (!defined($o_service) || !(is_pattern_valid($o_service))) + { print "Service selection must be set and be a valid regexp\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_nservice) || isnnum($o_nservice)) + { print "Service number must be set and be an integer\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT + 5"); + alarm($TIMEOUT+5); +} else { + verb("no global timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +# Get global status +my @oidlist=($be_global_status); +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_request(@oidlist) + : $session->get_request(-varbindlist => \@oidlist); + +if (!defined($resultat)) { + printf("ERROR: Gloabal status table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +if ($$resultat{$be_global_status} != 1) { + print "Global service is stopped (",$$resultat{$be_global_status},") : CRITICAL\n"; + exit $ERRORS{"CRITICAL"}; +} + +$resultat=undef; +# Get service table +$resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($be_service_table) + : $session->get_table(Baseoid => $be_service_table); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +$session->close; + +my $output=""; +my $output_perf=""; +my $global_status=0; +my ($nservice,$nservice_ok)=(0,0); +my (@found_service,@service_state)=undef; + +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( ($key =~ /$be_service_name\./) && ($$resultat{$key} =~ /$o_service/ )) { # Get index of service with name + $found_service[$nservice]=$$resultat{$key}; + $key =~ s/$be_service_name//; + $service_state[$nservice]=$$resultat{$be_service_status.$key}; + if (($service_state[$nservice] ne "RUNNING") || ($$resultat{$be_service_mode.$key}!=1)) { + $service_state[$nservice].="(".$$resultat{$be_service_mode.$key}.")"; + $global_status=2; + } else { + $nservice_ok++ + } + $nservice++; + verb ("Found service $found_service[$nservice-1]"); + } +} + +if ($o_nservice > $nservice_ok) { + for (my $i=0;$i<$nservice;$i++) { + if ($output ne "") { $output .= ", "; } + $output .= $found_service[$i] . ":" . $service_state[$i]; + } + if ($output ne "") { $output .= ", "; } + $output .= ":" . $nservice_ok . " services OK < ".$o_nservice; + print $output, " : CRITICAL\n"; + exit $ERRORS{"CRITICAL"}; +} + +$output = $nservice_ok . " services OK"; +if ($o_nservice < $nservice_ok) { + print $output," > $o_nservice : WARNING\n"; + exit $ERRORS{"WARNING"}; +} +print $output," : OK\n"; +exit $ERRORS{"OK"}; diff --git a/check_snmp_cpfw.pl b/check_snmp_cpfw.pl new file mode 100755 index 0000000..afed233 --- /dev/null +++ b/check_snmp_cpfw.pl @@ -0,0 +1,536 @@ +#!/usr/bin/perl -w +############################## check_snmp_cpfw ############## +# Version : 1.0 +# Date : Aug 23 2006 +# Author : Patrick Proy (patrick at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# TODO : +# - check sync method +################################################################# +# +# Help : ./check_snmp_cpfw.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +########### SNMP Datas ########### + +###### FW data +my $policy_state = "1.3.6.1.4.1.2620.1.1.1.0"; # "Installed" +my $policy_name = "1.3.6.1.4.1.2620.1.1.2.0"; # Installed policy name +my $connections = "1.3.6.1.4.1.2620.1.1.25.3.0"; # number of connections +#my $connections_peak = "1.3.6.1.4.1.2620.1.1.25.4.0"; # peak number of connections +my @fw_checks = ($policy_state,$policy_name,$connections); + +###### SVN data +my $svn_status = "1.3.6.1.4.1.2620.1.6.102.0"; # "OK" svn status +my %svn_checks = ($svn_status,"OK"); +my %svn_checks_n = ($svn_status,"SVN status"); +my @svn_checks_oid = ($svn_status); + +###### HA data + +my $ha_active = "1.3.6.1.4.1.2620.1.5.5.0"; # "yes" +my $ha_state = "1.3.6.1.4.1.2620.1.5.6.0"; # "active" +my $ha_block_state = "1.3.6.1.4.1.2620.1.5.7.0"; #"OK" : ha blocking state +my $ha_status = "1.3.6.1.4.1.2620.1.5.102.0"; # "OK" : ha status + +my %ha_checks =( $ha_active,"yes",$ha_state,"active",$ha_block_state,"OK",$ha_status,"OK"); +my %ha_checks_n =( $ha_active,"HA active",$ha_state,"HA state",$ha_block_state,"HA block state",$ha_status,"ha_status"); +my @ha_checks_oid =( $ha_active,$ha_state,$ha_block_state,$ha_status); + +my $ha_mode = "1.3.6.1.4.1.2620.1.5.11.0"; # "Sync only" : ha Working mode + +my $ha_tables = "1.3.6.1.4.1.2620.1.5.13.1"; # ha status table +my $ha_tables_index = ".1"; +my $ha_tables_name = ".2"; +my $ha_tables_state = ".3"; # "OK" +my $ha_tables_prbdesc = ".6"; # Description if state is != "OK" + +#my @ha_table_check = ("Synchronization","Filter","cphad","fwd"); # process to check + +####### MGMT data + +my $mgmt_status = "1.3.6.1.4.1.2620.1.7.5.0"; # "active" : management status +my $mgmt_alive = "1.3.6.1.4.1.2620.1.7.6.0"; # 1 : management is alive if 1 +my $mgmt_stat_desc = "1.3.6.1.4.1.2620.1.7.102.0"; # Management status description +my $mgmt_stats_desc_l = "1.3.6.1.4.1.2620.1.7.103.0"; # Management status long description + +my %mgmt_checks = ($mgmt_status,"active",$mgmt_alive,"1"); +my %mgmt_checks_n = ($mgmt_status,"Mgmt status",$mgmt_alive,"Mgmt alive"); +my @mgmt_checks_oid = ($mgmt_status,$mgmt_alive); + +#################################### Globals ##############################"" + +my $Version='1.0'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_version2 =undef; # Version 2 +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_timeout= 5; # Default 5s Timeout +my $o_warn= undef; # Warning for connections +my $o_crit= undef; # Crit for connections +my $o_svn= undef; # Check for SVN status +my $o_fw= undef; # Check for FW status +my $o_ha= undef; # Check for HA status +my $o_mgmt= undef; # Check for management status +my $o_policy= undef; # Check for policy name +my $o_conn= undef; # Check for connexions +my $o_perf= undef; # Performance data output + +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_cpfw version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-s] [-w [-p=pol_name] [-c=warn,crit]] [-m] [-a] [-f] [-p ] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub help { + print "\nSNMP Checkpoint FW-1 Monitor for Nagios version ",$Version,"\n"; + print "GPL Licence, (c)2004-2006 - Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-s, --svn + check for svn status +-w, --fw + check for fw status +-a, --ha + check for ha status +-m, --mgmt + check for management status +-p, --policy=POLICY_NAME + check if installed policy is POLICY_NAME (must have -w) +-c, --connexions=WARN,CRIT + check warn and critical number of connexions (must have -w) +-f, --perfparse + perfparse output (only works with -c) +-P, --port=PORT + SNMP port (Default 161) +-t, --timeout=INTEGER + timeout for SNMP (Default: Nagios default) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'P:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + 's' => \$o_svn, 'svn' => \$o_svn, + 'w' => \$o_fw, 'fw' => \$o_fw, + 'a' => \$o_ha, 'ha' => \$o_ha, + 'm' => \$o_mgmt, 'mgmt' => \$o_mgmt, + 'p:s' => \$o_policy, 'policy:s' => \$o_policy, + 'c:s' => \$o_conn, 'connexions:s' => \$o_conn, + 'f' => \$o_perf, 'perfparse' => \$o_perf + ); + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + # Check firewall options + if ( defined($o_conn)) { + if ( ! defined($o_fw)) + { print "Cannot check connexions without checking fw\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @warncrit=split(/,/ , $o_conn); + if ( $#warncrit != 1 ) + { print "Put warn,crit levels with -c option\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + ($o_warn,$o_crit)=@warncrit; + if ( isnnum($o_warn) || isnnum($o_crit) ) + { print "Numeric values for warning and critical in -c options\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_warn >= $o_crit) + { print "warning <= critical ! \n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if ( defined($o_policy)) { + if (! defined($o_fw)) + { print "Cannot check policy name without checking fw\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_policy eq "") + { print "Put a policy name !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (defined($o_perf) && ! defined ($o_conn)) + { print "Nothing selected for perfparse !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_fw) && !defined($o_ha) && !defined($o_mgmt) && !defined($o_svn)) + { print "Must select a product to check !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT"); + alarm($TIMEOUT); +} else { + verb("no timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +########### Global checks ################# + +my $global_status=0; # global status : 0=OK, 1=Warn, 2=Crit +my ($resultat,$key)=(undef,undef); + +########## Check SVN status ############# +my $svn_print=""; +my $svn_state=0; + +if (defined ($o_svn)) { + +$resultat = $session->get_request( + Varbindlist => \@svn_checks_oid +); + + if (defined($resultat)) { + foreach $key ( keys %svn_checks) { + verb("$svn_checks_n{$key} : $svn_checks{$key} / $$resultat{$key}"); + if ( $$resultat{$key} ne $svn_checks{$key} ) { + $svn_print .= $svn_checks_n{$key} . ":" . $$resultat{$key} . " "; + $svn_state=2; + } + } + } else { + $svn_print .= "cannot find oids"; + #Critical state if not found because it means soft is not activated + $svn_state=2; + } + + if ($svn_state == 0) { + $svn_print="SVN : OK"; + } else { + $svn_print="SVN : " . $svn_print; + } + verb("$svn_print"); +} +########## Check mgmt status ############# +my $mgmt_state=0; +my $mgmt_print=""; + +if (defined ($o_mgmt)) { +# Check all states + $resultat=undef; + $resultat = $session->get_request( + Varbindlist => \@mgmt_checks_oid + ); + if (defined($resultat)) { + foreach $key ( keys %mgmt_checks) { + verb("$mgmt_checks_n{$key} : $mgmt_checks{$key} / $$resultat{$key}"); + if ( $$resultat{$key} ne $mgmt_checks{$key} ) { + $mgmt_print .= $mgmt_checks_n{$key} . ":" . $$resultat{$key} . " "; + $mgmt_state=2; + } + } + } else { + $mgmt_print .= "cannot find oids"; + #Critical state if not found because it means soft is not activated + $mgmt_state=2; + } + if ($mgmt_state == 0) { + $mgmt_print="MGMT : OK"; + } else { + $mgmt_print="MGMT : " . $mgmt_print; + } + verb("$svn_print"); +} + +########### Check fw status ############## + +my $fw_state=0; +my $fw_print=""; +my $perf_conn=undef; + +if (defined ($o_fw)) { + +# Check all states + + $resultat = $session->get_request( + Varbindlist => \@fw_checks + ); + if (defined($resultat)) { + verb("State : $$resultat{$policy_state}"); + verb("Name : $$resultat{$policy_name}"); + verb("connections : $$resultat{$connections}"); + + if ($$resultat{$policy_state} ne "Installed") { + $fw_state=2; + $fw_print .= "Policy:". $$resultat{$policy_state}." "; + verb("Policy state not installed"); + } + + if (defined($o_policy)) { + if ($$resultat{$policy_name} ne $o_policy) { + $fw_state=2; + $fw_print .= "Policy installed : $$resultat{$policy_name}"; + } + } + + if (defined($o_conn)) { + if ($$resultat{$connections} > $o_crit) { + $fw_state=2; + $fw_print .= "Connexions : ".$$resultat{$connections}." > ".$o_crit." "; + } else { + if ($$resultat{$connections} > $o_warn) { + $fw_state=1; + $fw_print .= "Connexions : ".$$resultat{$connections}." > ".$o_warn." "; + } + } + $perf_conn=$$resultat{$connections}; + } + } else { + $fw_print .= "cannot find oids"; + #Critical state if not found because it means soft is not activated + $fw_state=2; + } + + if ($fw_state==0) { + $fw_print="FW : OK"; + } else { + $fw_print="FW : " . $fw_print; + } + +} +########### Check ha status ############## + +my $ha_state_n=0; +my $ha_print=""; + +if (defined ($o_ha)) { + # Check all states + + $resultat = $session->get_request( + Varbindlist => \@ha_checks_oid + ); + + if (defined($resultat)) { + foreach $key ( keys %ha_checks) { + verb("$ha_checks_n{$key} : $ha_checks{$key} / $$resultat{$key}"); + if ( $$resultat{$key} ne $ha_checks{$key} ) { + $ha_print .= $ha_checks_n{$key} . ":" . $$resultat{$key} . " "; + $ha_state_n=2; + } + } + #my $ha_mode = "1.3.6.1.4.1.2620.1.5.11.0"; # "Sync only" : ha Working mode + } else { + $ha_print .= "cannot find oids"; + #Critical state if not found because it means soft is not activated + $ha_state_n=2; + } + + # get ha status table + $resultat = $session->get_table( + Baseoid => $ha_tables + ); + my %status; + my (@index,@oid) = (undef,undef); + my $nindex=0; + my $index_search= $ha_tables . $ha_tables_index; + + if (defined($resultat)) { + foreach $key ( keys %$resultat) { + if ( $key =~ /$index_search/) { + @oid=split (/\./,$key); + pop(@oid); + $index[$nindex]=pop(@oid); + $nindex++; + } + } + } else { + $ha_print .= "cannot find oids" if ($ha_state_n ==0); + #Critical state if not found because it means soft is not activated + $ha_state_n=2; + } + verb ("found $nindex ha softs"); + if ( $nindex == 0 ) + { + $ha_print .= " no ha soft found" if ($ha_state_n ==0); + $ha_state_n=2; + } else { + my $ha_soft_name=undef; + + for (my $i=0;$i<$nindex;$i++) { + + $key=$ha_tables . $ha_tables_name . "." . $index[$i] . ".0"; + $ha_soft_name= $$resultat{$key}; + + $key=$ha_tables . $ha_tables_state . "." . $index[$i] . ".0"; + if (($status{$ha_soft_name} = $$resultat{$key}) ne "OK") { + $key=$ha_tables . $ha_tables_prbdesc . "." . $index[$i] . ".0"; + $status{$ha_soft_name} = $$resultat{$key}; + $ha_print .= $ha_soft_name . ":" . $status{$ha_soft_name} . " "; + $ha_state_n=2 + } + verb ("$ha_soft_name : $status{$ha_soft_name}"); + } + } + + if ($ha_state_n == 0) { + $ha_print = "HA : OK"; + } else { + $ha_print = "HA : " . $ha_print; + } + +} + +$session->close; + +########## print results and exit + +my $f_print=undef; + +if (defined ($o_fw)) { $f_print = $fw_print } +if (defined ($o_svn)) { $f_print = (defined ($f_print)) ? $f_print . " / ". $svn_print : $svn_print } +if (defined ($o_ha)) { $f_print = (defined ($f_print)) ? $f_print . " / ". $ha_print : $ha_print } +if (defined ($o_mgmt)) { $f_print = (defined ($f_print)) ? $f_print . " / ". $mgmt_print : $mgmt_print } + +my $exit_status=undef; +$f_print .= " / CPFW Status : "; +if (($ha_state_n+$svn_state+$fw_state+$mgmt_state) == 0 ) { + $f_print .= "OK"; + $exit_status= $ERRORS{"OK"}; +} else { + if (($fw_state==1) || ($ha_state_n==1) || ($svn_state==1) || ($mgmt_state==1)) { + $f_print .= "WARNING"; + $exit_status= $ERRORS{"WARNING"}; + } else { + $f_print .= "CRITICAL"; + $exit_status=$ERRORS{"CRITICAL"}; + } +} + +if (defined($o_perf) && defined ($perf_conn)) { + $f_print .= " | fw_connexions=" . $perf_conn; +} + +print "$f_print\n"; +exit $exit_status; + diff --git a/check_snmp_css.pl b/check_snmp_css.pl new file mode 100755 index 0000000..c2b8552 --- /dev/null +++ b/check_snmp_css.pl @@ -0,0 +1,480 @@ +#!/usr/bin/perl -w +############################## check_snmp_css.pl ################# +# Version : 1.0.1 +# Date : 27 Sept 2006 +# Author : Patrick Proy ( patrick at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Changelog : +# Contributors : +################################################################# +# +# Help : ./check_snmp_css.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas + +my $css_svc_table = "1.3.6.1.4.1.9.9.368.1.15.2.1"; # Svc table +my $css_svc_name = "1.3.6.1.4.1.9.9.368.1.15.2.1.1"; # Service Name / apSvcName +my $css_svc_index = "1.3.6.1.4.1.9.9.368.1.15.2.1.2"; # apSvcIndex +my $css_svc_enable = "1.3.6.1.4.1.9.9.368.1.15.2.1.12"; # apSvcEnable +my $css_svc_state= "1.3.6.1.4.1.9.9.368.1.15.2.1.17"; # apSvcState : suspended(1), down(2), alive(4), dying(5) +my $css_svc_maxconn = "1.3.6.1.4.1.9.9.368.1.15.2.1.19"; # Max connexions / apSvcMaxConnections +my $css_svc_conn = "1.3.6.1.4.1.9.9.368.1.15.2.1.20"; # apSvcConnections +my $css_svc_avgresp = "1.3.6.1.4.1.9.9.368.1.15.2.1.65"; # apSvcAvgResponseTime : average response time +my $css_svc_maxresp = "1.3.6.1.4.1.9.9.368.1.15.2.1.66"; # apSvcPeakAvgResponseTime : peak response time +my @css_svc_state_txt= ("","suspended","down","","alive","dying"); +my @css_svc_state_nag= (3,2,2,3,0,2); + +# Globals + +my $Version='1.0'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_timeout= undef; # Timeout (Default 5) +my $o_perf= undef; # Output performance data +my $o_version2= undef; # use snmp v2c +#Specific +my $o_dir= "/tmp/"; # Directory to store temp file in it. +my $o_dir_set= undef; # defined if names and index must be read form file. +my $o_name= undef; # service name (regexp) +my $o_warn_number= undef; # minimum number of service before warning +my $o_crit_number= undef; # minimum number of service before critical +my $o_warn_conn= undef; # % of max connexions for warning level +my $o_crit_conn= undef; # % of max connexions for critical level +my $o_warn_resp= undef; # average response time for warning level +my $o_crit_resp= undef; # average response time for critical level +my @o_levels= undef; +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_css version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) -n [-d directory] [-w ,, -c ,,] [-p ] [-f] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^-?(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub set_status { # return worst status with this order : OK, unknwonw, warning, critical + my $new_status=shift; + my $cur_status=shift; + if (($cur_status == 0)|| ($new_status==$cur_status)){ return $new_status; } + if ($new_status==3) { return $cur_status; } + if ($new_status > $cur_status) {return $new_status;} + return $cur_status; +} + +sub is_pattern_valid { # Test for things like "" or "+5-i" + my $pat = shift; + if (!defined($pat)) { $pat=" ";} # Just to get rid of compilation time warnings + return eval { "" =~ /$pat/; 1 } || 0; +} + +sub round ($$) { + sprintf "%.$_[1]f", $_[0]; +} + +sub help { + print "\nSNMP Cisco CSS monitor for Nagios version ",$Version,"\n"; + print "(c)2004-2006 Patrick Proy\n\n"; + print_usage(); + print < + regexp to select service +-w, --warning=,, + Optional. Warning level for + - minimum number of active & alive service + - average response time + - number of connexions + For no warnings, put -1 (ex : -w5,-1,3). + When using negative numbers, dont put space after "-w" +-d, --dir= + Directory where the temp file with index, created by check_snmp_css_main.pl, can be found + If no directory is set, /tmp will be used +-c, --critical=,resp>, + Optional. Critical levels (-1 for no critical levels) + See warning levels. +-C, --community=COMMUNITY NAME + community name for the host's SNMP agent (implies v1 protocol) +-2, --v2c + Use snmp v2c +-l, --login=LOGIN ; -x, --passwd=PASSWD + Login and auth password for snmpv3 authentication + If no priv password exists, implies AuthNoPriv +-X, --privpass=PASSWD + Priv password for snmpv3 (AuthPriv protocol) +-L, --protocols=, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-f, --perfparse + Perfparse compatible output +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'f' => \$o_perf, 'perfparse' => \$o_perf, + 'n:s' => \$o_name, 'name:s' => \$o_name, + 'w:s' => \$o_warn_conn, 'warning:s' => \$o_warn_conn, + 'c:s' => \$o_crit_conn, 'critical:s' => \$o_crit_conn, + 'd:s' => \$o_dir_set, 'dir:s' => \$o_dir_set + ); + # Basic checks + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (!defined($o_name) || ! (is_pattern_valid($o_name))) + {print "Need a service name!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined($o_warn_conn)) { + @o_levels=split(/,/,$o_warn_conn); + if (defined($o_levels[0])) { + if (isnnum($o_levels[0])) {print "Need number for warning!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_levels[0] != -1 ) {$o_warn_number=$o_levels[0];} + } + if (defined($o_levels[1])) { + if (isnnum($o_levels[1])) {print "Need number for warning!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_levels[1] != -1 ) {$o_warn_conn=$o_levels[1];} else {$o_warn_conn=undef;} + } else {$o_warn_conn=undef;} + if (defined($o_levels[2]) ) { + if (isnnum($o_levels[2])) {print "Need number for warning!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_levels[2] != -1 ) {$o_warn_resp=$o_levels[2];} + } + } + if (defined($o_crit_conn)) { + @o_levels=split(/,/,$o_crit_conn); + if (defined($o_levels[0]) ) { + if (isnnum($o_levels[0])) {print "Need number for critical!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_levels[0] != -1 ) { + $o_crit_number=$o_levels[0]; + if (defined($o_warn_number) && ($o_crit_number>=$o_warn_number)) + {print "critical must be < warning!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + } + if (defined($o_levels[1]) ) { + if (isnnum($o_levels[1])) {print "Need number for critical!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_levels[1] != -1 ) { + $o_crit_conn=$o_levels[1]; + if (defined($o_warn_conn) && ($o_warn_conn>=$o_crit_conn)) + {print "critical must be > warning!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } else {$o_crit_conn=undef;} + } else {$o_crit_conn=undef;} + if (defined($o_levels[2]) ) { + if (isnnum($o_levels[2])) {print "Need number for critical!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_levels[2] != -1 ) { + $o_crit_resp=$o_levels[1]; + if (defined($o_warn_resp) && ($o_warn_resp>=$o_crit_resp)) + {print "critical must be > warning!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + } + } + if (defined($o_dir_set)) { + if ($o_dir_set ne "") {$o_dir=$o_dir_set;} + verb("Tmp directory : $o_dir"); + } +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT + 5"); + alarm($TIMEOUT+5); +} else { + verb("no global timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} +$session->max_msg_size(10000); + +########### Cisco CSS checks ############## + +my (@index,@svcname)=(undef,undef); +my ($numsvc,$numoid,$numoid2)=0; +my (@oid,@oid_list,@oid_list2)=undef; +my $resultat = undef; +# Get load table by snmp or file +if (defined($o_dir_set)) { + my $file_name=$o_dir."/Nagios_css_".$o_host; + my $file_lock=$file_name.".lock"; + + # Check for lock file during 3 seconds max and quit if sill here. + my $file_timeout=0; + while (-e $file_lock) { + sleep(1); + if ($file_timeout==3) { + print "Lock file remaining for more than 3 sec : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; + } + $file_timeout++; + } + # Open file for reading. + open(FILE,"< ".$file_name); + while () { + my @file_line=split(/:/,$_); + if ((defined ($file_line[1])) && ($file_line[1] =~ /$o_name/)) { # select service by name + chomp($file_line[1]); + $svcname[$numsvc]=$file_line[1]; + my $key = $file_line[0]; + verb ("Found : $svcname[$numsvc]"); + $index[$numsvc++]=$key; + # Build oid for snmpget + $oid_list[$numoid++]=$css_svc_enable.$key; + $oid_list[$numoid++]=$css_svc_state.$key; + $oid_list2[$numoid2++]=$css_svc_maxconn.$key; + $oid_list2[$numoid2++]=$css_svc_conn.$key; + $oid_list2[$numoid2++]=$css_svc_avgresp.$key; + } + } + close (FILE); +} else { + $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($css_svc_name) + : $session->get_table(Baseoid => $css_svc_name); + + if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + + + # Get name data & index + + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ($$resultat{$key} =~ /$o_name/) { # select service by name + $svcname[$numsvc]=$$resultat{$key}; + $key =~ s/$css_svc_name//; + verb ("Found : $svcname[$numsvc]"); + $index[$numsvc++]=$key; + # Build oid for snmpget + $oid_list[$numoid++]=$css_svc_enable.$key; + $oid_list[$numoid++]=$css_svc_state.$key; + $oid_list2[$numoid2++]=$css_svc_maxconn.$key; + $oid_list2[$numoid2++]=$css_svc_conn.$key; + $oid_list2[$numoid2++]=$css_svc_avgresp.$key; + } + } +} +# Check if a least one service found +if ($numsvc == 0) { + print "No service matching ",$o_name," found : CRITICAL\n"; + exit $ERRORS{"CRITICAL"}; +} + +$resultat = undef; +$resultat = (Net::SNMP->VERSION < 4) ? + $session->get_request(@oid_list) + : $session->get_request(-varbindlist => \@oid_list); + +if (!defined($resultat)) { + printf("ERROR: Status get : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +my $resultat2 = undef; +$resultat2 = (Net::SNMP->VERSION < 4) ? + $session->get_request(@oid_list2) + : $session->get_request(-varbindlist => \@oid_list2); + +if (!defined($resultat2)) { + printf("ERROR: Conn get : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +my $output=""; +my $output_perf=""; +my $numsvc_ok=0; +my $output_done=0; +my $global_status=0; + +for (my $i=0;$i<$numsvc;$i++) { + my $key=$index[$i]; + if ($$resultat{$css_svc_enable.$key} == 0 ) { + # service disabled + if ($output ne "") { $output.=", ";} + $output .= $svcname[$i] . " : Disabled"; + } else { + if ($css_svc_state_nag[$$resultat{$css_svc_state.$key}] != 0) { + # state not OK + if ($output ne "") { $output.=", ";} + $output .= $svcname[$i] . " : " . $css_svc_state_txt[$$resultat{$css_svc_state.$key}]; + } else { + $numsvc_ok++; + $output_done=0; + # state OK + my $prctconn = round(($$resultat2{$css_svc_conn.$key}/$$resultat2{$css_svc_maxconn.$key}) * 100,0); + my $resptime = $$resultat2{$css_svc_avgresp.$key}; + if (defined ($o_warn_conn) && ($prctconn>$o_warn_conn)) { + if ($output ne "") { $output.=", ";} + $output .= $svcname[$i]. ":" . $prctconn ."%, ".$resptime."ms"; + set_status(1,$global_status);$output_done=1; + } + if (defined ($o_crit_conn) && ($prctconn>$o_crit_conn)) { + if ($output_done==0) { + $output .= $svcname[$i]. ":" . $prctconn ."%, ".$resptime."ms"; + $output_done=1; + } + set_status(2,$global_status); + } + if (defined ($o_warn_resp) && ($prctconn>$o_warn_resp)) { + if ($output_done==0) { + $output .= $svcname[$i]. ":" . $prctconn ."%, ".$resptime."ms"; + $output_done=1; + } + set_status(1,$global_status); + } + if (defined ($o_crit_resp) && ($prctconn>$o_crit_resp)) { + if ($output_done==0) { + $output .= $svcname[$i]. ":" . $prctconn ."%, ".$resptime."ms"; + $output_done=1; + } + set_status(2,$global_status); + } + } + } +} + + +$output .= " ".$numsvc_ok."/".$numsvc." services OK"; + +if (($global_status == 2) || ((defined ($o_crit_number)) && ($numsvc_ok<=$o_crit_number)) || ($numsvc_ok==0) ) { + print $output," : CRITICAL\n"; + exit $ERRORS{"CRITICAL"} +} +if (($global_status == 1) || ((defined ($o_warn_number)) && ($numsvc_ok<=$o_warn_number))) { + print $output," : WARNING\n"; + exit $ERRORS{"WARNING"} +} +print $output," : OK\n"; +exit $ERRORS{"OK"}; diff --git a/check_snmp_css_main.pl b/check_snmp_css_main.pl new file mode 100755 index 0000000..3a64bf0 --- /dev/null +++ b/check_snmp_css_main.pl @@ -0,0 +1,266 @@ +#!/usr/bin/perl -w +############################## check_snmp_css_main.pl ################# +# Version : 1.0 +# Date : 27 Sept 2006 +# Author : Patrick Proy ( patrick at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Changelog : +# Contributors : +################################################################# +# +# Help : ./check_snmp_css.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas + +my $css_svc_table = "1.3.6.1.4.1.9.9.368.1.15.2.1"; # Svc table +my $css_svc_name = "1.3.6.1.4.1.9.9.368.1.15.2.1.1"; # Service Name / apSvcName +my $css_svc_index = "1.3.6.1.4.1.9.9.368.1.15.2.1.2"; # apSvcIndex +my $css_svc_enable = "1.3.6.1.4.1.9.9.368.1.15.2.1.12"; # apSvcEnable +my $css_svc_state= "1.3.6.1.4.1.9.9.368.1.15.2.1.17"; # apSvcState : suspended(1), down(2), alive(4), dying(5) +my $css_svc_maxconn = "1.3.6.1.4.1.9.9.368.1.15.2.1.19"; # Max connexions / apSvcMaxConnections +my $css_svc_conn = "1.3.6.1.4.1.9.9.368.1.15.2.1.20"; # apSvcConnections +my $css_svc_avgresp = "1.3.6.1.4.1.9.9.368.1.15.2.1.65"; # apSvcAvgResponseTime : average response time +my $css_svc_maxresp = "1.3.6.1.4.1.9.9.368.1.15.2.1.66"; # apSvcPeakAvgResponseTime : peak response time +my @css_svc_state_txt= ("","suspended","down","","alive","dying"); +my @css_svc_state_nag= (3,2,2,3,0,2); + +# Globals + +my $Version='1.0'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_timeout= undef; # Timeout (Default 5) +my $o_version2= undef; # use snmp v2c +#Specific +my $o_dir= "/tmp/"; # Directory to store temp file in it. +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_css_main version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-d directory] [-p ] [-t ] [-V]\n"; +} + +sub help { + print "\nSNMP Cisco CSS monitor MAIN script for Nagios version ",$Version,"\n"; + print "GPL Licence, (c)2004-2006 Patrick Proy\n\n"; + print_usage(); + print < + Directory where temp file with index is written +-C, --community=COMMUNITY NAME + community name for the host's SNMP agent (implies v1 protocol) +-2, --v2c + Use snmp v2c +-l, --login=LOGIN ; -x, --passwd=PASSWD + Login and auth password for snmpv3 authentication + If no priv password exists, implies AuthNoPriv +-X, --privpass=PASSWD + Priv password for snmpv3 (AuthPriv protocol) +-L, --protocols=, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'd:s' => \$o_dir, 'dir:s' => \$o_dir + ); + # Basic checks + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (defined($o_dir)) { + verb("Tmp directory : $o_dir"); + } +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT + 5"); + alarm($TIMEOUT+5); +} else { + verb("no global timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} +$session->max_msg_size(10000); + +########### Cisco CSS checks ############## + +# Get load table +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($css_svc_name) + : $session->get_table(Baseoid => $css_svc_name); + +if (!defined($resultat)) { + printf("ERROR: Name table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + + +# Get name data & index +my (@index,@svcname)=(undef,undef); +my $numsvc=0; +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + $svcname[$numsvc]=$$resultat{$key}; + $key =~ s/$css_svc_name//; + verb ("Found : $svcname[$numsvc]"); + $index[$numsvc++]=$key; +} + +# Write file + +my $file_name=$o_dir."/Nagios_css_".$o_host; +my $file_lock=$file_name.".lock"; + +# First, make a lock file +system ("touch $file_lock"); +# allow scripts to finish reading file +sleep (0.5); +# create the file +if (!open(FILE,"> ".$file_name)) { + print "Cannot write $file_name\n"; + unlink($file_lock); + exit $ERRORS{"UNKNOWN"}; +} +for (my $i=0;$i<$numsvc;$i++) { + my $output=$index[$i].":".$svcname[$i]."\n"; + print FILE $output; +} +close (FILE); +unlink($file_lock); +print "Found $numsvc services : OK\n"; +exit $ERRORS{"OK"}; diff --git a/check_snmp_env.pl b/check_snmp_env.pl new file mode 100755 index 0000000..8840af2 --- /dev/null +++ b/check_snmp_env.pl @@ -0,0 +1,816 @@ +#!/usr/bin/perl -w +############################## check_snmp_env ################# +# Version : 1.1 +# Date : Jan 11 2007 +# Author : Patrick Proy ( patrick at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Changelog : +# Contributors : Fredrik Vocks +################################################################# +# +# Help : ./check_snmp_env.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + + +my @Nagios_state = ("UNKNOWN","OK","WARNING","CRITICAL"); # Nagios states coding + +# SNMP Datas + +# CISCO-ENVMON-MIB +my $ciscoEnvMonMIB = "1.3.6.1.4.1.9.9.13"; # Cisco env base table +my %CiscoEnvMonState = (1,"normal",2,"warning",3,"critical",4,"shutdown",5,"notPresent", + 6,"notFunctioning"); # Cisco states +my %CiscoEnvMonNagios = (1,1 ,2,2 ,3,3 ,4,3 ,5,0, 6,3); # Nagios states returned for CIsco states (coded see @Nagios_state). +my $ciscoVoltageTable = $ciscoEnvMonMIB.".1.2.1"; # Cisco voltage table +my $ciscoVoltageTableIndex = $ciscoVoltageTable.".1"; #Index table +my $ciscoVoltageTableDesc = $ciscoVoltageTable.".2"; #Description +my $ciscoVoltageTableValue = $ciscoVoltageTable.".3"; #Value +my $ciscoVoltageTableState = $ciscoVoltageTable.".7"; #Status +# CiscoEnvMonVoltageStatusEntry ::= + # 1 ciscoEnvMonVoltageStatusIndex Integer32 (0..2147483647), + # 2 ciscoEnvMonVoltageStatusDescr DisplayString, + # 3 ciscoEnvMonVoltageStatusValue CiscoSignedGauge, + # 4 ciscoEnvMonVoltageThresholdLow Integer32, + # 5 ciscoEnvMonVoltageThresholdHigh Integer32, + # 6 ciscoEnvMonVoltageLastShutdown Integer32, + # 7 ciscoEnvMonVoltageState CiscoEnvMonState +my $ciscoTempTable = $ciscoEnvMonMIB.".1.3.1"; # Cisco temprature table +my $ciscoTempTableIndex = $ciscoTempTable.".1"; #Index table +my $ciscoTempTableDesc = $ciscoTempTable.".2"; #Description +my $ciscoTempTableValue = $ciscoTempTable.".3"; #Value +my $ciscoTempTableState = $ciscoTempTable.".6"; #Status +# CiscoEnvMonTemperatureStatusEntry ::= + # ciscoEnvMonTemperatureStatusIndex Integer32 (0..2147483647), + # ciscoEnvMonTemperatureStatusDescr DisplayString, + # ciscoEnvMonTemperatureStatusValue Gauge32, + # ciscoEnvMonTemperatureThreshold Integer32, + # ciscoEnvMonTemperatureLastShutdown Integer32, + # ciscoEnvMonTemperatureState CiscoEnvMonState +my $ciscoFanTable = $ciscoEnvMonMIB.".1.4.1"; # Cisco fan table +my $ciscoFanTableIndex = $ciscoFanTable.".1"; #Index table +my $ciscoFanTableDesc = $ciscoFanTable.".2"; #Description +my $ciscoFanTableState = $ciscoFanTable.".3"; #Status +# CiscoEnvMonFanStatusEntry ::= + # ciscoEnvMonFanStatusIndex Integer32 (0..2147483647), + # ciscoEnvMonFanStatusDescr DisplayString, + # ciscoEnvMonFanState CiscoEnvMonState +my $ciscoPSTable = $ciscoEnvMonMIB.".1.5.1"; # Cisco power supply table +my $ciscoPSTableIndex = $ciscoPSTable.".1"; #Index table +my $ciscoPSTableDesc = $ciscoPSTable.".2"; #Description +my $ciscoPSTableState = $ciscoPSTable.".3"; #Status +# CiscoEnvMonSupplyStatusEntry ::= + # ciscoEnvMonSupplyStatusIndex Integer32 (0..2147483647), + # ciscoEnvMonSupplyStatusDescr DisplayString, + # ciscoEnvMonSupplyState CiscoEnvMonState, + # ciscoEnvMonSupplySource INTEGER + +# Nokia env mib +my $nokia_temp_tbl="1.3.6.1.4.1.94.1.21.1.1.5"; +my $nokia_temp="1.3.6.1.4.1.94.1.21.1.1.5.0"; +my $nokia_fan_table="1.3.6.1.4.1.94.1.21.1.2"; +my $nokia_fan_status="1.3.6.1.4.1.94.1.21.1.2.1.1.2"; +my $nokia_ps_table="1.3.6.1.4.1.94.1.21.1.3"; +my $nokia_ps_temp="1.3.6.1.4.1.94.1.21.1.3.1.1.2"; +my $nokia_ps_status="1.3.6.1.4.1.94.1.21.1.3.1.1.3"; + +# Bluecoat env mib +my @bc_SensorCode=("","ok","unknown","not-installed","voltage-low-warning","voltage-low-critical", + "no-power","voltage-high-warning","voltage-high-critical","voltage-high-severe", + "temperature-high-warning","temperature-high-critical","temperature-high-severe", + "fan-slow-warning","fan-slow-critical","fan-stopped"); # BC element status returned by MIB +my @bc_status_nagios=(3,0,3,3,1,2,2,1,2,2,1,2,2,1,2,2); # nagios status equivallent to BC status +my @bc_SensorStatus=("","ok","unavailable","nonoperational"); # ok(1),unavailable(2),nonoperational(3) +my @bc_mesure=("","","","Enum","volts","celsius","rpm"); + +my @bc_DiskStatus=("","present","initializing","inserted","offline","removed","not-present","empty","bad","unknown"); +my @bc_dsk_status_nagios=(3,0,0,1,1,1,2,2,2,3); + +my $bc_sensor_table = "1.3.6.1.4.1.3417.2.1.1.1.1.1"; # sensor table +my $bc_sensor_units = "1.3.6.1.4.1.3417.2.1.1.1.1.1.3"; # cf bc_mesure +my $bc_sensor_Scale = "1.3.6.1.4.1.3417.2.1.1.1.1.1.4"; # * 10^value +my $bc_sensor_Value = "1.3.6.1.4.1.3417.2.1.1.1.1.1.5"; # value +my $bc_sensor_Code = "1.3.6.1.4.1.3417.2.1.1.1.1.1.6"; # bc_SensorCode +my $bc_sensor_Status = "1.3.6.1.4.1.3417.2.1.1.1.1.1.7"; # bc_SensorStatus +my $bc_sensor_Name = "1.3.6.1.4.1.3417.2.1.1.1.1.1.9"; # name + +my $bc_dsk_table = "1.3.6.1.4.1.3417.2.2.1.1.1.1"; #disk table +my $bc_dsk_status = "1.3.6.1.4.1.3417.2.2.1.1.1.1.3"; # cf bc_DiskStatus +my $bc_dsk_vendor = "1.3.6.1.4.1.3417.2.2.1.1.1.1.5"; # cf bc_DiskStatus +my $bc_dsk_serial = "1.3.6.1.4.1.3417.2.2.1.1.1.1.8"; # cf bc_DiskStatus + +# Ironport env mib + +my $iron_ps_table = "1.3.6.1.4.1.15497.1.1.1.8"; # ps table +my $iron_ps_status = "1.3.6.1.4.1.15497.1.1.1.8.1.2"; # ps status +#powerSupplyNotInstalled(1), powerSupplyHealthy(2), powerSupplyNoAC(3), powerSupplyFaulty(4) +my @iron_ps_status_name=("","powerSupplyNotInstalled","powerSupplyHealthy","powerSupplyNoAC","powerSupplyFaulty"); +my @iron_ps_status_nagios=(3,3,0,2,2); +my $iron_ps_ha = "1.3.6.1.4.1.15497.1.1.1.8.1.3"; # ps redundancy status +#powerSupplyRedundancyOK(1), powerSupplyRedundancyLost(2) +my @iron_ps_ha_name=("","powerSupplyRedundancyOK","powerSupplyRedundancyLost"); +my @iron_ps_ha_nagios=(3,0,1); +my $iron_ps_name = "1.3.6.1.4.1.15497.1.1.1.8.1.4"; # ps name + +my $iron_tmp_table = "1.3.6.1.4.1.15497.1.1.1.9"; # temp table +my $iron_tmp_celcius = "1.3.6.1.4.1.15497.1.1.1.9.1.2"; # temp in celcius +my $iron_tmp_name = "1.3.6.1.4.1.15497.1.1.1.9.1.3"; # name + +my $iron_fan_table = "1.3.6.1.4.1.15497.1.1.1.10"; # fan table +my $iron_fan_rpm = "1.3.6.1.4.1.15497.1.1.1.10.1.2"; # fan speed in RPM +my $iron_fan_name = "1.3.6.1.4.1.15497.1.1.1.10.1.3"; # fan name + +# Globals + +my $Version='1.1'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_timeout= undef; # Timeout (Default 5) +my $o_perf= undef; # Output performance data +my $o_version2= undef; # use snmp v2c +# check type +my $o_check_type= "cisco"; # default Cisco +my @valid_types =("cisco","nokia","bc","iron"); +my $o_temp= undef; # max temp +my $o_fan= undef; # min fan speed + +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_env version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-p ] -T (cisco|nokia|lp|iron) [-F ] [-c ] [-f] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub set_status { # return worst status with this order : OK, unknwonw, warning, critical + my $new_status=shift; + my $cur_status=shift; + if (($cur_status == 0)|| ($new_status==$cur_status)){ return $new_status; } + if ($new_status==3) { return $cur_status; } + if ($new_status > $cur_status) {return $new_status;} + return $cur_status; +} + +sub help { + print "\nSNMP environmental Monitor for Nagios version ",$Version,"\n"; + print "GPL Licence, (c)2006-2007 Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-T, --type=cisco|nokia|bc + Environemental check : + cisco : voltage,temp,fan,power supply status + will try to check everything present + nokia : fan and power supply + bc : fans, power supply, voltage, disks + iron : fans, power supply, temp +-F, --fan= + Minimum fan rpm value +-c, --celcius= + Maximum temp in degree celcius +-f, --perfparse + Perfparse compatible output +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + + '2' => \$o_version2, 'v2c' => \$o_version2, + 'f' => \$o_perf, 'perfparse' => \$o_perf, + 'T:s' => \$o_check_type, 'type:s' => \$o_check_type, + 'F:i' => \$o_fan, 'fan:i' => \$o_fan, + 'c:i' => \$o_temp, 'celcius:i' => \$o_temp + ); + # check the -T option + my $T_option_valid=0; + foreach (@valid_types) { if ($_ eq $o_check_type) {$T_option_valid=1} }; + if ( $T_option_valid == 0 ) + {print "Invalid check type (-T)!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + # Basic checks + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT + 5"); + alarm($TIMEOUT+5); +} else { + verb("no global timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +my $exit_val=undef; +########### Cisco env checks ############## + +if ($o_check_type eq "cisco") { + +verb("Checking cisco env"); + +# Get load table +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($ciscoEnvMonMIB) + : $session->get_table(Baseoid => $ciscoEnvMonMIB); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +$session->close; + +# Get env data index +my (@voltindex,@tempindex,@fanindex,@psindex)=(undef,undef,undef,undef); +my ($voltexist,$tempexist,$fanexist,$psexist)=(0,0,0,0); +my @oid=undef; +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$ciscoVoltageTableDesc/ ) { + @oid=split (/\./,$key); + $voltindex[$voltexist++] = pop(@oid); + } + if ( $key =~ /$ciscoTempTableDesc/ ) { + @oid=split (/\./,$key); + $tempindex[$tempexist++] = pop(@oid); + } + if ( $key =~ /$ciscoFanTableDesc/ ) { + @oid=split (/\./,$key); + $fanindex[$fanexist++] = pop(@oid); + } + if ( $key =~ /$ciscoPSTableDesc/ ) { + @oid=split (/\./,$key); + $psindex[$psexist++] = pop(@oid); + } +} + +if ( ($voltexist ==0) && ($tempexist ==0) && ($fanexist ==0) && ($psexist ==0) ) { + print "No Environemental data found : UNKNOWN"; + exit $ERRORS{"UNKNOWN"}; +} + +# Get the data +my ($i,$cur_status)=(undef,undef); + +my $fan_global=0; +my %fan_status; +if ($fanexist !=0) { + for ($i=0;$i < $fanexist; $i++) { + $cur_status=$$resultat{$ciscoFanTableState . "." . $fanindex[$i]}; + verb ($$resultat{$ciscoFanTableDesc .".".$fanindex[$i]}); + verb ($cur_status); + if (!defined ($cur_status)) { ### Error TODO + $fan_global=1; + } + if ($CiscoEnvMonNagios{$cur_status} ne "OK") { + $fan_global= 1; + $fan_status{$$resultat{$ciscoFanTableDesc .".".$fanindex[$i]}}=$cur_status; + } + } +} + +my $ps_global=0; +my %ps_status; +if ($psexist !=0) { + for ($i=0;$i < $psexist; $i++) { + $cur_status=$$resultat{$ciscoPSTableState . "." . $psindex[$i]}; + if (!defined ($cur_status)) { ### Error TODO + $fan_global=1; + } + if ($CiscoEnvMonNagios{$cur_status} ne "OK") { + $ps_global= 1; + $ps_status{$$resultat{$ciscoPSTableDesc .".".$psindex[$i]}}=$cur_status; + } + } +} + +my $global_state=0; +my $output=""; +if ($fanexist !=0) { + if ($fan_global ==0) { + $output .= $fanexist." Fan OK"; + } else { + foreach (keys %fan_status) { + $output .= "Fan " . $_ . ":" . $CiscoEnvMonState {$fan_status{$_}} ." "; + if ($global_state < $CiscoEnvMonNagios{$fan_status{$_}} ) { + $global_state = $CiscoEnvMonNagios{$fan_status{$_}} ; + } + } + } +} + +$output .= "," if ($output ne ""); +if ($psexist !=0) { + if ($ps_global ==0) { + $output .= $psexist." ps OK"; + } else { + foreach (keys %ps_status) { + $output .= "ps " . $_ . ":" . $CiscoEnvMonState {$ps_status{$_}} ." "; + if ($global_state < $CiscoEnvMonNagios{$ps_status{$_}} ) { + $global_state = $CiscoEnvMonNagios{$ps_status{$_}} ; + } + } + } +} + +print $output," : ",$Nagios_state[$global_state],"\n"; +$exit_val=$ERRORS{$Nagios_state[$global_state]}; + +exit $exit_val; + +} + +############# Nokia checks +if ($o_check_type eq "nokia") { + +verb("Checking nokia env"); + +my $resultat; +# status : 0=ok, 1=nok, 2=temp prb +my ($fan_status,$ps_status,$temp_status)=(0,0,0); +my ($fan_exist,$ps_exist,$temp_exist)=(0,0,0); +my ($num_fan,$num_ps)=(0,0); +my ($num_fan_nok,$num_ps_nok)=(0,0); +my $global_status=0; +my $output=""; +# get temp +$resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($nokia_temp_tbl) + : $session->get_table(Baseoid => $nokia_temp_tbl); +if (defined($resultat)) { + verb ("temp found"); + $temp_exist=1; + if ($$resultat{$nokia_temp} != 1) { + $temp_status=2;$global_status=1; + $output="Temp CRITICAL "; + } else { + $output="Temp OK "; + } +} + +# Get fan table +$resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($nokia_fan_table) + : $session->get_table(Baseoid => $nokia_fan_table); + +if (defined($resultat)) { + $fan_exist=1; + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$nokia_fan_status/ ) { + if ($$resultat{$key} != 1) { $fan_status=1; $num_fan_nok++} + $num_fan++; + } + } + if ($fan_status==0) { + $output.= ", ".$num_fan." fan OK"; + } else { + $output.= ", ".$num_fan_nok."/".$num_fan." fan CRITICAL"; + $global_status=2; + } +} + +# Get ps table +$resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($nokia_ps_table) + : $session->get_table(Baseoid => $nokia_ps_table); + +if (defined($resultat)) { + $ps_exist=1; + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$nokia_ps_status/ ) { + if ($$resultat{$key} != 1) { $ps_status=1; $num_ps_nok++;} + $num_ps++; + } + if ( $key =~ /$nokia_ps_temp/ ) { + if ($$resultat{$key} != 1) { if ($ps_status==0) {$ps_status=2;$num_ps_nok++;} } + } + } + if ($ps_status==0) { + $output.= ", ".$num_ps." ps OK"; + } elsif ($ps_status==2) { + $output.= ", ".$num_ps_nok."/".$num_ps." ps WARNING (temp)"; + if ($global_status != 2) {$global_status=1;} + } else { + $output.= ", ".$num_ps_nok."/".$num_ps." ps CRITICAL"; + $global_status=2; + } +} + +$session->close; + +verb ("status : $global_status"); + +if ( ($fan_exist+$ps_exist+$temp_exist) == 0) { + print "No environemental informations found : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +if ($global_status==0) { + print $output." : all OK\n"; + exit $ERRORS{"OK"}; +} + +if ($global_status==1) { + print $output." : WARNING\n"; + exit $ERRORS{"WARNING"}; +} + +if ($global_status==2) { + print $output." : CRITICAL\n"; + exit $ERRORS{"CRITICAL"}; +} +} + +############# Bluecoat checks +if ($o_check_type eq "bc") { + + verb("Checking bluecoat env"); + + my $resultat; + my $global_status=0; + my ($num_fan,$num_other,$num_volt,$num_temp,$num_disk)=(0,0,0,0,0); + my ($num_fan_ok,$num_other_ok,$num_volt_ok,$num_temp_ok,$num_disk_ok)=(0,0,0,0,0); + my $output=""; + my $output_perf=""; + + + # get sensor table + $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($bc_sensor_table) + : $session->get_table(Baseoid => $bc_sensor_table); + if (defined($resultat)) { + verb ("sensor table found"); + my ($sens_name,$sens_status,$sens_value,$sens_unit)=(undef,undef,undef,undef); + foreach my $key ( keys %$resultat) { + if ($key =~ /$bc_sensor_Name/) { + $sens_name = $$resultat{$key}; + $key =~ s/$bc_sensor_Name//; + $sens_unit = $$resultat{$bc_sensor_units.$key}; + if ($$resultat{$bc_sensor_Status.$key} != 1) { # sensor not operating : output and status unknown + if ($output ne "") { $output.=", ";} + $output .= $sens_name ." sensor ".$bc_SensorStatus[$$resultat{$bc_sensor_Status.$key}]; + if ($global_status==0) {$global_status=3;} + } else { # Get status + $sens_status=$bc_status_nagios[$$resultat{$bc_sensor_Code.$key}]; + if ($sens_status != 0) { # warn/critical/unknown : output + if ($output ne "") { $output.=", ";} + $output .= $sens_name . ":".$bc_SensorCode[$sens_status]; + set_status($sens_status,$global_status); + } + } + if (defined($o_perf)) { + if ($output_perf ne "") { $output_perf .=" ";} + $output_perf .= "'".$sens_name."'="; + my $perf_value = $$resultat{$bc_sensor_Value.$key} * 10 ** $$resultat{$bc_sensor_Scale.$key}; + $output_perf .= $perf_value; + } + ### FAN + if ($bc_mesure[$sens_unit] eq "rpm") { + $num_fan++;if ($sens_status == 0) { $num_fan_ok++; } + } elsif ($bc_mesure[$sens_unit] eq "celsius") { + $num_fan++;if ($sens_status == 0) { $num_temp_ok++; } + } elsif ($bc_mesure[$sens_unit] eq "volts") { + $num_volt++;if ($sens_status == 0) { $num_volt_ok++; } + } else { + $num_other++;if ($sens_status == 0) { $num_other_ok++;}} + } + } + } + + # Get disk table + $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($bc_dsk_table) + : $session->get_table(Baseoid => $bc_dsk_table); + + if (defined($resultat)) { + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + my ($dsk_name,$dsk_status)=(undef,undef,undef); + if ( $key =~ /$bc_dsk_status/ ) { + $num_disk++; + $dsk_status=$bc_dsk_status_nagios[$$resultat{$key}]; + if ( $dsk_status != 0) { + $key =~ s/$bc_dsk_status//; + $dsk_name = $$resultat{$bc_dsk_vendor.$key} . "(".$$resultat{$bc_dsk_serial.$key} . ")"; + if ($output ne "") { $output.=", ";} + $output .= $dsk_name . ":" . $bc_DiskStatus[$$resultat{$bc_dsk_status.$key}]; + set_status($dsk_status,$global_status); + } else { + $num_disk_ok++; + } + } + } + } + + if ($num_fan+$num_other+$num_volt+$num_temp+$num_disk == 0) { + print "No information found : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; + } + + if ($output ne "") { $output.=", ";} + if ($num_fan_ok != 0) { $output.= $num_fan_ok." fan OK ";} + if ($num_other_ok != 0) { $output.= $num_other_ok." other OK ";} + if ($num_volt_ok != 0) { $output.= $num_volt_ok." voltage OK ";} + if ($num_temp_ok != 0) { $output.= $num_temp_ok." temp OK ";} + if ($num_disk_ok != 0) { $output.= $num_disk_ok." disk OK ";} + + if (defined($o_perf)) { $output_perf = " | " . $output_perf;} + if ($global_status==3) { + print $output," : UNKNOWN",$output_perf,"\n"; + exit $ERRORS{"UNKNOWN"}; + } + if ($global_status==2) { + print $output," : CRITICAL",$output_perf,"\n"; + exit $ERRORS{"CRITICAL"}; + } + if ($global_status==1) { + print $output," : WARNING",$output_perf,"\n"; + exit $ERRORS{"WARNING"}; + } + print $output," : OK",$output_perf,"\n"; + exit $ERRORS{"OK"}; + +} + + +############# Ironport checks +if ($o_check_type eq "iron") { + +verb("Checking Ironport env"); + +my $resultat; +# status : 0=ok, 1=warn, 2=crit +my ($fan_status,$ps_status,$temp_status)=(0,0,0); +my ($fan_exist,$ps_exist,$temp_exist)=(0,0,0); +my ($num_fan,$num_ps,$num_temp)=(0,0,0); +my ($num_fan_nok,$num_ps_nok,$num_temp_nok)=(0,0,0); +my $global_status=0; +my $output=""; +# get temp if $o_temp is defined +if (defined($o_temp)) { + verb("Checking temp < $o_temp"); + $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($iron_tmp_table) + : $session->get_table(Baseoid => $iron_tmp_table); + if (defined($resultat)) { + verb ("temp found"); + $temp_exist=1; + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$iron_tmp_celcius/ ) { + verb("Status : $$resultat{$key}"); + if ($$resultat{$key} > $o_temp) { + my @index_oid=split(/\./,$key); + my $index_oid_key=pop(@index_oid); + $output .= ",Temp : ". $$resultat{ $iron_tmp_name.".".$index_oid_key}." : ".$$resultat{$key}." C"; + $temp_status=2; + $num_temp_nok++; + } + $num_temp++; + } + } + if ($temp_status==0) { + $output.= ", ".$num_temp." temp < ".$o_temp." OK"; + } else { + $output.= ", ".$num_temp_nok."/".$num_temp." temp probes CRITICAL"; + $global_status=2; + } + } +} + +# Get fan status if $o_fan is defined +if (defined($o_fan)) { + verb("Checking fan > $o_fan"); + $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($iron_fan_table) + : $session->get_table(Baseoid => $iron_fan_table); + if (defined($resultat)) { + verb ("fan found"); + $fan_exist=1; + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$iron_fan_rpm/ ) { + verb("Status : $$resultat{$key}"); + if ($$resultat{$key} < $o_fan) { + my @index_oid=split(/\./,$key); + my $index_oid_key=pop(@index_oid); + $output .= ",Fan ". $$resultat{ $iron_fan_name.".".$index_oid_key}." : ".$$resultat{$key}." RPM"; + $fan_status=2; + $num_fan_nok++; + } + $num_fan++; + } + } + if ($fan_status==0) { + $output.= ", ".$num_fan." fan > ".$o_fan." OK"; + } else { + $output.= ", ".$num_fan_nok."/".$num_fan." fans CRITICAL"; + $global_status=2; + } + } +} + +# Get power supply status + verb("Checking PS"); + $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($iron_ps_table) + : $session->get_table(Baseoid => $iron_ps_table); + if (defined($resultat)) { + verb ("ps found"); + $ps_exist=1; + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$iron_ps_status/ ) { + verb("Status : $iron_ps_status_name[$$resultat{$key}]"); + if ($iron_ps_status_nagios[$$resultat{$key}] != 0) { + my @index_oid=split(/\./,$key); + my $index_oid_key=pop(@index_oid); + $output .= ",PS ". $$resultat{$iron_ps_name.".".$index_oid_key}." : ".$iron_ps_status_name[$$resultat{$key}]; + $ps_status=2; + $num_ps_nok++; + } + $num_ps++; + } + } + if ($ps_status==0) { + $output.= ", ".$num_ps." ps OK"; + } else { + $output.= ", ".$num_ps_nok."/".$num_ps." ps CRITICAL"; + $global_status=2; + } + } + +$session->close; + +verb ("status : $global_status"); + +if ( ($fan_exist+$ps_exist+$temp_exist) == 0) { + print "No environemental informations found : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +$output =~ s/^,//; + +if ($global_status==0) { + print $output." : all OK\n"; + exit $ERRORS{"OK"}; +} + +if ($global_status==1) { + print $output." : WARNING\n"; + exit $ERRORS{"WARNING"}; +} + +if ($global_status==2) { + print $output." : CRITICAL\n"; + exit $ERRORS{"CRITICAL"}; +} +} + diff --git a/check_snmp_int.pl b/check_snmp_int.pl new file mode 100755 index 0000000..be8cdb8 --- /dev/null +++ b/check_snmp_int.pl @@ -0,0 +1,612 @@ +#!/usr/bin/perl -w +############################## check_snmp_int ############## +# Version : 1.4.3 +# Date : Dec 11 2006 +# Author : Patrick Proy ( patrick at proy.org ) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Contrib : J. Jungmann, S. Probst +# TODO : +# Check isdn "dormant" state +# Maybe put base directory for performance as an option +################################################################# +# +# Help : ./check_snmp_int.pl -h +# +use strict; +use Net::SNMP; +use Getopt::Long; + +############### BASE DIRECTORY FOR TEMP FILE ######## +my $o_base_dir="/tmp/tmp_Nagios_int."; +my $file_history=200; # number of data to keep in files. + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 5; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas + +my $inter_table= '.1.3.6.1.2.1.2.2.1'; +my $index_table = '1.3.6.1.2.1.2.2.1.1'; +my $descr_table = '1.3.6.1.2.1.2.2.1.2'; +my $oper_table = '1.3.6.1.2.1.2.2.1.8.'; +my $admin_table = '1.3.6.1.2.1.2.2.1.7.'; +my $in_octet_table = '1.3.6.1.2.1.2.2.1.10.'; +my $in_error_table = '1.3.6.1.2.1.2.2.1.14.'; +my $in_discard_table = '1.3.6.1.2.1.2.2.1.13.'; +my $out_octet_table = '1.3.6.1.2.1.2.2.1.16.'; +my $out_error_table = '1.3.6.1.2.1.2.2.1.20.'; +my $out_discard_table = '1.3.6.1.2.1.2.2.1.19.'; + +my %status=(1=>'UP',2=>'DOWN',3=>'TESTING',4=>'UNKNOWN',5=>'DORMANT',6=>'NotPresent',7=>'lowerLayerDown'); + +# Globals + +my $Version='1.4.3'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_version2 = undef; #use snmp v2c +my $o_port = 161; # port +my $o_descr = undef; # description filter +my $o_help= undef; # wan't some help ? +my $o_admin= undef; # admin status instead of oper +my $o_inverse= undef; # Critical when up +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_noreg= undef; # Do not use Regexp for name +my $o_perf= undef; # Output performance data +my $o_perfe= undef; # Output discard/error also in perf data +my $o_checkperf= undef; # checks in/out/err/disc values +my $o_delta= 300; # delta of time of perfcheck (default 5min) +my $o_ext_checkperf= undef; # extended perf checks (+error+discard) +my $o_warn_opt= undef; # warning options +my $o_crit_opt= undef; # critical options +my $o_kbits= undef; # Warn and critical in Kbits instead of KBytes +my @o_warn= undef; # warning levels of perfcheck +my @o_crit= undef; # critical levels of perfcheck +my $o_short= undef; # set maximum of n chars to be displayed + +my $o_timeout= undef; # Timeout (Default 5) +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub read_file { + # Input : File, items_number + # Returns : array of value : [line][item] + my ($traffic_file,$items_number)=@_; + my ($ligne,$n_rows)=(undef,0); + my (@last_values,@file_values,$i); + open(FILE,"<".$traffic_file) || return (1,0,0); + + while($ligne = ) + { + chomp($ligne); + @file_values = split(":",$ligne); + #verb("@file_values"); + if ($#file_values >= ($items_number-1)) { + # check if there is enough data, else ignore line + for ( $i=0 ; $i< $items_number ; $i++ ) {$last_values[$n_rows][$i]=$file_values[$i];} + $n_rows++; + } + } + close FILE; + if ($n_rows != 0) { + return (0,$n_rows,@last_values); + } else { + return (1,0,0); + } +} + +sub write_file { + # Input : file , rows, items, array of value : [line][item] + # Returns : 0 / OK, 1 / error + my ($file_out,$rows,$item,@file_values)=@_; + my $start_line= ($rows > $file_history) ? $rows - $file_history : 0; + if ( open(FILE2,">".$file_out) ) { + for (my $i=$start_line;$i<$rows;$i++) { + for (my $j=0;$j<$item;$j++) { + print FILE2 $file_values[$i][$j]; + if ($j != ($item -1)) { print FILE2 ":" }; + } + print FILE2 "\n"; + } + close FILE2; + return 0; + } else { + return 1; + } +} + +sub p_version { print "check_snmp_int version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,) [-p ] -n [-i] [-a] [-r] [-f[e]] [-k[qB] -w -c -d] [-t ] [-s] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub help { + print "\nSNMP Network Interface Monitor for Nagios version ",$Version,"\n"; + print "GPL licence, (c)2004-2006 Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-n, --name=NAME + Name in description OID (eth0, ppp0 ...). + This is treated as a regexp : -n eth will match eth0,eth1,... + Test it before, because there are known bugs (ex : trailling /) +-i, --inverse + Make critical when up +-a, --admin + Use administrative status instead of operational +-f, --perfparse + Perfparse compatible output (no output when interface is down). +-e, --error + Add error & discard to Perfparse output +-r, --noregexp + Do not use regexp to match NAME in description OID +-k, --perfcheck ; -q, --extperfcheck + -k check the input/ouput bandwidth of the interface + -q also check the error and discard input/output +-d, --delta=seconds + make an average of seconds (default 300=5min) +-B, --kbits + Make the warning and critical levels in KBits/s instead of KBytes/s +-w, --warning=input,output[,error in,error out,discard in,discard out] + warning level for input / output bandwidth in KBytes/s (0 for no warning) + warning for error & discard input / output in error/min (need -q) +-c, --critical=input,output[,error in,error out,discard in,discard out] + critical level for input / output bandwidth in KBytes/s (0 for no critical) + critical for error & discard input / output in error/min (need -q) +-s, --short=int + Make the output shorter : only the first chars of the interface(s) + If the number is negative, then get the LAST caracters. +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +Note : when multiple interface are selected with regexp, + all be must be up (or down with -i) to get an OK result. +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'n:s' => \$o_descr, 'name:s' => \$o_descr, + 'C:s' => \$o_community, 'community:s' => \$o_community, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'i' => \$o_inverse, 'inverse' => \$o_inverse, + 'a' => \$o_admin, 'admin' => \$o_admin, + 'r' => \$o_noreg, 'noregexp' => \$o_noreg, + 'V' => \$o_version, 'version' => \$o_version, + 'f' => \$o_perf, 'perfparse' => \$o_perf, + 'e' => \$o_perfe, 'error' => \$o_perfe, + 'k' => \$o_checkperf, 'perfcheck' => \$o_checkperf, + 'q' => \$o_ext_checkperf, 'extperfcheck' => \$o_ext_checkperf, + 'w:s' => \$o_warn_opt, 'warning:s' => \$o_warn_opt, + 'c:s' => \$o_crit_opt, 'critical:s' => \$o_crit_opt, + 'B' => \$o_kbits, 'kbits' => \$o_kbits, + 's:i' => \$o_short, 'short:i' => \$o_short, + 'd:i' => \$o_delta, 'delta:i' => \$o_delta + ); + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_descr) || ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + # check if -e without -f + if ( defined($o_perfe) && !defined($o_perf)) + { print "Cannot output error without -f option!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($o_short)) { + #TODO maybe some basic tests ? caracters return empty string + } + if (defined ($o_checkperf)) { + @o_warn=split(/,/,$o_warn_opt); + if (defined($o_ext_checkperf) && ($#o_warn != 5)) { + print "6 warning levels for extended checks \n"; print_usage(); exit $ERRORS{"UNKNOWN"} + } + if (!defined($o_ext_checkperf) &&($#o_warn !=1 )){ + print "2 warning levels for bandwidth checks \n"; print_usage(); exit $ERRORS{"UNKNOWN"} + } + @o_crit=split(/,/,$o_crit_opt); + #verb(" $o_crit_opt :: $#o_crit : @o_crit"); + if (defined($o_ext_checkperf) && ($#o_crit != 5)) { + print "6 critical levels for extended checks \n"; print_usage(); exit $ERRORS{"UNKNOWN"} + } + if (!defined($o_ext_checkperf) && ($#o_crit !=1 )) { + print "2 critical levels for bandwidth checks \n"; print_usage(); exit $ERRORS{"UNKNOWN"} + } + for (my $i=0;$i<=$#o_warn;$i++) { + if (($o_crit[$i]!=0)&&($o_warn[$i] > $o_crit[$i])) { + print "Warning must be < Critical level \n"; print_usage(); exit $ERRORS{"UNKNOWN"} + } + } + } +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT + 5"); + alarm($TIMEOUT+5); +} else { + verb("no timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2c Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +# Get desctiption table +my $resultat = $session->get_table( + Baseoid => $descr_table +); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +my @tindex = undef; +my @oids = undef; +my @descr = undef; +my (@oid_perf,@oid_perf_outoct,@oid_perf_inoct,@oid_perf_inerr,@oid_perf_outerr,@oid_perf_indisc,@oid_perf_outdisc)= + (undef,undef,undef,undef,undef,undef,undef); +my $num_int = 0; + +# Select interface by regexp of exact match +# and put the oid to query in an array + +verb("Filter : $o_descr"); +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + # test by regexp or exact match + my $test = defined($o_noreg) + ? $$resultat{$key} eq $o_descr + : $$resultat{$key} =~ /$o_descr/; + if ($test) { + # get the index number of the interface + my @oid_list = split (/\./,$key); + $tindex[$num_int] = pop (@oid_list); + # get the full description + $descr[$num_int]=$$resultat{$key}; + # Get rid of special caracters (specially for Windows) + $descr[$num_int] =~ s/[[:cntrl:]]//g; + # put the admin or oper oid in an array + $oids[$num_int]= defined ($o_admin) ? $admin_table . $tindex[$num_int] + : $oper_table . $tindex[$num_int] ; + # Put the performance oid + if (defined($o_perf) || defined($o_checkperf)) { + $oid_perf_inoct[$num_int]= $in_octet_table . $tindex[$num_int]; + $oid_perf_outoct[$num_int]= $out_octet_table . $tindex[$num_int]; + if (defined($o_ext_checkperf) || defined($o_perfe)) { + $oid_perf_indisc[$num_int]= $in_discard_table . $tindex[$num_int]; + $oid_perf_outdisc[$num_int]= $out_discard_table . $tindex[$num_int]; + $oid_perf_inerr[$num_int]= $in_error_table . $tindex[$num_int]; + $oid_perf_outerr[$num_int]= $out_error_table . $tindex[$num_int]; + } + } + verb("Name : $descr[$num_int], Index : $tindex[$num_int]"); + $num_int++; + } +} +# No interface found -> error +if ( $num_int == 0 ) { print "ERROR : Unknown interface $o_descr\n" ; exit $ERRORS{"UNKNOWN"};} + +my ($result,$resultf)=(undef,undef); +# Get the requested oid values +$result = $session->get_request( + Varbindlist => \@oids +); +if (!defined($result)) { printf("ERROR: Status table : %s.\n", $session->error); $session->close; + exit $ERRORS{"UNKNOWN"}; +} +# Get the perf value if -f (performance) option defined or -k (check bandwidth) +if (defined($o_perf)||defined($o_checkperf)) { + @oid_perf=(@oid_perf_outoct,@oid_perf_inoct,@oid_perf_inerr,@oid_perf_outerr,@oid_perf_indisc,@oid_perf_outdisc); + $resultf = $session->get_request( + Varbindlist => \@oid_perf + ); + if (!defined($resultf)) { printf("ERROR: Statistics table : %s.\n", $session->error); $session->close; + exit $ERRORS{"UNKNOWN"}; + } +} + + +$session->close; + +my $num_ok=0; +my @checkperf_out=undef; +### Bandwidth test variables +my $temp_file_name; +my ($return,@file_values)=(undef,undef); +my $n_rows=0; +my $n_items_check=(defined($o_ext_checkperf))?7:3; +my $timenow=time; +my $trigger=$timenow - ($o_delta - ($o_delta/10)); +my $trigger_low=$timenow - 3*$o_delta; +my ($old_value,$old_time)=undef; + +# define the OK value depending on -i option +my $ok_val= defined ($o_inverse) ? 2 : 1; +my $final_status = 0; +my ($print_out,$perf_out)=(undef,undef); + +# make all checks and output for all interfaces +for (my $i=0;$i < $num_int; $i++) { + $print_out.=", " if (defined($print_out)); + $perf_out .= " " if (defined ($perf_out)) ; + + # Get the status of the current interface + my $int_status= defined ($o_admin) ? $$result{$admin_table . $tindex[$i]} + : $$result{ $oper_table . $tindex[$i] }; + + # Make the bandwith & error checks if necessary + if (defined ($o_checkperf) && $int_status==1) { + $temp_file_name=$descr[$i]; + $temp_file_name =~ s/[ ;\/]/_/g; + $temp_file_name = $o_base_dir . $o_host ."." . $temp_file_name; + # First, read entire file + my @ret_array=read_file($temp_file_name,$n_items_check); + $return = shift(@ret_array); + $n_rows = shift(@ret_array); + if ($n_rows != 0) { @file_values = @ret_array }; + verb ("File read returns : $return with $n_rows rows"); + #make the checks if the file is OK + if ($return ==0) { + my $j=$n_rows-1; + @checkperf_out=undef; + do { + if ($file_values[$j][0] < $trigger) { + if ($file_values[$j][0] > $trigger_low) { + # check if the counter is back to 0 after 2^32. + my $overfl = ($$resultf{$oid_perf_inoct[$i]} >= $file_values[$j][1] ) ? 0 : 4294967296; + my $speed_metric = (defined($o_kbits))? 128 : 1024; + $checkperf_out[0] = ( ($overfl + $$resultf{$oid_perf_inoct[$i]} - $file_values[$j][1])/ + ($timenow - $file_values[$j][0] ))/$speed_metric; + + $overfl = ($$resultf{$oid_perf_outoct[$i]} >= $file_values[$j][2] ) ? 0 : 4294967296; + $checkperf_out[1] = ( ($overfl + $$resultf{$oid_perf_outoct[$i]} - $file_values[$j][2])/ + ($timenow - $file_values[$j][0] ))/$speed_metric; + + if (defined($o_ext_checkperf)) { + $checkperf_out[2] = ( ($$resultf{$oid_perf_inerr[$i]} - $file_values[$j][3])/ + ($timenow - $file_values[$j][0] ))*60; + $checkperf_out[3] = ( ($$resultf{$oid_perf_outerr[$i]} - $file_values[$j][4])/ + ($timenow - $file_values[$j][0] ))*60; + $checkperf_out[4] = ( ($$resultf{$oid_perf_indisc[$i]} - $file_values[$j][5])/ + ($timenow - $file_values[$j][0] ))*60; + $checkperf_out[5] = ( ($$resultf{$oid_perf_outdisc[$i]} - $file_values[$j][6])/ + ($timenow - $file_values[$j][0] ))*60; + } + } + } + $j--; + } while ( ($j>=0) && (!defined($checkperf_out[0])) ); + } + # Put the new values in the array and write the file + $file_values[$n_rows][0]=$timenow; + $file_values[$n_rows][1]=$$resultf{$oid_perf_inoct[$i]}; + $file_values[$n_rows][2]=$$resultf{$oid_perf_outoct[$i]}; + if (defined($o_ext_checkperf)) { # Add other values (error & disc) + $file_values[$n_rows][3]=$$resultf{$oid_perf_inerr[$i]}; + $file_values[$n_rows][4]=$$resultf{$oid_perf_outerr[$i]}; + $file_values[$n_rows][5]=$$resultf{$oid_perf_indisc[$i]}; + $file_values[$n_rows][6]=$$resultf{$oid_perf_outdisc[$i]}; + } + $n_rows++; + $return=write_file($temp_file_name,$n_rows,$n_items_check,@file_values); + verb ("Write file returned : $return"); + # Print the basic status + if (defined ($o_short)) { + my $short_desc=undef; + if ($o_short < 0) {$short_desc=substr($descr[$i],$o_short);} + else {$short_desc=substr($descr[$i],0,$o_short);} + $print_out.=sprintf("%s:%s",$short_desc, $status{$int_status} ); + } else { + $print_out.=sprintf("%s:%s",$descr[$i], $status{$int_status} ); + } + if ($return !=0) { # On error writing, return Unknown status + $final_status=3; + $print_out.= " !!Unable to write file ".$temp_file_name." !! "; + } + # print the other checks if it was calculated + if (defined($checkperf_out[0])) { + $print_out.= " ("; + # check 2 or 6 values depending on ext_check_perf + my $num_checkperf=(defined($o_ext_checkperf))?6:2; + for (my $l=0;$l < $num_checkperf;$l++) { + if ($l!=0) {$print_out.="/";} + if (($o_crit[$l]!=0) && ($checkperf_out[$l]>$o_crit[$l])) { + $final_status=2; + $print_out.= sprintf("CRIT : %.1f",$checkperf_out[$l]); + } elsif (($o_warn[$l]!=0) && ($checkperf_out[$l]>$o_warn[$l])) { + $final_status=($final_status==2)?2:1; + $print_out.= sprintf("WARN : %.1f",$checkperf_out[$l]); + } else { + $print_out.= sprintf("%.1f",$checkperf_out[$l]); + } + } + $print_out .= ")"; + } else { # Return unknown when no data + $print_out.= " No usable data on file (".$n_rows." rows) "; + $final_status=3; + } + } else { + if (defined ($o_short)) { + my $short_desc=undef; + if ($o_short < 0) {$short_desc=substr($descr[$i],$o_short);} + else {$short_desc=substr($descr[$i],0,$o_short);} + $print_out.=sprintf("%s:%s",$short_desc, $status{$int_status} ); + } else { + $print_out.=sprintf("%s:%s",$descr[$i], $status{$int_status} ); + } + } + # Get rid of special caracters for performance in description + $descr[$i] =~ s/'\/\(\)/_/g; + if ( $int_status == $ok_val) { + $num_ok++; + } + if (( $int_status == 1 ) && defined ($o_perf)) { + $perf_out .= "'" . $descr[$i] ."_in_octet'=". $$resultf{$oid_perf_inoct[$i]} ."c "; + $perf_out .= "'" . $descr[$i] ."_out_octet'=". $$resultf{$oid_perf_outoct[$i]} ."c"; + if (defined ($o_perfe)) { + $perf_out .= " '" . $descr[$i] ."_in_error'=". $$resultf{$oid_perf_inerr[$i]} ."c "; + $perf_out .= "'" . $descr[$i] ."_in_discard'=". $$resultf{$oid_perf_indisc[$i]} ."c "; + $perf_out .= "'" . $descr[$i] ."_out_error'=". $$resultf{$oid_perf_outerr[$i]} ."c "; + $perf_out .= "'" . $descr[$i] ."_out_discard'=". $$resultf{$oid_perf_outdisc[$i]} ."c"; + } + } +} + +# Only a few ms left... +alarm(0); + +# Check if all interface are OK +if ($num_ok == $num_int) { + if ($final_status==0) { + print $print_out,":", $num_ok, " UP: OK"; + if (defined ($o_perf)) { print " | ",$perf_out; } + print "\n"; + exit $ERRORS{"OK"}; + } elsif ($final_status==1) { + print $print_out,":(", $num_ok, " UP): WARNING"; + if (defined ($o_perf)) { print " | ",$perf_out; } + print "\n"; + exit $ERRORS{"WARNING"}; + } elsif ($final_status==2) { + print $print_out,":(", $num_ok, " UP): CRITICAL"; + if (defined ($o_perf)) { print " | ",$perf_out; } + print "\n"; + exit $ERRORS{"CRITICAL"}; + } else { + print $print_out,":(", $num_ok, " UP): UNKNOWN"; + if (defined ($o_perf)) { print " | ",$perf_out; } + print "\n"; + exit $ERRORS{"UNKNOWN"}; + } +} + +# else print the not OK interface number and exit (return is always critical if at least one int is down). + +print $print_out,": ", $num_int-$num_ok, " int NOK : CRITICAL"; +if (defined ($o_perf) && defined ($perf_out)) { print " | ",$perf_out; } +print "\n"; +exit $ERRORS{"CRITICAL"}; + diff --git a/check_snmp_linkproof_nhr.pl b/check_snmp_linkproof_nhr.pl new file mode 100755 index 0000000..387f188 --- /dev/null +++ b/check_snmp_linkproof_nhr.pl @@ -0,0 +1,319 @@ +#!/usr/bin/perl -w +############################## check_snmp_linkproof_nhr ################# +# Version : 1.0 +# Date : Aug 24 2006 +# Author : Patrick Proy ( patrick at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Changelog : +# Contributors : +################################################################# +# +# Help : ./check_snmp_linkproof_nhr.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas + +my $lp_type = "1.3.6.1.4.1.89.35.1.38.1.1.13"; # node type (1=regular, 2=nhr). +my $lp_name = "1.3.6.1.4.1.89.35.1.38.1.1.2"; # nhr name +my $lp_users = "1.3.6.1.4.1.89.35.1.38.1.1.5"; # nhr users +my $lp_state = "1.3.6.1.4.1.89.35.1.38.1.1.3"; # state : 1=active, 2=Notinservice, 3= nonewsessions. +my $lp_port = "1.3.6.1.4.1.89.35.1.38.1.1.15"; # nhr users + + +# Globals + +my $Version='1.0'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +# specific +my $o_nhr_num= undef; # nhr number TODO +my $o_nhr_max= undef; # Maximum connexions TODO + +my $o_timeout= undef; # Timeout (Default 5) +my $o_perf= undef; # Output performance data +my $o_version2= undef; # use snmp v2c +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_linkproof_nhr version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-p ] [-f] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub help { + print "\nSNMP Radware Linkproof NHR monitor for Nagios version ",$Version,"\n"; + print "(c)2004-2006 Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-f, --perfparse + Perfparse compatible output +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'f' => \$o_perf, 'perfparse' => \$o_perf, + ); + # Basic checks + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT + 5"); + alarm($TIMEOUT+5); +} else { + verb("no global timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +my $exit_val=undef; +########### NHR checks ############## + +my $nhr_num=0; # nujmber of NHR +my @nhr_table=undef; # index of NHR +my $output=undef; +my $perf_output=""; +my @oids=undef; +my $inactive_nhr=0; +my $global_status=0; + +# Get load table +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($lp_type) + : $session->get_table(Baseoid => $lp_type); + +if (!defined($resultat)) { + printf("ERROR: NHR table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +my $oidindex=0; +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ($$resultat{$key} == 2) { # found NHR + $key =~ s/$lp_type\.//; + $nhr_table[$nhr_num++]=$key; + $oids[$oidindex++]=$lp_name.".".$key; + $oids[$oidindex++]=$lp_users.".".$key; + $oids[$oidindex++]=$lp_state.".".$key; + $oids[$oidindex++]=$lp_port.".".$key; + verb ("found nhr : $key"); + } +} + +if ($nhr_num==0) { + print "No NHR found : CRITICAL\n"; + exit $ERRORS{"CRITICAL"}; +} + +my $result=undef; +if (Net::SNMP->VERSION < 4) { + $result = $session->get_request(@oids); +} else { + if ($session->version == 0) { + # snmpv1 + $result = $session->get_request(-varbindlist => \@oids); + } else { + # snmp v2c or v3 : get_bulk_request is not really good for this, so do simple get + $result = $session->get_request(-varbindlist => \@oids); + } +} + +if (!defined($result)) { + printf("ERROR: NHR table get : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +my ($nhr_name,$nhr_state,$nhr_users)=(undef,undef,undef); +my @nhr_text_state=("","active","Not in service","No new session"); +for (my $i=0;$i<$nhr_num;$i++) { + if (defined ($output)) { $output .= "; ";} + $nhr_name=$$result{$lp_name .".".$nhr_table[$i]}; + $nhr_state=$$result{$lp_state .".".$nhr_table[$i]}; + $nhr_users=$$result{$lp_users .".".$nhr_table[$i]}; + $output .= $nhr_name ."(" . $nhr_users . "):" . $nhr_text_state[$nhr_state]; + if ($nhr_state == 1) { + if (defined ($o_perf)) { + if (defined ($perf_output)) { $perf_output .= " ";} + $perf_output .= $nhr_name."=".$nhr_users; + } + } elsif ($nhr_state == 2) { + $inactive_nhr++; $global_status=1; + } else { $global_status=1;} +} + +$session->close; + +if ($inactive_nhr == $nhr_num) { + $output .= " : CRITICAL"; + if (defined ($o_perf)) {$output .= " | " . $perf_output;} + print $output,"\n"; + exit $ERRORS{"CRITICAL"}; +} + +if ($global_status ==1) { + $output .= " : WARNING"; + if (defined ($o_perf)) {$output .= " | " . $perf_output;} + print $output,"\n"; + exit $ERRORS{"WARNING"}; +} + +$output .= " : OK"; +if (defined ($o_perf)) {$output .= " | " . $perf_output;} +print $output,"\n"; +exit $ERRORS{"OK"}; diff --git a/check_snmp_load.pl b/check_snmp_load.pl new file mode 100755 index 0000000..83c3ce3 --- /dev/null +++ b/check_snmp_load.pl @@ -0,0 +1,726 @@ +#!/usr/bin/perl -w +############################## check_snmp_load ################# +# Version : 1.3.1 +# Date : 8 Sept 2006 +# Author : Patrick Proy ( patrick at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Changelog : HP-UX load added. +# Contributors : F. Lacroix and many others !!! +################################################################# +# +# Help : ./check_snmp_load.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas + +# Generic with host-ressource-mib +my $base_proc = "1.3.6.1.2.1.25.3.3.1"; # oid for all proc info +my $proc_id = "1.3.6.1.2.1.25.3.3.1.1"; # list of processors (product ID) +my $proc_load = "1.3.6.1.2.1.25.3.3.1.2"; # %time the proc was not idle over last minute + +# Linux load + +my $linload_table= "1.3.6.1.4.1.2021.10.1"; # net-snmp load table +my $linload_name = "1.3.6.1.4.1.2021.10.1.2"; # text 'Load-1','Load-5', 'Load-15' +my $linload_load = "1.3.6.1.4.1.2021.10.1.3"; # effective load table + +# Cisco cpu/load + +my $cisco_cpu_5m = "1.3.6.1.4.1.9.2.1.58.0"; # Cisco CPU load (5min %) +my $cisco_cpu_1m = "1.3.6.1.4.1.9.2.1.57.0"; # Cisco CPU load (1min %) +my $cisco_cpu_5s = "1.3.6.1.4.1.9.2.1.56.0"; # Cisco CPU load (5sec %) + +# Cisco catalyst cpu/load + +my $ciscocata_cpu_5m = ".1.3.6.1.4.1.9.9.109.1.1.1.1.5.9"; # Cisco CPU load (5min %) +my $ciscocata_cpu_1m = ".1.3.6.1.4.1.9.9.109.1.1.1.1.3.9"; # Cisco CPU load (1min %) +my $ciscocata_cpu_5s = ".1.3.6.1.4.1.9.9.109.1.1.1.1.4.9"; # Cisco CPU load (5sec %) + +# Netscreen cpu/load + +my $nsc_cpu_5m = "1.3.6.1.4.1.3224.16.1.4.0"; # NS CPU load (5min %) +my $nsc_cpu_1m = "1.3.6.1.4.1.3224.16.1.2.0"; # NS CPU load (1min %) +my $nsc_cpu_5s = "1.3.6.1.4.1.3224.16.1.3.0"; # NS CPU load (5sec %) + +# AS/400 CPU + +my $as400_cpu = "1.3.6.1.4.1.2.6.4.5.1.0"; # AS400 CPU load (10000=100%); + +# Net-SNMP CPU + +my $ns_cpu_idle = "1.3.6.1.4.1.2021.11.11.0"; # Net-snmp cpu idle +my $ns_cpu_user = "1.3.6.1.4.1.2021.11.9.0"; # Net-snmp user cpu usage +my $ns_cpu_system = "1.3.6.1.4.1.2021.11.10.0"; # Net-snmp system cpu usage + +# Procurve CPU +my $procurve_cpu = "1.3.6.1.4.1.11.2.14.11.5.1.9.6.1.0"; # Procurve CPU Counter + +# Nokia CPU +my $nokia_cpu = "1.3.6.1.4.1.94.1.21.1.7.1.0"; # Nokia CPU % usage + +# Bluecoat Appliance +my $bluecoat_cpu = "1.3.6.1.4.1.3417.2.4.1.1.1.4.1"; # Bluecoat %cpu usage. + +# Fortigate CPU +my $fortigate_cpu = ".1.3.6.1.4.1.12356.1.8.0"; # Fortigate CPU % usage + +# Linkproof Appliance +my $linkproof_cpu= "1.3.6.1.4.1.89.35.1.55.0"; # CPU RE (Routing Engine Tasks) +# 1.3.6.1.4.1.89.35.1.53.0 : Ressource utilisation (%) Considers network utilization and internal CPU utilization +# 1.3.6.1.4.1.89.35.1.54 : CPU only (%) +# 1.3.6.1.4.1.89.35.1.55 : network only (%) + +# HP-UX cpu usage (thanks to krizb for the OIDs). +my $hpux_load_1_min="1.3.6.1.4.1.11.2.3.1.1.3.0"; +my $hpux_load_5_min="1.3.6.1.4.1.11.2.3.1.1.4.0"; +my $hpux_load_15_min="1.3.6.1.4.1.11.2.3.1.1.5.0"; + +# valid values +my @valid_types = ("stand","netsc","netsl","as400","cisco","cata","nsc","fg","bc","nokia","hp","lp","hpux"); +# CPU OID array +my %cpu_oid = ("netsc",$ns_cpu_idle,"as400",$as400_cpu,"bc",$bluecoat_cpu,"nokia",$nokia_cpu,"hp",$procurve_cpu,"lp",$linkproof_cpu,"fg",$fortigate_cpu); + +# Globals + +my $Version='1.3.1'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +# check type : stand | netsc | netsl | as400 | cisco | cata | nsc | fg | bc | nokia | hp | lp | hpux +my $o_check_type= "stand"; +# End compatibility +my $o_warn= undef; # warning level +my @o_warnL= undef; # warning levels for Linux Load or Cisco CPU +my $o_crit= undef; # critical level +my @o_critL= undef; # critical level for Linux Load or Cisco CPU +my $o_timeout= undef; # Timeout (Default 5) +my $o_perf= undef; # Output performance data +my $o_version2= undef; # use snmp v2c +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_load version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-p ] -w -c -T=[stand|netsl|netsc|as400|cisco|cata|nsc|fg|bc|nokia|hp|lp|hpux] [-f] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub help { + print "\nSNMP Load & CPU Monitor for Nagios version ",$Version,"\n"; + print "GPL licence, (c)2004-2006 Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-w, --warn=INTEGER | INT,INT,INT + 1 value check : warning level for cpu in percent (on one minute) + 3 value check : comma separated level for load or cpu for 1min, 5min, 15min +-c, --crit=INTEGER | INT,INT,INT + critical level for cpu in percent (on one minute) + 1 value check : critical level for cpu in percent (on one minute) + 3 value check : comma separated level for load or cpu for 1min, 5min, 15min +-T, --type=stand|netsl|netsc|as400|cisco|bc|nokia|hp|lp + CPU check : + stand : standard MIBII (works with Windows), + can handle multiple CPU. + netsl : linux load provided by Net SNMP (1,5 & 15 minutes values) + netsc : cpu usage given by net-snmp (100-idle) + as400 : as400 CPU usage + cisco : Cisco CPU usage + cata : Cisco catalyst CPU usage + nsc : NetScreen CPU usage + fg : Fortigate CPU usage + bc : Bluecoat CPU usage + nokia : Nokia CPU usage + hp : HP procurve switch CPU usage + lp : Linkproof CPU usage + hpux : HP-UX load (1,5 & 15 minutes values) +-f, --perfparse + Perfparse compatible output +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'c:s' => \$o_crit, 'critical:s' => \$o_crit, + 'w:s' => \$o_warn, 'warn:s' => \$o_warn, + 'f' => \$o_perf, 'perfparse' => \$o_perf, + 'T:s' => \$o_check_type, 'type:s' => \$o_check_type + ); + # check the -T option + my $T_option_valid=0; + foreach (@valid_types) { if ($_ eq $o_check_type) {$T_option_valid=1} }; + if ( $T_option_valid == 0 ) + {print "Invalid check type (-T)!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + # Basic checks + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + # Check warnings and critical + if (!defined($o_warn) || !defined($o_crit)) + { print "put warning and critical info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + # Get rid of % sign + $o_warn =~ s/\%//g; + $o_crit =~ s/\%//g; + # Check for multiple warning and crit in case of -L + if (($o_check_type eq "netsl") || ($o_check_type eq "cisco") || ($o_check_type eq "cata") || + ($o_check_type eq "nsc") || ($o_check_type eq "hpux")) { + @o_warnL=split(/,/ , $o_warn); + @o_critL=split(/,/ , $o_crit); + if (($#o_warnL != 2) || ($#o_critL != 2)) + { print "3 warnings and critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + for (my $i=0;$i<3;$i++) { + if ( isnnum($o_warnL[$i]) || isnnum($o_critL[$i])) + { print "Numeric value for warning or critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_warnL[$i] > $o_critL[$i]) + { print "warning <= critical ! \n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } + } else { + if (($o_warn =~ /,/) || ($o_crit =~ /,/)) { + { print "Multiple warning/critical levels not available for this check\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if ( isnnum($o_warn) || isnnum($o_crit) ) + { print "Numeric value for warning or critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_warn > $o_crit) + { print "warning <= critical ! \n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT + 5"); + alarm($TIMEOUT+5); +} else { + verb("no global timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +my $exit_val=undef; +########### Linux load check ############## + +if ($o_check_type eq "netsl") { + +verb("Checking linux load"); +# Get load table +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($linload_table) + : $session->get_table(Baseoid => $linload_table); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +$session->close; + +my @load = undef; +my @iload = undef; +my @oid=undef; +my $exist=0; +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$linload_name/ ) { + @oid=split (/\./,$key); + $iload[0]= pop(@oid) if ($$resultat{$key} eq "Load-1"); + $iload[1]= pop(@oid) if ($$resultat{$key} eq "Load-5"); + $iload[2]= pop(@oid) if ($$resultat{$key} eq "Load-15"); + $exist=1 + } +} + +if ($exist == 0) { + print "Can't find snmp information on load : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +for (my $i=0;$i<3;$i++) { $load[$i] = $$resultat{$linload_load . "." . $iload[$i]}}; + +print "Load : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | load_1_min=$load[0];$o_warnL[0];$o_critL[0] "; + print "load_5_min=$load[1];$o_warnL[1];$o_critL[1] "; + print "load_15_min=$load[2];$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} +exit $exit_val; +} + +############## Cisco CPU check ################ + +if ($o_check_type eq "cisco") { +my @oidlists = ($cisco_cpu_5m, $cisco_cpu_1m, $cisco_cpu_5s); +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_request(@oidlists) + : $session->get_request(-varbindlist => \@oidlists); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +if (!defined ($$resultat{$cisco_cpu_5s})) { + print "No CPU information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my @load = undef; + +$load[0]=$$resultat{$cisco_cpu_5s}; +$load[1]=$$resultat{$cisco_cpu_1m}; +$load[2]=$$resultat{$cisco_cpu_5m}; + +print "CPU : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | load_5_sec=$load[0]%;$o_warnL[0];$o_critL[0],"; + print "load_1_min=$load[1]%;$o_warnL[1];$o_critL[1],"; + print "load_5_min=$load[2]%;$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} + +exit $exit_val; +} + +############## Cisco Catalyst CPU check ################ + +if ($o_check_type eq "cata") { +my @oidlists = ($ciscocata_cpu_5m, $ciscocata_cpu_1m, $ciscocata_cpu_5s); +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_request(@oidlists) + : $session->get_request(-varbindlist => \@oidlists); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +if (!defined ($$resultat{$ciscocata_cpu_5s})) { + print "No CPU information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my @load = undef; + +$load[0]=$$resultat{$ciscocata_cpu_5s}; +$load[1]=$$resultat{$ciscocata_cpu_1m}; +$load[2]=$$resultat{$ciscocata_cpu_5m}; + +print "CPU : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | load_5_sec=$load[0]%;$o_warnL[0];$o_critL[0],"; + print "load_1_min=$load[1]%;$o_warnL[1];$o_critL[1],"; + print "load_5_min=$load[2]%;$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} + +exit $exit_val; +} + +############## Netscreen CPU check ################ + +if ($o_check_type eq "nsc") { +my @oidlists = ($nsc_cpu_5m, $nsc_cpu_1m, $nsc_cpu_5s); +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_request(@oidlists) + : $session->get_request(-varbindlist => \@oidlists); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +if (!defined ($$resultat{$nsc_cpu_5s})) { + print "No CPU information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my @load = undef; + +$load[0]=$$resultat{$nsc_cpu_5s}; +$load[1]=$$resultat{$nsc_cpu_1m}; +$load[2]=$$resultat{$nsc_cpu_5m}; + +print "CPU : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | cpu_5_sec=$load[0]%;$o_warnL[0];$o_critL[0],"; + print "cpu_1_min=$load[1]%;$o_warnL[1];$o_critL[1],"; + print "cpu_5_min=$load[2]%;$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} + +exit $exit_val; +} + +################## CPU for : AS/400 , Netsnmp, HP, Bluecoat, linkproof, fortigate ########### +if ( $o_check_type =~ /netsc|as400|bc|nokia|^hp$|lp|fg/ ) { + +# Get load table +my @oidlist = $cpu_oid{$o_check_type}; +verb("Checking OID : @oidlist"); +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_request(@oidlist) + : $session->get_request(-varbindlist => \@oidlist); +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +$session->close; + +if (!defined ($$resultat{$cpu_oid{$o_check_type}})) { + print "No CPU information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my $load=$$resultat{$cpu_oid{$o_check_type}}; +verb("OID returned $load"); +# for AS400, divide by 100 +if ($o_check_type eq "as400") {$load /= 100; }; +# for Net-snmp : oid returned idle time so load = 100-idle. +if ($o_check_type eq "netsc") {$load = 100 - $load; }; + +printf("CPU used %.1f%% (",$load); + +$exit_val=$ERRORS{"OK"}; +if ($load > $o_crit) { + print ">$o_crit) : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; +} else { + if ($load > $o_warn) { + print ">$o_warn) : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } +} +print "<$o_warn) : OK" if ($exit_val eq $ERRORS{"OK"}); +(defined($o_perf)) ? + print " | cpu_prct_used=$load%;$o_warn;$o_crit\n" + : print "\n"; +exit $exit_val; + +} + +##### Checking hpux load +if ($o_check_type eq "hpux") { + +verb("Checking hpux load"); + +my @oidlists = ($hpux_load_1_min, $hpux_load_5_min, $hpux_load_15_min); +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_request(@oidlists) + : $session->get_request(-varbindlist => \@oidlists); + +if (!defined($resultat)) { + printf("ERROR: Load table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +if (!defined ($$resultat{$hpux_load_1_min})) { + print "No Load information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my @load = undef; + +$load[0]=$$resultat{$hpux_load_1_min}/100; +$load[1]=$$resultat{$hpux_load_5_min}/100; +$load[2]=$$resultat{$hpux_load_15_min}/100; + +print "Load : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | load_1_min=$load[0]%;$o_warnL[0];$o_critL[0],"; + print "load_5_min=$load[1]%;$o_warnL[1];$o_critL[1],"; + print "load_15_min=$load[2]%;$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} + +exit $exit_val; +} + +########## Standard cpu usage check ############ +# Get desctiption table +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($base_proc) + : $session->get_table(Baseoid => $base_proc); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +my ($cpu_used,$ncpu)=(0,0); +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$proc_load/) { + $cpu_used += $$resultat{$key}; + $ncpu++; + } +} + +if ($ncpu==0) { + print "Can't find CPU usage information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +$cpu_used /= $ncpu; + +print "$ncpu CPU, ", $ncpu==1 ? "load" : "average load"; +printf(" %.1f",$cpu_used); +$exit_val=$ERRORS{"OK"}; + +if ($cpu_used > $o_crit) { + print " > $o_crit : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; +} else { + if ($cpu_used > $o_warn) { + print " > $o_warn : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } +} +print " < $o_warn : OK" if ($exit_val eq $ERRORS{"OK"}); +(defined($o_perf)) ? + print " | cpu_prct_used=$cpu_used%;$o_warn;$o_crit\n" + : print "\n"; +exit $exit_val; + diff --git a/check_snmp_mem.pl b/check_snmp_mem.pl new file mode 100755 index 0000000..4cda8d2 --- /dev/null +++ b/check_snmp_mem.pl @@ -0,0 +1,525 @@ +#!/usr/bin/perl -w +############################## check_snmp_mem ############## +# Version : 1.1 +# Date : Jul 09 2006 +# Author : Patrick Proy (nagios at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Contrib : Jan Jungmann +# TODO : +################################################################# +# +# Help : ./check_snmp_mem.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas + +# Net-snmp memory + +my $nets_ram_free = "1.3.6.1.4.1.2021.4.6.0"; # Real memory free +my $nets_ram_total = "1.3.6.1.4.1.2021.4.5.0"; # Real memory total +my $nets_ram_cache = "1.3.6.1.4.1.2021.4.15.0"; # Real memory cached +my $nets_swap_free = "1.3.6.1.4.1.2021.4.4.0"; # swap memory free +my $nets_swap_total = "1.3.6.1.4.1.2021.4.3.0"; # Swap memory total +my @nets_oids = ($nets_ram_free,$nets_ram_total,$nets_swap_free,$nets_swap_total,$nets_ram_cache); + +# Cisco + +my $cisco_mem_pool = "1.3.6.1.4.1.9.9.48.1.1.1"; # Cisco memory pool +my $cisco_index = "1.3.6.1.4.1.9.9.48.1.1.1.2"; # memory pool name and index +my $cisco_valid = "1.3.6.1.4.1.9.9.48.1.1.1.4"; # Valid memory if 1 +my $cisco_used = "1.3.6.1.4.1.9.9.48.1.1.1.5"; # Used memory +my $cisco_free = "1.3.6.1.4.1.9.9.48.1.1.1.6"; # Free memory +# .1 : type, .2 : name, .3 : alternate, .4 : valid, .5 : used, .6 : free, .7 : max free + +# HP Procurve + +my $hp_mem_pool = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1"; # HP memory pool +my $hp_mem_index = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.1"; # memory slot index +my $hp_mem_total = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.5"; # Total Bytes +my $hp_mem_free = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.6"; # Free Bytes +my $hp_mem_free_seg = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.3"; # Free segments + +# AS/400 + +# Windows NT/2K/(XP?) + +# check_snmp_storage.pl -C -H -m "^Virtual Memory$" -w -c + + +# Globals + +my $Version='1.1'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_netsnmp= 1; # Check with netsnmp (default) +my $o_cisco= undef; # Check cisco router mem +my $o_hp= undef; # Check hp procurve mem +my $o_warn= undef; # warning level option +my $o_warnR= undef; # warning level for Real memory +my $o_warnS= undef; # warning levels for swap +my $o_crit= undef; # Critical level option +my $o_critR= undef; # critical level for Real memory +my $o_critS= undef; # critical level for swap +my $o_perf= undef; # Performance data option +my $o_cache= undef; # Include cached memory as used memory +my $o_timeout= undef; # Timeout (Default 5) +my $o_version2= undef; # use snmp v2c +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_mem version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-p ] -w -c [-I|-N|-E] [-f] [-m] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub round ($$) { + sprintf "%.$_[1]f", $_[0]; +} + +sub help { + print "\nSNMP Memory Monitor for Nagios version ",$Version,"\n"; + print "(c)2004-2006 to my cat Ratoune - Author: Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-w, --warn=INTEGER | INT,INT + warning level for memory in percent (0 for no checks) + Default (-N switch) : comma separated level for Real Memory and Swap + -I switch : warning level +-c, --crit=INTEGER | INT,INT + critical level for memory in percent (0 for no checks) + Default (-N switch) : comma separated level for Real Memory and Swap + -I switch : critical level +-N, --netsnmp (default) + check linux memory & swap provided by Net SNMP +-m, --memcache + include cached memory in used memory (only with Net-SNMP) +-I, --cisco + check cisco memory (sum of all memory pools) +-E, --hp + check HP proccurve memory +-f, --perfdata + Performance data output +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +# Get the alarm signal (just in case snmp timout screws up) +$SIG{'ALRM'} = sub { + print ("ERROR: Alarm signal (Nagios time-out)\n"); + exit $ERRORS{"UNKNOWN"}; +}; + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + 'I' => \$o_cisco, 'cisco' => \$o_cisco, + 'N' => \$o_netsnmp, 'netsnmp' => \$o_netsnmp, + 'E' => \$o_hp, 'hp' => \$o_hp, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'c:s' => \$o_crit, 'critical:s' => \$o_crit, + 'w:s' => \$o_warn, 'warn:s' => \$o_warn, + 'm' => \$o_cache, 'memcache' => \$o_cache, + 'f' => \$o_perf, 'perfdata' => \$o_perf + ); + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print "No host defined!\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + #Check Warning and crit are present + if ( ! defined($o_warn) || ! defined($o_crit)) + { print "Put warning and critical values!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + # Get rid of % sign + $o_warn =~ s/\%//g; + $o_crit =~ s/\%//g; + # if -N or -E switch , undef $o_netsnmp + if (defined($o_cisco) || defined($o_hp) ) { + $o_netsnmp=undef; + if ( isnnum($o_warn) || isnnum($o_crit)) + { print "Numeric value for warning or critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"} } + if ( ($o_crit != 0) && ($o_warn > $o_crit) ) + { print "warning <= critical ! \n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (defined($o_netsnmp)) { + my @o_warnL=split(/,/ , $o_warn); + my @o_critL=split(/,/ , $o_crit); + if (($#o_warnL != 1) || ($#o_critL != 1)) + { print "2 warnings and critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + for (my $i=0;$i<2;$i++) { + if ( isnnum($o_warnL[$i]) || isnnum($o_critL[$i])) + { print "Numeric value for warning or critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"} } + if (($o_critL[$i]!= 0) && ($o_warnL[$i] > $o_critL[$i])) + { print "warning <= critical ! \n";print_usage(); exit $ERRORS{"UNKNOWN"}} + if ( $o_critL[$i] > 100) + { print "critical percent must be < 100 !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } + $o_warnR=$o_warnL[0];$o_warnS=$o_warnL[1]; + $o_critR=$o_critL[0];$o_critS=$o_critL[1]; + } + +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT"); + alarm($TIMEOUT); +} else { + verb("no timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +# Global variable +my $resultat=undef; + +########### Cisco memory check ############ +if (defined ($o_cisco)) { + + # Get Cisco memory table + $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($cisco_mem_pool) + :$session->get_table(Baseoid => $cisco_mem_pool); + + if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + my (@oid,@index)=(undef,undef); + my $nindex=0; + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$cisco_index/ ) { + @oid=split (/\./,$key); + $index[$nindex++] = pop(@oid); + } + } + + # Check if at least 1 memory pool exists + if ($nindex == 0) { + printf("ERROR: No memory pools found"); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + + # Test every memory pool + my ($c_output,$prct_free)=(undef,undef); + my ($warn_s,$crit_s)=(0,0); + my ($used,$free)=(0,0); + foreach (@index) { + $c_output .="," if defined ($c_output); + if ( $$resultat{$cisco_valid . "." . $_} == 1 ) { + $used += $$resultat{$cisco_used . "." . $_}; + $free += $$resultat{$cisco_free . "." . $_}; + $prct_free=round($$resultat{$cisco_used . "." . $_}*100/($$resultat{$cisco_free . "." . $_}+$$resultat{$cisco_used . "." . $_}) ,0); + $c_output .= $$resultat{$cisco_index . "." . $_} . ":" . $prct_free . "%"; + if (($o_crit!=0)&&($o_crit <= $prct_free)) { + $crit_s =1; + } elsif (($o_warn!=0)&&($o_warn <= $prct_free)) { + $warn_s=1; + } + } else { + $c_output .= $$resultat{$cisco_index . "." . $_} . ": INVALID"; + $crit_s =1; + } + } + my $total=$used+$free; + $prct_free=round($used*100/($total),0); + verb("Total used : $used, free: $free, output : $c_output"); + my $c_status="OK"; + $c_output .=" : " . $prct_free ."% : "; + if ($crit_s == 1 ) { + $c_output .= " > " . $o_crit ; + $c_status="CRITICAL"; + } else { + if ($warn_s == 1 ) { + $c_output.=" > " . $o_warn; + $c_status="WARNING"; + } + } + $c_output .= " ; ".$c_status; + if (defined ($o_perf)) { + $c_output .= " | ram_used=" . $used.";"; + $c_output .= ($o_warn ==0)? ";" : round($o_warn * $total/100,0).";"; + $c_output .= ($o_crit ==0)? ";" : round($o_crit * $total/100,0).";"; + $c_output .= "0;" . $total ; + } + $session->close; + print "$c_output \n"; + exit $ERRORS{$c_status}; +} + +########### HP Procurve memory check ############ +if (defined ($o_hp)) { + + # Get hp memory table + $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($hp_mem_pool) + :$session->get_table(Baseoid => $hp_mem_pool); + + if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + my (@oid,@index)=(undef,undef); + my $nindex=0; + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$hp_mem_index/ ) { + @oid=split (/\./,$key); + $index[$nindex++] = pop(@oid); + } + } + + # Check if at least 1 memory slots exists + if ($nindex == 0) { + printf("ERROR: No memory slots found"); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + + # Consolidate the datas + my ($total,$free)=(0,0); + my ($c_output,$prct_free)=(undef,undef); + foreach (@index) { + $c_output .="," if defined ($c_output); + $total += $$resultat{$hp_mem_total . "." . $_}; + $free += $$resultat{$hp_mem_free . "." . $_}; + $c_output .= "Slot " . $$resultat{$hp_mem_index . "." . $_} . ":" + .round( + 100 - ($$resultat{$hp_mem_free . "." . $_} *100 / + $$resultat{$hp_mem_total . "." . $_}) ,0) + . "%"; + } + my $used = $total - $free; + $prct_free=round($used*100/($total),0); + verb("Used : $used, Free: $free, Output : $c_output"); + my $c_status="OK"; + $c_output .=" : " . $prct_free ."% : "; + if (($o_crit!=0)&&($o_crit <= $prct_free)) { + $c_output .= " > " . $o_crit ; + $c_status="CRITICAL"; + } else { + if (($o_warn!=0)&&($o_warn <= $prct_free)) { + $c_output.=" > " . $o_warn; + $c_status="WARNING"; + } + } + $c_output .= " ; ".$c_status; + if (defined ($o_perf)) { + $c_output .= " | ram_used=" . $used.";"; + $c_output .= ($o_warn ==0)? ";" : round($o_warn * $total/100,0).";"; + $c_output .= ($o_crit ==0)? ";" : round($o_crit * $total/100,0).";"; + $c_output .= "0;" . $total ; + } + $session->close; + print "$c_output \n"; + exit $ERRORS{$c_status}; +} + +########### Net snmp memory check ############ +if (defined ($o_netsnmp)) { + + # Get NetSNMP memory values + $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_request(@nets_oids) + :$session->get_request(-varbindlist => \@nets_oids); + + if (!defined($resultat)) { + printf("ERROR: netsnmp : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + + my ($realused,$swapused)=(undef,undef); + + $realused= defined($o_cache) ? + ($$resultat{$nets_ram_total}-$$resultat{$nets_ram_free})/$$resultat{$nets_ram_total} + : + ($$resultat{$nets_ram_total}-($$resultat{$nets_ram_free}+$$resultat{$nets_ram_cache}))/$$resultat{$nets_ram_total}; + + if($$resultat{$nets_ram_total} == 0) { $realused = 0; } + + $swapused= ($$resultat{$nets_swap_total} == 0) ? 0 : + ($$resultat{$nets_swap_total}-$$resultat{$nets_swap_free})/$$resultat{$nets_swap_total}; + $realused=round($realused*100,0); + $swapused=round($swapused*100,0); + defined($o_cache) ? + verb ("Ram : $$resultat{$nets_ram_free} / $$resultat{$nets_ram_total} : $realused") + : + verb ("Ram : $$resultat{$nets_ram_free} ($$resultat{$nets_ram_cache} cached) / $$resultat{$nets_ram_total} : $realused"); + verb ("Swap : $$resultat{$nets_swap_free} / $$resultat{$nets_swap_total} : $swapused"); + + my $n_status="OK"; + my $n_output="Ram : " . $realused . "%, Swap : " . $swapused . "% :"; + if ((($o_critR!=0)&&($o_critR <= $realused)) || (($o_critS!=0)&&($o_critS <= $swapused))) { + $n_output .= " > " . $o_critR . ", " . $o_critS; + $n_status="CRITICAL"; + } else { + if ((($o_warnR!=0)&&($o_warnR <= $realused)) || (($o_warnS!=0)&&($o_warnS <= $swapused))) { + $n_output.=" > " . $o_warnR . ", " . $o_warnS; + $n_status="WARNING"; + } + } + $n_output .= " ; ".$n_status; + if (defined ($o_perf)) { + if (defined ($o_cache)) { + $n_output .= " | ram_used=" . ($$resultat{$nets_ram_total}-$$resultat{$nets_ram_free}).";"; + } + else { + $n_output .= " | ram_used=" . ($$resultat{$nets_ram_total}-$$resultat{$nets_ram_free}-$$resultat{$nets_ram_cache}).";"; + } + $n_output .= ($o_warnR ==0)? ";" : round($o_warnR * $$resultat{$nets_ram_total}/100,0).";"; + $n_output .= ($o_critR ==0)? ";" : round($o_critR * $$resultat{$nets_ram_total}/100,0).";"; + $n_output .= "0;" . $$resultat{$nets_ram_total}. " "; + $n_output .= "swap_used=" . ($$resultat{$nets_swap_total}-$$resultat{$nets_swap_free}).";"; + $n_output .= ($o_warnS ==0)? ";" : round($o_warnS * $$resultat{$nets_swap_total}/100,0).";"; + $n_output .= ($o_critS ==0)? ";" : round($o_critS * $$resultat{$nets_swap_total}/100,0).";"; + $n_output .= "0;" . $$resultat{$nets_swap_total}; + } + $session->close; + print "$n_output \n"; + exit $ERRORS{$n_status}; + +} diff --git a/check_snmp_nsbox.pl b/check_snmp_nsbox.pl new file mode 100755 index 0000000..498adb2 --- /dev/null +++ b/check_snmp_nsbox.pl @@ -0,0 +1,351 @@ +#!/usr/bin/perl -w +############################## check_snmp_nsbox ################# +# Version : 1.0 +# Date : 27 aug 2006 +# Author : Patrick Proy ( patrick at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Changelog : +# Contributors : +################################################################# +# +# Help : ./check_snmp_nsbox.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas +my $ns_service_status= "1.3.6.1.4.1.14020.2.2.1.3.0"; # service status 1= ok ?? + +my $ns_service_table= "1.3.6.1.4.1.14020.2.3"; # vhost & diode table +my $ns_vhost_table= "1.3.6.1.4.1.14020.2.3.1"; # vhost table +my $ns_vhost_name= "1.0"; # GUI Vhost Name +my $ns_vhost_requests= "2.0"; # Instant Vhost Requests per Second : NOT POPULATED IN V 2.0.8 +my $ns_vhost_Trequests= "2.0"; # Total Vhost Requests : NOT POPULATED IN V 2.0.8 +my $ns_diode_table= "1.3.6.1.4.1.14020.2.3.2"; # diode table +my $ns_diode_name= "1.0"; # GUI Diode Name +my $ns_diode_status= "2.0"; # Last diode Status (" " = OK?) (undocumented) + +my $ns_rsa_prct_usage= ".1.3.6.1.4.1.14020.1.1.1.3.0"; # % usage of RSA operations. (undocumented) +my $ns_rsa_oper_second= ".1.3.6.1.4.1.14020.1.1.3.4.0;"; # number of RSA operations/s (undocumented) + +# Globals + +my $Version='1.0'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_timeout= undef; # Timeout (Default 5) +my $o_perf= undef; # Output performance data +my $o_version2= undef; # use snmp v2c +# specific +my $o_vhost= undef; # vhost regexp +my $o_diode= undef; # diode regexp +my $o_nvhost= undef; # vhost number +my $o_ndiode= undef; # diode number + +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_nsbox version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) -d -s -n , [-p ] [-f] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub set_status { # return worst status with this order : OK, unknwonw, warning, critical + my $new_status=shift; + my $cur_status=shift; + if (($cur_status == 0)|| ($new_status==$cur_status)){ return $new_status; } + if ($new_status==3) { return $cur_status; } + if ($new_status > $cur_status) {return $new_status;} + return $cur_status; +} + +sub is_pattern_valid { # Test for things like "" or "+5-i" + my $pat = shift; + if (!defined($pat)) { $pat=" ";} # Just to get rid of compilation time warnings + return eval { "" =~ /$pat/; 1 } || 0; +} + +sub help { + print "\nSNMP NetSecureOne Netbox monitor for Nagios version ",$Version,"\n"; + print "(c)2004-2006 Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-d, --diode= + Diode selection by regexp +-s, --vhost= + Vhost selection by regexp +-n, --number=, + number of diode and vhost that must be up. +-P, --port=PORT + SNMP port (Default 161) +-f, --perfparse + Perfparse compatible output +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'f' => \$o_perf, 'perfparse' => \$o_perf, + 'd:s' => \$o_diode, 'diode:s' => \$o_diode, + 's:s' => \$o_vhost, 'vhost:s' => \$o_vhost, + 'n:s' => \$o_nvhost, 'number:s' => \$o_nvhost + ); + # Basic checks + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (!defined($o_vhost) || !(is_pattern_valid($o_vhost))) + { print "Vhost selection must be set and be a valid regexp (-s)\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_diode) || !(is_pattern_valid($o_diode))) + { print "Diode selection must be set and be a valid regexp (-d)\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_nvhost)) + { print "Diode and vhost number must be set (-n)\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @nsbox_number=split(/,/,$o_nvhost); + if ($#nsbox_number != 1) + { print "2 numbers must be set with -n option\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (isnnum($nsbox_number[0]) || isnnum($nsbox_number[1])) + { print "2 numbers must be set with -n option\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + $o_ndiode=$nsbox_number[0]; + $o_nvhost=$nsbox_number[1]; +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT + 5"); + alarm($TIMEOUT+5); +} else { + verb("no global timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + + +########### check global status ############## +my @oidlist=($ns_service_status); +my $resultat = (Net::SNMP->VERSION < 4) ? + $session->get_request(@oidlist) + : $session->get_request(-varbindlist => \@oidlist); + +if (!defined($resultat) || ($$resultat{$ns_service_status} eq "noSuchObject")) { + printf("ERROR: Global status oid not found : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +if ($$resultat{$ns_service_status} != 1) { + print "Global service is in state ",$$resultat{$ns_service_status}," : CRITICAL\n"; + exit $ERRORS{"CRITICAL"}; +} + +########### check vhost & diode status ############## +$resultat=undef; +$resultat = (Net::SNMP->VERSION < 4) ? + $session->get_table($ns_service_table) + : $session->get_table(Baseoid => $ns_service_table); + +if (!defined($resultat)) { + printf("ERROR: vhost and diode status table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +$session->close; + +my $output=""; +my $output_perf=""; +my ($index,$name)=undef; +my ($nvhost,$ndiode)=(0,0); +my (@found_vhost,@found_diode)=(undef,undef); + +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /($ns_vhost_table)\.(\d+)\.($ns_vhost_name)/ ) { # Get index of vhost with name + $index=$2;$name=$$resultat{$key}; + if ($name =~ /$o_vhost/) { + $found_vhost[$nvhost++]=$name; + verb ("found vhost $name"); + } + } + if ( $key =~ /($ns_diode_table)\.(\d+)\.($ns_diode_name)/ ) { # Get index of diode with name + $index=$2;$name=$$resultat{$key}; + if ($name =~ /$o_diode/) { + # TODO Check diode status : undocumented for now. + $found_diode[$ndiode++]=$name; + verb ("found diode $name"); + } + } +} + +if (($ndiode<$o_ndiode) || ($nvhost<$o_nvhost)) { + $output = "Diode"; + if ($ndiode == 0 ) { $output.= ": none ";} + else { + $output.= "(".$ndiode."): :"; + for (my $i=0;$i<$ndiode;$i++) { + $output.=$found_diode[$i]." "; + } + } + $output .= "Vhost"; + if ($nvhost == 0 ) { $output.= ": none ";} + else { + $output.= "(".$nvhost."): :"; + for (my $i=0;$i<$nvhost;$i++) { + $output.=$found_vhost[$i]." "; + } + } + $output .= " < " . $o_ndiode .",". $o_nvhost ." : CRITICAL"; + print $output,"\n"; + exit $ERRORS{"CRITICAL"}; +} + +$output = $ndiode . " diodes, " .$nvhost." vhosts :"; +if (($ndiode>$o_ndiode) || ($nvhost>$o_nvhost)) { + $output .= " > " . $o_ndiode .",". $o_nvhost ." : WARNING"; +} else { + $output .= " OK"; +} +print $output,"\n"; +exit $ERRORS{"OK"}; + diff --git a/check_snmp_process.pl b/check_snmp_process.pl new file mode 100755 index 0000000..5958ea3 --- /dev/null +++ b/check_snmp_process.pl @@ -0,0 +1,610 @@ +#!/usr/bin/perl -w +############################## check_snmp_process ############## +# Version : 1.3 +# Date : Sept 4 2006 +# Author : Patrick Proy (patrick at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# TODO : put $o_delta as an option +# Contrib : +############################################################### +# +# help : ./check_snmp_process -h + +############### BASE DIRECTORY FOR TEMP FILE ######## +my $o_base_dir="/tmp/tmp_Nagios_proc."; +my $file_history=200; # number of data to keep in files. +my $delta_of_time_to_make_average=300; # 5minutes by default + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/local/nagios/libexec"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 5; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas +my $process_table= '1.3.6.1.2.1.25.4.2.1'; +my $index_table = '1.3.6.1.2.1.25.4.2.1.1'; +my $run_name_table = '1.3.6.1.2.1.25.4.2.1.2'; +my $run_path_table = '1.3.6.1.2.1.25.4.2.1.4'; +my $proc_mem_table = '1.3.6.1.2.1.25.5.1.1.2'; # Kbytes +my $proc_cpu_table = '1.3.6.1.2.1.25.5.1.1.1'; # Centi sec of CPU +my $proc_run_state = '1.3.6.1.2.1.25.4.2.1.7'; + +# Globals + +my $Version='1.3.1'; + +my $o_host = undef; # hostname +my $o_community =undef; # community +my $o_port = 161; # port +my $o_version2 = undef; #use snmp v2c +my $o_descr = undef; # description filter +my $o_warn = 0; # warning limit +my @o_warnL= undef; # warning limits (min,max) +my $o_crit= 0; # critical limit +my @o_critL= undef; # critical limits (min,max) +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_noreg= undef; # Do not use Regexp for name +my $o_path= undef; # check path instead of name +my $o_inverse= undef; # checks max instead of min number of process +my $o_get_all= undef; # get all tables at once +my $o_timeout= 5; # Default 5s Timeout +# SNMP V3 specific +my $o_login= undef; # snmp v3 login +my $o_passwd= undef; # snmp v3 passwd +# Memory & CPU +my $o_mem= undef; # checks memory (max) +my @o_memL= undef; # warn and crit level for mem +my $o_mem_avg= undef; # cheks memory average +my $o_cpu= undef; # checks CPU usage +my @o_cpuL= undef; # warn and crit level for cpu +my $o_delta= $delta_of_time_to_make_average; # delta time for CPU check + +# functions + +sub p_version { print "check_snmp_process version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd) [-p ] -n [-w [,] -c [,max_proc] ] [-m, -a -u, ] [-t ] [-f ] [-r] [-V] [-g]\n"; +} + +sub isnotnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^-?(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +# Get the alarm signal (just in case snmp timout screws up) +$SIG{'ALRM'} = sub { + print ("ERROR: Alarm signal (Nagios time-out)\n"); + exit $ERRORS{"UNKNOWN"}; +}; + +sub read_file { + # Input : File, items_number + # Returns : array of value : [line][item] + my ($traffic_file,$items_number)=@_; + my ($ligne,$n_rows)=(undef,0); + my (@last_values,@file_values,$i); + open(FILE,"<".$traffic_file) || return (1,0,0); + + while($ligne = ) + { + chomp($ligne); + @file_values = split(":",$ligne); + #verb("@file_values"); + if ($#file_values >= ($items_number-1)) { + # check if there is enough data, else ignore line + for ( $i=0 ; $i< $items_number ; $i++ ) {$last_values[$n_rows][$i]=$file_values[$i]; } + $n_rows++; + } + } + close FILE; + if ($n_rows != 0) { + return (0,$n_rows,@last_values); + } else { + return (1,0,0); + } +} + +sub write_file { + # Input : file , rows, items, array of value : [line][item] + # Returns : 0 / OK, 1 / error + my ($file_out,$rows,$item,@file_values)=@_; + my $start_line= ($rows > $file_history) ? $rows - $file_history : 0; + if ( open(FILE2,">".$file_out) ) { + for (my $i=$start_line;$i<$rows;$i++) { + for (my $j=0;$j<$item;$j++) { + print FILE2 $file_values[$i][$j]; + if ($j != ($item -1)) { print FILE2 ":" }; + } + print FILE2 "\n"; + } + close FILE2; + return 0; + } else { + return 1; + } +} + +sub help { + print "\nSNMP Process Monitor for Nagios version ",$Version,"\n"; + print "GPL licence, (c)2004-2006 Patrick Proy\n\n"; + print_usage(); + print <0. Ex : -w-1,50 +-c, --critical=MIN[,MAX] + number of process that will cause an error ( + -1 for no critical, MAX must be >0. Ex : -c-1,50 +Notes on warning and critical : + with the following options : -w m1,x1 -c m2,x2 + you must have : m2 <= m1 < x1 <= x2 + you can omit x1 or x2 or both +-m, --memory=WARN,CRIT + checks memory usage (default max of all process) + values are warning and critical values in Mb +-a, --average + makes an average of memory used by process instead of max +-u, --cpu=WARN,CRIT + checks cpu usage of all process + values are warning and critical values in % of CPU usage + if more than one CPU, value can be > 100% : 100%=1 CPU +-g, --getall + In some cases, it is necessary to get all data at once because + process die very frequently. + This option eats bandwidth an cpu (for remote host) at breakfast. +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +Note : + CPU usage is in % of one cpu, so maximum can be 100% * number of CPU + example : + Browse process list :