—# SNMP::Info::Layer3::IBMGbTor - SNMP Interface to IBM Rackswitch devices
#
# 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
warnings;
use
Exporter;
use
SNMP::Info::Layer3;
@SNMP::Info::Layer3::IBMGbTor::ISA
=
qw/SNMP::Info::LLDP SNMP::Info::Layer3 Exporter/
;
@SNMP::Info::Layer3::IBMGbTor::EXPORT_OK
=
qw//
;
our
(
$VERSION
,
%GLOBALS
,
%FUNCS
,
%MIBS
,
%MUNGE
);
$VERSION
=
'3.972002'
;
%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'
=>
'lldpInfoRemoteDevicesSystemName'
,
'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
eq
'ipV4'
;
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
=
$desc
;
# 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
lldp_platform {
my
$ibm
=
shift
;
my
$partial
=
shift
;
return
$ibm
->lldpInfoRemoteDevicesSystemDescription(
$partial
);
}
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'
;
}
# TODO: from os version 8 this should return lenovo
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 Lenovo/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 => 2
)
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. Lenovo acquired these from IBM and is now selling
them under the Lenovo brand.
=head2 Inherited Classes
=over
=item SNMP::Info::Layer3;
=item SNMP::Info::LLDP;
=back
=head2 Required MIBs
=over
=item F<IBM-GbTOR-10G-L2L3-MIB>
=item Inherited Classes' MIBs
See L<SNMP::Info::Layer3/"Required MIBs"> for its own MIB requirements.
=back
=head1 GLOBALS
These are methods that return scalar value from SNMP
=over
=item $ibm->model()
Returns model type. Attempts to pull model from device description.
Otherwise checks $ibm->id() against the F<IBM-GbTOR-10G-L2L3-MIB>.
=item $ibm->vendor()
Returns 'ibm'
=item $ibm->os()
Returns 'ibm'
=item $ibm->os_ver()
Returns the software version
(C<agSoftwareVersion>)
=item $ibm->temp()
(C<hwTempSensors>)
=item $ibm->fan()
(C<hwFanSpeed>)
=back
=head2 Overrides
=over
=item $ibm->hasLLDP()
Is LLDP is active in this device?
Note: LLDP may be active, but nothing in C<lldpRemoteSystemsData> 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.
=back
=head2 Global Methods imported from SNMP::Info::Layer3
See documentation in L<SNMP::Info::Layer3/"GLOBALS"> for details.
=head2 Global Methods imported from SNMP::Info::LLDP
See documentation in L<SNMP::Info::LLDP/"GLOBALS"> 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<portInfoMode>)
=item $ibm->lldp_if()
Returns the mapping to the SNMP Interface Table. Tries to cross reference
(C<lldpInfoRemoteDevicesLocalPort>) with (C<ifDescr>) and (C<ifAlias>)
to get (C<ifIndex>).
=item $ibm->lldp_ip()
Returns remote IPv4 address. Returns for all other address types, use
lldp_addr if you want any return address type.
=item $ibm->lldp_platform()
Returns remote device system description.
(C<lldpInfoRemoteDevicesSystemDescription>)
=back
=head2 Table Methods imported from SNMP::Info::Layer3
See documentation in L<SNMP::Info::Layer3/"TABLE METHODS"> for details.
=head2 Table Methods imported from SNMP::Info::LLDP
See documentation in L<SNMP::Info::LLDP/"TABLE METHODS"> for details.
=cut