#!/usr/bin/perl # # Router bgp (Border Gateway Protocol v4 ) monitor # look at each router and get the status of all is BGP neigbor # # Version 1.00 (5 april 2002) # # Copyright 2002, Marc Hauswirth, Safe Host SA # # License: GNU GPL v2, see http://www.gnu.org/copyleft/gpl.html # # Some inspiration is taked from others mon monitors and from # routerinfo.pl by Ben Buxton (bb@zipworld.net), also under GPL, see http://www.zipworld.com.au/~bb/linux/ # and from routerint.monitor by P. Strauss (philou@philou.ch) and me self (marc@safehostnet.com). # # This script works nice for me with Cisco routers (7xxx) and Cisco L3 switchs (65xx). # # Fell free to send me your comments to marc@safehostnet.com # # This script need the SNMP Session module from Simon Leinen # 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 strict; ## -- # The only things that should be changed : my $community = "public"; ## -- my @summary; my @warnings; my $details; my $summary; # 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", "bgpVersion" => "1.3.6.1.2.1.15.1.0", "bgpLocalAs" => "1.3.6.1.2.1.15.2.0", # "bgpPeerTable" => "1.3.6.1.2.1.15.3", "bgpPeerEntry" => "1.3.6.1.2.1.15.3.1", "bgpPeerIdentifier" => "1.3.6.1.2.1.15.3.1.1", "bgpPeerState" => "1.3.6.1.2.1.15.3.1.2", "bgpPeerAdminStatus" => "1.3.6.1.2.1.15.3.1.3", "bgpPeerNegotiatedVersion" => "1.3.6.1.2.1.15.3.1.4", "bgpPeerLocalAddr" => "1.3.6.1.2.1.15.3.1.5", "bgpPeerLocalPort" => "1.3.6.1.2.1.15.3.1.6", "bgpPeerRemoteAddr" => "1.3.6.1.2.1.15.3.1.7", "bgpPeerRemotePort" => "1.3.6.1.2.1.15.3.1.8", "bgpPeerRemoteAs" => "1.3.6.1.2.1.15.3.1.9", "bgpPeerInUpdates" => "1.3.6.1.2.1.15.3.1.10", "bgpPeerOutUpdates" => "1.3.6.1.2.1.15.3.1.11", "bgpPeerInTotalMessages" => "1.3.6.1.2.1.15.3.1.12", "bgpPeerOutTotalMessages" => "1.3.6.1.2.1.15.3.1.13", "bgpPeerLastError" => "1.3.6.1.2.1.15.3.1.14", "bgpPeerFsmEstablishedTransitions" => "1.3.6.1.2.1.15.3.1.15", "bgpPeerFsmEstablishedTime" => "1.3.6.1.2.1.15.3.1.16", "bgpPeerConnectRetryInterval" => "1.3.6.1.2.1.15.3.1.17", "bgpPeerHoldTime" => "1.3.6.1.2.1.15.3.1.18", "bgpPeerKeepAlive" => "1.3.6.1.2.1.15.3.1.19", "bgpPeerHoldTimeConfigured" => "1.3.6.1.2.1.15.3.1.20", "bgpPeerKeepAliveConfigured" => "1.3.6.1.2.1.15.3.1.21", "bgpPeerMinASOriginationInterval" => "1.3.6.1.2.1.15.3.1.22", "bgpPeerMinRouteAdvertisementInterval" => "1.3.6.1.2.1.15.3.1.23", "bgpPeerInUpdateElapsedTime" => "1.3.6.1.2.1.15.3.1.24", "bgpIdentifier" => "1.3.6.1.2.1.15.4", "bgpRcvdPathAttrTable" => "1.3.6.1.2.1.15.5", "bgp4PathAttrTable" => "1.3.6.1.2.1.15.6", "bgpPathAttrEntry" => "1.3.6.1.2.1.15.5.1", "bgpPathAttrPeer" => "1.3.6.1.2.1.15.5.1.1", "bgpPathAttrDestNetwork" => "1.3.6.1.2.1.15.5.1.2", "bgpPathAttrOrigin" => "1.3.6.1.2.1.15.5.1.3", "bgpPathAttrASPath" => "1.3.6.1.2.1.15.5.1.4", "bgpPathAttrNextHop" => "1.3.6.1.2.1.15.5.1.5", "bgpPathAttrInterASMetric" => "1.3.6.1.2.1.15.5.1.6", "bgp4PathAttrEntry" => "1.3.6.1.2.1.15.6.1", "bgp4PathAttrPeer" => "1.3.6.1.2.1.15.6.1.1", "bgp4PathAttrIpAddrPrefixLen" => "1.3.6.1.2.1.15.6.1.2", "bgp4PathAttrIpAddrPrefix" => "1.3.6.1.2.1.15.6.1.3", "bgp4PathAttrOrigin" => "1.3.6.1.2.1.15.6.1.4", "bgp4PathAttrASPathSegment" => "1.3.6.1.2.1.15.6.1.5", "bgp4PathAttrNextHop" => "1.3.6.1.2.1.15.6.1.6", "bgp4PathAttrMultiExitDisc" => "1.3.6.1.2.1.15.6.1.7", "bgp4PathAttrLocalPref" => "1.3.6.1.2.1.15.6.1.8", "bgp4PathAttrAtomicAggregate" => "1.3.6.1.2.1.15.6.1.9", "bgp4PathAttrAggregatorAS" => "1.3.6.1.2.1.15.6.1.10", "bgp4PathAttrAggregatorAddr" => "1.3.6.1.2.1.15.6.1.11", "bgp4PathAttrCalcLocalPref" => "1.3.6.1.2.1.15.6.1.12", "bgp4PathAttrBest" => "1.3.6.1.2.1.15.6.1.13", "bgp4PathAttrUnknown" => "1.3.6.1.2.1.15.6.1.14", ); my %BgpPeerState = ( 1 => "idle", 2 => "connect", 3 => "active", 4 => "opensnet", 5 => "openconfirm", 6 => "established" ); my %state; foreach my $router (@ARGV) { # Get some infos about this router my $sess = new SNMP::Session ( DestHost => $router, Community => $community ); my $bgpLocalAs = $sess->get("\." . $oids{bgpLocalAs}); my $bgpIdentifier = $sess->get("\." . $oids{bgpIdentifier} . ".0"); $details .= "Router: $router (AS $bgpLocalAs) Id : $bgpIdentifier\n"; # Get trougnt the SNMP tree to fetch all peer infos my $vars = new SNMP::VarList([$oids{bgpPeerIdentifier}],[$oids{bgpPeerRemoteAs}],[$oids{bgpPeerState}],[$oids{bgpPeerFsmEstablishedTime}]); for (my @vals = $sess->getnext($vars); $vars->[0]->tag =~ /15\.3\.1\.1/ # 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 $textState = $BgpPeerState{$vals[2]}; my $texttime = sectotime($vals[3]); $details .= sprintf(" Neighbor %-16s AS %-5u status : %-15s since : %-16s\n",$vals[0], $vals[1], $textState, $texttime); if ($vals[2] != 6) { $summary .= "Neighbor relation : $router - $vals[0] (AS $vals[1]) is in state $textState"; }; } $details .= "\n"; } if ($summary) { print $summary . "\n"; print "--------------------------------------------------------------\n"; print "Summary : \n"; print " " . $summary . "\n"; } else { print "\n"; }; print "--------------------------------------------------------------\n"; print "Details \n"; print "--------------------------------------------------------------\n"; print $details ; if ($summary) { # Error state exit exit 1; } else { # Correct exit exit 0; }; # Transform secondes into a readable format (NNNdNNhNNm). sub sectotime { my($sec) = @_; my $texttime = ""; if ($sec >= 86400) { $texttime = int($sec/86400) . "d"; $sec -= int($sec/86400)*86400; }; if ($sec >= 3600) { $texttime .= int($sec/3600) ."h"; $sec -= int($sec/3600)*3600; } else { $texttime .= "0h"; } $texttime .= int($sec/60) . "min"; return ($texttime); };