diff --git a/ChangeLog b/ChangeLog index 5c09c5c0..f0e5ef85 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,10 +2,24 @@ SNMP::Info - Friendly OO-style interface to Network devices using SNMP. ChangeLog $Id$ verison 0.9 () + + ** Added full Nortel/Bay/BayStack support + by new developer Eric Miller. + L2::Bay now depricated. + + Added Alteon Ace support (Eric Miller) + + Added Nortel Cotivity support (Eric Miller) + + Added Nortel BayRS support (Eric Miller) + + Added Nortel Centillion support (Eric Miller) + + Added Nortel AP 222x support (Eric Miller) + + Added Orinco AP support (Eric Miller) + Added i_lastchange() per suggestion of Nicolai Petri + Added BULKWALK patch by Bradley Baetz - This should greatly speed up requests on SNMPv2c devices. * Added C3560s to the C3550 class. Thanks to Nicolai. + * Fixed Bug where older Cisco's would append nulls to certain + CDP information. Would come up a 'DBD::Pg parser' error in Netdisco + * Changed so a failed _global() call is cached so it won't retry + an error over and over again if the same global is used. + + Added MibDirs option to new() to allow specifying non-system MIB directories. version 0.8 (03/21/04) + Added Q-BRIDGE-MIB support to SNMP::Info::Bridge diff --git a/DeviceMatrix.txt b/DeviceMatrix.txt index 0af2237e..c32af960 100644 --- a/DeviceMatrix.txt +++ b/DeviceMatrix.txt @@ -4,7 +4,7 @@ # This file is meant to detail the cababilities # of network devices to supply data via SNMP. -# $Id$ +# $Id: DeviceMatrix.txt,Modified by Eric Miller 10/17/2004 # Allied device-vendor: Allied Telesyn @@ -37,19 +37,8 @@ duplex: no device: 1012 # Bay -device-vendor: Bay Networks -class: Layer2::Bay -ver: 1 - -device-family: BayStack -macsuck: yes -cdp: proprietary -note: SNMP interface does not respond after 2+ months of uptime. Reboot to fix. - -device: 303 -device: 304 -device: 450 -note: Labels full duplex as 20Mbit connection. +device-vendor: Bay +note: See Nortel # CISCO device-vendor: Cisco @@ -339,6 +328,163 @@ duplex: link device: 4108GL,8000,2626,2650,8000 note: VLAN info in Q-BRIDGE-MIB +# NORTEL +device-vendor: Nortel Networks + +device-family: BayStack Hub +macsuck: yes +duplex: both +cdp: proprietary +ver: 1 +class: Layer1::Bayhub +note: !Uses proprietary MIBs to provide MAC to port mapping. + +device: 102 + +device-family: Baystack Switch +macsuck: yes +duplex: both +cdp: proprietary +class: Layer2::Baystack + +device: 303,304 + +device: 350 + +device: 380 + +device: 410 + +device: 420 + +device: 450 +note: !Some versions > 4.X in stacked configuration have SNMP timeout issues. +note: Labels full duplex as 20Mbit connection. + +device: 460,470 + +device: 5510,5520 + +device: BPS + +device-family: Centillion +macsuck: yes +duplex: both +cdp: proprietary +class: Layer2::Centillion +note: !Must be on version 4.x or 5.x (VLAN based) software. + +device: 5000BH + +device: 5005BH + +device: C100 + +device: C50 + +device-family: AP222x +macsuck: yes +duplex: both +cdp: proprietary +class: Layer2::NAP222x +note: !Upgrade to version 1.3 or higher. +note: Sends out topology packets if enabled but does not build neighbor table. + +device: AP-2220 + +device: AP-2221 + +device: AP-2225 + +device-family: Alteon AD +arpnip: yes +macsuck: yes +duplex: both +cdp: no +class: Layer3::AlteonAD +note: !Some versions have issues with continuous SNMP polling. Upgrade to 10.0.30.7 or higher. + +device: AD2 + +device: AD3 + +device: AD4 + +device: 180 + +device: 183 + +device: 184 + +device-family: BayRS +arpnip: yes +macsuck: yes +portmac: yes +duplex: both +cdp: no +class: Layer3::BayRS + +device: AN + +device: ARN + +device: ASN + +device: BLN + +device: Passport 2430 + +device: Passport 5430 + +device-family: Contivity +arpnip: yes +macsuck: no +portmac: yes +duplex: no +cdp: no +class: Layer3::Contivity + +device: 100,400,600 + +device: 1000,1010,1050 + +device: 1500,1600,1700,1740 + +device: 2500,2600,2700 + +device: 4500,4600,5000 + + +device-family: Passport LAN +arpnip: yes +macsuck: yes +portmac: yes +duplex: both +cdp: proprietary +class: Layer3::Passport +note: !Code versions < 3.2 vlan based mac-suck and are unsupported. Upgrade code. +note: !3.2 code versions < 3.2.2.2 have Bridge MIB loop. Upgrade code. + +device: 8603,8606,8610 + +device: 8610co + +# Proxim +device-vendor: Proxim + +device-family: Orinoco +macsuck: yes +duplex: no +cdp: no +class: Layer2::Orinoco + +device: AP-1000 + +device: AP-2000 + +device: WavePOINT-II + +# Zyxel device-vendor: Zyxel class: Layer2::ZyXEL_DSLAM note: Doesn't report sysServices (layers) diff --git a/Info/Layer1/Bayhub.pm b/Info/Layer1/Bayhub.pm new file mode 100644 index 00000000..cd448e70 --- /dev/null +++ b/Info/Layer1/Bayhub.pm @@ -0,0 +1,532 @@ +# SNMP::Info::Layer1::Bayhub +# Eric Miller +# +# Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. +# +# Copyright (c) 2002,2003 Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::Layer1::Bayhub; +$VERSION = 0.9; +use strict; + +use Exporter; +use SNMP::Info; +use SNMP::Info::Bridge; +use SNMP::Info::NortelStack; +use SNMP::Info::SONMP; + +@SNMP::Info::Layer1::Bayhub::ISA = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::NortelStack SNMP::Info::SONMP Exporter/; +@SNMP::Info::Layer1::Bayhub::EXPORT_OK = qw//; + +use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG/; + +%MIBS = ( + %SNMP::Info::MIBS, + %SNMP::Info::Bridge::MIBS, + %SNMP::Info::NortelStack::MIBS, + %SNMP::Info::SONMP::MIBS, + 'S5-ETHERNET-COMMON-MIB' => 's5EnPortTable', + 'S5-COMMON-STATS-MIB' => 's5CmStat', + ); + +%GLOBALS = ( + %SNMP::Info::GLOBALS, + %SNMP::Info::Bridge::GLOBALS, + %SNMP::Info::NortelStack::GLOBALS, + %SNMP::Info::SONMP::GLOBALS, + ); + +%FUNCS = ( + %SNMP::Info::FUNCS, + %SNMP::Info::Bridge::FUNCS, + %SNMP::Info::NortelStack::FUNCS, + %SNMP::Info::SONMP::FUNCS, + # S5-ETHERNET-COMMON-MIB::s5EnPortTable + 'bayhub_pb_index' => 's5EnPortBrdIndx', + 'bayhub_pp_index' => 's5EnPortIndx', + 'bayhub_up_admin' => 's5EnPortPartStatus', + 'bayhub_up' => 's5EnPortLinkStatus', + # S5-COMMON-STATS-MIB::s5CmSNodeTable + 'bayhub_nb_index' => 's5CmSNodeBrdIndx', + 'bayhub_np_index' => 's5CmSNodePortIndx', + 'fw_mac' => 's5CmSNodeMacAddr', + ); + +%MUNGE = ( + %SNMP::Info::MUNGE, + %SNMP::Info::Bridge::MUNGE, + %SNMP::Info::NortelStack::MUNGE, + %SNMP::Info::SONMP::MUNGE, + ); + +sub layers { + return '00000011'; +} + +sub os { + return 'bay_hub'; +} + +sub vendor { + return 'nortel'; +} + +sub model { + my $bayhub = shift; + my $id = $bayhub->id(); + return undef unless defined $id; + my $model = &SNMP::translateObj($id); + return $id unless defined $model; + $model =~ s/^sreg-//i; + + return 'Baystack Hub' if ($model =~ /BayStackEth/); + return '5000' if ($model =~ /5000/); + return '5005' if ($model =~ /5005/); + return $model; +} + +# Hubs do not support ifMIB requirements for get MAC +# and port status +sub i_index { + my $bayhub = shift; + my $b_index = $bayhub->bayhub_pb_index(); + my $p_index = $bayhub->bayhub_pp_index(); + my $model = $bayhub->model(); + + my %i_index; + foreach my $iid (keys %$b_index){ + my $board = $b_index->{$iid}; + next unless defined $board; + my $port = $p_index->{$iid}||0; + + if ($model eq 'Baystack Hub') { + my $comidx = $board; + if (! ($comidx % 5)) { + $board = ($board / 5); + } elsif ($comidx =~ /[16]$/) { + $board = int($board/5); + $port = 25; + } elsif ($comidx =~ /[27]$/) { + $board = int($board/5); + $port = 26; + } + } + + my $index = ($board*256)+$port; + + $i_index{$iid} = $index; + } + return \%i_index; +} + +sub interfaces { + my $bayhub = shift; + my $i_index = $bayhub->i_index(); + + my %if; + foreach my $iid (keys %$i_index){ + my $index = $i_index->{$iid}; + next unless defined $index; + + # Index numbers are deterministic slot * 256 + port + my $port = $index % 256; + my $slot = int($index / 256); + + my $slotport = "$slot.$port"; + + $if{$index} = $slotport; + } + + return \%if; +} + +sub i_duplex { + my $bayhub = shift; + my $port_index = $bayhub->i_index(); + + my %i_duplex; + foreach my $iid (keys %$port_index){ + my $index = $port_index->{$iid}; + next unless defined $index; + + my $duplex = 'half'; + $i_duplex{$index}=$duplex; + } + return \%i_duplex; +} + +sub i_duplex_admin { + my $bayhub = shift; + my $port_index = $bayhub->i_index(); + + my %i_duplex_admin; + foreach my $iid (keys %$port_index){ + my $index = $port_index->{$iid}; + next unless defined $index; + + my $duplex = 'half'; + $i_duplex_admin{$index}=$duplex; + } + return \%i_duplex_admin; +} + +sub i_speed { + my $bayhub = shift; + my $port_index = $bayhub->i_index(); + + my %i_speed; + foreach my $iid (keys %$port_index){ + my $index = $port_index->{$iid}; + next unless defined $index; + + my $speed = '10 Mbps'; + $i_speed{$index}=$speed; + } + return \%i_speed; +} + +sub i_up { + my $bayhub = shift; + my $port_index = $bayhub->i_index(); + my $link_stat = $bayhub->bayhub_up(); + + my %i_up; + foreach my $iid (keys %$port_index){ + my $index = $port_index->{$iid}; + next unless defined $index; + my $link_stat = $link_stat->{$iid}; + next unless defined $link_stat; + + $link_stat = 'up' if $link_stat =~ /on/i; + $link_stat = 'down' if $link_stat =~ /off/i; + + $i_up{$index}=$link_stat; + } + return \%i_up; +} + +sub i_up_admin { + my $bayhub = shift; + my $i_index = $bayhub->i_index(); + my $link_stat = $bayhub->bayhub_up_admin(); + + my %i_up_admin; + foreach my $iid (keys %$i_index){ + my $index = $i_index->{$iid}; + next unless defined $index; + my $link_stat = $link_stat->{$iid}; + next unless defined $link_stat; + + $i_up_admin{$index}=$link_stat; + } + return \%i_up_admin; +} +# Hubs do not support the standard Bridge MIB +sub bp_index { + my $bayhub = shift; + my $b_index = $bayhub->bayhub_nb_index(); + my $p_index = $bayhub->bayhub_np_index(); + my $model = $bayhub->model(); + + my %bp_index; + foreach my $iid (keys %$b_index){ + my $board = $b_index->{$iid}; + next unless defined $board; + my $port = $p_index->{$iid}||0; + + if ($model eq 'Baystack Hub') { + my $comidx = $board; + if (! ($comidx % 5)) { + $board = ($board / 5); + } elsif ($comidx =~ /[16]$/) { + $board = int($board/5); + $port = 25; + } elsif ($comidx =~ /[27]$/) { + $board = int($board/5); + $port = 26; + } + } + + my $index = ($board*256)+$port; + + $bp_index{$index} = $index; + } + return \%bp_index; +} + +sub fw_port { + my $bayhub = shift; + my $b_index = $bayhub->bayhub_nb_index(); + my $p_index = $bayhub->bayhub_np_index(); + my $model = $bayhub->model(); + + my %fw_port; + foreach my $iid (keys %$b_index){ + my $board = $b_index->{$iid}; + next unless defined $board; + my $port = $p_index->{$iid}||0; + + if ($model eq 'Baystack Hub') { + my $comidx = $board; + if (! ($comidx % 5)) { + $board = ($board / 5); + } elsif ($comidx =~ /[16]$/) { + $board = int($board/5); + $port = 25; + } elsif ($comidx =~ /[27]$/) { + $board = int($board/5); + $port = 26; + } + } + + my $index = ($board*256)+$port; + + $fw_port{$iid} = $index; + } + return \%fw_port; +} + +sub index_factor { + return 256; +} + +sub slot_offset { + return 0; +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer1::Bayhub - SNMP Interface to Bay / Nortel Hubs + +=head1 AUTHOR + +Eric Miller (C) + +=head1 SYNOPSIS + + #Let SNMP::Info determine the correct subclass for you. + + my $bayhub = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + + or die "Can't connect to DestHost.\n"; + + my $class = $bayhub->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Provides abstraction to the configuration information obtainable from a +Bayhub device through SNMP. Also provides device MAC to port mapping through the propietary MIB. + +For speed or debugging purposes you can call the subclass directly, but not after determining +a more specific class using the method above. + +my $bayhub = new SNMP::Info::Layer1::Bayhub(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info + +=item SNMP::Info::Bridge + +=item SNMP::Info::NortelStack + +=item SNMP::Info::SONMP + +=back + +=head2 Required MIBs + +=over + +=item S5-ETHERNET-COMMON-MIB + +=item S5-COMMON-STATS-MIB + +=item Inherited Classes' MIBs + +See SNMP::Info for its own MIB requirements. + +See SNMP::Info::Bridge for its own MIB requirements. + +See SNMP::Info::NortelStack for its own MIB requirements. + +See SNMP::Info::SONMP for its own MIB requirements. + +=back + +MIBs can be found on the CD that came with your product. + +Or, they can be downloaded directly from Nortel Networks regardless of support +contract status. Go to http://www.nortelnetworks.com Technical Support, Browse Technical Support, +Select by Product Families, BayStack, BayStack: Hubs - 150 Series, 10BASE-T, +Software. Filter on mibs and download the latest version's archive. + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $bayhub->vendor() + +Returns 'Nortel' + +=item $bayhub->os() + +Returns 'Bay Hub' + +=item $bayhub->model() + +Cross references $bayhub->id() to the SYNOPTICS-MIB and returns +the results. + +Removes sreg- from the model name + +=back + +=head2 Overrides + +=over + +=item $bayhub->layers() + +Returns 00000011. Class emulates Layer 2 functionality through proprietary MIBs. + +=item $bayhub->index_factor() + +Required by SNMP::Info::SONMP. Number representing the number of ports +reserved per slot within the device MIB. Returns 256. + +=item $bayhub->slot_offset() + +Required by SNMP::Info::SONMP. Offset if slot numbering does not +start at 0. Returns 0. + +=back + +=head2 Globals imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Globals imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Global Methods imported from SNMP::Info::NortelStack + +See documentation in SNMP::Info::NortelStack for details. + +=head2 Global Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=head1 TABLE ENTRIES + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $bayhub->i_index() + +Returns reference to map of IIDs to Interface index. + +Since hubs do not support ifIndex, the interface index is created using the +formula (board * 256 + port). + +=item $bayhub->interfaces() + +Returns reference to map of IIDs to physical ports. + +=item $bayhub->i_duplex() + +Returns half, hubs do not support full duplex. + +=item $bayhub->i_duplex_admin() + +Returns half, hubs do not support full duplex. + +=item $bayhub->i_speed() + +Currently returns 10 Mbps. The class does not currently support 100 Mbps hubs. + +=item $bayhub->i_up() + +Returns (B) for each port. Translates on/off to up/down. + +=item $bayhub->i_up_admin() + +Returns (B) for each port. + +=item $bayhub->bp_index() + +Simulates bridge MIB by returning reference to a hash containing the index for +both the keys and values. + +=item $bayhub->fw_port() + +Returns reference to map of IIDs of the S5-COMMON-STATS-MIB::s5CmSNodeTable +to the Interface index. + +=item $bayhub->fw_mac() + +(B) + +=back + +=head2 Table Methods imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Table Methods imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Table Methods imported from SNMP::Info::NortelStack + +See documentation in SNMP::Info::NortelStack for details. + +=head2 Table Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=cut diff --git a/Info/Layer2/Bay.pm b/Info/Layer2/Bay.pm index 747abd38..99f59f0e 100644 --- a/Info/Layer2/Bay.pm +++ b/Info/Layer2/Bay.pm @@ -1,5 +1,6 @@ # SNMP::Info::Layer2::Bay # Max Baker +# This module depricated. See Layer2::BayStack # # Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. # @@ -276,19 +277,7 @@ Max Baker (C) =head1 SYNOPSIS - # Let SNMP::Info determine the correct subclass for you. - my $bay = new SNMP::Info( - AutoSpecify => 1, - Debug => 1, - # These arguments are passed directly on to SNMP::Session - DestHost => 'myswitch', - Community => 'public', - Version => 2 - ) - or die "Can't connect to DestHost.\n"; - - my $class = $bay->class(); - print "SNMP::Info determined this device to fall under subclass : $class\n"; +This module is Depricated. Please use Layer2::BayStack instead. =head1 DESCRIPTION diff --git a/Info/Layer2/Baystack.pm b/Info/Layer2/Baystack.pm new file mode 100644 index 00000000..a77a2f80 --- /dev/null +++ b/Info/Layer2/Baystack.pm @@ -0,0 +1,425 @@ +# SNMP::Info::Layer2::Baystack +# Eric Miller +# +# Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::Layer2::Baystack; +$VERSION = 0.9; +use strict; + +use Exporter; +use SNMP::Info; +use SNMP::Info::Bridge; +use SNMP::Info::NortelStack; +use SNMP::Info::SONMP; +use SNMP::Info::RapidCity; + +@SNMP::Info::Layer2::Baystack::ISA = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::NortelStack SNMP::Info::SONMP SNMP::Info::RapidCity Exporter/; +@SNMP::Info::Layer2::Baystack::EXPORT_OK = qw//; + +use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG/; + +%MIBS = ( + %SNMP::Info::MIBS, + %SNMP::Info::Bridge::MIBS, + %SNMP::Info::NortelStack::MIBS, + %SNMP::Info::SONMP::MIBS, + %SNMP::Info::RapidCity::MIBS, + ); + +%GLOBALS = ( + %SNMP::Info::GLOBALS, + %SNMP::Info::Bridge::GLOBALS, + %SNMP::Info::NortelStack::GLOBALS, + %SNMP::Info::SONMP::GLOBALS, + %SNMP::Info::RapidCity::GLOBALS, + ); + +%FUNCS = ( + %SNMP::Info::FUNCS, + %SNMP::Info::Bridge::FUNCS, + %SNMP::Info::NortelStack::FUNCS, + %SNMP::Info::SONMP::FUNCS, + %SNMP::Info::RapidCity::FUNCS, + 'i_name2' => 'ifName', + 'i_mac2' => 'ifPhysAddress', + ); + +# 450's report full duplex as speed = 20mbps?! +$SNMP::Info::SPEED_MAP{20_000_000} = '10 Mbps'; +$SNMP::Info::SPEED_MAP{200_000_000} = '100 Mbps'; +$SNMP::Info::SPEED_MAP{2_000_000_000} = '1.0 Gbps'; + +%MUNGE = ( + %SNMP::Info::MUNGE, + %SNMP::Info::Bridge::MUNGE, + %SNMP::Info::NortelStack::MUNGE, + %SNMP::Info::SONMP::MUNGE, + %SNMP::Info::RapidCity::MUNGE, + 'i_mac2' => \&SNMP::Info::munge_mac, + ); + +sub os { + my $baystack = shift; + my $descr = $baystack->description(); + my $model = $baystack->model(); + + if ((defined $model and $model =~ /(470|460|BPS|5510|5520)/) and (defined $descr and $descr =~ m/SW:v[3-5]/i)) { + return 'boss'; + } + return 'baystack'; +} + +sub os_bin { + my $baystack = shift; + my $descr = $baystack->description(); + return undef unless defined $descr; + + # 303 / 304 + if ($descr =~ m/Rev: \d+\.(\d+\.\d+\.\d+)-\d+\.\d+\.\d+\.\d+/){ + return $1; + } + + # 450 + if ($descr =~ m/FW:V(\d+\.\d+)/){ + return $1; + } + + if ($descr =~ m/FW:(\d+\.\d+\.\d+\.\d+)/i){ + return $1; + } + return undef; +} + +sub vendor { + return 'nortel'; +} + +sub model { + my $baystack = shift; + my $id = $baystack->id(); + return undef unless defined $id; + my $model = &SNMP::translateObj($id); + return $id unless defined $model; + $model =~ s/^sreg-//i; + + my $descr = $baystack->description(); + + return '303' if (defined $descr and $descr =~ /\D303\D/); + return '304' if (defined $descr and $descr =~ /\D304\D/); + return '350' if ($model =~ /BayStack350/); + return '380' if ($model =~ /BayStack380/); + return '410' if ($model =~ /BayStack410/); + return '420' if ($model =~ /BayStack420/); + return '425' if ($model =~ /BayStack425/); + return '450' if ($model =~ /BayStack450/); + return '470' if ($model =~ /BayStack470/i); + return '460' if ($model =~ /BayStack460/i); + return 'BPS' if ($model =~ /BPS2000/i); + return '5510' if ($model =~ /BayStack5510/i); + return '5520' if ($model =~ /BayStack5520/i); + + return $model; +} + +sub i_ignore { + my $baystack = shift; + my $i_type = $baystack->i_type(); + + my %i_ignore; + foreach my $if (keys %$i_type){ + my $type = $i_type->{$if}; + next unless defined $type; + $i_ignore{$if}++ if $type =~ /(54|loopback|propvirtual|cpu)/i; + } + return \%i_ignore; +} + +sub interfaces { + my $baystack = shift; + my $i_index = $baystack->i_index(); + my $index_factor = $baystack->index_factor(); + my $slot_offset = $baystack->slot_offset(); + + my %if; + foreach my $iid (keys %$i_index){ + my $index = $i_index->{$iid}; + next unless defined $index; + # Ignore cascade ports + next if $index > 513; + + my $port = ($index % $index_factor); + my $slot = (int($index / $index_factor)) + $slot_offset; + + my $slotport = "$slot.$port"; + $if{$iid} = $slotport; + } + return \%if; +} + +sub i_mac { + my $baystack = shift; + my $i_mac = $baystack->i_mac2(); + + my %i_mac; + # Baystack 303's with a hw rev < 2.11.4.5 report the mac as all zeros + foreach my $iid (keys %$i_mac){ + my $mac = $i_mac->{$iid}; + next unless defined $mac; + next if $mac eq '00:00:00:00:00:00'; + $i_mac{$iid}=$mac; + } + return \%i_mac; +} + +sub i_name { + my $baystack = shift; + my $i_index = $baystack->i_index(); + my $i_alias = $baystack->i_alias(); + my $i_name2 = $baystack->i_name2(); + + my %i_name; + foreach my $iid (keys %$i_name2){ + my $name = $i_name2->{$iid}; + my $alias = $i_alias->{$iid}; + $i_name{$iid} = (defined $alias and $alias !~ /^\s*$/) ? + $alias : + $name; + } + + return \%i_name; +} + +sub index_factor { + my $baystack = shift; + my $model = $baystack->model(); + my $os = $baystack->os(); + my $op_mode = $baystack->ns_op_mode(); + + $op_mode = 'pure' unless defined $op_mode; + + my $index_factor = 32; + $index_factor = 64 if ((defined $model and $model =~ /(470)/) or ($os eq 'BoSS') and ($op_mode eq 'pure')); + + return $index_factor; +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer2::Baystack - SNMP Interface to Nortel Networks' Baystack Switches + +=head1 AUTHOR + +Max Baker (C), +Eric Miller (C) + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $baystack = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $baystack->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Provides abstraction to the configuration information obtainable from a Nortel Networks' +Baystack device through SNMP. + +For speed or debugging purposes you can call the subclass directly, but not after determining +a more specific class using the method above. + +my $baystack = new SNMP::Info::Layer2::Baystack(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info + +=item SNMP::Info::Bridge + +=item SNMP::Info::NortelStack + +=item SNMP::Info::SONMP + +=item SNMP::Info::RapidCity + +=back + +=head2 Required MIBs + +=over + +=item Inherited Classes' MIBs + +See SNMP::Info for its own MIB requirements. + +See SNMP::Info::Bridge for its own MIB requirements. + +See SNMP::Info::NortelStack for its own MIB requirements. + +See SNMP::Info::SONMP for its own MIB requirements. + +See SNMP::Info::RapidCity for its own MIB requirements. + +=back + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $baystack->vendor() + +Returns 'Nortel' + +=item $baystack->model() + +Cross references $baystack->id() to the SYNOPTICS-MIB and returns +the results. 303s and 304s have the same ID, so we have a hack +to return depending on which it is. + +Removes sreg- from the model name + +=item $baystack->os() + +Returns 'Baystack' or 'BoSS' depending on software version. + +=item $baystack->os_bin() + +Returns the firmware version extracted from B. + +=back + +=head2 Overrides + +=over + +=item $baystack->index_factor() + +Required by SNMP::Info::SONMP. Number representing the number of ports +reserved per slot within the device MIB. + +Index factor on the Baystack switches are determined by the formula: Index +Factor = 64 if (model = 470 or (os eq 'BoSS' and operating in pure mode)) +or else Index factor = 32. + +Returns either 32 or 64 based upon the formula. + +=back + +=head2 Globals imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Globals imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Globals imported from SNMP::Info::NortelStack + +See documentation in SNMP::Info::NortelStack for details. + +=head2 Global Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=head2 Global Methods imported from SNMP::Info::RapidCity + +See documentation in SNMP::Info::RapidCity for details. + +=head1 TABLE ENTRIES + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $baystack->interfaces() + +Returns reference to the map between IID and physical Port. + + Slot and port numbers on the Baystack switches are determined by the formula: + + port = (Interface index % Index factor) + slot = (int(Interface index / Index factor)) + Slot offset + + The physical port name is returned as slot.port. + +=item $baystack->i_ignore() + +Returns reference to hash of IIDs to ignore. + +=item $baystack->i_mac() + +Returns the B table entries. + +Removes all entries matching '00:00:00:00:00:00' -- Certain +revisions of Baystack firmware report all zeros for each port mac. + +=item $baystack->i_name() + +Crosses ifName with ifAlias and returns the human set port name if exists. + +=back + +=head2 Table Methods imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Table Methods imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Table Methods imported from SNMP::Info::NortelStack + +See documentation in SNMP::Info::NortelStack for details. + +=head2 Table Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=head2 Table Methods imported from SNMP::Info::RapidCity + +See documentation in SNMP::Info::RapidCity for details. + +=cut diff --git a/Info/Layer2/Centillion.pm b/Info/Layer2/Centillion.pm new file mode 100644 index 00000000..5e105232 --- /dev/null +++ b/Info/Layer2/Centillion.pm @@ -0,0 +1,523 @@ +# SNMP::Info::Layer2::Centillion +# Eric Miller +# +# Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. +# +# Copyright (c) 2002,2003 Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::Layer2::Centillion; +$VERSION = 0.9; + +use strict; + +use Exporter; +use SNMP::Info; +use SNMP::Info::Bridge; +use SNMP::Info::NortelStack; +use SNMP::Info::SONMP; + +@SNMP::Info::Layer2::Centillion::ISA = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::NortelStack SNMP::Info::SONMP Exporter/; +@SNMP::Info::Layer2::Centillion::EXPORT_OK = qw//; + +use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG/; + +%MIBS = ( + %SNMP::Info::MIBS, + %SNMP::Info::Bridge::MIBS, + %SNMP::Info::NortelStack::MIBS, + %SNMP::Info::SONMP::MIBS, + 'CENTILLION-DOT3-EXTENSIONS-MIB' => 'cnDot3ExtnTable', + 'S5-COMMON-STATS-MIB' => 's5CmStat', + 'CENTILLION-VLAN-MIB' => 'cnVlanENETMgt', + 'CENTILLION-CONFIG-MIB' => 'sysTFTPStart', + ); + +%GLOBALS = ( + %SNMP::Info::GLOBALS, + %SNMP::Info::Bridge::GLOBALS, + %SNMP::Info::NortelStack::GLOBALS, + %SNMP::Info::SONMP::GLOBALS, + 'tftp_action' => 'sysTFTPStart', + 'tftp_host' => 'sysTFTPIpAddress', + 'tftp_file' => 'sysTFTPFileName', + 'tftp_type' => 'sysTFTPFileType', + 'tftp_result' => 'sysTFTPResult', + ); + +%FUNCS = ( + %SNMP::Info::FUNCS, + %SNMP::Info::Bridge::FUNCS, + %SNMP::Info::NortelStack::FUNCS, + %SNMP::Info::SONMP::FUNCS, + # CENTILLION-DOT3-EXTENSIONS-MIB::cnDot3ExtnTable + 'centillion_p_index' => 'cnDot3ExtnIfIndex', + 'centillion_p_duplex' => 'cnDot3ExtnIfOperConnectionType', + 'centillion_p_duplex_admin' => 'cnDot3ExtnIfAdminConnectionType', + # S5-COMMON-STATS-MIB::s5CmSNodeTable + 'fw_mac' => 's5CmSNodeMacAddr', + 'fw_port' => 's5CmSNodeIfIndx', + # CENTILLION-VLAN-MIB::cnVlanPortMemberTable + 'centillion_i_vlan_index' => 'cnVlanPortMemberIfIndex', + 'centillion_i_vlan' => 'cnVlanPortMemberVID', + 'centillion_i_vlan_type' => 'cnVlanPortMemberIngressType', + ); + +%MUNGE = ( + # Inherit all the built in munging + %SNMP::Info::MUNGE, + %SNMP::Info::Bridge::MUNGE, + %SNMP::Info::NortelStack::MUNGE, + %SNMP::Info::SONMP::MUNGE, + ); + +sub os { + return 'centillion'; +} + +sub vendor { + return 'nortel'; +} + +sub i_ignore { + my $centillion = shift; + my $descr = $centillion->i_description(); + + my %i_ignore; + foreach my $if (keys %$descr){ + my $type = $descr->{$if}; + # Skip virtual interfaces + $i_ignore{$if}++ if $type =~ /(VE|VID|vc|lp)/i; + } + return \%i_ignore; +} + +sub interfaces { + my $centillion = shift; + my $i_index = $centillion->i_index(); + my $i_descr = $centillion->i_description(); + + my %if; + foreach my $iid (keys %$i_index){ + my $index = $i_index->{$iid}; + next unless defined $index; + my $descr = $i_descr->{$iid}; + # Skip ATM and virtual interfaces + next if $descr =~ /(VE|VID|vc|lp)/i; + + # Index numbers are deterministic slot * 256 + port + my $port = $index % 256; + my $slot = int($index / 256); + my $slotport = "$slot.$port"; + + $slotport = "$descr" if $descr =~ /(mcp)/i; + + $if{$index} = $slotport; + } + + return \%if; +} + +sub i_duplex { + my $centillion = shift; + + my $port_index = $centillion->centillion_p_index(); + my $port_duplex = $centillion->centillion_p_duplex(); + + my %i_duplex; + foreach my $iid (keys %$port_index){ + my $index = $port_index->{$iid}; + next unless defined $index; + my $duplex = $port_duplex->{$iid}; + next unless defined $duplex; + + $duplex = 'half' if $duplex =~ /half/i; + $duplex = 'full' if $duplex =~ /full/i; + $i_duplex{$index}=$duplex; + } + return \%i_duplex; +} + +sub i_duplex_admin { + my $centillion = shift; + + my $port_index = $centillion->centillion_p_index(); + my $port_admin = $centillion->centillion_p_duplex_admin(); + + my %i_duplex_admin; + foreach my $iid (keys %$port_index){ + my $index = $port_index->{$iid}; + next unless defined $index; + my $duplex = $port_admin->{$iid}; + next unless defined $duplex; + + $duplex = 'half' if $duplex =~ /half/i; + $duplex = 'full' if $duplex =~ /full/i; + $duplex = 'auto' if $duplex =~ /auto/i; + $i_duplex_admin{$index}=$duplex; + } + return \%i_duplex_admin; +} + +sub i_vlan { + my $centillion = shift; + + my $cn_vlan_index = $centillion->centillion_i_vlan_index(); + my $cn_vlan = $centillion->centillion_i_vlan(); + + my %i_vlan; + foreach my $iid (keys %$cn_vlan_index){ + my $index = $cn_vlan_index->{$iid}; + next unless defined $index; + my $vlan = $cn_vlan->{$iid}; + next unless defined $vlan; + + $i_vlan{$index}=$vlan; + } + return \%i_vlan; +} + +sub model { + my $centillion = shift; + my $id = $centillion->id(); + return undef unless defined $id; + my $model = &SNMP::translateObj($id); + return $id unless defined $model; + $model =~ s/^sreg-//i; + + return '5000BH' if ($model =~ /5000BH/); + return '5005BH' if ($model =~ /5005BH/); + return 'C100' if ($model =~ /Centillion100/); + return 'C50N' if ($model =~ /Centillion50N/); + return 'C50T' if ($model =~ /Centillion50T/); + return $model; +} + +sub bp_index { + my $centillion = shift; + my $index = $centillion->fw_port(); + + my %bp_index; + foreach my $iid (keys %$index){ + my $b_index = $index->{$iid}; + next unless defined $b_index; + + #Index value is the same as ifIndex + $bp_index{$b_index} = $b_index; + } + + return \%bp_index; +} + +sub index_factor { + return 256; +} + +sub slot_offset { + return 0; +} + + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer2::Centillion - SNMP Interface to Nortel Centillion based ATM Switches + +=head1 AUTHOR + +Eric Miller (C) + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $centillion = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $centillion->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Provides abstraction to the configuration information obtainable from a +Centillion device through SNMP. + +For speed or debugging purposes you can call the subclass directly, but not after determining +a more specific class using the method above. + + my $centillion = new SNMP::Info::Layer2::centillion(...); + +Note: This class supports version 4.X and 5.X which are VLAN based rather +than bridge group based. + +=head2 Inherited Classes + +=over + +=item SNMP::Info + +=item SNMP::Info::Bridge + +=item SNMP::Info::NortelStack + +=item SNMP::Info::SONMP + +=back + +=head2 Required MIBs + +=over + +=item CENTILLION-DOT3-EXTENSIONS-MIB + +=item S5-COMMON-STATS-MIB + +=item CENTILLION-VLAN-MIB + +=item CENTILLION-CONFIG-MIB + +=item Inherited Classes' MIBs + +See SNMP::Info for its own MIB requirements. + +See SNMP::Info::Bridge for its own MIB requirements. + +See SNMP::Info::NortelStack for its own MIB requirements. + +See SNMP::Info::SONMP for its own MIB requirements. + +=back + +MIBs can be found on the CD that came with your product. + +Or, they can be downloaded directly from Nortel Networks regardless of support +contract status. + +Go to http://www.nortelnetworks.com Techninal Support, Browse Technical Support, +Select by Product Families, Centillion, Centillion C100-C50 ATM Speed Modules, +Software. Filter on mibs and download the latest version's archive. + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $centillion->vendor() + +Returns 'Nortel' + +=item $centillion->model() + +Cross references $centillion->id() to the SYNOPTICS-MIB and returns +the results. + +Removes sreg- from the model name + +=item $centillion->os() + +Returns 'Centillion' + +=item $centillion->tftp_action() + +(B) + +=item $centillion->tftp_host() + +(B) + +=item $centillion->tftp_file() + +(B) + +=item $centillion->tftp_type() + +(B) + +=item $centillion->tftp_result() + +(B) + +=back + +=head2 Overrides + +=over + +=item $centillion->layers() + +Returns 00000011. Class emulates Layer 2 functionality through proprietary MIBs. + +=item $centillion->index_factor() + +Required by SNMP::Info::SONMP. Number representing the number of ports +reserved per slot within the device MIB. Returns 256. + +=item $centillion->slot_offset() + +Required by SNMP::Info::SONMP. Offset if slot numbering does not +start at 0. Returns 0. + +=back + +=head2 Globals imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Globals imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Globals imported from SNMP::Info::NortelStack + +See documentation in SNMP::Info::NortelStack for details. + +=head2 Global Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=head1 TABLE ENTRIES + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $centillion->interfaces() + + Returns reference to the map between IID and physical Port. + + Slot and port numbers on the Passport switches are determined by the formula: + port = index % 256 + slot = int(index / 256) + + The physical port name is returned as slot.port. + +=item $centillion->i_duplex() + +Returns reference to map of IIDs to current link duplex + +=item $centillion->i_duplex_admin() + +Returns reference to hash of IIDs to admin duplex setting + +=item $centillion->i_ignore() + +Returns reference to hash of IIDs to ignore. + +=item $centillion->fw_mac() + +(B) + +=item $centillion->fw_port() + +(B) + +=item $centillion->bp_index() + +Returns a mapping between ifIndex and the Bridge Table. + +=item $centillion->i_vlan() + +Returns a mapping between ifIndex and the VLAN. + +=back + +=head2 Centillion 802.3 Extension Table (B) + +=over + +=item $centillion->centillion_p_index() + +Returns reference to hash. Maps table IIDs to Interface IIDs + +(B) + +=item $centillion->centillion_p_duplex() + +Returns reference to hash. Maps port operational duplexes to IIDs + +(B) + +=item $centillion->rc_centillion_p_duplex_admin() + +Returns reference to hash. Maps port admin duplexes to IIDs + +(B) + +=back + +=head2 Centillion VLAN Table (B) + +=over + +=item $centillion->centillion_i_vlan_index() + +Returns reference to hash. Key: Table entry, Value: Index + +(B) + +=item $centillion->centillion_i_vlan() + +Returns reference to hash. Key: Table entry, Value: VLAN ID + +(B) + +=item $centillion->centillion_i_vlan_type() + +Returns reference to hash. Key: Table entry, Value: VLAN Type + +(B) + +=back + +=head2 Table Methods imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Table Methods imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Table Methods imported from SNMP::Info::NortelStack + +See documentation in SNMP::Info::NortelStack for details. + +=head2 Table Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=cut diff --git a/Info/Layer2/NAP222x.pm b/Info/Layer2/NAP222x.pm new file mode 100644 index 00000000..83236ef5 --- /dev/null +++ b/Info/Layer2/NAP222x.pm @@ -0,0 +1,502 @@ +# SNMP::Info::Layer2::NAP222x +# Eric Miller +# +# Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. +# +# Copyright (c) 2002,2003 Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::Layer2::NAP222x; +$VERSION = 0.9; +use strict; + +use Exporter; +use SNMP::Info; +use SNMP::Info::Bridge; +use SNMP::Info::SONMP; + +@SNMP::Info::Layer2::NAP222x::ISA = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::SONMP Exporter/; +@SNMP::Info::Layer2::NAP222x::EXPORT_OK = qw//; + +use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG/; + +%MIBS = ( + %SNMP::Info::MIBS, + %SNMP::Info::Bridge::MIBS, + %SNMP::Info::SONMP::MIBS, + 'NORTEL-WLAN-AP-MIB' => 'ntWlanSwHardwareVer', + ); + +%GLOBALS = ( + %SNMP::Info::GLOBALS, + %SNMP::Info::Bridge::GLOBALS, + %SNMP::Info::SONMP::GLOBALS, + 'nt_hw_ver' => 'ntWlanSwHardwareVer', + 'nt_fw_ver' => 'ntWlanSwBootRomVer', + 'nt_sw_ver' => 'ntWlanSwOpCodeVer', + 'nt_cc' => 'ntWlanSwCountryCode', + 'tftp_action' => 'ntWlanTransferStart', + 'tftp_host' => 'ntWlanFileServer', + 'tftp_file' => 'ntWlanDestFile', + 'tftp_type' => 'ntWlanFileType', + 'tftp_result' => 'ntWlanFileTransferStatus', + 'tftp_xtype' => 'ntWlanTransferType', + 'tftp_src_file' => 'ntWlanSrcFile', + 'ftp_user' => 'ntWlanUserName', + 'ftp_pass' => 'ntWlanPassword', + ); + +%FUNCS = ( + %SNMP::Info::FUNCS, + %SNMP::Info::Bridge::FUNCS, + %SNMP::Info::SONMP::FUNCS, + 'i_name2' => 'ifName', + 'bp_index_2' => 'dot1dTpFdbPort', + # From ntWlanPortTable + 'nt_prt_name' => 'ntWlanPortName', + 'nt_dpx_admin' => 'ntWlanPortCapabilities', + 'nt_auto' => 'ntWlanPortAutonegotiation', + 'nt_dpx' => 'ntWlanPortSpeedDpxStatus', + ); + +%MUNGE = ( + %SNMP::Info::MUNGE, + %SNMP::Info::Bridge::MUNGE, + %SNMP::Info::SONMP::MUNGE, + ); + +sub os { + return 'nortel'; +} + +sub os_ver { + my $nap222x = shift; + my $ver = $nap222x->nt_sw_ver(); + return undef unless defined $ver; + + if ($ver =~ m/(\d+\.\d+\.\d+\.\d+)/){ + return $1; + } + return undef; +} + +sub os_bin { + my $nap222x = shift; + my $bin = $nap222x->nt_fw_ver(); + return undef unless defined $bin; + + if ($bin =~ m/(\d+\.\d+\.\d+)/){ + return $1; + } + return undef; +} + +sub vendor { + return 'nortel'; +} + +sub model { + my $nap222x = shift; + my $descr = $nap222x->description(); + return undef unless defined $descr; + + return 'AP-2220' if ($descr =~ /2220/); + return 'AP-2221' if ($descr =~ /2221/); + return 'AP-2225' if ($descr =~ /2225/); + return undef; +} + +sub mac { + my $nap222x = shift; + my $i_mac = $nap222x->i_mac(); + +# Return Interface MAC + foreach my $entry (keys %$i_mac){ + my $sn = $i_mac->{$entry}; + next unless $sn; + return $sn; + } + return undef; +} + +sub serial { + my $nap222x = shift; + my $i_mac = $nap222x->i_mac(); + +# Return Interface MAC + foreach my $entry (keys %$i_mac){ + my $sn = $i_mac->{$entry}; + next unless $sn; + return $sn; + } + return undef; +} + +sub i_ignore { + my $nap222x = shift; + my $descr = $nap222x->i_description(); + + my %i_ignore; + foreach my $if (keys %$descr){ + my $type = $descr->{$if}; + # Skip virtual interfaces + $i_ignore{$if}++ if $type =~ /(loopback|lo|other)/i; + } + return \%i_ignore; +} + +sub interfaces { + my $nap222x = shift; + my $interfaces = $nap222x->i_index(); + my $description = $nap222x->i_description(); + + my %interfaces = (); + foreach my $iid (keys %$interfaces){ + my $desc = $description->{$iid}; + next unless defined $desc; + next if $desc =~ /lo/i; + + $interfaces{$iid} = $desc; + } + return \%interfaces; +} + +sub i_duplex { + my $nap222x = shift; + + my $mode = $nap222x->nt_dpx(); + my $port_name = $nap222x->nt_prt_name(); + my $interfaces = $nap222x->interfaces(); + + my %i_duplex; + foreach my $if (keys %$interfaces){ + my $port = $interfaces->{$if}; + next unless $port =~ /dp/i; + foreach my $idx (keys %$mode) { + my $name = $port_name->{$idx}||'unknown'; + next unless $name eq $port; + my $duplex = $mode->{$idx}; + + $duplex = 'other' unless defined $duplex; + $duplex = 'half' if $duplex =~ /half/i; + $duplex = 'full' if $duplex =~ /full/i; + + $i_duplex{$if}=$duplex; + } + } + return \%i_duplex; +} + +sub i_duplex_admin { + my $nap222x = shift; + + my $dpx_admin = $nap222x->nt_dpx_admin(); + my $nt_auto = $nap222x->nt_auto(); + my $interfaces = $nap222x->interfaces(); + my $port_name = $nap222x->nt_prt_name(); + + my %i_duplex_admin; + foreach my $if (keys %$interfaces){ + my $port = $interfaces->{$if}; + next unless $port =~ /dp/i; + foreach my $idx (keys %$dpx_admin) { + my $name = $port_name->{$idx}||'unknown'; + next unless $name eq $port; + my $duplex = $dpx_admin->{$idx}; + my $auto = $nt_auto->{$idx}; + + $duplex = 'other' unless defined $duplex; + $duplex = 'half' if ($duplex =~ /half/i and $auto =~ /disabled/i); + $duplex = 'full' if ($duplex =~ /full/i and $auto =~ /disabled/i); + $duplex = 'auto' if $auto =~ /enabled/i; + + $i_duplex_admin{$if}=$duplex; + } + } + return \%i_duplex_admin; +} + +sub i_name { + my $nap222x = shift; + my $interfaces = $nap222x->interfaces(); + + my %i_name; + foreach my $if (keys %$interfaces){ + my $desc = $interfaces->{$if}; + next unless defined $desc; + + my $name = 'unknown'; + $name = 'Ethernet Interface' if $desc =~ /dp/i; + $name = 'Wireless Interface B' if $desc =~ /ndc/i; + $name = 'Wireless Interface A' if $desc =~ /ar/i; + + $i_name{$if} = $name; + } + return \%i_name; +} + +# dot1dBasePortTable does not exist and dot1dTpFdbPort does not map to ifIndex +sub bp_index { + my $nap222x = shift; + my $interfaces = $nap222x->interfaces(); + + my %bp_index; + foreach my $iid (keys %$interfaces){ + my $desc = $interfaces->{$iid}; + next unless defined $desc; + next unless $desc =~ /(ndc|ar)/i; + + my $port = 1; + $port = 2 if $desc =~ /ndc/i; + + $bp_index{$port} = $iid; + } + return \%bp_index; +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer2::nap222x - SNMP Interface to Nortel 2220 Series Access Points + +=head1 AUTHOR + +Eric Miller (C) + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $nap222x = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $nap222x->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Provides abstraction to the configuration information obtainable from a Nortel +2220 series wireless Access Points through SNMP. + +For speed or debugging purposes you can call the subclass directly, but not after determining +a more specific class using the method above. + + my $nap222x = new SNMP::Info::Layer2::nap222x(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info + +=item SNMP::Info::Bridge + +=item SNMP::Info::SONMP + +=back + +=head2 Required MIBs + +=over + +=item NORTEL-WLAN-AP-MIB + +=item Inherited classes + +See SNMP::Info for its own MIB requirements. + +See SNMP::Info::Bridge for its own MIB requirements. + +See SNMP::Info::SONMP for its own MIB requirements. + +=back + +MIBs can be found on the CD that came with your product. + +Or, they can be downloaded directly from Nortel Networks regardless of support +contract status. + +Go to http://www.nortelnetworks.com Techninal Support, Browse Technical Support, +Select by Product Families, Wireless LAN, WLAN - Access Point 2220, Software. +Filter on mibs and download the latest version's archive. + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $nap222x->vendor() + +Returns 'Nortel' + +=item $nap222x->model() + +Returns the model extracted from B. + +=item $nap222x->os() + +Returns 'Nortel' + +=item $nap222x->os_ver() + +Returns the software version extracted from B. + +=item $nap222x->os_bin() + +Returns the firmware version extracted from B. + +=item $nap222x->mac() + +Returns the MAC address of the first Ethernet Interface. + +=item $nap222x->serial() + +Returns the MAC address of the first Ethernet Interface. + +=item $nap222x->nt_hw_ver() + +Returns the hardware version. + +B + +=item $nap222x->nt_cc() + +Returns the country code of the AP. + +B + +=item $nap222x->tftp_action() + +B + +=item $nap222x->tftp_host() + +B + +=item $nap222x->tftp_file() + +B + +=item $nap222x->tftp_type() + +B + +=item $nap222x->tftp_result() + +B + +=item $nap222x->tftp_xtype() + +B + +=item $nap222x->tftp_src_file() + +B + +=item $nap222x->ftp_user() + +B + +=item $nap222x->ftp_pass() + +B + +=back + +=head2 Globals imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Globals imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Global Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=head1 TABLE ENTRIES + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $nap222x->interfaces() + +Returns reference to map of IIDs to physical ports. + +=item $nap222x->i_ignore() + +Returns reference to hash of IIDs to ignore. + +=item $nap222x->i_duplex() + +Returns reference to hash. Maps port operational duplexes to IIDs. + +B + +=item $nap222x->i_duplex_admin() + +Returns reference to hash. Maps port admin duplexes to IIDs. + +B + +=item $nap222x->i_name() + +Returns a human name based upon port description. + +=item $nap222x->bp_index() + +Returns a mapping between ifIndex and the Bridge Table. This does not exist in +the MIB and bridge port index is not the same as ifIndex so it is created. + +=back + +=head2 Table Methods imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Table Methods imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Table Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=cut diff --git a/Info/Layer2/Orinoco.pm b/Info/Layer2/Orinoco.pm new file mode 100644 index 00000000..dda7c98c --- /dev/null +++ b/Info/Layer2/Orinoco.pm @@ -0,0 +1,280 @@ +# SNMP::Info::Layer2::Orinoco +# Eric Miller +# +# Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. +# +# Copyright (c) 2002,2003 Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::Layer2::Orinoco; +$VERSION = 0.9; +use strict; + +use Exporter; +use SNMP::Info; +use SNMP::Info::Bridge; + +@SNMP::Info::Layer2::Orinoco::ISA = qw/SNMP::Info SNMP::Info::Bridge Exporter/; +@SNMP::Info::Layer2::Orinoco::EXPORT_OK = qw//; + +use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG/; + +%MIBS = ( + %SNMP::Info::MIBS, + %SNMP::Info::Bridge::MIBS, + ); + +%GLOBALS = ( + %SNMP::Info::GLOBALS, + %SNMP::Info::Bridge::GLOBALS, + ); + +%FUNCS = ( + %SNMP::Info::FUNCS, + %SNMP::Info::Bridge::FUNCS, + ); + +%MUNGE = ( + %SNMP::Info::MUNGE, + %SNMP::Info::Bridge::MUNGE, + ); + +sub os { + return 'orinoco'; +} + +sub os_ver { + my $orinoco = shift; + my $descr = $orinoco->description(); + return undef unless defined $descr; + + if ($descr =~ m/V(\d+\.\d+)/){ + return $1; + } + if ($descr =~ m/v(\d+\.\d+\.\d+)/){ + return $1; + } + + return undef; +} + +sub os_bin { + my $orinoco = shift; + my $descr = $orinoco->description(); + return undef unless defined $descr; + + if ($descr =~ m/V(\d+\.\d+)$/){ + return $1; + } + if ($descr =~ m/v(\d+\.\d+\.\d+)$/){ + return $1; + } + + return undef; +} + +sub vendor { + return 'Proxim'; +} + +sub model { + my $orinoco = shift; + my $descr = $orinoco->description(); + return undef unless defined $descr; + + return 'AP-1000' if ($descr =~ /AP-1000/); + return 'AP-2000' if ($descr =~ /AP-2000/); + return 'WavePOINT-II' if ($descr =~ /WavePOINT-II/); + return undef; +} + +sub serial { + my $orinoco = shift; + my $descr = $orinoco->description(); + return undef unless defined $descr; + + $descr = $1 if $descr =~ /SN-(\S+)/; + return $descr; +} + +sub i_ignore { + my $orinoco = shift; + my $descr = $orinoco->i_description(); + + my %i_ignore; + foreach my $if (keys %$descr){ + my $type = $descr->{$if}; + # Skip virtual interfaces + $i_ignore{$if}++ if $type =~ /(lo|empty|PCMCIA)/i; + } + return \%i_ignore; +} + +sub interfaces { + my $orinoco = shift; + my $interfaces = $orinoco->i_index(); + my $descriptions = $orinoco->i_description(); + + my %interfaces = (); + foreach my $iid (keys %$interfaces){ + my $desc = $descriptions->{$iid}; + next unless defined $desc; + next if $desc =~ /(lo|empty|PCMCIA)/i; + + $desc = 'AMD' if $desc =~ /AMD/; + + $interfaces{$iid} = $desc; + } + return \%interfaces; +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer2::Orinoco - SNMP Interface to Orinoco Series Access Points + +=head1 AUTHOR + +Eric Miller (C) + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $orinoco = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $orinoco->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Provides abstraction to the configuration information obtainable from a Orinoco +Access Point through SNMP. + +For speed or debugging purposes you can call the subclass directly, but not after +determining a more specific class using the method above. + + my $orinoco = new SNMP::Info::Layer2::Orinoco(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info + +=item SNMP::Info::Bridge + +=back + +=head2 Required MIBs + +=over + +=item Inherited classes + +See SNMP::Info for its own MIB requirements. + +See SNMP::Info::Bridge for its own MIB requirements. + +=back + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $orinoco->vendor() + +Returns 'Proxim' :) + +=item $orinoco->model() + +Returns the model extracted from B. + +=item $orinoco->os() + +Returns 'Orinoco' + +=item $orinoco->os_ver() + +Returns the software version extracted from B. + +=item $orinoco->os_bin() + +Returns the firmware version extracted from B. + +=item $orinoco->serial() + +Returns the serial number extracted from B. + +=back + +=head2 Globals imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Globals imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head1 TABLE ENTRIES + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $orinoco->interfaces() + +Returns reference to map of IIDs to physical ports. + +=item $orinoco->i_ignore() + +Returns reference to hash of IIDs to ignore. + +=back + +=head2 Table Methods imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Table Methods imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=cut diff --git a/Info/Layer3/AlteonAD.pm b/Info/Layer3/AlteonAD.pm new file mode 100644 index 00000000..925c2d31 --- /dev/null +++ b/Info/Layer3/AlteonAD.pm @@ -0,0 +1,468 @@ +# SNMP::Info::Layer3::AlteonAD +# Eric Miller +# +# Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::Layer3::AlteonAD; +$VERSION = 0.9; + +use strict; + +use Exporter; +use SNMP::Info; +use SNMP::Info::Bridge; + +use vars qw/$VERSION $DEBUG %GLOBALS %FUNCS $INIT %MIBS %MUNGE /; + +@SNMP::Info::Layer3::AlteonAD::ISA = qw/SNMP::Info SNMP::Info::Bridge Exporter/; +@SNMP::Info::Layer3::AlteonAD::EXPORT_OK = qw//; + +$DEBUG=0; + +# See SNMP::Info for the details of these data structures and +# the interworkings. +$INIT = 0; + +%MIBS = ( + %SNMP::Info::MIBS, + %SNMP::Info::Bridge::MIBS, + 'ALTEON-TIGON-SWITCH-MIB' => 'agSoftwareVersion', + 'ALTEON-TS-PHYSICAL-MIB' => 'agPortTableMaxEnt', + 'ALTEON-TS-NETWORK-MIB' => 'agPortTableMaxEnt', + ); + +%GLOBALS = ( + %SNMP::Info::GLOBALS, + %SNMP::Info::Bridge::GLOBALS, + 'sw_ver' => 'agSoftwareVersion', + 'tftp_action' => 'agTftpAction', + 'tftp_host' => 'agTftpServer', + 'tftp_file' => 'agTftpCfgFileName', + 'tftp_result' => 'agTftpLastActionStatus', + ); + +%FUNCS = ( + %SNMP::Info::FUNCS, + %SNMP::Info::Bridge::FUNCS, + 'bp_index_2' => 'dot1dBasePortIfIndex', + 'i_name2' => 'ifName', + # From RFC1213-MIB + 'at_index' => 'ipNetToMediaIfIndex', + 'at_paddr' => 'ipNetToMediaPhysAddress', + 'at_netaddr' => 'ipNetToMediaNetAddress', + # From agPortCurCfgTable + 'ag_p_cfg_idx' => 'agPortCurCfgIndx', + 'ag_p_cfg_pref' => 'agPortCurCfgPrefLink', + 'ag_p_cfg_pvid' => 'agPortCurCfgPVID', + 'ag_p_cfg_fe_auto' => 'agPortCurCfgFastEthAutoNeg', + 'ag_p_cfg_fe_mode' => 'agPortCurCfgFastEthMode', + 'ag_p_cfg_ge_auto' => 'agPortCurCfgGigEthAutoNeg', + 'ag_p_cfg_name' => 'agPortCurCfgPortName', + # From portInfoTable + 'p_info_idx' => 'portInfoIndx', + 'p_info_mode' => 'portInfoMode', + # From portInfoTable + 'ip_cfg_vlan' => 'ipCurCfgIntfVlan', + ); + +%MUNGE = ( + %SNMP::Info::MUNGE, + %SNMP::Info::Bridge::MUNGE, + 'at_paddr' => \&SNMP::Info::munge_mac, + ); + +sub model { + my $alteon = shift; + my $desc = $alteon->description(); + return undef unless defined $desc; + + return 'AD2' if ($desc =~ /AD2/); + return 'AD3' if ($desc =~ /AD3/); + return 'AD4' if ($desc =~ /AD4/); + return '180' if ($desc =~ /180/); + return '183' if ($desc =~ /183/); + return '184' if ($desc =~ /184/); + + return $desc; +} + +sub vendor { + return 'nortel'; +} + +sub os { + return 'webos'; +} + +sub os_ver { + my $alteon = shift; + my $version = $alteon->sw_ver(); + return undef unless defined $version; + + return $version; +} + +sub interfaces { + my $alteon = shift; + my $interfaces = $alteon->i_index(); + my $descriptions = $alteon->i_description(); + + my %interfaces = (); + foreach my $iid (keys %$interfaces){ + my $desc = $descriptions->{$iid}; + next unless defined $desc; + + if ($desc =~ /(^net\d+)/) { + $desc = $1; + } + elsif (($iid > 256) and ($iid < 266)) { + $desc = ($iid % 256); + } + $interfaces{$iid} = $desc; + } + return \%interfaces; +} + +sub i_duplex { + my $alteon = shift; + + my $p_mode = $alteon->p_info_mode(); + + my %i_duplex; + foreach my $if (keys %$p_mode){ + my $duplex = $p_mode->{$if}; + next unless defined $duplex; + + $duplex = 'half' if $duplex =~ /half/i; + $duplex = 'full' if $duplex =~ /full/i; + + my $idx = $if + 256; + + $i_duplex{$idx}=$duplex; + } + return \%i_duplex; +} + +sub i_duplex_admin { + my $alteon = shift; + + my $ag_pref = $alteon->ag_p_cfg_pref(); + my $ag_fe_auto = $alteon->ag_p_cfg_fe_auto(); + my $ag_fe_mode = $alteon->ag_p_cfg_fe_mode(); + my $ag_ge_auto = $alteon->ag_p_cfg_ge_auto(); + + my %i_duplex_admin; + foreach my $if (keys %$ag_pref){ + my $pref = $ag_pref->{$if}; + next unless defined $pref; + + my $string = 'other'; + if ($pref =~ /gigabit/i) { + my $ge_auto = $ag_ge_auto->{$if}; + $string = 'full' if ($ge_auto =~ /off/i); + $string = 'auto' if ($ge_auto =~ /on/i); + } + elsif ($pref =~ /fast/i) { + my $fe_auto = $ag_fe_auto->{$if}; + my $fe_mode = $ag_fe_mode->{$if}; + $string = 'half' if ($fe_mode =~ /half/i and $fe_auto =~ /off/i); + $string = 'full' if ($fe_mode =~ /full/i and $fe_auto =~ /off/i); + $string = 'auto' if $fe_auto =~ /on/i; + } + my $idx = $if + 256; + + $i_duplex_admin{$idx}=$string; + } + return \%i_duplex_admin; +} + +sub i_vlan { + my $alteon = shift; + + my $ag_vlans = $alteon->ag_p_cfg_pvid(); + my $ip_vlans = $alteon->ip_cfg_vlan(); + + + my %i_vlan; + foreach my $if (keys %$ip_vlans){ + my $ip_vlanid = $ip_vlans->{$if}; + next unless defined $ip_vlanid; + + $i_vlan{$if}=$ip_vlanid; + } + foreach my $if (keys %$ag_vlans){ + my $ag_vlanid = $ag_vlans->{$if}; + next unless defined $ag_vlanid; + + my $idx = $if + 256; + $i_vlan{$idx}=$ag_vlanid; + } + return \%i_vlan; +} + +sub i_name { + my $alteon = shift; + my $p_name = $alteon->ag_p_cfg_name(); + + my %i_name; + foreach my $iid (keys %$p_name){ + my $name = $p_name->{$iid}; + next unless defined $name; + my $idx = $iid + 256; + $i_name{$idx} = $name; + } + return \%i_name; +} + +# Bridge MIB does not map Bridge Port to ifIndex correctly +sub bp_index { + my $alteon = shift; + my $b_index = $alteon->bp_index_2(); + + my %bp_index; + foreach my $iid (keys %$b_index){ + my $port = $b_index->{$iid}; + next unless defined $port; + $port = $port + 256; + + $bp_index{$iid} = $port; + } + return \%bp_index; +} + +sub root_ip { + my $alteon = shift; + my $ip_table = $alteon->ip_table(); + +# Return First IP Address + foreach my $entry (keys %$ip_table){ + my $router_ip = $ip_table->{$entry}; + print " SNMP::Layer3::AlteonAD::root_ip() using $router_ip\n" if $DEBUG; + next unless $router_ip; + return $router_ip if ($router_ip ne '0.0.0.0'); + } + return undef; +} + + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer3::AlteonAD - Perl5 Interface to Nortel Networks' Alteon Ace +Director Series Layer 2-7 Switches. + +=head1 AUTHOR + +Eric Miller (C) + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $alteon = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $alteon->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Abstraction subclass for Layer 2-7 load balancing switches running Nortel Networks' +Alteon Web OS Traffic Control Software. + +For speed or debugging purposes you can call the subclass directly, but not after +determining a more specific class using the method above. + + my $alteon = new SNMP::Info::Layer3::AlteonAD(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info + +=item SNMP::Info::Bridge + +=back + +=head2 Required MIBs + +=over + +=item ALTEON-TIGON-SWITCH-MIB + +=item ALTEON-TS-PHYSICAL-MIB + +=item ALTEON-TS-NETWORK-MIB + +MIBs can be found on the CD that came with your product. + +Or, they can be downloaded directly from Nortel Networks regardless of support +contract status. Go to http://www.nortelnetworks.com Techninal Support, +Browse Technical Support, Select by Product Families, Alteon, +Alteon Web OS Traffic Control Software, Software. Filter on mibs and download +the latest version's archive. + +=item Inherited Classes' MIBs + +See SNMP::Info for its own MIB requirements. + +See SNMP::Info::Bridge for its own MIB requirements. + +=back + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $alteon->model() + +Returns the model extracted from B + +=item $alteon->vendor() + +Returns 'Nortel' + +=item $alteon->os() + +Returns 'WebOS' + +=item $alteon->os_ver() + +Returns the software version reported by B + +=item $alteon->root_ip() + +Returns the primary IP used to communicate with the device. Currently returns +the first interfaces IP. + +=item $alteon->tftp_action() + +(B) + +=item $alteon->tftp_host() + +(B) + +=item $alteon->tftp_file() + +(B) + +=item $alteon->tftp_result() + +(B) + +=back + +=head2 Globals imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Globals imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head1 TABLE ENTRIES + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $alteon->interfaces() + +Returns reference to the map between IID and physical port. + +Utilizes description for network interfaces. Ports are determined by +formula (ifIndex mod 256). + +=item $alteon->i_duplex() + +Returns reference to hash. Maps port operational duplexes to IIDs. + +=item $alteon->i_duplex_admin() + +Returns reference to hash. Maps port admin duplexes to IIDs. + +=item $alteon->i_vlan() + +Returns reference to hash. Maps port VLAN ID to IIDs. + +=item $alteon->i_name() + +Maps (B) to port and returns the human set port name if exists. + +=item $alteon->bp_index() + +Returns a mapping between ifIndex and the Bridge Table. + +=back + +=head2 RFC1213 Arp Cache Table (B) + +=over + +=item $alteon->at_index() + +Returns reference to hash. Maps ARP table entries to Interface IIDs + +(B) + +=item $alteon->at_paddr() + +Returns reference to hash. Maps ARP table entries to MAC addresses. + +(B) + +=item $alteon->at_netaddr() + +Returns reference to hash. Maps ARP table entries to IPs + +(B) + +=back + +=head2 Table Methods imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Table Methods imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=cut diff --git a/Info/Layer3/BayRS.pm b/Info/Layer3/BayRS.pm new file mode 100644 index 00000000..0e39b30e --- /dev/null +++ b/Info/Layer3/BayRS.pm @@ -0,0 +1,551 @@ +# SNMP::Info::Layer3::BayRS +# Eric Miller +# +# Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. +# +# Copyright (c) 2002,2003 Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::Layer3::BayRS; +$VERSION = 0.9; + +use strict; + +use Exporter; +use SNMP::Info; +use SNMP::Info::Bridge; + +use vars qw/$VERSION $DEBUG %GLOBALS %FUNCS $INIT %MIBS %MUNGE %MODEL_MAP/; + +@SNMP::Info::Layer3::BayRS::ISA = qw/SNMP::Info SNMP::Info::Bridge Exporter/; +@SNMP::Info::Layer3::BayRS::EXPORT_OK = qw//; + +$DEBUG=0; + +# See SNMP::Info for the details of these data structures and +# the interworkings. +$INIT = 0; + +%MIBS = ( + %SNMP::Info::MIBS, + %SNMP::Info::Bridge::MIBS, + 'Wellfleet-HARDWARE-MIB' => 'wfHwBpIdOpt', + 'Wellfleet-OSPF-MIB' => 'wfOspfRouterId', + 'Wellfleet-DOT1QTAG-CONFIG-MIB' => 'wfDot1qTagCfgVlanName', + 'Wellfleet-CSMACD-MIB' => 'wfCSMACDCct', + ); + +%GLOBALS = ( + %SNMP::Info::GLOBALS, + %SNMP::Info::Bridge::GLOBALS, + 'bp_id' => 'wfHwBpIdOpt', + 'bp_serial' => 'wfHwBpSerialNumber', + 'ospf_rtr_id' => 'wfOspfRouterId', + ); + +%FUNCS = ( + %SNMP::Info::FUNCS, + %SNMP::Info::Bridge::FUNCS, + 'i_name2' => 'ifName', + # From RFC1213-MIB + 'at_index' => 'ipNetToMediaIfIndex', + 'at_paddr' => 'ipNetToMediaPhysAddress', + 'at_netaddr' => 'ipNetToMediaNetAddress', + # From Wellfleet-CSMACD-MIB::wfCSMACDTable + 'wf_csmacd_cct' => 'wfCSMACDCct', + 'wf_csmacd_slot' => 'wfCSMACDSlot', + 'wf_csmacd_conn' => 'wfCSMACDConnector', + 'wf_csmacd_mtu' => 'wfCSMACDMtu', + 'wf_duplex' => 'wfCSMACDLineCapability', + 'wf_csmacd_line' => 'wfCSMACDLineNumber', + # From Wellfleet-CSMACD-MIB::wfCSMACDAutoNegTable + 'wf_auto' => 'wfCSMACDAutoNegSpeedSelect', + # From Wellfleet-DOT1QTAG-CONFIG-MIB::wfDot1qTagConfigTable + 'wf_vlan_name' => 'wfDot1qTagCfgVlanName', + 'wf_local_vlan_id' => 'wfDot1qTagCfgLocalVlanId', + 'wf_global_vlan_id' => 'wfDot1qTagCfgGlobalVlanId', + 'wf_vlan_port' => 'wfDot1qTagCfgPhysicalPortId', + # From Wellfleet-HARDWARE-MIB::wfHwTable + 'wf_hw_slot' => 'wfHwSlot', + 'wf_hw_mod_id' => 'wfHwModIdOpt', + 'wf_hw_mod_rev' => 'wfHwModRev', + 'wf_hw_mod_ser' => 'wfHwModSerialNumber', + 'wf_hw_mobo_id' => 'wfHwMotherBdIdOpt ', + 'wf_hw_mobo_rev' => 'wfHwMotherBdRev', + 'wf_hw_mobo_ser' => 'wfHwMotherBdSerialNumber', + 'wf_hw_diag' => 'wfHwDiagPromRev', + 'wf_hw_boot' => 'wfHwBootPromRev', + 'wf_hw_mobo_mem' => 'wfHwMotherBdMemorySize', + 'wf_hw_cfg_time' => 'wfHwConfigDateAndTime ', + ); + +%MUNGE = ( + %SNMP::Info::MUNGE, + %SNMP::Info::Bridge::MUNGE, + 'at_paddr' => \&SNMP::Info::munge_mac, + ); + +%MODEL_MAP = ( + 'acefn' => 'FN', + 'aceln' => 'LN', + 'acecn' => 'CN', + 'afn' => 'AFN', + 'in' => 'IN', + 'an' => 'AN', + 'arn' => 'ARN', + 'sys5000' => '5000', + 'freln' => 'BLN', + 'frecn' => 'BCN', + 'frerbln' => 'BLN-2', + 'asn' => 'ASN', + 'asnzcable' => 'ASN-Z', + 'asnbcable' => 'ASN-B', + ); + +sub model { + my $bayrs = shift; + my $bp_id = $bayrs->bp_id(); + + return defined $MODEL_MAP{$bp_id} ? $MODEL_MAP{$bp_id} : $bp_id; +} + +sub vendor { + return 'nortel'; +} + +sub os { + return 'bayrs'; +} + +sub os_ver { + my $bayrs = shift; + my $descr = $bayrs->description(); + return undef unless defined $descr; + + if ($descr =~ m/rel\/(\d+\.\d+\.\d+\.\d+)/){ + return $1; + } + return undef; +} + +sub serial { + my $bayrs = shift; + my $serialnum = $bayrs->bp_serial(); + $serialnum = hex(join('','0x',map{sprintf "%02X", $_}unpack("C*",$serialnum))); + + return $serialnum if defined $serialnum ; + return undef; +} + +sub interfaces { + my $bayrs = shift; + my $description = $bayrs->i_description(); + my $vlan_ids = $bayrs->wf_global_vlan_id(); + my $vlan_idx = $bayrs->wf_local_vlan_id(); + + my %interfaces = (); + foreach my $iid (keys %$description){ + my $desc = $description->{$iid}; + next unless defined $desc; + + $desc = $1 if $desc =~ /(^[A-Z]\d+)/; + + $interfaces{$iid} = $desc; + } + foreach my $iid (keys %$vlan_ids){ + my $vlan = $vlan_ids->{$iid}; + next unless defined $vlan; + my $vlan_if = $vlan_idx->{$iid}; + next unless defined $vlan_if; + + my $desc = 'V' . $vlan; + + $interfaces{$vlan_if} = $desc; + } + return \%interfaces; +} + +sub i_name { + my $bayrs = shift; + my $i_index = $bayrs->i_index(); + my $description = $bayrs->i_description(); + my $v_name = $bayrs->wf_vlan_name(); + my $vlan_idx = $bayrs->wf_local_vlan_id(); + + my %i_name; + foreach my $iid (keys %$description){ + my $name = $description->{$iid}; + next unless defined $name; + $i_name{$iid} = $name; + } + # Get VLAN Virtual Router Interfaces + foreach my $vid (keys %$v_name){ + my $v_name = $v_name->{$vid}; + next unless defined $v_name; + my $vlan_if = $vlan_idx->{$vid}; + next unless defined $vlan_if; + + $i_name{$vlan_if} = $v_name; + } + return \%i_name; +} + +sub i_duplex { + my $bayrs = shift; + + my $wf_cct = $bayrs->wf_csmacd_cct(); + my $wf_duplex = $bayrs->wf_duplex(); + + my %i_duplex; + foreach my $if (keys %$wf_cct){ + my $idx = $wf_cct->{$if}; + next unless defined $idx; + my $duplex = $wf_duplex->{$if}; + next unless defined $duplex; + + my $string = 'half'; + $string = 'full' if $duplex =~ /duplex/i; + + $i_duplex{$idx}=$string; + } + return \%i_duplex; +} + +sub i_duplex_admin { + my $bayrs = shift; + + my $wf_cct = $bayrs->wf_csmacd_cct(); + my $wf_duplex = $bayrs->wf_duplex(); + my $wf_auto = $bayrs->wf_auto(); + my $wf_slot = $bayrs->wf_csmacd_slot(); + my $wf_conn = $bayrs->wf_csmacd_conn(); + + my %i_duplex_admin; + foreach my $if (keys %$wf_cct){ + my $idx = $wf_cct->{$if}; + next unless defined $idx; + my $duplex = $wf_duplex->{$if}; + next unless defined $duplex; + my $slot = $wf_slot->{$if}; + my $conn = $wf_conn->{$if}; + my $auto_idx = "$slot.$conn"; + my $auto = $wf_auto->{$auto_idx}; + + my $string = 'other'; + if ($auto) { + $string = 'half'; + $string = 'full' if $auto =~ /duplex/i; + $string = 'auto' if $auto =~ /nway/i; + } + elsif ($duplex) { + $string = 'half'; + $string = 'full' if $duplex =~ /duplex/i; + } + + $i_duplex_admin{$idx}=$string; + } + return \%i_duplex_admin; +} + +sub i_vlan { + my $bayrs = shift; + + my $wf_cct = $bayrs->wf_csmacd_cct(); + my $wf_mtu = $bayrs->wf_csmacd_mtu(); + my $wf_line = $bayrs->wf_csmacd_line(); + my $wf_local_vid = $bayrs->wf_local_vlan_id(); + my $wf_global_vid = $bayrs->wf_global_vlan_id(); + my $wf_vport = $bayrs->wf_vlan_port(); + + my %i_vlan; + # Look for VLANs on Ethernet Interfaces + foreach my $if (keys %$wf_cct){ + my $idx = $wf_cct->{$if}; + next unless defined $idx; + # Check MTU size, if unable to carry VLAN tag skip. + my $mtu = $wf_mtu->{$if}; + next if (($mtu =~ /default/i) or ($mtu < 1522)); + my $line = $wf_line->{$if}; + my @vlans = (); + foreach my $v_idx (keys %$wf_vport){ + my $port = $wf_vport->{$v_idx}; + next unless defined $port; + next if ($port != $line); + + my $vlan = $wf_global_vid->{$v_idx}; + push(@vlans, $vlan); + } + my $vlans = join (',', @vlans); + $i_vlan{$idx}=$vlans; + } + # Add VLAN on VLAN Interfaces + foreach my $idx (keys %$wf_global_vid){ + my $v_if = $wf_local_vid->{$idx}; + next unless defined $v_if; + my $vlan = $wf_global_vid->{$idx}; + next unless defined $vlan; + + $i_vlan{$v_if}=$vlan; + } + return \%i_vlan; +} + +sub root_ip { + my $bayrs = shift; + + my $ip_index = $bayrs->ip_index(); + my $ip_table = $bayrs->ip_table(); + + # Check for CLIP + foreach my $entry (keys %$ip_index){ + my $idx = $ip_index->{$entry}; + next unless $idx == 0; + my $clip = $ip_table->{$entry}; + next unless ((defined $clip) and ($clip eq '0.0.0.0')); + print " SNMP::Layer3::BayRS::root_ip() using $clip\n" if $DEBUG; + return $clip; + } + # Check for OSPF Router ID + my $ospf_ip = $bayrs->ospf_rtr_id(); + if ((defined $ospf_ip) and ($ospf_ip ne '0.0.0.0')) { + print " SNMP::Layer3::BayRS::root_ip() using $ospf_ip\n" if $DEBUG; + return $ospf_ip; + } + # Else Return First IP Address + foreach my $entry (keys %$ip_table){ + my $ip = $ip_table->{$entry}; + print " SNMP::Layer3::BayRS::root_ip() using $ip\n" if $DEBUG; + next unless $ip; + return $ip if ($ip ne '0.0.0.0'); + } + return undef; +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer3::BayRS - Perl5 Interface to Nortel Networks' routers running BayRS. + +=head1 AUTHOR + +Eric Miller (C) + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $bayrs = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $bayrs->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Abstraction subclass for routers running Nortel Networks' BayRS. + +For speed or debugging purposes you can call the subclass directly, but not after determining +a more specific class using the method above. + + my $bayrs = new SNMP::Info::Layer3::BayRS(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info + +=item SNMP::Info::Bridge + +=back + +=head2 Required MIBs + +=over + +=item Wellfleet-HARDWARE-MIB + +=item Wellfleet-OSPF-MIB + +=item Wellfleet-DOT1QTAG-CONFIG-MIB + +=item Wellfleet-CSMACD-MIB + +=item Inherited Classes' MIBs + +See SNMP::Info for its own MIB requirements. + +See SNMP::Info::Bridge for its own MIB requirements. + +MIBs can be found on the CD that came with your product. + +Or, they can be downloaded directly from Nortel Networks regardless of support +contract status. Go to http://www.nortelnetworks.com Techninal Support, Browse +Technical Support, Select by Product Families, BayRS Router Software, +Router Software v 15.x, Software. Filter on mibs and download the latest +version's archive. + +=back + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $bayrs->model() + +Returns the model of the BayRS router. Will translate between the MIB model and +the common model with this map : + +%MODEL_MAP = ( + 'acefn' => 'FN', + 'aceln' => 'LN', + 'acecn' => 'CN', + 'afn' => 'AFN', + 'in' => 'IN', + 'an' => 'AN', + 'arn' => 'ARN', + 'sys5000' => '5000', + 'freln' => 'BLN', + 'frecn' => 'BCN', + 'frerbln' => 'BLN-2', + 'asn' => 'ASN', + 'asnzcable' => 'ASN-Z', + 'asnbcable' => 'ASN-B', + ); + +=item $bayrs->vendor() + +Returns 'Nortel' + +=item $bayrs->os() + +Returns 'BayRS' + +=item $bayrs->os_ver() + +Returns the software version extracted from B + +=item $bayrs->serial() + +Returns (B) after conversion to ASCII decimal + +=item $bayrs->root_ip() + +Returns the primary IP used to communicate with the router. + +Returns the first found: CLIP (CircuitLess IP), (B), or the first +IP interface. + +=back + +=head2 Globals imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Globals imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head1 TABLE ENTRIES + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $bayrs->interfaces() + +Returns reference to the map between IID and physical Port. + +The physical port name is stripped to letter and numbers to signify +port type and slot port (S11) if the default platform naming was +maintained. Otherwise the port is the interface description. + +=item $bayrs->i_name() + +Returns (B) along with VLAN name (B) for VLAN +interfaces. + +=item $bayrs->i_duplex() + +Returns reference to hash. Maps port operational duplexes to IIDs for Ethernet +interfaces. + +=item $bayrs->i_duplex_admin() + +Returns reference to hash. Maps port admin duplexes to IIDs for Ethernet interfaces. + +=item $bayrs->i_vlan() + +Returns reference to hash. Maps port VLAN ID to IIDs. + +=back + +=head2 RFC1213 Arp Cache Table (B) + +=over + +=item $bayrs->at_index() + +Returns reference to hash. Maps ARP table entries to Interface IIDs + +(B) + +=item $bayrs->at_paddr() + +Returns reference to hash. Maps ARP table entries to MAC addresses. + +(B) + +=item $bayrs->at_netaddr() + +Returns reference to hash. Maps ARP table entries to IPs + +(B) + +=back + +=head2 Table Methods imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Table Methods imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=cut diff --git a/Info/Layer3/Contivity.pm b/Info/Layer3/Contivity.pm new file mode 100644 index 00000000..0e283434 --- /dev/null +++ b/Info/Layer3/Contivity.pm @@ -0,0 +1,348 @@ +# SNMP::Info::Layer3::Contivity +# Eric Miller +# +# Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. +# +# Copyright (c) 2002,2003 Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::Layer3::Contivity; +$VERSION = 0.9; + +use strict; + +use Exporter; +use SNMP::Info; +use SNMP::Info::Entity; + +use vars qw/$VERSION $DEBUG %GLOBALS %FUNCS $INIT %MIBS %MUNGE/; + +@SNMP::Info::Layer3::Contivity::ISA = qw/SNMP::Info SNMP::Info::Entity Exporter/; +@SNMP::Info::Layer3::Contivity::EXPORT_OK = qw//; + +$DEBUG=0; + +# See SNMP::Info for the details of these data structures and +# the interworkings. +$INIT = 0; + +%MIBS = ( + %SNMP::Info::MIBS, + %SNMP::Info::Entity::MIBS, + ); + +%GLOBALS = ( + %SNMP::Info::GLOBALS, + %SNMP::Info::Entity::GLOBALS, + ); + +%FUNCS = ( + %SNMP::Info::FUNCS, + %SNMP::Info::Entity::FUNCS, + 'i_name2' => 'ifName', + # From RFC1213-MIB + 'at_index' => 'ipNetToMediaIfIndex', + 'at_paddr' => 'ipNetToMediaPhysAddress', + 'at_netaddr' => 'ipNetToMediaNetAddress', + ); + +%MUNGE = ( + %SNMP::Info::MUNGE, + %SNMP::Info::Entity::MUNGE, + 'at_paddr' => \&SNMP::Info::munge_mac, + ); + +sub layers { + return '00000100'; +} + +sub vendor { + return 'nortel'; +} + +sub model { + my $contivity = shift; + my $e_model = $contivity->e_model() || {}; + + my $model = $e_model->{1} || undef; + + return $1 if (defined $model and $model =~ /(CES\d+)/i); + return undef; +} + +sub os { + return 'contivity'; +} + +sub os_ver { + my $contivity = shift; + my $descr = $contivity->description(); + return undef unless defined $descr; + + if ($descr =~ m/V(\d+_\d+\.\d+)/i){ + return $1; + } + return undef; +} + +sub mac { + my $contivity = shift; + my $i_mac = $contivity->i_mac(); + +# Return Interface MAC + foreach my $entry (keys %$i_mac){ + my $sn = $i_mac->{$entry}; + next unless $sn; + return $sn; + } + return undef; +} + +sub serial { + my $contivity = shift; + my $e_serial = $contivity->e_serial() || {}; + + my $serial = $e_serial->{1} || undef; + + return $1 if (defined $serial and $serial =~ /(\d+)/); + return undef; +} + + +sub interfaces { + my $contivity = shift; + my $description = $contivity->i_description(); + + my %interfaces = (); + foreach my $iid (keys %$description){ + my $desc = $description->{$iid}; + # Skip everything except Ethernet interfaces + next unless (defined $desc and $desc =~ /fe/i); + + $interfaces{$iid} = $desc; + } + return \%interfaces; +} + +sub i_name { + my $contivity = shift; + my $i_name2 = $contivity->i_name2(); + + my %i_name; + foreach my $iid (keys %$i_name2){ + my $name = $i_name2->{$iid}; + #Skip everything except Ethernet interfaces + next unless (defined $name and $name =~ /fe/i); + + $name = $1 if $name =~ /(fei\.\d+\.\d+)/; + + $i_name{$iid} = $name; + } + return \%i_name; +} + +sub root_ip { + my $contivity = shift; + my $ip_table = $contivity->ip_table(); + +# Return First IP Address + foreach my $entry (keys %$ip_table){ + my $router_ip = $ip_table->{$entry}; + print " SNMP::Layer3::Contivity::root_ip() using $router_ip\n" if $DEBUG; + next unless $router_ip; + return $router_ip if ($router_ip ne '0.0.0.0'); + } + return undef; +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer3::Contivity - Perl5 Interface to Nortel Networks' Contivity +Extranet Switches (CES). + +=head1 AUTHOR + +Eric Miller (C) + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $contivity = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $contivity->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Abstraction subclass for Nortel Networks' Contivity Extranet Switch (CES). + +For speed or debugging purposes you can call the subclass directly, but not after determining +a more specific class using the method above. + + my $contivity = new SNMP::Info::Layer3::Contivity(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info + +=item SNMP::Info::Entity + +=back + +=head2 Required MIBs + +=over + +=item Inherited Classes' MIBs + +See SNMP::Info for its own MIB requirements. + +See SNMP::Info::Entity for its own MIB requirements. + +=back + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $contivity->vendor() + +Returns 'Nortel' + +=item $contivity->model() + +Returns the chassis name. + +(B) + +=item $contivity->os() + +Returns 'CES' + +=item $contivity->os_ver() + +Returns the software version extracted from (B). + +=item $contivity->serial() + +Returns the chassis serial number. + +(B) + +=item $contivity->mac() + +Returns the MAC address of the first Ethernet Interface. + +=item $contivity->root_ip() + +Returns the primary IP used to communicate with the router. Returns the first +IP interface. + +=back + +=head2 Overrides + +=over + +=item $contivity->layers() + +Returns 00000100. Contivity does not support bridge MIB, so override reported +layers. + +=back + +=head2 Globals imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Globals imported from SNMP::Info::Entity + +See documentation in SNMP::Info::Entity for details. + +=head1 TABLE ENTRIES + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $contivity->interfaces() + +Returns reference to the map between IID and physical Port. Skips loopback and +tunnel interfaces. + +=back + +=head2 RFC1213 Arp Cache Table (B) + +=over + +=item $contivity->at_index() + +Returns reference to hash. Maps ARP table entries to Interface IIDs + +(B) + +=item $contivity->at_paddr() + +Returns reference to hash. Maps ARP table entries to MAC addresses. + +(B) + +=item $contivity->at_netaddr() + +Returns reference to hash. Maps ARP table entries to IPs + +(B) + +=back + +=head2 Table Methods imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Table Methods imported from SNMP::Info::Entity + +See documentation in SNMP::Info::Entity for details. + +=cut diff --git a/Info/Layer3/Passport.pm b/Info/Layer3/Passport.pm new file mode 100644 index 00000000..3f8e464f --- /dev/null +++ b/Info/Layer3/Passport.pm @@ -0,0 +1,654 @@ +# SNMP::Info::Layer3::Passport +# Eric Miller +# +# Copyright (c) 2004 Max Baker changes from version 0.8 and beyond. +# +# Copyright (c) 2002,2003 Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::Layer3::Passport; +$VERSION = 0.9; + +use strict; + +use Exporter; +use SNMP::Info; +use SNMP::Info::Bridge; +use SNMP::Info::SONMP; +use SNMP::Info::RapidCity; + +use vars qw/$VERSION $DEBUG %GLOBALS %FUNCS $INIT %MIBS %MUNGE/; + +@SNMP::Info::Layer3::Passport::ISA = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::SONMP SNMP::Info::RapidCity Exporter/; +@SNMP::Info::Layer3::Passport::EXPORT_OK = qw//; + +$DEBUG=0; + +# See SNMP::Info for the details of these data structures and +# the interworkings. + +$INIT = 0; + +%MIBS = ( + %SNMP::Info::MIBS, + %SNMP::Info::Bridge::MIBS, + %SNMP::Info::SONMP::MIBS, + %SNMP::Info::RapidCity::MIBS, + 'OSPF-MIB' => 'ospfRouterId', + ); + +%GLOBALS = ( + %SNMP::Info::GLOBALS, + %SNMP::Info::Bridge::GLOBALS, + %SNMP::Info::SONMP::GLOBALS, + %SNMP::Info::RapidCity::GLOBALS, + 'router_ip' => 'ospfRouterId' + ); + +%FUNCS = ( + %SNMP::Info::FUNCS, + %SNMP::Info::Bridge::FUNCS, + %SNMP::Info::SONMP::FUNCS, + %SNMP::Info::RapidCity::FUNCS, + 'i_index2' => 'ifIndex', + 'i_mac2' => 'ifPhysAddress', + 'i_description2' => 'ifDescr', + 'i_name2' => 'ifName', + 'ip_index2' => 'ipAdEntIfIndex', + # From RFC1213-MIB + 'at_index' => 'ipNetToMediaIfIndex', + 'at_paddr' => 'ipNetToMediaPhysAddress', + 'at_netaddr' => 'ipNetToMediaNetAddress', + 'i_name2' => 'ifName' + ); + +%MUNGE = ( + %SNMP::Info::MUNGE, + %SNMP::Info::Bridge::MUNGE, + %SNMP::Info::SONMP::MUNGE, + %SNMP::Info::RapidCity::MUNGE, + 'i_mac2' => \&SNMP::Info::munge_mac, + 'at_paddr' => \&SNMP::Info::munge_mac, + ); + +sub model { + my $passport = shift; + my $desc = $passport->description(); + return undef unless defined $desc; + + return '8603' if ($desc =~ /8603/); + return '8606' if ($desc =~ /8606/); + return '8610co' if ($desc =~ /8610co/); + return '8610' if ($desc =~ /8610/); + + return $desc; +} + +sub vendor { + return 'nortel'; +} + +sub os { + return 'passport'; +} + +sub os_ver { + my $passport = shift; + my $descr = $passport->description(); + return undef unless defined $descr; + + if ($descr =~ m/(\d+\.\d+\.\d+\.\d+)/){ + return $1; + } + return undef; +} + +sub i_index { + my $passport = shift; + my $i_index = $passport->i_index2(); + my $vlan_index = $passport->rc_vlan_if(); + my $cpu_index = $passport->rc_cpu_ifindex(); + my $virt_ip = $passport->rc_virt_ip(); + + my %if_index; + foreach my $iid (keys %$i_index){ + my $index = $i_index->{$iid}; + next unless defined $index; + + $if_index{$iid} = $index; + } + + # Get VLAN Virtual Router Interfaces + foreach my $vid (keys %$vlan_index){ + my $v_index = $vlan_index->{$vid}; + next unless defined $v_index; + next if $v_index == 0; + + $if_index{$v_index} = $v_index; + } + + # Get CPU Ethernet Interfaces + foreach my $cid (keys %$cpu_index){ + my $c_index = $cpu_index->{$cid}; + next unless defined $c_index; + next if $c_index == 0; + + $if_index{$c_index} = $c_index; + } + + # Check for Virtual Mgmt Interface + unless ($virt_ip eq '0.0.0.0') { + # Make up an index number, 1 is not reserved AFAIK + $if_index{1} = 1; + } + + return \%if_index; +} + +sub interfaces { + my $passport = shift; + my $i_index = $passport->i_index(); + my $vlan_id = $passport->rc_vlan_id(); + my $vlan_index = $passport->rc_vlan_if(); + my $model = $passport->model(); + + my %reverse_vlan = reverse %$vlan_index; + + my %if; + foreach my $iid (keys %$i_index){ + my $index = $i_index->{$iid}; + next unless defined $index; + + if ($index == 1) { + $if{$index} = 'CPU.Virtual'; + } + + elsif (($index == 192) and ($model eq '8603')) { + $if{$index} = 'CPU3'; + } + + elsif ($index == 320) { + $if{$index} = 'CPU5'; + } + + elsif ($index == 384) { + $if{$index} = 'CPU6'; + } + + elsif ($index > 2000) { + my $vlan_index = $reverse_vlan{$iid}; + my $v_id = $vlan_id->{$vlan_index}; + next unless defined $v_id; + + my $v_port = 'V'."$v_id"; + $if{$index} = $v_port; + } + + else { + my $port = ($index % 64) + 1; + my $slot = int($index / 64); + + my $slotport = "$slot.$port"; + $if{$iid} = $slotport; + } + + } + return \%if; +} + +sub i_mac { + my $passport = shift; + my $i_mac = $passport->i_mac2(); + my $vlan_mac = $passport->rc_vlan_mac(); + my $vlan_index = $passport->rc_vlan_if(); + my $cpu_mac = $passport->rc_cpu_mac(); + my $chassis_base_mac = $passport->rc_base_mac(); + my $virt_ip = $passport->rc_virt_ip(); + + my %if_mac; + foreach my $iid (keys %$i_mac){ + my $mac = $i_mac->{$iid}; + next unless defined $mac; + + $if_mac{$iid} = $mac; + } + + # Get VLAN Virtual Router Interfaces + foreach my $iid (keys %$vlan_mac){ + my $v_mac = $vlan_mac->{$iid}; + my $v_id = $vlan_index->{$iid}; + next unless defined $v_mac; + + $if_mac{$v_id} = $v_mac; + } + + # Get CPU Ethernet Interfaces + foreach my $iid (keys %$cpu_mac){ + my $mac = $cpu_mac->{$iid}; + next unless defined $mac; + + $if_mac{$iid} = $mac; + } + + # Check for Virtual Mgmt Interface + unless ($virt_ip eq '0.0.0.0'){ + my @virt_mac = split /:/, $chassis_base_mac; + $virt_mac[0] = hex($virt_mac[0]); + $virt_mac[1] = hex($virt_mac[1]); + $virt_mac[2] = hex($virt_mac[2]); + $virt_mac[3] = hex($virt_mac[3]); + $virt_mac[4] = hex($virt_mac[4]) + 0x03; + $virt_mac[5] = hex($virt_mac[5]) + 0xF8; + + my $mac = join(':',map { sprintf "%02x",$_ } @virt_mac); + + $if_mac{1} = $mac; + } + + return \%if_mac; +} + +sub i_description { + my $passport = shift; + my $i_descr = $passport->i_description2(); + my $v_descr = $passport->rc_vlan_name(); + my $vlan_index = $passport->rc_vlan_if(); + + my %descr; + foreach my $iid (keys %$i_descr){ + my $if_descr = $i_descr->{$iid}; + next unless defined $if_descr; + + $descr{$iid} = $if_descr; + } + + # Get VLAN Virtual Router Interfaces + foreach my $vid (keys %$v_descr){ + my $vl_descr = $v_descr->{$vid}; + my $v_id = $vlan_index->{$vid}; + next unless defined $vl_descr; + + $descr{$v_id} = $vl_descr; + } + return \%descr; +} + +sub i_name { + my $passport = shift; + my $i_index = $passport->i_index(); + my $rc_alias = $passport->rc_alias(); + my $i_name2 = $passport->i_name2(); + my $v_name = $passport->rc_vlan_name(); + my $vlan_index = $passport->rc_vlan_if(); + my $model = $passport->model(); + + my %reverse_vlan = reverse %$vlan_index; + + my %i_name; + foreach my $iid (keys %$i_index){ + + if ($iid == 1) { + $i_name{$iid} = 'CPU Virtual Management IP'; + } + + elsif (($iid == 192) and ($model eq '8603')) { + $i_name{$iid} = 'CPU 3 Ethernet Port'; + } + + elsif ($iid == 320) { + $i_name{$iid} = 'CPU 5 Ethernet Port'; + } + + elsif ($iid == 384) { + $i_name{$iid} = 'CPU 5 Ethernet Port'; + } + + elsif ($iid > 2000) { + my $vlan_index = $reverse_vlan{$iid}; + my $vlan_name = $v_name->{$vlan_index}; + next unless defined $vlan_name; + + $i_name{$iid} = $vlan_name; + } + + else { + my $name = $i_name2->{$iid}; + my $alias = $rc_alias->{$iid}; + $i_name{$iid} = (defined $alias and $alias !~ /^\s*$/) ? + $alias : + $name; + } + } + + return \%i_name; +} + +sub ip_index { + my $passport = shift; + my $ip_index = $passport->ip_index2(); + my $cpu_ip = $passport->rc_cpu_ip(); + my $virt_ip = $passport->rc_virt_ip(); + + my %ip_index; + foreach my $ip (keys %$ip_index){ + my $iid = $ip_index->{$ip}; + next unless defined $iid; + + $ip_index{$ip} = $iid; + } + + # Get CPU Ethernet IP + foreach my $cid (keys %$cpu_ip){ + my $c_ip = $cpu_ip->{$cid}; + next unless defined $c_ip; + + $ip_index{$c_ip} = $cid; + } + + # Get Virtual Mgmt IP + $ip_index{$virt_ip} = 1; + + return \%ip_index; +} + +sub root_ip { + my $passport = shift; + my $rc_ip_addr = $passport->rc_ip_addr(); + my $rc_ip_type = $passport->rc_ip_type(); + my $virt_ip = $passport->rc_virt_ip(); + my $router_ip = $passport->router_ip(); + my $sonmp_topo_port = $passport->sonmp_topo_port(); + my $sonmp_topo_ip = $passport->sonmp_topo_ip(); + + # Return CLIP (CircuitLess IP) + foreach my $iid (keys %$rc_ip_type){ + my $ip_type = $rc_ip_type->{$iid}; + next unless ((defined $ip_type) and ($ip_type =~ /circuitLess/i)); + my $ip = $rc_ip_addr->{$iid}; + next unless defined $ip; + + return $ip; + } + + # Return Management Virtual IP address + return $virt_ip if ((defined $virt_ip) and ($virt_ip ne '0.0.0.0')); + + # Return OSPF Router ID + return $router_ip if ((defined $router_ip) and ($router_ip ne '0.0.0.0')); + + # Otherwise Return SONMP Advertised IP Address + foreach my $entry (keys %$sonmp_topo_port){ + my $port = $sonmp_topo_port->{$entry}; + next unless $port == 0; + my $ip = $sonmp_topo_ip->{$entry}; + return $ip if ((defined $ip) and ($ip ne '0.0.0.0')); + } + return undef; +} + +# Required for SNMP::Info::SONMP +sub index_factor { + return 64; +} + +sub slot_offset { + return 0; +} + +sub port_offset { + return 1; +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer3::Passport - Perl5 Interface to Nortel Networks' Passport +8600 Series Switches + +=head1 AUTHOR + +Eric Miller (C) + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $passport = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $passport->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Abstraction subclass for Nortel Networks' Passport 8600 Series Switches. + +These devices run Passport OS but have some of the same charactersitics as the Baystack family. +For example, extended interface information is gleened from RAPID-CITY. + +For speed or debugging purposes you can call the subclass directly, but not after determining +a more specific class using the method above. + + my $passport = new SNMP::Info::Layer3::Passport(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info + +=item SNMP::Info::Bridge + +=item SNMP::Info::SONMP + +=item SNMP::Info::RapidCity + +=back + +=head2 Required MIBs + +=over + +=item OSPF-MIB + +=item Inherited Classes' MIBs + +See SNMP::Info for its own MIB requirements. + +See SNMP::Info::Bridge for its own MIB requirements. + +See SNMP::Info::SONMP for its own MIB requirements. + +See SNMP::Info::RapidCity for its own MIB requirements. + +OSPF-MIB is included in the archive at ftp://ftp.cisco.com/pub/mibs/v2/v2.tar.gz + +=back + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $passport->model() + +Returns the model extracted from B + +=item $passport->vendor() + +Returns 'Nortel' + +=item $passport->os() + +Returns 'Passport' + +=item $passport->os_ver() + +Returns the software version extracted from B + +=item $passport->serial() + +Returns (B) + +=item $passport->root_ip() + +Returns the primary IP used to communicate with the device. Returns the first +found: CLIP (CircuitLess IP), Management Virtual IP (B), +OSPF Router ID (B), SONMP Advertised IP Address. + +=back + +=head2 Overrides + +=over + +=item $passport->index_factor() + +Required by SNMP::Info::SONMP. Returns 64. + +=item $passport->port_offset() + +Required by SNMP::Info::SONMP. Returns 1. + +=item $passport->slot_offset() + +Required by SNMP::Info::SONMP. Returns 0. + +=back + +=head2 Globals imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Globals imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Global Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=head2 Global Methods imported from SNMP::Info::RapidCity + +See documentation in SNMP::Info::RapidCity for details. + +=head1 TABLE ENTRIES + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $passport->i_index() + +Returns SNMP IID to Interface index. Extends (B) by adding the index of +the CPU virtual management IP (if present), each CPU Ethernet port, and each VLAN +to ensure the virtual router ports are captured. + +=item $passport->interfaces() + +Returns reference to the map between IID and physical Port. + +Slot and port numbers on the Passport switches are determined by the formula: +port = (ifIndex % 64) + 1, slot = int(ifIndex / 64). + +The physical port name is returned as slot.port. CPU Ethernet ports are prefixed +with CPU and VLAN interfaces are returned as the VLAN ID prefixed with V. + +=item $passport->i_mac() + +MAC address of the interface. Note this is just the MAC of the port, not anything +connected to it. + +=item $passport->i_description() + +Description of the interface. Usually a little longer single word name that is both +human and machine friendly. Not always. + +=item $passport->i_name() + +Crosses rc_alias() (B) with ifAlias() and returns the human set port +name if exists. + +=item $passport->ip_index() + +Maps the IP Table to the IID. Extends (B) by adding the index of +the CPU virtual management IP (if present) and each CPU Ethernet port. + +=back + +=head2 RFC1213 Arp Cache Table (B) + +=over + +=item $passport->at_index() + +Returns reference to hash. Maps ARP table entries to Interface IIDs + +(B) + +=item $passport->at_paddr() + +Returns reference to hash. Maps ARP table entries to MAC addresses. + +(B) + +=item $passport->at_netaddr() + +Returns reference to hash. Maps ARP table entries to IPs + +(B) + +=back + +=head2 Table Methods imported from SNMP::Info + +See documentation in SNMP::Info for details. + +=head2 Table Methods imported from SNMP::Info::Bridge + +See documentation in SNMP::Info::Bridge for details. + +=head2 Table Methods imported from SNMP::Info::SONMP + +See documentation in SNMP::Info::SONMP for details. + +=head2 Table Methods imported from SNMP::Info::RapidCity + +See documentation in SNMP::Info::RapidCity for details. + +=cut diff --git a/Info/RapidCity.pm b/Info/RapidCity.pm new file mode 100644 index 00000000..9fbed358 --- /dev/null +++ b/Info/RapidCity.pm @@ -0,0 +1,707 @@ +# SNMP::Info::RapidCity +# Eric Miller +# +# Copyright (c) 2004 Max Baker +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::RapidCity; +$VERSION = 0.9; +use strict; + +use Exporter; +use SNMP::Info; +use Carp; + +@SNMP::Info::RapidCity::ISA = qw/SNMP::Info Exporter/; +@SNMP::Info::RapidCity::EXPORT_OK = qw//; + +use vars qw/$VERSION $DEBUG %FUNCS %GLOBALS %MIBS %MUNGE $INIT/; +# Debug +$DEBUG=0; +$SNMP::debugging=$DEBUG; + +# Five data structures required by SNMP::Info +$INIT = 0; + +%MIBS = ( + 'RAPID-CITY' => 'rapidCity', + ); + +%GLOBALS = ( + 'serial' => 'rcChasSerialNumber', + 'chassis' => 'rcChasType', + 'slots' => 'rcChasNumSlots', + 'tftp_host' => 'rcTftpHost', + 'tftp_file' => 'rcTftpFile', + 'tftp_action' => 'rcTftpAction', + 'tftp_result' => 'rcTftpResult', + 'rc_ch_rev' => 'rcChasHardwareRevision', + 'rc_base_mac' => 'rc2kChassisBaseMacAddr', + 'rc_virt_ip' => 'rcSysVirtualIpAddr', + ); + +%FUNCS = ( + # From RAPID-CITY::rcPortTable + 'rc_index' => 'rcPortIndex', + 'rc_duplex' => 'rcPortOperDuplex', + 'rc_duplex_admin' => 'rcPortAdminDuplex', + 'rc_speed_admin' => 'rcPortAdminSpeed', + 'rc_auto' => 'rcPortAutoNegotiate', + 'rc_alias' => 'rcPortName', + # From RAPID-CITY::rc2kCpuEthernetPortTable + 'rc_cpu_ifindex' => 'rc2kCpuEthernetPortIfIndex', + 'rc_cpu_admin' => 'rc2kCpuEthernetPortAdminStatus', + 'rc_cpu_oper' => 'rc2kCpuEthernetPortOperStatus', + 'rc_cpu_ip' => 'rc2kCpuEthernetPortAddr', + 'rc_cpu_auto' => 'rc2kCpuEthernetPortAutoNegotiate', + 'rc_cpu_duplex_admin' => 'rc2kCpuEthernetPortAdminDuplex', + 'rc_cpu_duplex' => 'rc2kCpuEthernetPortOperDuplex', + 'rc_cpu_speed_admin' => 'rc2kCpuEthernetPortAdminSpeed', + 'rc_cpu_speed_oper' => 'rc2kCpuEthernetPortOperSpeed', + 'rc_cpu_mac' => 'rc2kCpuEthernetPortMgmtMacAddr', + # From RAPID-CITY::rcVlanPortTable + 'rc_i_vlan_if' => 'rcVlanPortIndex', + 'rc_i_vlan_num' => 'rcVlanPortNumVlanIds', + 'rc_i_vlan' => 'rcVlanPortVlanIds', + 'rc_i_vlan_type' => 'rcVlanPortType', + 'rc_i_vlan_pvid' => 'rcVlanPortDefaultVlanId', + 'rc_i_vlan_tag' => 'rcVlanPortPerformTagging', + # From RAPID-CITY::rcVlanTable + 'rc_vlan_id' => 'rcVlanId', + 'rc_vlan_name' => 'rcVlanName', + 'rc_vlan_color' => 'rcVlanColor', + 'rc_vlan_if' => 'rcVlanIfIndex', + 'rc_vlan_stg' => 'rcVlanStgId', + 'rc_vlan_type' => 'rcVlanType', + 'rc_vlan_members' => 'rcVlanPortMembers', + 'rc_vlan_mac' => 'rcVlanMacAddress', + # From RAPID-CITY::rcIpAddrTable + 'rc_ip_index' => 'rcIpAdEntIfIndex', + 'rc_ip_addr' => 'rcIpAdEntAddr', + 'rc_ip_type' => 'rcIpAdEntIfType', + # From RAPID-CITY::rcChasFanTable + 'rc_fan_op' => 'rcChasFanOperStatus', + # From RAPID-CITY::rcChasPowerSupplyTable + 'rc_ps_op' => 'rcChasPowerSupplyOperStatus', + # From RAPID-CITY::rcChasPowerSupplyDetailTable + 'rc_ps_type' => 'rcChasPowerSupplyDetailType', + 'rc_ps_serial' => 'rcChasPowerSupplyDetailSerialNumber', + 'rc_ps_rev' => 'rcChasPowerSupplyDetailHardwareRevision', + 'rc_ps_part' => 'rcChasPowerSupplyDetailPartNumber', + 'rc_ps_detail' => 'rcChasPowerSupplyDetailDescription', + # From RAPID-CITY::rcCardTable + 'rc_c_type' => 'rcCardType', + 'rc_c_serial' => 'rcCardSerialNumber', + 'rc_c_rev' => 'rcCardHardwareRevision', + 'rc_c_part' => 'rcCardPartNumber', + # From RAPID-CITY::rc2kCardTable + 'rc2k_c_ftype' => 'rc2kCardFrontType', + 'rc2k_c_fdesc' => 'rc2kCardFrontDescription', + 'rc2k_c_fserial' => 'rc2kCardFrontSerialNum', + 'rc2k_c_frev' => 'rc2kCardFrontHwVersion', + 'rc2k_c_fpart' => 'rc2kCardFrontPartNumber', + 'rc2k_c_fdate' => 'rc2kCardFrontDateCode', + 'rc2k_c_fdev' => 'rc2kCardFrontDeviations', + 'rc2k_c_btype' => 'rc2kCardBackType', + 'rc2k_c_bdesc' => 'rc2kCardBackDescription', + 'rc2k_c_bserial' => 'rc2kCardBackSerialNum', + 'rc2k_c_brev' => 'rc2kCardBackHwVersion', + 'rc2k_c_bpart' => 'rc2kCardBackPartNumber', + 'rc2k_c_bdate' => 'rc2kCardBackDateCode', + 'rc2k_c_bdev' => 'rc2kCardBackDeviations', + # From RAPID-CITY::rc2kMdaCardTable + 'rc2k_mda_type' => 'rc2kMdaCardType', + 'rc2k_mda_desc' => 'rc2kMdaCardDescription', + 'rc2k_mda_serial' => 'rc2kMdaCardSerialNum', + 'rc2k_mda_rev' => 'rc2kMdaCardHwVersion', + 'rc2k_mda_part' => 'rc2kMdaCardPartNumber', + 'rc2k_mda_date' => 'rc2kMdaCardDateCode', + 'rc2k_mda_dev' => 'rc2kMdaCardDeviations', + ); + +%MUNGE = ( + 'rc_base_mac' => \&SNMP::Info::munge_mac, + 'rc_vlan_mac' => \&SNMP::Info::munge_mac, + 'rc_cpu_mac' => \&SNMP::Info::munge_mac, + ); + + +sub i_duplex { + my $rapidcity = shift; + + my $interfaces = $rapidcity->interfaces(); + my $rc_index = $rapidcity->rc_index(); + my $rc_duplex = $rapidcity->rc_duplex(); + my $rc_cpu_duplex = $rapidcity->rc_cpu_duplex(); + + my %i_duplex; + foreach my $if (keys %$interfaces){ + my $duplex = $rc_duplex->{$if}; + next unless defined $duplex; + + $duplex = 'half' if $duplex =~ /half/i; + $duplex = 'full' if $duplex =~ /full/i; + $i_duplex{$if}=$duplex; + } + + # Get CPU Ethernet Interfaces for 8600 Series + foreach my $iid (keys %$rc_cpu_duplex){ + my $c_duplex = $rc_cpu_duplex->{$iid}; + next unless defined $c_duplex; + + $i_duplex{$iid} = $c_duplex; + } + + return \%i_duplex; +} + +sub i_duplex_admin { + my $rapidcity = shift; + + my $interfaces = $rapidcity->interfaces(); + my $rc_index = $rapidcity->rc_index(); + my $rc_duplex_admin = $rapidcity->rc_duplex_admin(); + my $rc_auto = $rapidcity->rc_auto(); + my $rc_cpu_auto = $rapidcity->rc_cpu_auto(); + my $rc_cpu_duplex_admin = $rapidcity->rc_cpu_duplex_admin(); + + my %i_duplex_admin; + foreach my $if (keys %$interfaces){ + my $duplex = $rc_duplex_admin->{$if}; + next unless defined $duplex; + my $auto = $rc_auto->{$if}||'false'; + + my $string = 'other'; + $string = 'half' if ($duplex =~ /half/i and $auto =~ /false/i); + $string = 'full' if ($duplex =~ /full/i and $auto =~ /false/i); + $string = 'auto' if $auto =~ /true/i; + + $i_duplex_admin{$if}=$string; + } + + # Get CPU Ethernet Interfaces for 8600 Series + foreach my $iid (keys %$rc_cpu_duplex_admin){ + my $c_duplex = $rc_cpu_duplex_admin->{$iid}; + next unless defined $c_duplex; + my $c_auto = $rc_cpu_auto->{$iid}; + + my $string = 'other'; + $string = 'half' if ($c_duplex =~ /half/i and $c_auto =~ /false/i); + $string = 'full' if ($c_duplex =~ /full/i and $c_auto =~ /false/i); + $string = 'auto' if $c_auto =~ /true/i; + + $i_duplex_admin{$iid} = $string; + } + + return \%i_duplex_admin; +} + +sub i_vlan { + my $rapidcity = shift; + + my $rc_vlans = $rapidcity->rc_i_vlan(); + my $rc_vlan_id = $rapidcity->rc_vlan_id(); + my $rc_vlan_if = $rapidcity->rc_vlan_if(); + + my %i_vlan; + foreach my $if (keys %$rc_vlans){ + my $rc_vlanid = $rc_vlans->{$if}; + next unless defined $rc_vlanid; + my @vlanids = map { sprintf "%02x",$_ } unpack('C*',$rc_vlanid); + + my @vlans = (); + + while($#vlanids > 0) { + my $h = join('', splice(@vlanids,0,2)); + push(@vlans, hex($h)); + } + my $vlans = join (',', @vlans); + $i_vlan{$if}=$vlans; + } + foreach my $if (keys %$rc_vlan_if){ + my $vlan_if = $rc_vlan_if->{$if}; + next unless defined $vlan_if; + my $vlan = $rc_vlan_id->{$if}; + + $i_vlan{$vlan_if}=$vlan; + } + return \%i_vlan; +} + +1; + +__END__ + +=head1 NAME + +SNMP::Info::Layer2::RapidCity - SNMP Interface to Nortel Networks' RapidCity MIB + +=head1 AUTHOR + +Eric Miller (C) + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $rapidcity = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly on to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $rapidcity->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +SNMP::Info::RapidCity is a subclass of SNMP::Info that provides an interface +to the C MIB. This MIB is used across the Nortel Networks' Passport +LAN, as well as, the BayStack and Acclear families. + +Use or create in a subclass of SNMP::Info. Do not use directly. + +=head2 Inherited Classes + +None. + +=head2 Required MIBs + +=over + +=item RAPID-CITY + +=back + +MIBs can be found on the CD that came with your product. + +Or, they can be downloaded directly from Nortel Networks regardless of support +contract status. + +Go to http://www.nortelnetworks.com Techninal Support, Browse Technical Support, +Select by product, Java Device Manager, Software. Download the latest version. +After installation, all mibs are located under the install directory under mibs +and the repspective product line. + +Note: Required version of RAPID-CITY, rapid_city.mib, must be from the Passport +8600 version 3.3 or higher (located in JDM\mibs\passport8k\). + +=head1 GLOBAL METHODS + +These are methods that return scalar values from SNMP + +=over + +=item $rapidcity->chassis_base_mac() + +(B) + +=item $rapidcity->ch_serial() + +(B) + +=item $rapidcity->rc_ch_rev() + +(B) + +=item $rapidcity->chassis() + +(B) + +=item $rapidcity->slots() + +(B) + +=item $rapidcity->rc_virt_ip() + +(B) + +=item $rapidcity->tftp_host() + +(B) + +=item $rapidcity->tftp_file() + +(B) + +=item $rapidcity->tftp_action() + +(B) + +=item $rapidcity->tftp_result() + +(B) + +=back + +=head1 TABLE METHODS + +These are methods that return tables of information in the form of a reference +to a hash. + +=over + +=item $rapidcity->i_duplex() + +Returns reference to map of IIDs to current link duplex. + +=item $rapidcity->i_duplex_admin() + +Returns reference to hash of IIDs to admin duplex setting. + +=item $rapidcity->i_vlan() + +Returns a mapping between ifIndex and the VLAN. + +=back + +=head2 RAPID-CITY Port Table (B) + +=over + +=item $rapidcity->rc_index() + +(B) + +=item $rapidcity->rc_duplex() + +(B) + +=item $rapidcity->rc_duplex_admin() + +(B) + +=item $rapidcity->rc_speed_admin() + +(B) + +=item $rapidcity->rc_auto() + +(B) + +=item $rapidcity->rc_alias() + +(B) + +=back + +=head2 RAPID-CITY CPU Ethernet Port Table (B) + +=over + +=item $rapidcity->rc_cpu_ifindex() + +(B) + +=item $rapidcity->rc_cpu_admin() + +(B) + +=item $rapidcity->rc_cpu_oper() + +(B) + +=item $rapidcity->rc_cpu_ip() + +(B) + +=item $rapidcity->rc_cpu_auto() + +(B) + +=item $rapidcity->rc_cpu_duplex_admin() + +(B) + +=item $rapidcity->rc_cpu_duplex() + +(B) + +=item $rapidcity->rc_cpu_speed_admin() + +(B) + +=item $rapidcity->rc_cpu_speed_oper() + +(B) + +=item $rapidcity->rc_cpu_mac() + +(B) + +=back + +=head2 RAPID-CITY VLAN Port Table (B) + +=over + +=item $rapidcity->rc_i_vlan_if() + +(B) + +=item $rapidcity->rc_i_vlan_num() + +(B) + +=item $rapidcity->rc_i_vlan() + +(B) + +=item $rapidcity->rc_i_vlan_type() + +(B) + +=item $rapidcity->rc_i_vlan_pvid() + +(B) + +=item $rapidcity->rc_i_vlan_tag() + +(B) + +=back + +=head2 RAPID-CITY VLAN Table (B) + +=over + +=item $rapidcity->rc_vlan_id() + +(B) + +=item $rapidcity->rc_vlan_name() + +(B) + +=item $rapidcity->rc_vlan_color() + +(B) + +=item $rapidcity->rc_vlan_if() + +(B) + +=item $rapidcity->rc_vlan_stg() + +(B) + +=item $rapidcity->rc_vlan_type() + +(B) + +=item $rapidcity->rc_vlan_members() + +(B) + +=item $rapidcity->rc_vlan_mac() + +(B) + +=back + +=head2 RAPID-CITY IP Address Table (B) + +=over + +=item $rapidcity->rc_ip_index() + +(B) + +=item $rapidcity->rc_ip_addr() + +(B) + +=item $rapidcity->rc_ip_type() + +(B) + +=back + +=head2 RAPID-CITY Chassis Fan Table (B) + +=over + +=item $rapidcity->rc_fan_op() + +(B) + +=back + +=head2 RAPID-CITY Power Supply Table (B) + +=over + +=item $rapidcity->rc_ps_op() + +(B) + +=back + +=head2 RAPID-CITY Power Supply Detail Table (B) + +=over + +=item $rapidcity->rc_ps_type() + +(B) + +=item $rapidcity->rc_ps_serial() + +(B) + +=item $rapidcity->rc_ps_rev() + +(B) + +=item $rapidcity->rc_ps_part() + +(B) + +=item $rapidcity->rc_ps_detail() + +(B) + +=back + +=head2 RAPID-CITY Card Table (B) + +=over + +=item $rapidcity->rc_c_type() + +(B) + +=item $rapidcity->rc_c_serial() + +(B) + +=item $rapidcity->rc_c_rev() + +(B) + +=item $rapidcity->rc_c_part() + +(B) + +=back + +=head2 RAPID-CITY 2k Card Table (B) + +=over + +=item $rapidcity->rc2k_c_ftype() + +(B) + +=item $rapidcity->rc2k_c_fdesc() + +(B) + +=item $rapidcity->rc2k_c_fserial() + +(B) + +=item $rapidcity->rc2k_c_frev() + +(B) + +=item $rapidcity->rc2k_c_fpart() + +(B) + +=item $rapidcity->rc2k_c_fdate() + +(B) + +=item $rapidcity->rc2k_c_fdev() + +(B) + +=item $rapidcity->rc2k_c_btype() + +(B) + +=item $rapidcity->rc2k_c_bdesc() + +(B) + +=item $rapidcity->rc2k_c_bserial() + +(B) + +=item $rapidcity->rc2k_c_brev() + +(B) + +=item $rapidcity->rc2k_c_bpart() + +(B) + +=item $rapidcity->rc2k_c_bdate() + +(B) + +=item $rapidcity->rc2k_c_bdev() + +(B) + +=back + +=head2 RAPID-CITY MDA Card Table (B) + +=over + +=item $rapidcity->rc2k_mda_type() + +(B) + +=item $rapidcity->rc2k_mda_desc() + +(B) + +=item $rapidcity->rc2k_mda_serial() + +(B) + +=item $rapidcity->rc2k_mda_rev() + +(B) + +=item $rapidcity->rc2k_mda_part() + +(B) + +=item $rapidcity->rc2k_mda_date() + +(B) + +=item $rapidcity->rc2k_mda_dev() + +(B) + +=cut diff --git a/Info/SONMP.pm b/Info/SONMP.pm new file mode 100644 index 00000000..abcbd12e --- /dev/null +++ b/Info/SONMP.pm @@ -0,0 +1,505 @@ +# SNMP::Info::SONMP +# Eric Miller +# +# Copyright (c) 2004 Max Baker +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of the University of California, Santa Cruz nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package SNMP::Info::SONMP; +$VERSION = 0.9; + +use strict; + +use Exporter; +use SNMP::Info; +use Carp; + +@SNMP::Info::SONMP::ISA = qw/SNMP::Info Exporter/; +@SNMP::Info::SONMP::EXPORT_OK = qw//; + +use vars qw/$VERSION $DEBUG %FUNCS %GLOBALS %MIBS %MUNGE $INIT/; +# Debug +$DEBUG=0; +$SNMP::debugging=$DEBUG; + +# Five data structures required by SNMP::Info +$INIT = 0; + +%MIBS = ( + 'SYNOPTICS-ROOT-MIB' => 'synoptics', + 'S5-ETH-MULTISEG-TOPOLOGY-MIB' => 's5EnMsTop', + ); + +%GLOBALS = ( + 'cdp_id' => 's5EnMsTopIpAddr', + 'cdp_run' => 's5EnMsTopStatus', + ); + +%FUNCS = ( + # From S5-ETH-MULTISEG-TOPOLOGY-MIB::TopNmmTable + 'sonmp_topo_slot' => 's5EnMsTopNmmSlot', + 'sonmp_topo_port' => 's5EnMsTopNmmPort', + 'sonmp_topo_ip' => 's5EnMsTopNmmIpAddr', + 'sonmp_topo_seg' => 's5EnMsTopNmmSegId', + 'sonmp_topo_mac' => 's5EnMsTopNmmMacAddr', + 'sonmp_topo_platform' => 's5EnMsTopNmmChassisType', + 'sonmp_topo_localseg' => 's5EnMsTopNmmLocalSeg', + ); + +%MUNGE = ( + 'sonmp_topo_mac' => \&SNMP::Info::munge_mac + ); + +sub index_factor { + return 32; +} + +sub slot_offset { + return 1; +} + +sub port_offset { + return 0; +} + +sub hasCDP { + my $sonmp = shift; + return $sonmp->cdp_run(); +} + + +sub c_if { + my $sonmp = shift; + my $sonmp_topo_port = $sonmp->sonmp_topo_port(); + my $sonmp_topo_slot = $sonmp->sonmp_topo_slot(); + my $index_factor = $sonmp->index_factor(); + my $slot_offset = $sonmp->slot_offset(); + my $port_offset = $sonmp->port_offset(); + my $model = $sonmp->model(); + + my %c_if; + foreach my $entry (keys %$sonmp_topo_port){ + my $port = $sonmp_topo_port->{$entry}; + next unless defined $port; + next if $port == 0; + my $slot = $sonmp_topo_slot->{$entry}||0; + + if ($model eq 'Baystack Hub') { + my $comidx = $slot; + if (! ($comidx % 5)) { + $slot = ($slot / 5); + } elsif ($comidx =~ /[16]$/) { + $slot = int($slot/5); + $port = 25; + } elsif ($comidx =~ /[27]$/) { + $slot = int($slot/5); + $port = 26; + } + } + + my $index = (($slot-$slot_offset)*$index_factor) + ($port-$port_offset); + + $c_if{"$index.1"} = $index; + } + return \%c_if; +} + +sub c_ip { + my $sonmp = shift; + my $sonmp_topo_ip = $sonmp->sonmp_topo_ip(); + my $sonmp_topo_port = $sonmp->sonmp_topo_port(); + my $sonmp_topo_slot = $sonmp->sonmp_topo_slot(); + my $ip = $sonmp->cdp_id(); + my $index_factor = $sonmp->index_factor(); + my $slot_offset = $sonmp->slot_offset(); + my $port_offset = $sonmp->port_offset(); + my $model = $sonmp->model(); + + + # Count the number of devices seen on each port. + # more than one device seen means connected to a non-sonmp + # device, but other sonmp devices are squawking further away. + my %ip_port; + foreach my $entry (keys %$sonmp_topo_ip){ + my $port = $sonmp_topo_port->{$entry}; + next unless defined $port; + next if ($port =~ /^[\d\.]+$/ and $port == 0); + my $slot = $sonmp_topo_slot->{$entry}||0; + + if ($model eq 'Baystack Hub') { + my $comidx = $slot; + if (! ($comidx % 5)) { + $slot = ($slot / 5); + } elsif ($comidx =~ /[16]$/) { + $slot = int($slot/5); + $port = 25; + } elsif ($comidx =~ /[27]$/) { + $slot = int($slot/5); + $port = 26; + } + } + + my $index = (($slot-$slot_offset)*$index_factor) + ($port-$port_offset); + + my $ip = $sonmp_topo_ip->{$entry}; + push(@{$ip_port{$index}},$ip); + } + + my %c_ip; + foreach my $port (keys %ip_port){ + my $ips = $ip_port{$port}; + if (scalar @$ips == 1) { + $c_ip{"$port.1"} = $ips->[0]; + } else { + $c_ip{"$port.1"} = $ips; + } + } + return \%c_ip; +} + +sub c_port { + my $sonmp = shift; + my $sonmp_topo_port = $sonmp->sonmp_topo_port(); + my $sonmp_topo_seg = $sonmp->sonmp_topo_seg(); + my $sonmp_topo_slot = $sonmp->sonmp_topo_slot(); + my $index_factor = $sonmp->index_factor(); + my $slot_offset = $sonmp->slot_offset(); + my $port_offset = $sonmp->port_offset(); + my $model = $sonmp->model(); + my $sonmp_topo_platform = $sonmp->sonmp_topo_platform(); + + my %c_port; + foreach my $entry (keys %$sonmp_topo_seg){ + my $port = $sonmp_topo_port->{$entry}; + next unless defined $port; + next if $port == 0; + my $slot = $sonmp_topo_slot->{$entry}; + $slot = 0 unless defined $slot; + + if ($model eq 'Baystack Hub') { + my $comidx = $slot; + if (! ($comidx % 5)) { + $slot = ($slot / 5); + } elsif ($comidx =~ /[16]$/) { + $slot = int($slot/5); + $port = 25; + } elsif ($comidx =~ /[27]$/) { + $slot = int($slot/5); + $port = 26; + } + } + + my $index = (($slot-$slot_offset)*$index_factor) + ($port-$port_offset); + + # For fake remotes (multiple IPs for a c_ip), use first found + next if defined $c_port{"$index.1"}; + + my $seg = $sonmp_topo_seg->{$entry}; + my $platform = $sonmp_topo_platform->{$entry}; + # AP-222x Series does not adhere to port numbering + if ($platform =~ /AccessPoint/i) { + $c_port{"$index.1"} = 'dp0'; + } + # BayHubs send the lower three bytes of the MAC not the slot/port + elsif ($seg > 4000) { + $c_port{"$index.1"} = 'unknown'; + } + else { + # Segment id is (256 * remote slot_num) + (remote_port) + my $remote_port = $seg % 256; + my $remote_slot = int($seg / 256); + + $c_port{"$index.1"} = "$remote_slot.$remote_port"; + } + } + return \%c_port; +} + +sub c_platform { + my $sonmp = shift; + my $sonmp_topo_port = $sonmp->sonmp_topo_port(); + my $sonmp_topo_slot = $sonmp->sonmp_topo_slot(); + my $sonmp_topo_platform = $sonmp->sonmp_topo_platform(); + my $index_factor = $sonmp->index_factor(); + my $slot_offset = $sonmp->slot_offset(); + my $port_offset = $sonmp->port_offset(); + my $model = $sonmp->model(); + + my %c_platform; + foreach my $entry (keys %$sonmp_topo_platform){ + my $port = $sonmp_topo_port->{$entry}||0; + next if $port == 0; + my $slot = $sonmp_topo_slot->{$entry}; + $slot = 0 unless defined $slot; + + if ($model eq 'Baystack Hub') { + my $comidx = $slot; + if (! ($comidx % 5)) { + $slot = ($slot / 5); + } elsif ($comidx =~ /[16]$/) { + $slot = int($slot/5); + $port = 25; + } elsif ($comidx =~ /[27]$/) { + $slot = int($slot/5); + $port = 26; + } + } + + my $index = (($slot-$slot_offset)*$index_factor) + ($port-$port_offset); + + # For fake remotes (multiple IPs for a c_ip), use first found + next if defined $c_platform{"$index.1"}; + + my $platform = $sonmp_topo_platform->{$entry}; + + $c_platform{"$index.1"} = $platform; + } + return \%c_platform; +} + +sub mac { + my $sonmp = shift; + my $sonmp_topo_port = $sonmp->sonmp_topo_port(); + my $sonmp_topo_mac = $sonmp->sonmp_topo_mac(); + + foreach my $entry (keys %$sonmp_topo_port){ + my $port = $sonmp_topo_port->{$entry}; + next unless $port == 0; + my $mac = $sonmp_topo_mac->{$entry}; + return $mac; + } +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::SONMP - Perl5 Interface to SynOptics Network Management Protocol (SONMP) using SNMP + +=head1 AUTHOR + +Max Baker (C), +Eric Miller (C) + +=head1 SYNOPSIS + + my $sonmp = new SNMP::Info ( + AutoSpecify => 1, + Debug => 1, + DestHost => 'router', + Community => 'public', + Version => 2 + ); + + my $class = $sonmp->class(); + print " Using device sub class : $class\n"; + + $hascdp = $sonmp->hasCDP() ? 'yes' : 'no'; + + # Print out a map of device ports with CDP neighbors: + my $interfaces = $sonmp->interfaces(); + my $c_if = $sonmp->c_if(); + my $c_ip = $sonmp->c_ip(); + my $c_port = $sonmp->c_port(); + + foreach my $cdp_key (keys %$c_ip){ + my $iid = $c_if->{$cdp_key}; + my $port = $interfaces->{$iid}; + my $neighbor = $c_ip->{$cdp_key}; + my $neighbor_port = $c_port->{$cdp_key}; + print "Port : $port connected to $neighbor / $neighbor_port\n"; + } + +=head1 DESCRIPTION + +SNMP::Info::SONMP is a subclass of SNMP::Info that provides an object oriented +interface to the SynOptics Network Management Protocol (SONMP) information +through SNMP. + +SONMP is a Layer 2 protocol that supplies topology information of devices that also speak SONMP, +mostly switches and hubs. SONMP is implemented in SynOptics, Bay, and Nortel Networks devices. +SONMP has been rebranded by Bay then Nortel Networks and is know by several different +names. + +Create or use a device subclass that inherits this class. Do not use directly. + +Each device implements a subset of the global and cache entries. +Check the return value to see if that data is held by the device. + +=head2 Inherited Classes + +None. + +=head2 Required MIBs + +=over + +=item SYNOPTICS-ROOT-MIB + +=item S5-ETH-MULTISEG-TOPOLOGY-MIB + +=back + +MIBs can be found on the CD that came with your product. + +Or, they can be downloaded directly from Nortel Networks regardless of support +contract status. + +Go to http://www.nortelnetworks.com Techninal Support, Browse Technical Support, +Select by product, Java Device Manager, Software. Download the latest version. +After installation, all mibs are located under the install directory under mibs +and the repspective product line. + +Note: Required version of SYNOPTICS-ROOT-MIB, must be version 199 or higher, +for example synro199.mib. + +=head1 GLOBAL METHODS + +These are methods that return scalar values from SNMP + +=over + +=item $sonmp->index_factor() + +Returns a number representing the number of ports reserved per slot or switch +within the device MIB. Defaults to 32. + +=item $sonmp->slot_offset() + +Returns the offset if slot numbering does not start at 0. Defaults to 1. + +=item $sonmp->port_offset() + +Returns the offset if port numbering does not start at 0. Defaults to 0. + +=item $cdp->hasCDP() + +Is CDP is active in this device? + +=item $sonmp->cdp_id() + +Returns the IP that the device is sending out for its Nmm topology info. + +(B) + +=item $sonmp->cdp_run() + +Returns if the S5-ETH-MULTISEG-TOPOLOGY info is on for this device. + +(B) + +=item $sonmp->mac() + +Returns MAC of the advertised IP address of the device. + +=back + +=head1 TABLE METHODS + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Layer2 Topology info (s5EnMsTopNmmTable) + +=over + +=item $sonmp->sonmp_topo_slot() + +Returns reference to hash. Key: Table entry, Value:slot number + +(B) + +=item $sonmp->sonmp_topo_port() + +Returns reference to hash. Key: Table entry, Value:Port Number (interface iid) + +(B) + +=item $sonmp->sonmp_topo_ip() + +Returns reference to hash. Key: Table entry, Value:Remote IP address of entry + +(B) + +=item $sonmp->sonmp_topo_seg() + +Returns reference to hash. Key: Table entry, Value:Remote Segment ID + +(B) + +=item $sonmp->sonmp_topo_mac + +(B) + +Returns reference to hash. Key: Table entry, Value:Remote MAC address + +=item $sonmp->sonmp_topo_platform + +Returns reference to hash. Key: Table entry, Value:Remote Device Type + +(B) + +=item $sonmp->sonmp_topo_localseg + +Returns reference to hash. Key: Table entry, Value:Boolean, if bay_topo_seg() is local + +(B) + +=back + +=head2 Psuedo CDP information + +All entries with port=0 are local and ignored. + +=over + +=item $sonmp->c_if() + +Returns reference to hash. Key: ifIndex.1 Value: port (iid) + +=item $sonmp->c_ip() + +Returns referenece to hash. Key: ifIndex.1 + +The value of each hash entry can either be a scalar or an array. +A scalar value is most likely a direct neighbor to that port. +It is possible that there is a non-SONMP device in between this device and the remote device. + +An array value represents a list of seen devices. The only time you will get an array +of neighbors, is if there is a non-SONMP device in between two or more devices. + +Use the data from the Layer2 Topology Table below to dig deeper. + +=item $sonmp->c_port() + +Returns reference to hash. Key: ifIndex.1 Value: remote port + +=item $sonmp->c_platform() + +Returns reference to hash. Key: ifIndex.1 Value: Remote Device Type + +=back + +=cut diff --git a/MANIFEST b/MANIFEST index d70f76bd..2eac7bc8 100644 --- a/MANIFEST +++ b/MANIFEST @@ -11,20 +11,31 @@ Info/EtherLike.pm Info/Layer1.pm Info/Layer1/Allied.pm Info/Layer1/Asante.pm +Info/Layer1/Bayhub.pm Info/Layer2.pm Info/Layer2/Aironet.pm -Info/Layer2/Bay.pm +Info/Layer2/Baystack.pm Info/Layer2/C1900.pm Info/Layer2/C2900.pm Info/Layer2/Catalyst.pm +Info/Layer2/Centillion.pm Info/Layer2/HP.pm +Info/Layer2/NAP222x.pm +Info/Layer2/Orinoco.pm Info/Layer2/ZyXEL_DSLAM.pm Info/Layer3.pm Info/Layer3/Aironet.pm +Info/Layer3/AlteonAD.pm +Info/Layer3/BayRS.pm Info/Layer3/C3550.pm Info/Layer3/C6500.pm +Info/Layer3/Contivity.pm Info/Layer3/Foundry.pm +Info/Layer3/Passport.pm Info/MAU.pm +Info/NortelStack.pm +Info/RapidCity.pm +Info/SONMP.pm MANIFEST Makefile.PL README