#!/usr/bin/perl # # SNMP monitoring of ethernet repeaters # # Returns 1 on SNMP errors, 2 for other errors (usually failure to # communicate with device). # # Phil Gregory # # rptr.monitor, v. 0.9, 2000-02-28 # # Initially derived from the hpnp.monitor code. # # # Copyright (C) 2000, Phil Gregory # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # Still TODO: # # - Be more discerning about errors. Currently, everything not # "operational" is considered an error. Depending on how people use # this, the monitor may only want to report "malfunctioning" groups # and ports. # # - The program should try to detect cases where the host exists, but # does not support the correct MIB. (In this case, the repeater MIB.) # # - Checking the ports to see if they're autopartitioned might be # useful. # # - There may be a better way to work through the ports. In particular, # there should only be entries in rptrGroupTable for existing groups. # Querying only existing groups is much better on the bandwidth than # trying all possible groups and ignoring the errors (which is how the # script currently works). It also appears possible for ports to be # numbered higher than the maximum number of ports--e.g. the 3Com SSII # switch 1000 where the 13 ports are numbered 1-12 and 14. (I need to # look at UCD's snmptable and see how they get table dimensions.) use SNMP; use Getopt::Long; GetOptions (\%opt, "community=s", "timeout=i", "retries=i", "lpq"); die "no host arguments\n" if (@ARGV == 0); $RET = 0; @ERRS = (); $COMM = $opt{"community"} || "public"; $TIMEOUT = $opt{"timeout"} * 1000 * 1000 || 2000000; $RETRIES = $opt{"retries"} || 5; @rptrDesc = ("", "other", "ok", "repeater failure", "group failure", "port failure", "general failure"); @groupDesc = ("", "other", "operational", "malfunctioning", "not present", "under test", "resetting"); @portDesc = ("", "operational", "not operational", "not present"); foreach $host (@ARGV) { undef $s; if (!defined($s = new SNMP::Session (DestHost => $host, Timeout => $TIMEOUT, Community => $COMM, Retries => $RETRIES))) { print "cannot create SNMP session to $host\n"; $RET = ($RET == 1) ? 1 : 2; next; } undef $rptrVars; $rptrVars = new SNMP::VarList ( ['.1.3.6.1.2.1.22.1.1.2', 0], # rptrOperStatus ['.1.3.6.1.2.1.22.1.1.3', 0], # rptrHealthText ['.1.3.6.1.2.1.22.1.1.1', 0], # rptrGroupCapacity ); if (!defined($s->get($rptrVars))) { push(@hosts, $host); push(@ERRS, "$host unreachable\n\n"); $RET = ($RET == 1) ? 1 : 2; next; } $rptrHealth = ""; @groupHealth = @groupDescr = @groupNum = (); @portHealth = @portNum = @portGroupDescr = @portGroupNum = (); if (${$rptrVars}[0]->val != 2) { $rptrHealth = ${$rptrVars}[1]->val . "\n\n"; } for ($group = 1; $group <= ${$rptrVars}[2]->val; $group++) { undef $groupVars; $groupVars = new SNMP::VarList ( ['.1.3.6.1.2.1.22.1.2.1.1.4', $group], # rptrGroupOperStatus ['.1.3.6.1.2.1.22.1.2.1.1.2', $group], # rptrGroupDescr ['.1.3.6.1.2.1.22.1.2.1.1.6', $group], # rptrGroupPortCapacity ); if (!defined ($s->get($groupVars)) or !(${$groupVars}[0]->val)) { next; } if (${$groupVars}[0]->val != 2) { push (@groupHealth, $groupDesc[${$groupVars}[0]->val]); push (@groupDescr, ${$groupVars}[1]->val); push (@groupNum, $group); } for ($port = 1; $port <= ${$groupVars}[2]->val; $port++) { undef $portVars; $portVars = new SNMP::VarList ( ['.1.3.6.1.2.1.22.1.3.1.1.5.$group', $port], # rptrPortOperStatus ); if (!defined ($s->get($portVars)) or !(${$portVars}[0]->val)) { next; } if (${$portVars}[0]->val != 1) { push (@portHealth, $portDesc[${$portVars}[0]->val]); push (@portNum, $port); push (@portGroupDescr, ${$groupVars}[1]->val); push (@portGroupNum, $group); } } } if ($rptrHealth) { $headline = "Repeater Error"; } elsif (@groupHealth > 0) { $headline = "Group Error"; } elsif (@portHealth > 0) { $headline = "Port Error"; } else { $headline = ""; } if ($headline) { $RET = 1; push (@hosts, $host); push (@ERRS, "$host\n" . "-" x length($host) . "\n\n"); if ($rptrHealth) { push (@ERRS, "Repeater Error\n" . "-" x 14 . "\n" . $rptrHealth); } if (@groupHealth > 0) { push (@ERRS, "Group Errors\n" . "-" x 12 . "\n"); for ($i = 0; $i < @groupHealth; $i++) { push (@ERRS, "Group $groupNum[$i], $groupDescr[$i]: $groupHealth[$i]\n"); } push (@ERRS, "\n"); } if (@portHealth > 0) { push (@ERRS, "Port Errors\n" . "-" x 11 . "\n"); for ($i = 0; $i < @portHealth; $i++) { push (@ERRS, "Group $portGroupNum[$i], Port $portNum[$i]: " . "$portHealth[$i]\n"); } push (@ERRS, "\n"); } } } if (@hosts > 0) { print join (" ", @hosts), "\n"; print "\n"; print @ERRS; } exit $RET;