diff --git a/Info.pm b/Info.pm index d8b7e7de..9c171910 100644 --- a/Info.pm +++ b/Info.pm @@ -23,7 +23,7 @@ use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG %SPEED_MAP $NOSUCH $BIGINT $REPEATERS/; -$VERSION = '2.09-cvs'; +$VERSION = '2.09'; =head1 NAME @@ -759,6 +759,12 @@ Subclass for Juniper NetScreen. See documentation in L for details. +=item SNMP::Info::Layer3::Nexus + +Subclass for Cisco Nexus devices running NX-OS + +See documentation in L for details. + =item SNMP::Info::Layer3::PacketFront Subclass for PacketFront DRG series CPE. @@ -1364,6 +1370,10 @@ sub device_type { $objtype = 'SNMP::Info::Layer3::C6500' if ( $desc =~ /cisco/i and $desc =~ /CBS3[0-9A-Za-z]{3}/ ); + # Cisco Nexus running NX-OS + $objtype = 'SNMP::Info::Layer3::Nexus' + if ( $desc =~ /^Cisco\s+NX-OS/ ); + # HP, older ProCurve models (1600, 2400, 2424m, 4000, 8000) $objtype = 'SNMP::Info::Layer2::HP4000' if $desc =~ /\b(J4093A|J4110A|J4120A|J4121A|J4122A|J4122B)\b/; diff --git a/Info/Layer3/Nexus.pm b/Info/Layer3/Nexus.pm new file mode 100644 index 00000000..9994c438 --- /dev/null +++ b/Info/Layer3/Nexus.pm @@ -0,0 +1,563 @@ +# SNMP::Info::Layer3::Nexus +# +# Copyright (c) 2012 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::Nexus; + +use strict; +use Exporter; +use SNMP::Info::LLDP; +use SNMP::Info::CDP; +use SNMP::Info::CiscoImage; +use SNMP::Info::CiscoPortSecurity; +use SNMP::Info::CiscoConfig; +use SNMP::Info::CiscoPower; +use SNMP::Info::Layer3; +use SNMP::Info::CiscoStpExtensions; +use SNMP::Info::CiscoVTP; + +use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; + +# NOTE : Top-most items gets precedence for @ISA +@SNMP::Info::Layer3::Nexus::ISA = qw/ + SNMP::Info::CiscoVTP + SNMP::Info::CiscoStpExtensions + SNMP::Info::LLDP + SNMP::Info::CDP + SNMP::Info::CiscoImage + SNMP::Info::CiscoPortSecurity + SNMP::Info::CiscoConfig + SNMP::Info::CiscoPower + SNMP::Info::Layer3 + Exporter +/; + +@SNMP::Info::Layer3::Nexus::EXPORT_OK = qw//; + +use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; + +$VERSION = '2.09'; + +# NOTE: Order creates precedence +# Example: v_name exists in Bridge.pm and CiscoVTP.pm +# Bridge is called from Layer3 and CiscoStpExtensions +# So we want CiscoVTP to come last to get the right one. +# The @ISA order should be reverse of these orders. + +%MIBS = ( + %SNMP::Info::Layer3::MIBS, + %SNMP::Info::CiscoPower::MIBS, + %SNMP::Info::CiscoConfig::MIBS, + %SNMP::Info::CiscoPortSecurity::MIBS, + %SNMP::Info::CiscoImage::MIBS, + %SNMP::Info::CDP::MIBS, + %SNMP::Info::LLDP::MIBS, + %SNMP::Info::CiscoStpExtensions::MIBS, + %SNMP::Info::CiscoVTP::MIBS, + 'CISCO-ENTITY-VENDORTYPE-OID-MIB' => 'cevMIBObjects', +); + +%GLOBALS = ( + %SNMP::Info::Layer3::GLOBALS, + %SNMP::Info::CiscoPower::GLOBALS, + %SNMP::Info::CiscoConfig::GLOBALS, + %SNMP::Info::CiscoPortSecurity::GLOBALS, + %SNMP::Info::CiscoImage::GLOBALS, + %SNMP::Info::CDP::GLOBALS, + %SNMP::Info::LLDP::GLOBALS, + %SNMP::Info::CiscoStpExtensions::GLOBALS, + %SNMP::Info::CiscoVTP::GLOBALS, + 'mac' => 'dot1dBaseBridgeAddress', +); + +%FUNCS = ( + %SNMP::Info::Layer3::FUNCS, + %SNMP::Info::CiscoPower::FUNCS, + %SNMP::Info::CiscoConfig::FUNCS, + %SNMP::Info::CiscoPortSecurity::FUNCS, + %SNMP::Info::CiscoImage::FUNCS, + %SNMP::Info::CDP::FUNCS, + %SNMP::Info::LLDP::FUNCS, + %SNMP::Info::CiscoStpExtensions::FUNCS, + %SNMP::Info::CiscoVTP::FUNCS, +); + + +%MUNGE = ( + %SNMP::Info::Layer3::MUNGE, + %SNMP::Info::CiscoPower::MUNGE, + %SNMP::Info::CiscoConfig::MUNGE, + %SNMP::Info::CiscoPortSecurity::MUNGE, + %SNMP::Info::CiscoImage::MUNGE, + %SNMP::Info::CDP::MUNGE, + %SNMP::Info::LLDP::MUNGE, + %SNMP::Info::CiscoStpExtensions::MUNGE, + %SNMP::Info::CiscoVTP::MUNGE, +); + +sub cisco_comm_indexing { return 1; } + +sub vendor { + return 'cisco'; +} + +sub os { + return 'nx-os'; +} + +sub os_ver { + my $nexus = shift; + my $descr = $nexus->description(); + + return $1 if ( $descr =~ /\),\s+Version\s+(.+?),/ ); +} + +sub serial { + my $nexus = shift; + + my $e_class = $nexus->e_class(); + + foreach my $iid ( keys %$e_class ) { + my $class = $e_class->{$iid} || ''; + if ($class =~ /chassis/) { + my $serial = $nexus->e_serial($iid); + return $serial->{$iid}; + } + } + return; +} + +# sysObjectID returns an IID to an entry in the CISCO-ENTITY-VENDORTYPE-OID-MIB. +# Look it up and return it. +sub model { + my $nexus = shift; + my $id = $nexus->id(); + + unless ( defined $id ) { + print + " SNMP::Info::Layer3::Nexus::model() - Device does not support sysObjectID\n" + if $nexus->debug(); + return; + } + + my $model = &SNMP::translateObj($id); + + return $id unless defined $model; + + $model =~ s/^cevChassis//i; + return $model; +} + +# Use CDP and/or LLDP +sub hasCDP { + my $nexus = shift; + + return $nexus->hasLLDP() || $nexus->SUPER::hasCDP(); +} + +sub c_ip { + my $nexus = shift; + my $partial = shift; + + my $cdp = $nexus->SUPER::c_ip($partial) || {}; + my $lldp = $nexus->lldp_ip($partial) || {}; + + my %c_ip; + foreach my $iid ( keys %$cdp ) { + my $ip = $cdp->{$iid}; + next unless defined $ip; + + $c_ip{$iid} = $ip; + } + + foreach my $iid ( keys %$lldp ) { + my $ip = $lldp->{$iid}; + next unless defined $ip; + + $c_ip{$iid} = $ip; + } + return \%c_ip; +} + +sub c_if { + my $nexus = shift; + my $partial = shift; + + my $lldp = $nexus->lldp_if($partial) || {}; + my $cdp = $nexus->SUPER::c_if($partial) || {}; + + my %c_if; + foreach my $iid ( keys %$cdp ) { + my $if = $cdp->{$iid}; + next unless defined $if; + + $c_if{$iid} = $if; + } + + foreach my $iid ( keys %$lldp ) { + my $if = $lldp->{$iid}; + next unless defined $if; + + $c_if{$iid} = $if; + } + return \%c_if; +} + +sub c_port { + my $nexus = shift; + my $partial = shift; + + my $lldp = $nexus->lldp_port($partial) || {}; + my $cdp = $nexus->SUPER::c_port($partial) || {}; + + my %c_port; + foreach my $iid ( keys %$cdp ) { + my $port = $cdp->{$iid}; + next unless defined $port; + + $c_port{$iid} = $port; + } + + foreach my $iid ( keys %$lldp ) { + my $port = $lldp->{$iid}; + next unless defined $port; + $c_port{$iid} = $port; + } + return \%c_port; +} + +sub c_id { + my $nexus = shift; + my $partial = shift; + + my $lldp = $nexus->lldp_id($partial) || {}; + my $cdp = $nexus->SUPER::c_id($partial) || {}; + + my %c_id; + foreach my $iid ( keys %$cdp ) { + my $id = $cdp->{$iid}; + next unless defined $id; + + $c_id{$iid} = $id; + } + + foreach my $iid ( keys %$lldp ) { + my $id = $lldp->{$iid}; + next unless defined $id; + + $c_id{$iid} = $id; + } + return \%c_id; +} + +sub c_platform { + my $nexus = shift; + my $partial = shift; + + my $lldp = $nexus->lldp_rem_sysdesc($partial) || {}; + my $cdp = $nexus->SUPER::c_platform($partial) || {}; + + my %c_platform; + foreach my $iid ( keys %$cdp ) { + my $platform = $cdp->{$iid}; + next unless defined $platform; + + $c_platform{$iid} = $platform; + } + + foreach my $iid ( keys %$lldp ) { + my $platform = $lldp->{$iid}; + next unless defined $platform; + + $c_platform{$iid} = $platform; + } + return \%c_platform; +} + +1; +__END__ + +=head1 NAME + +SNMP::Info::Layer3::Nexus - SNMP Interface to Cisco Nexus Switches running +NX-OS + +=head1 AUTHOR + +Eric Miller + +=head1 SYNOPSIS + + # Let SNMP::Info determine the correct subclass for you. + my $nexus = new SNMP::Info( + AutoSpecify => 1, + Debug => 1, + # These arguments are passed directly to SNMP::Session + DestHost => 'myswitch', + Community => 'public', + Version => 2 + ) + or die "Can't connect to DestHost.\n"; + + my $class = $nexus->class(); + print "SNMP::Info determined this device to fall under subclass : $class\n"; + +=head1 DESCRIPTION + +Abstraction subclass for Cisco Nexus Switches running NX-OS. + +For speed or debugging purposes you can call the subclass directly, but not +after determining a more specific class using the method above. + + my $nexus = new SNMP::Info::Layer3::Nexus(...); + +=head2 Inherited Classes + +=over + +=item SNMP::Info::Layer3 + +=item SNMP::Info::CiscoVTP + +=item SNMP::Info::CDP + +=item SNMP::Info::CiscoImage + +=item SNMP::Info::CiscoPortSecurity + +=item SNMP::Info::CiscoConfig + +=item SNMP::Info::CiscoPower + +=item SNMP::Info::CiscoStpExtensions + +=item SNMP::Info::LLDP + +=back + +=head2 Required MIBs + +=over + +=item F + +=back + +=over + +=item Inherited Classes' MIBs + +See L for its own MIB requirements. + +See L for its own MIB requirements. + +See L for its own MIB requirements. + +See L for its own MIB requirements. + +See L for its own MIB +requirements. + +See L for its own MIB requirements. + +See L for its own MIB requirements. + +See L for its own MIB requirements. + +See L for its own MIB requirements. + +=back + +=head1 GLOBALS + +These are methods that return a scalar value from SNMP + +=over + +=item $nexus->vendor() + +Returns 'cisco' + +=item $nexus->os() + +Returns 'nx-os' + +=item $nexus->os_ver() + +Returns operating system version extracted fron C. + +=item $nexus->serial() + +Returns the serial number of the chassis from F. + +=item $nexus->model() + +Tries to reference $nexus->id() to F + +Removes 'cevChassis' for readability. + +=item $nexus->mac() + +C + +=item $nexus->cisco_comm_indexing() + +Returns 1. Use vlan indexing. + +=back + +=head2 Globals imported from SNMP::Info::Layer3 + +See documentation in L for details. + +=head2 Global Methods imported from SNMP::Info::CiscoVTP + +See documentation in L for details. + +=head2 Globals imported from SNMP::Info::CDP + +See documentation in L for details. + +=head2 Globals imported from SNMP::Info::CiscoImage + +See documentation in L for details. + +=head2 Globals imported from SNMP::Info::CiscoPortSecurity + +See documentation in L for details. + +=head2 Globals imported from SNMP::Info::CiscoConfig + +See documentation in L for details. + +=head2 Globals imported from SNMP::Info::CiscoPower + +See documentation in L for details. + +=head2 Globals imported from SNMP::Info::CiscoStpExtensions + +See documentation in L for details. + +=head2 Globals 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 Topology information + +Based upon the firmware version Cisco devices may support Link Layer Discover +Protocol (LLDP) in addition to the Cisco-proprietary CDP. These methods +will query both and return the combination of all information. As a result, +there may be identical topology information returned from the two protocols +causing duplicate entries. It is the calling program's responsibility to +identify any duplicate entries and remove duplicates if necessary. + +=over + +=item $nexus->hasCDP() + +Returns true if the device is running either CDP or LLDP. + +=item $nexus->c_if() + +Returns reference to hash. Key: iid Value: local device port (interfaces) + +=item $nexus->c_ip() + +Returns reference to hash. Key: iid Value: remote IPv4 address + +If multiple entries exist with the same local port, c_if(), with the same IPv4 +address, c_ip(), it may be a duplicate entry. + +If multiple entries exist with the same local port, c_if(), with different +IPv4 addresses, c_ip(), there is either a non-CDP/LLDP device in between two +or more devices or multiple devices which are not directly connected. + +Use the data from the Layer2 Topology Table below to dig deeper. + +=item $nexus->c_port() + +Returns reference to hash. Key: iid Value: remote port (interfaces) + +=item $nexus->c_id() + +Returns reference to hash. Key: iid Value: string value used to identify the +chassis component associated with the remote system. + +=item $nexus->c_platform() + +Returns reference to hash. Key: iid Value: Remote Device Type + +=back + +=head2 Table Methods imported from SNMP::Info::Layer3 + +See documentation in L for details. + +=head2 Table Methods imported from SNMP::Info::CiscoVTP + +See documentation in L for details. + +=head2 Table Methods imported from SNMP::Info::CDP + +See documentation in L for details. + +=head2 Table Methods imported from SNMP::Info::CiscoStats + +See documentation in L for details. + +=head2 Table Methods imported from SNMP::Info::CiscoImage + +See documentation in L for details. + +=head2 Table Methods imported from SNMP::Info::CiscoPortSecurity + +See documentation in L for +details. + +=head2 Table Methods imported from SNMP::Info::CiscoConfig + +See documentation in L for details. + +=head2 Table Methods imported from SNMP::Info::CiscoPower + +See documentation in L for details. + +=head2 Table Methods imported from SNMP::Info::CiscoStpExtensions + +See documentation in L for details. + +=head2 Table Methods imported from SNMP::Info::LLDP + +See documentation in L for details. + +=cut diff --git a/MANIFEST b/MANIFEST index e97e1a18..1e8821a0 100644 --- a/MANIFEST +++ b/MANIFEST @@ -76,6 +76,7 @@ Info/Layer3/Mikrotik.pm Info/Layer3/N1600.pm Info/Layer3/Netscreen.pm Info/Layer3/NetSNMP.pm +Info/Layer3/Nexus.pm Info/Layer3/PacketFront.pm Info/Layer3/Passport.pm Info/Layer3/Pf.pm