On Mon, Feb 06, 2006 at 01:53:58AM -0500, Ed Ravin wrote: > Attached is my first try at an OSPF monitoring script meant for use in Mon. > It's loosely based on bgp.monitor. ... > The script will also tell you about addressless interfaces that have > OSPF enabled - I need to put a bit more code in the script to identify > them (currently you just see an ifIndex without explanation).
I started feeling guilty about not including that feature, so here's an updated version that properly displays addressless interfaces, and in addition fixes the --exclude option so the monitor is actually useful. I'll drop this into the contrib directory after I've had some time to shake it out and get feedback. -- Ed
#!/usr/bin/perl # # Router ospf (Open Shortest Path First) monitor # Look at each router and get the status of all OSPF neighbors. # Issue alarm if any interfaces configured for neighbors do not # have a full adjacencies # Detail log shows status of all enabled OSPF interfaces. # Usage: # ospf.monitor [--exclude pattern] [--community str] router1 [...] # # --exclude - don't alarm for IP addresses that match <pattern>. Periods # in the IP address will be escaped so that they only match periods. Use # [0-9] or the like if you need character class matching. Use 'ip|ip|ip' # to exclude multiple peers. # # --community - SNMPv1 community name to use. But it's more secure # to pass the community in via the environment variable COMMUNITY. # # Edit history below # Version 0.1 # # By Ed Ravin <[EMAIL PROTECTED]> This code is made available courtesy of # PANIX http://www.panix.com. # Copyright 2005, by Ed Ravin # # License: GNU GPL v2, see http://www.gnu.org/copyleft/gpl.html # # Loosely based on bgp.monitor which is: # Copyright 2002, by Marc Hauswirth, Safe Host SA <[EMAIL PROTECTED]> # # Some inspiration is taked from others mon monitors and from # routerinfo.pl by Ben Buxton ([EMAIL PROTECTED]), also under GPL, see http://www.zipworld.com.au/~bb/linux/ # and from routerint.monitor by P. Strauss ([EMAIL PROTECTED]) and me self ([EMAIL PROTECTED]). # # This script need the SNMP Session module from Simon Leinen <[EMAIL PROTECTED]> # Wich you could found under http://www.switch.ch/misc/leinen/snmp/perl/ # It is also part of MRTG (http://people.ee.ethz.ch/~oetiker/webtools/mrtg/) use SNMP; use SNMP_Session; use Getopt::Long; use strict; my %opt; $opt{'community'}= undef; $opt{'exclude'}= ""; $opt{'debug'}= undef; my $usage="Usage: [COMMUNITY=str] ospf.monitor [--exclude regexp] [--community str] router [...]\n"; GetOptions(\%opt, "exclude=s", "community=s", "debug") or die $usage; # It's highly unlikely someone wants dots in an IP address to be treated # as a regexp pattern, so we'll escape them to make behavior more predictable. # If you really want to use pattern matching, use a character class like # [0-9] instead. $opt{exclude} =~ s/\./\\./g; $opt{exclude}= '^(' . $opt{exclude} . ')'; $opt{exclude}= "NOT_USED" if $opt{exclude} eq "^()"; ## -- my $community = $opt{'community'} || $ENV{'COMMUNITY'} || "public"; ## -- my @failures; my @details; $ENV{'MIBS'}= ""; # all OIDs needed are specified in script # OID's to the SNMP elements that I want to show... # From Cisco's MIB and RFC's # http://sunsite.cnlab-switch.ch/ftp/doc/standard/rfc/16xx/1657 # http://www.telecomm.uh.edu/stats/rfc/BGP4-MIB.html my %oids = ( "SysUptime" => "1.3.6.1.2.1.1.3.0", "ifDescr" => "1.3.6.1.2.1.2.2.1.2", "ospfRouterId" => "1.3.6.1.2.1.14.1.1" , "ospfIfIpAddress" => "1.3.6.1.2.1.14.7.1.1" , "ospfAddressLessIf" => "1.3.6.1.2.1.14.7.1.2" , "ospfIfAdminStat" => "1.3.6.1.2.1.14.7.1.5" , "ospfIfState" => "1.3.6.1.2.1.14.7.1.12" , ); my %ospfIfStates = ( 1 => "down", 2 => "loopback", 3 => "waiting", 4 => "pointToPoint", 5 => "designatedRouter", 6 => "backupDesignatedRouter", 7 => "otherDesignatedRouter", ); my %ospfAdminStatus = ( 1 => "enabled", 2 => "disabled", ); my %state; my $router; sub snmpget1 # session, oid-hashstr, instance { my $session= shift; my $oidstr= shift; my $instance = shift; my $result= $session->get(".$oids{$oidstr}.$instance"); if ($session->{ErrorNum}) { push @failures, $router; push @details, "$router: error on SNMP get of $oidstr.$instance: $session->{ErrorStr}"; return 0; } return $result; } foreach $router (@ARGV) { # Get some infos about this router my $sess = new SNMP::Session ( DestHost => $router, Community => $community ); if (!defined($sess)) { push @failures, $router; push @details, "$router: cannot create SNMP session"; next; } my $ospfRouterID = snmpget1($sess, "ospfRouterId", "0") || next; push @details, "$router (Router-ID $ospfRouterID)"; # Find the indexes of the interfaces with OSPF enabled my @ospfinterfaces; my $vars = new SNMP::VarList([$oids{ospfIfAdminStat}]); for (my @vals = $sess->getnext($vars); $vars->[0]->tag =~ /1\.3\.6\.1\.2\.1\.14\.7\.1\.5/ # still in table (Did you have a cleaner solutions ?) and not $sess->{ErrorStr}; # and not end of mib or other error @vals = $sess->getnext($vars)) { my $textIfAdminStatus = $ospfAdminStatus{$vals[0]}; push @ospfinterfaces, $vars->[0]->tag if $textIfAdminStatus eq "enabled"; } # trim down OID to keep just the interface part, which we will use # shortly as an instance ID map {s/^\.$oids{ospfIfAdminStat}\.//} @ospfinterfaces; foreach my $int (@ospfinterfaces) { my $ifstate = snmpget1($sess, "ospfIfState", "$int"); my $ifinfo= $int; if ($int =~ /0\.0\.0\.0\.(\d+)$/) { my $ifindex= $1; $ifinfo= snmpget1($sess, "ifDescr", $ifindex) . " (.$ifindex)"; } push @details, sprintf("$router: Interface %-23s %-15s",$ifinfo, $ospfIfStates{$ifstate}); # if ospfIfState not in [4..7] (OSPF full adjacency states) if ($ifstate < 4 or $ifstate > 7) { push @failures, $router unless $int =~ $opt{exclude} or grep(/$router/, @failures); $details[$#details] .= " [NO ADJACENCY]"; } } } if (@failures) { print join(' ', @failures), "\n"; }; if (@details) { print "\n"; print join("\n", @details), "\n"; } if (@failures) { # Error state exit exit 1; } else { # Correct exit exit 0; };
_______________________________________________ mon mailing list mon@linux.kernel.org http://linux.kernel.org/mailman/listinfo/mon