From 3d48f4e210a715c3dd79939445ed25c8eb1dd73d Mon Sep 17 00:00:00 2001 From: "Eric A. Miller" Date: Wed, 23 Oct 2013 23:18:26 -0400 Subject: [PATCH] [#45] IBM (Blade Network Technologies) Rackswitch support in new class L3::IBMGbTor --- ChangeLog | 10 +- Info.pm | 9 + Info/Layer3/IBMGbTor.pm | 393 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 411 insertions(+), 1 deletion(-) create mode 100644 Info/Layer3/IBMGbTor.pm diff --git a/ChangeLog b/ChangeLog index a306dc14..55859df4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,14 @@ SNMP::Info - Friendly OO-style interface to Network devices using SNMP. -version 3.08 () +version 3.09 () + + [NEW FEATURES] + + * [#45] IBM (Blade Network Technologies) Rackswitch support in new class + L3::IBMGbTor + + +version 3.08 (2013-10-22) [ENHANCEMENTS] diff --git a/Info.pm b/Info.pm index 97b78cd0..c2d42f82 100644 --- a/Info.pm +++ b/Info.pm @@ -766,6 +766,13 @@ Original Equipment Manufacturer (OEM) such as the HP ProCurve 9300 and 6300 seri See documentation in L for details. +=item SNMP::Info::Layer3::IBMGbTor + +SNMP Interface to IBM Rackswitch (formerly Blade Network Technologies) +network devices. + +See documentation in L for details. + =item SNMP::Info::Layer3::Juniper Subclass for Juniper devices @@ -1397,6 +1404,7 @@ sub device_type { 14525 => 'SNMP::Info::Layer2::Trapeze', 14988 => 'SNMP::Info::Layer3::Mikrotik', 25506 => 'SNMP::Info::Layer3::H3C', + 26543 => 'SNMP::Info::Layer3::IBMGbTor', 30065 => 'SNMP::Info::Layer3::Arista', 35098 => 'SNMP::Info::Layer3::Pica8', ); @@ -1422,6 +1430,7 @@ sub device_type { 14179 => 'SNMP::Info::Layer2::Airespace', 14525 => 'SNMP::Info::Layer2::Trapeze', 14823 => 'SNMP::Info::Layer3::Aruba', + 26543 => 'SNMP::Info::Layer3::IBMGbTor', ); my %l7sysoidmap = ( diff --git a/Info/Layer3/IBMGbTor.pm b/Info/Layer3/IBMGbTor.pm new file mode 100644 index 00000000..ae27d42a --- /dev/null +++ b/Info/Layer3/IBMGbTor.pm @@ -0,0 +1,393 @@ +# SNMP::Info::Layer3::IBMGbTor - SNMP Interface to IBM Rackswitch devices +# $Id$ +# +# Copyright (c) 2013 Eric Miller +# 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::IBMGbTor; + +use strict; +use Exporter; +use SNMP::Info::Layer3; +use SNMP::Info::LLDP; + +@SNMP::Info::Layer3::IBMGbTor::ISA + = qw/SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/; +@SNMP::Info::Layer3::IBMGbTor::EXPORT_OK = qw//; + +use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/; + +$VERSION = '3.07_001'; + +%MIBS = ( + %SNMP::Info::Layer3::MIBS, + + # LLDP MIBs not loaded to prevent possible unqualified namespace conflict + # with IBM definitions + 'IBM-GbTOR-10G-L2L3-MIB' => 'lldpInfoRemoteDevicesLocalPort', +); + +%GLOBALS = ( + %SNMP::Info::Layer3::GLOBALS, + %SNMP::Info::LLDP::GLOBALS, + 'temp' => 'hwTempSensors', + 'fan' => 'hwFanSpeed', + + # Can't find the equivalent in IBM-GbTOR-10G-L2L3-MIB + # use a different strategy for lldp_sys_cap in hasLLDP() + #'lldp_sysname' => 'lldpLocSysName', + #'lldp_sysdesc' => 'lldpLocSysDesc', + #'lldp_sys_cap' => 'lldpLocSysCapEnabled', +); + +%FUNCS = ( + %SNMP::Info::Layer3::FUNCS, + %SNMP::Info::LLDP::FUNCS, + + # IBM-GbTOR-10G-L2L3-MIB::portInfoTable + 'sw_duplex' => 'portInfoMode', + + # Can't find the equivalent in IBM-GbTOR-10G-L2L3-MIB + # not currently used in LLDP class + #'lldp_lman_addr' => 'lldpLocManAddrIfId', + + # IBM-GbTOR-10G-L2L3-MIB::lldpInfoPortTable + 'lldp_port_status' => 'lldpInfoPortAdminStatus', + + # IBM-GbTOR-10G-L2L3-MIB::lldpInfoRemoteDevicesTable + 'lldp_rem_id_type' => 'lldpInfoRemoteDevicesChassisSubtype', + 'lldp_rem_id' => 'lldpInfoRemoteDevicesChassisId', + 'lldp_rem_pid_type' => 'lldpInfoRemoteDevicesPortSubtype', + 'lldp_rem_pid' => 'lldpInfoRemoteDevicesPortId', + 'lldp_rem_desc' => 'lldpInfoRemoteDevicesPortDescription', + 'lldp_rem_sysname' => 'lldpInfoRemoteDevicesSystemName', + 'lldp_rem_sysdesc' => 'lldpInfoRemoteDevicesSystemDescription', + 'lldp_rem_sys_cap' => 'lldpInfoRemoteDevicesSystemCapEnabled', + + # IBM-GbTOR-10G-L2L3-MIB::lldpInfoRemoteDevicesManAddrTable + 'lldp_rman_type' => 'lldpInfoRemoteDevicesManAddrSubtype', + 'lldp_rman_addr' => 'lldpInfoRemoteDevicesManAddr', +); + +%MUNGE = ( %SNMP::Info::Layer3::MUNGE, %SNMP::Info::LLDP::MUNGE, ); + +sub hasLLDP { + my $ibm = shift; + + # We may be have LLDP, but nothing in lldpRemoteSystemsData Tables + # Look to see if LLDP Rx enabled on any port + my $lldp_cap = $ibm->lldp_port_status(); + + foreach my $if ( keys %$lldp_cap ) { + if ( $lldp_cap->{$if} =~ /enabledRx/i ) { + return 1; + } + } + return; +} + +sub lldp_ip { + my $ibm = shift; + my $partial = shift; + + my $rman_type = $ibm->lldp_rman_type($partial) || {}; + my $rman_addr = $ibm->lldp_rman_addr($partial) || {}; + + my %lldp_ip; + foreach my $key ( keys %$rman_addr ) { + my $type = $rman_type->{$key}; + next unless defined $type; + next unless $type == 1; + if ( $key =~ /^(\d+)\./ ) { + $lldp_ip{$1} = $rman_addr->{$key}; + } + } + return \%lldp_ip; +} + +sub lldp_if { + my $lldp = shift; + my $partial = shift; + + my $lldp_desc = $lldp->lldpInfoRemoteDevicesLocalPort($partial) || {}; + my $i_descr = $lldp->i_description() || {}; + my $i_alias = $lldp->i_alias() || {}; + my %r_i_descr = reverse %$i_descr; + my %r_i_alias = reverse %$i_alias; + + my %lldp_if; + foreach my $key ( keys %$lldp_desc ) { + + # Cross reference lldpLocPortDesc with ifDescr and ifAlias to get ifIndex, + # prefer ifAlias over ifDescr since MIB says 'alias'. + my $desc = $lldp_desc->{$key}; + next unless $desc; + my $port; + +# If cross reference is successful use it, otherwise stick with lldpRemLocalPortNum + if ( exists $r_i_alias{$desc} ) { + $port = $r_i_alias{$desc}; + } + elsif ( exists $r_i_descr{$desc} ) { + $port = $r_i_descr{$desc}; + } + + $lldp_if{$key} = $port; + } + return \%lldp_if; +} + +sub i_ignore { + my $ibm = shift; + my $partial = shift; + + my $interfaces = $ibm->interfaces($partial) || {}; + + my %i_ignore; + foreach my $if ( keys %$interfaces ) { + if ( $interfaces->{$if} =~ /(tunnel|loopback|\blo\b|lb|null)/i ) { + $i_ignore{$if}++; + } + } + return \%i_ignore; +} + +sub i_duplex { + my $ibm = shift; + my $partial = shift; + + return $ibm->sw_duplex($partial); +} + +sub model { + my $ibm = shift; + my $id = $ibm->id(); + my $descr = $ibm->description(); + my $model = &SNMP::translateObj($id); + + if ( $descr =~ /RackSwitch\s(.*)/ ) { + return $1; + } + + return $model || $id; +} + +sub os { + return 'ibm'; +} + +sub vendor { + return 'ibm'; +} + +sub os_ver { + my $ibm = shift; + + return $ibm->agSoftwareVersion(); +} + +sub interfaces { + my $ibm = shift; + my $partial = shift; + + my $i_descr = $ibm->i_description($partial) || {}; + my $i_name = $ibm->i_name($partial) || {}; + + foreach my $iid ( keys %$i_name ) { + my $name = $i_name->{$iid}; + next unless defined $name; + $i_descr->{$iid} = $name + if $name =~ /^port\d+/i; + } + + return $i_descr; +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer3::IBMGbTor - SNMP Interface to IBM Rackswitch devices + +=head1 AUTHOR + +Eric Miller + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $ibm = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + DestHost => 'myswitch', + Community => 'public', + Version => 1 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $ibm->class(); + + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Abstraction subclass for IBM Rackswitch (formerly Blade Network Technologies) +network devices. + +For speed or debugging purposes you can call the subclass directly, but not +after determining a more specific class using the method above. + + my $ibm = new SNMP::Info::Layer3::IBMGbTor(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info::Layer3; + +=item SNMP::Info::LLDP; + +=back + +=head2 Required MIBs + +=over + +=item F + +=item Inherited Classes' MIBs + +See L for its own MIB requirements. + +=back + +=head1 GLOBALS + +These are methods that return scalar value from SNMP + +=over + +=item $ibm->model() + +Returns model type. Attemps to pull model from device description. +Otherwsie checks $ibm->id() against the F. + +=item $ibm->vendor() + +Returns 'ibm' + +=item $ibm->os() + +Returns 'ibm' + +=item $ibm->os_ver() + +Returns the software version + +(C) + +=item $ibm->temp() + +(C) + +=item $ibm->fan() + +(C) + +=back + +=head2 Overrides + +=over + +=item $ibm->hasLLDP() + +Is LLDP is active in this device? + +Note: LLDP may be active, but nothing in C Tables so +the device would not return any useful topology information. + +Checks to see if at least one interface is enabled to receive LLDP packets. + +=item $lldp->lldp_if() + +Returns the mapping to the SNMP Interface Table. Tries to cross reference +(C) with (C) and (C) +to get (C). + +=item $lldp->lldp_ip() + +Returns remote IPv4 address. Returns for all other address types, use +lldp_addr if you want any return address type. + +=back + +=head2 Global Methods imported from SNMP::Info::Layer3 + +See documentation in L for details. + +=head2 Global Methods imported from SNMP::Info::LLDP + +See documentation in L for details. + +=head1 TABLE METHODS + +These are methods that return tables of information in the form of a reference +to a hash. + +=head2 Overrides + +=over + +=item $ibm->interfaces() + +Returns reference to hash of interface names to iids. + +=item $ibm->i_ignore() + +Returns reference to hash of interfaces to be ignored. + +Ignores interfaces with descriptions of tunnel, loopback, and null. + +=item $ibm->i_duplex() + +Returns reference to hash of interface link duplex status. + +(C) + +=back + +=head2 Table Methods imported from SNMP::Info::Layer3 + +See documentation in L for details. + +=head2 Table Methods imported from SNMP::Info::LLDP + +See documentation in L for details. + +=cut