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
[email protected]
http://linux.kernel.org/mailman/listinfo/mon