1284 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			1284 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| # SNMP::Info::Layer3::Foundry - SNMP Interface to Foundry devices
 | |
| # $Id$
 | |
| #
 | |
| # Copyright (c) 2008 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::Foundry;
 | |
| 
 | |
| use strict;
 | |
| use Exporter;
 | |
| use SNMP::Info::Layer3;
 | |
| use SNMP::Info::FDP;
 | |
| use SNMP::Info::LLDP;
 | |
| 
 | |
| @SNMP::Info::Layer3::Foundry::ISA = qw/
 | |
|     SNMP::Info::FDP
 | |
|     SNMP::Info::LLDP
 | |
|     SNMP::Info::Layer3
 | |
|     Exporter
 | |
| /;
 | |
| @SNMP::Info::Layer3::Foundry::EXPORT_OK = qw//;
 | |
| 
 | |
| use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 | |
| 
 | |
| $VERSION = '3.65';
 | |
| 
 | |
| %MIBS = (
 | |
|     %SNMP::Info::Layer3::MIBS,
 | |
|     %SNMP::Info::LLDP::MIBS,
 | |
|     %SNMP::Info::FDP::MIBS,
 | |
| 
 | |
|     'FOUNDRY-SN-ROOT-MIB'         => 'foundry',
 | |
|     'FOUNDRY-SN-AGENT-MIB'        => 'snChasPwrSupplyDescription',
 | |
|     'FOUNDRY-SN-SWITCH-GROUP-MIB' => 'snSwGroupOperMode',
 | |
|     'FOUNDRY-SN-STACKING-MIB'     => 'snStackingOperUnitRole',
 | |
|     'FOUNDRY-POE-MIB'             => 'snAgentPoeGblPowerCapacityTotal',
 | |
|     'FOUNDRY-SN-SWITCH-GROUP-MIB' => 'snSwGroupOperMode',
 | |
|     'BROCADE-PRODUCTS-MIB'        => 'brocadeProducts',
 | |
| );
 | |
| 
 | |
| %GLOBALS = (
 | |
|     %SNMP::Info::Layer3::GLOBALS,
 | |
|     %SNMP::Info::LLDP::GLOBALS,
 | |
|     %SNMP::Info::FDP::GLOBALS,
 | |
| 
 | |
|     'mac'        => 'ifPhysAddress.1',
 | |
|     'chassis'    => 'entPhysicalDescr.1',
 | |
|     'temp'       => 'snChasActualTemperature',
 | |
|     'ps1_type'   => 'snChasPwrSupplyDescription.1',
 | |
|     'ps1_status' => 'snChasPwrSupplyOperStatus.1',
 | |
|     'fan'        => 'snChasFanOperStatus.1',
 | |
|     'img_ver'    => 'snAgImgVer',
 | |
|     'ch_serial'  => 'snChasSerNum',
 | |
| 
 | |
| );
 | |
| 
 | |
| %FUNCS = (
 | |
|     %SNMP::Info::Layer3::FUNCS,
 | |
|     %SNMP::Info::LLDP::FUNCS,
 | |
|     %SNMP::Info::FDP::FUNCS,
 | |
| 
 | |
|     # FOUNDRY-SN-SWITCH-GROUP-MIB
 | |
|     # snSwPortInfoTable - Switch Port Information Group
 | |
|     'sw_index'  => 'snSwPortIfIndex',
 | |
|     'sw_duplex' => 'snSwPortInfoChnMode',
 | |
|     'sw_type'   => 'snSwPortInfoMediaType',
 | |
|     'sw_speed'  => 'snSwPortInfoSpeed',
 | |
| 
 | |
|     # FOUNDRY-SN-AGENT-MIB::snAgentConfigModule2Table
 | |
|     'ag_mod2_type' => 'snAgentConfigModule2Type',
 | |
| 
 | |
|     # FOUNDRY-SN-AGENT-MIB::snAgentConfigModuleTable
 | |
|     'ag_mod_type' => 'snAgentConfigModuleType',
 | |
| 
 | |
|     # FOUNDRY-SN-AGENT-MIB::snVLanByPortTable
 | |
|     'stp_i_id'        => 'snVLanByPortVLanId',
 | |
|     'stp_i_mac'       => 'snVLanByPortBaseBridgeAddress',
 | |
|     'stp_i_time'      => 'snVLanByPortStpTimeSinceTopologyChange',
 | |
|     'stp_i_ntop'      => 'snVLanByPortStpTopChanges',
 | |
|     'stp_i_root'      => 'snVLanByPortStpDesignatedRoot',
 | |
|     'stp_i_root_port' => 'snVLanByPortStpRootPort',
 | |
|     'stp_i_priority'  => 'snVLanByPortStpPriority',
 | |
| 
 | |
|     # FOUNDRY-SN-AGENT-MIB::snPortStpTable
 | |
|     'stp_p_id'       => 'snPortStpPortNum',
 | |
|     'stp_p_stg_id'   => 'snPortStpVLanId',
 | |
|     'stp_p_priority' => 'snPortStpPortPriority',
 | |
|     'stp_p_state'    => 'snPortStpPortState',
 | |
|     'stp_p_cost'     => 'snPortStpPortDesignatedCost',
 | |
|     'stp_p_root'     => 'snPortStpPortDesignatedRoot',
 | |
|     'stp_p_bridge'   => 'snPortStpPortDesignatedBridge',
 | |
|     'stp_p_port'     => 'snPortStpPortDesignatedPort',
 | |
| );
 | |
| 
 | |
| %MUNGE = (
 | |
|     %SNMP::Info::Layer3::MUNGE,
 | |
|     %SNMP::Info::LLDP::MUNGE,
 | |
|     %SNMP::Info::FDP::MUNGE,
 | |
| 
 | |
|     'ag_mod2_type' => \&SNMP::Info::munge_e_type,
 | |
|     'ag_mod_type'  => \&SNMP::Info::munge_e_type,
 | |
|     'stp_i_mac'    => \&SNMP::Info::munge_mac,
 | |
|     'stp_i_root'   => \&SNMP::Info::munge_prio_mac,
 | |
|     'stp_p_root'   => \&SNMP::Info::munge_prio_mac,
 | |
|     'stp_p_bridge' => \&SNMP::Info::munge_prio_mac,
 | |
|     'stp_p_port'   => \&SNMP::Info::munge_prio_port,
 | |
| );
 | |
| 
 | |
| sub i_ignore {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $interfaces = $foundry->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 $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $sw_index  = $foundry->sw_index($partial);
 | |
|     my $sw_duplex = $foundry->sw_duplex($partial);
 | |
| 
 | |
|     unless ( defined $sw_index and defined $sw_duplex ) {
 | |
|         return $foundry->SUPER::i_duplex();
 | |
|     }
 | |
| 
 | |
|     my %i_duplex;
 | |
|     foreach my $sw_port ( keys %$sw_duplex ) {
 | |
|         my $iid    = $sw_index->{$sw_port};
 | |
|         my $duplex = $sw_duplex->{$sw_port};
 | |
|         next if $duplex =~ /none/i;
 | |
|         $i_duplex{$iid} = 'half' if $duplex =~ /half/i;
 | |
|         $i_duplex{$iid} = 'full' if $duplex =~ /full/i;
 | |
|     }
 | |
|     return \%i_duplex;
 | |
| }
 | |
| 
 | |
| sub model {
 | |
|     my $foundry = shift;
 | |
|     my $id      = $foundry->id();
 | |
|     my $model   = &SNMP::translateObj($id);
 | |
| 
 | |
|     # EdgeIron
 | |
|     if ( $id =~ /\.1991\.1\.[45]\./ ) {
 | |
| 
 | |
|         my $e_name = $foundry->e_name();
 | |
| 
 | |
|         # Find entity table entry for "unit.1"
 | |
|         my $unit_iid = undef;
 | |
|         foreach my $e ( keys %$e_name ) {
 | |
|             my $name = $e_name->{$e} || '';
 | |
|             $unit_iid = $e if $name eq 'unit.1';
 | |
|         }
 | |
| 
 | |
|         # Find Model Name
 | |
|         my $e_model = $foundry->e_model();
 | |
|         if ( defined $e_model->{$unit_iid} ) {
 | |
|             return $e_model->{$unit_iid};
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return $id unless defined $model;
 | |
| 
 | |
|     $model =~ s/^sn//;
 | |
|     $model =~ s/Switch//;
 | |
| 
 | |
|     return $model;
 | |
| }
 | |
| 
 | |
| sub os {
 | |
|     return 'brocade';
 | |
| }
 | |
| 
 | |
| sub vendor {
 | |
|     return 'brocade';
 | |
| }
 | |
| 
 | |
| sub os_ver {
 | |
|     my $foundry = shift;
 | |
| 
 | |
|     return $foundry->img_ver() if ( defined $foundry->img_ver() );
 | |
| 
 | |
|     # Some older ones don't have this value,so we cull it from the description
 | |
|     my $descr = $foundry->description();
 | |
|     if ( $descr =~ m/Version (\d\S*)/ ) {
 | |
|         return $1;
 | |
|     }
 | |
| 
 | |
|     # EdgeIron
 | |
|     my $e_name = $foundry->e_name();
 | |
| 
 | |
|     # find entity table entry for "stackmanaget.1"
 | |
|     my $unit_iid = undef;
 | |
|     foreach my $e ( keys %$e_name ) {
 | |
|         my $name = $e_name->{$e} || '';
 | |
|         $unit_iid = $e if $name eq 'stackmanaget.1';
 | |
|     }
 | |
| 
 | |
|     if ( defined $unit_iid ) {
 | |
| 
 | |
|         # Find Model Name
 | |
|         my $e_fwver = $foundry->e_fwver();
 | |
|         if ( defined $e_fwver->{$unit_iid} ) {
 | |
|             return $e_fwver->{$unit_iid};
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # See if we report from Flash if wouldn't report from running above
 | |
|     return $foundry->snAgFlashImgVer() if ( defined $foundry->snAgFlashImgVer() );
 | |
| 
 | |
|     # Last resort
 | |
|     return $foundry->SUPER::os_ver();
 | |
| 
 | |
| }
 | |
| 
 | |
| sub serial {
 | |
|     my $foundry = shift;
 | |
| 
 | |
|     # Return chassis serial number if available
 | |
|     return $foundry->ch_serial() if ( $foundry->ch_serial() );
 | |
| 
 | |
|     # If no chassis serial use first module serial
 | |
|     my $mod_serials = $foundry->snAgentConfigModuleSerialNumber() || {};
 | |
| 
 | |
|     foreach my $mod ( sort keys %$mod_serials ) {
 | |
|         my $serial = $mod_serials->{$mod} || '';
 | |
|         next unless defined $serial;
 | |
|         return $serial;
 | |
|     }
 | |
| 
 | |
|     # EdgeIron
 | |
|     my $e_name = $foundry->e_name();
 | |
| 
 | |
|     # find entity table entry for "unit.1"
 | |
|     my $unit_iid = undef;
 | |
|     foreach my $e ( keys %$e_name ) {
 | |
|         my $name = $e_name->{$e} || '';
 | |
|         $unit_iid = $e if $name eq 'unit.1';
 | |
|     }
 | |
| 
 | |
|     if ( defined $unit_iid ) {
 | |
| 
 | |
|         # Look up serial of found entry.
 | |
|         my $e_serial = $foundry->e_serial();
 | |
|         return $e_serial->{$unit_iid} if defined $e_serial->{$unit_iid};
 | |
|     }
 | |
| 
 | |
|     # Last resort
 | |
|     return $foundry->SUPER::serial();
 | |
| }
 | |
| 
 | |
| sub interfaces {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $i_descr = $foundry->i_description($partial) || {};
 | |
|     my $i_name  = $foundry->i_name($partial)        || {};
 | |
| 
 | |
|     # Use ifName for EdgeIrons else use ifDescr
 | |
|     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;
 | |
| }
 | |
| 
 | |
| # Entity MIB is supported on the Brocade NetIron XMR, NetIron MLX, MLXe,
 | |
| # NetIron CES, NetIron CER, and older EdgeIron series devices.
 | |
| # Try Entity MIB methods first and fall back to Pseudo ENTITY-MIB methods for
 | |
| # other devices.
 | |
| # e_fwver, e_hwver, e_swver not supported in psuedo methods, no need to
 | |
| # override
 | |
| 
 | |
| sub e_index {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $foundry->SUPER::e_index($partial)
 | |
|         || $foundry->brcd_e_index($partial);
 | |
| }
 | |
| 
 | |
| sub e_class {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $foundry->SUPER::e_class($partial)
 | |
|         || $foundry->brcd_e_class($partial);
 | |
| }
 | |
| 
 | |
| sub e_descr {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $foundry->SUPER::e_descr($partial)
 | |
|         || $foundry->brcd_e_descr($partial);
 | |
| }
 | |
| 
 | |
| sub e_name {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $foundry->SUPER::e_name($partial)
 | |
|         || $foundry->brcd_e_name($partial);
 | |
| }
 | |
| 
 | |
| sub e_parent {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $foundry->SUPER::e_parent($partial)
 | |
|         || $foundry->brcd_e_parent($partial);
 | |
| }
 | |
| 
 | |
| sub e_pos {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $foundry->SUPER::e_pos($partial) || $foundry->brcd_e_pos($partial);
 | |
| }
 | |
| 
 | |
| sub e_serial {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $foundry->SUPER::e_serial($partial)
 | |
|         || $foundry->brcd_e_serial($partial);
 | |
| }
 | |
| 
 | |
| sub e_type {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $foundry->SUPER::e_type($partial)
 | |
|         || $foundry->brcd_e_type($partial);
 | |
| }
 | |
| 
 | |
| sub e_vendor {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $foundry->SUPER::e_vendor($partial)
 | |
|         || $foundry->brcd_e_vendor($partial);
 | |
| }
 | |
| 
 | |
| # Pseudo ENTITY-MIB methods
 | |
| 
 | |
| # This class supports both stackable and chassis based switches, identify if
 | |
| # we have a stackable so that we return appropriate entPhysicalClass
 | |
| 
 | |
| # Identify if the stackable is actually a stack vs. single switch
 | |
| sub _brcd_stack_master {
 | |
|     my $foundry = shift;
 | |
| 
 | |
|     my $roles = $foundry->snStackingOperUnitRole() || {};
 | |
| 
 | |
|     foreach my $iid ( keys %$roles ) {
 | |
|         my $role = $roles->{$iid};
 | |
|         next unless $role;
 | |
|         if ( $role eq 'active' ) {
 | |
|             return $iid;
 | |
|         }
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| sub brcd_e_index {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $stack_master = $foundry->_brcd_stack_master();
 | |
|     my $brcd_e_idx
 | |
|         = $foundry->snAgentConfigModule2Description($partial)
 | |
|         || $foundry->snAgentConfigModuleDescription($partial)
 | |
|         || {};
 | |
| 
 | |
|     my %brcd_e_index;
 | |
|     if ($stack_master) {
 | |
| 
 | |
|         # Stack Entity
 | |
|         $brcd_e_index{0} = 1;
 | |
|     }
 | |
| 
 | |
|     foreach my $iid ( keys %$brcd_e_idx ) {
 | |
| 
 | |
|         my $index = $iid;
 | |
| 
 | |
|         # Format into consistent integer format so that numeric sorting works
 | |
|         if ( $iid =~ /(\d+)\.(\d+)/ ) {
 | |
|             $index = "$1" . sprintf "%02d", $2;
 | |
|         }
 | |
|         $brcd_e_index{$iid} = $index;
 | |
|     }
 | |
|     return \%brcd_e_index;
 | |
| }
 | |
| 
 | |
| sub brcd_e_class {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $e_idx = $foundry->brcd_e_index($partial) || {};
 | |
| 
 | |
|     my %e_class;
 | |
|     foreach my $iid ( keys %$e_idx ) {
 | |
|         if ( $iid == 0 ) {
 | |
|             $e_class{$iid} = 'stack';
 | |
|         }
 | |
| 
 | |
|         # Were going to assume chassis at slot/index 1
 | |
|         # If this turns out to be false in some cases we can check
 | |
|         # snAgentConfigModuleNumberOfCpus as other modules won't have cpus?
 | |
|         elsif ( $iid =~ /1$/ ) {
 | |
|             $e_class{$iid} = 'chassis';
 | |
|         }
 | |
|         else {
 | |
|             $e_class{$iid} = 'module';
 | |
|         }
 | |
|     }
 | |
|     return \%e_class;
 | |
| }
 | |
| 
 | |
| sub brcd_e_descr {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $brcd_e_idx = $foundry->brcd_e_index($partial) || {};
 | |
|     my $m_descrs
 | |
|         = $foundry->snAgentConfigModule2Description($partial)
 | |
|         || $foundry->snAgentConfigModuleDescription($partial)
 | |
|         || {};
 | |
| 
 | |
|     my %brcd_e_descr;
 | |
|     foreach my $iid ( keys %$brcd_e_idx ) {
 | |
| 
 | |
|         if ( $iid == 0 ) {
 | |
|             $brcd_e_descr{$iid} = $foundry->description();
 | |
|         }
 | |
| 
 | |
|         my $descr = $m_descrs->{$iid};
 | |
|         next unless defined $descr;
 | |
| 
 | |
|         $brcd_e_descr{$iid} = $descr;
 | |
|     }
 | |
|     return \%brcd_e_descr;
 | |
| }
 | |
| 
 | |
| sub brcd_e_name {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $stack_master = $foundry->_brcd_stack_master();
 | |
|     my $e_idx = $foundry->brcd_e_index($partial) || {};
 | |
| 
 | |
|     my %brcd_e_name;
 | |
|     foreach my $iid ( keys %$e_idx ) {
 | |
|         if ( $iid == 0 ) {
 | |
|             $brcd_e_name{$iid} = 'Stack Master Unit';
 | |
|         }
 | |
| 
 | |
|         elsif ( $stack_master && $iid =~ /(\d+)\.1$/ ) {
 | |
|             $brcd_e_name{$iid} = "Switch Stack Unit $1";
 | |
|         }
 | |
|         elsif ( $iid =~ /1$/ ) {
 | |
|             $brcd_e_name{$iid} = "Switch";
 | |
|         }
 | |
|         else {
 | |
|             $brcd_e_name{$iid} = 'Module';
 | |
|         }
 | |
|     }
 | |
|     return \%brcd_e_name;
 | |
| }
 | |
| 
 | |
| sub brcd_e_vendor {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $e_idx = $foundry->brcd_e_index($partial) || {};
 | |
| 
 | |
|     my %brcd_e_vendor;
 | |
|     foreach my $iid ( keys %$e_idx ) {
 | |
|         my $vendor = 'brocade';
 | |
| 
 | |
|         $brcd_e_vendor{$iid} = $vendor;
 | |
|     }
 | |
|     return \%brcd_e_vendor;
 | |
| }
 | |
| 
 | |
| sub brcd_e_serial {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $e_idx = $foundry->brcd_e_index($partial) || {};
 | |
|     my $serials
 | |
|         = $foundry->snAgentConfigModule2SerialNumber($partial)
 | |
|         || $foundry->snAgentConfigModuleSerialNumber($partial)
 | |
|         || {};
 | |
| 
 | |
|     my %brcd_e_serial;
 | |
|     foreach my $iid ( keys %$e_idx ) {
 | |
| 
 | |
|         if ( $iid == 0 ) {
 | |
|             $brcd_e_serial{$iid} = $foundry->serial();
 | |
|         }
 | |
| 
 | |
|         my $serial = $serials->{$iid};
 | |
|         next unless defined $serial;
 | |
| 
 | |
|         $brcd_e_serial{$iid} = $serial;
 | |
|     }
 | |
|     return \%brcd_e_serial;
 | |
| }
 | |
| 
 | |
| sub brcd_e_type {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $e_idx = $foundry->brcd_e_index($partial) || {};
 | |
|     my $types
 | |
|         = $foundry->ag_mod2_type($partial)
 | |
|         || $foundry->ag_mod_type($partial)
 | |
|         || {};
 | |
| 
 | |
|     my %brcd_e_type;
 | |
|     foreach my $iid ( keys %$e_idx ) {
 | |
| 
 | |
|         if ( $iid == 0 ) {
 | |
|             $brcd_e_type{$iid} = $foundry->model();
 | |
|         }
 | |
| 
 | |
|         my $type = $types->{$iid};
 | |
|         next unless defined $type;
 | |
| 
 | |
|         $brcd_e_type{$iid} = $type;
 | |
|     }
 | |
|     return \%brcd_e_type;
 | |
| }
 | |
| 
 | |
| sub brcd_e_pos {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $e_idx = $foundry->brcd_e_index($partial) || {};
 | |
| 
 | |
|     my %brcd_e_pos;
 | |
|     foreach my $iid ( keys %$e_idx ) {
 | |
| 
 | |
|         my $pos;
 | |
|         if ( $iid == 0 ) {
 | |
|             $pos = -1;
 | |
|         }
 | |
|         elsif ( $iid =~ /(\d+)\.1$/ ) {
 | |
|             $pos = $1;
 | |
|         }
 | |
|         elsif ( $iid =~ /(\d+)$/ ) {
 | |
|             $pos = $1;
 | |
|         }
 | |
| 
 | |
|         $brcd_e_pos{$iid} = $pos;
 | |
|     }
 | |
|     return \%brcd_e_pos;
 | |
| }
 | |
| 
 | |
| sub brcd_e_parent {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $stack_master = $foundry->_brcd_stack_master();
 | |
|     my $e_idx = $foundry->brcd_e_index($partial) || {};
 | |
| 
 | |
|     my %brcd_e_parent;
 | |
|     foreach my $iid ( keys %$e_idx ) {
 | |
| 
 | |
|         if ( $iid == 0 ) {
 | |
|             $brcd_e_parent{$iid} = 0;
 | |
|         }
 | |
|         elsif ( $stack_master && $iid =~ /(\d+)\.1$/ ) {
 | |
|             $brcd_e_parent{$iid} = 1;
 | |
|         }
 | |
|         elsif ( $iid =~ /1$/ ) {
 | |
|             $brcd_e_parent{$iid} = 0;
 | |
|         }
 | |
|         elsif ( $iid =~ /(\d+).\d+/ ) {
 | |
|             $brcd_e_parent{$iid} = "$1" . "01";
 | |
|         }
 | |
| 
 | |
|         # assume non-stacked and chassis at index 1
 | |
|         else {
 | |
|             $brcd_e_parent{$iid} = 1;
 | |
|         }
 | |
|     }
 | |
|     return \%brcd_e_parent;
 | |
| }
 | |
| 
 | |
| # The index of snAgentPoePortTable is snAgentPoePortNumber which equals
 | |
| # ifIndex; however, to emulate POWER-ETHERNET-MIB we need a "module.port"
 | |
| # index.  If ifDescr has the format x/x/x use it to determine the module
 | |
| # otherwise default to 1.  Unfortunately, this means we can't map any
 | |
| # snAgentPoePortTable leafs directly and partials will not be supported.
 | |
| sub peth_port_ifindex {
 | |
|     my $foundry = shift;
 | |
| 
 | |
|     my $indexes = $foundry->snAgentPoePortNumber();
 | |
|     my $descrs  = $foundry->i_description();
 | |
| 
 | |
|     my $peth_port_ifindex = {};
 | |
|     foreach my $i ( keys %$indexes ) {
 | |
|         my $descr = $descrs->{$i};
 | |
|         next unless $descr;
 | |
| 
 | |
|         my $new_idx = "1.$i";
 | |
| 
 | |
|         if ( $descr =~ /(\d+)\/\d+\/\d+/ ) {
 | |
|             $new_idx = "$1.$i";
 | |
|         }
 | |
|         $peth_port_ifindex->{$new_idx} = $i;
 | |
|     }
 | |
|     return $peth_port_ifindex;
 | |
| }
 | |
| 
 | |
| sub peth_port_admin {
 | |
|     my $foundry = shift;
 | |
| 
 | |
|     my $p_index      = $foundry->peth_port_ifindex()     || {};
 | |
|     my $admin_states = $foundry->snAgentPoePortControl() || {};
 | |
| 
 | |
|     my $peth_port_admin = {};
 | |
|     foreach my $i ( keys %$p_index ) {
 | |
|         my ( $module, $port ) = split( /\./, $i );
 | |
|         my $state = $admin_states->{$port};
 | |
| 
 | |
|         if ( $state =~ /enable/ ) {
 | |
|             $peth_port_admin->{$i} = 'true';
 | |
|         }
 | |
|         else {
 | |
|             $peth_port_admin->{$i} = 'false';
 | |
|         }
 | |
|     }
 | |
|     return $peth_port_admin;
 | |
| }
 | |
| 
 | |
| sub peth_port_neg_power {
 | |
|     my $foundry = shift;
 | |
| 
 | |
|     my $p_index         = $foundry->peth_port_ifindex()   || {};
 | |
|     my $peth_port_class = $foundry->snAgentPoePortClass() || {};
 | |
| 
 | |
|     my $poemax = {
 | |
|         '0' => 12950,
 | |
|         '1' => 3840,
 | |
|         '2' => 6490,
 | |
|         '3' => 12950,
 | |
|         '4' => 25500
 | |
|     };
 | |
| 
 | |
|     my $peth_port_neg_power = {};
 | |
|     foreach my $i ( keys %$p_index ) {
 | |
|         my ( $module, $port ) = split( /\./, $i );
 | |
|         my $power = $poemax->{ $peth_port_class->{$port} };
 | |
|         next unless $power;
 | |
| 
 | |
|         $peth_port_neg_power->{$i} = $power;
 | |
|     }
 | |
|     return $peth_port_neg_power;
 | |
| }
 | |
| 
 | |
| sub peth_port_power {
 | |
|     my $foundry = shift;
 | |
| 
 | |
|     my $p_index       = $foundry->peth_port_ifindex()      || {};
 | |
|     my $port_consumed = $foundry->snAgentPoePortConsumed() || {};
 | |
| 
 | |
|     my $peth_port_power = {};
 | |
|     foreach my $i ( keys %$p_index ) {
 | |
|         my ( $module, $port ) = split( /\./, $i );
 | |
|         my $power = $port_consumed->{$port};
 | |
|         next unless $power;
 | |
| 
 | |
|         $peth_port_power->{$i} = $power;
 | |
|     }
 | |
|     return $peth_port_power;
 | |
| }
 | |
| 
 | |
| sub peth_port_class {
 | |
|     my $foundry = shift;
 | |
| 
 | |
|     my $p_index    = $foundry->peth_port_ifindex()   || {};
 | |
|     my $port_class = $foundry->snAgentPoePortClass() || {};
 | |
| 
 | |
|     my $peth_port_class = {};
 | |
|     foreach my $i ( keys %$p_index ) {
 | |
|         my ( $module, $port ) = split( /\./, $i );
 | |
|         my $power = $port_class->{$port};
 | |
|         next unless $power;
 | |
| 
 | |
|         $peth_port_class->{$i} = "class$power";
 | |
|     }
 | |
|     return $peth_port_class;
 | |
| }
 | |
| 
 | |
| sub peth_port_status {
 | |
|     my $foundry = shift;
 | |
| 
 | |
|     my $p_index      = $foundry->peth_port_ifindex()     || {};
 | |
|     my $admin_states = $foundry->snAgentPoePortControl() || {};
 | |
| 
 | |
|     my $peth_port_status = {};
 | |
|     foreach my $i ( keys %$p_index ) {
 | |
|         my ( $module, $port ) = split( /\./, $i );
 | |
|         my $state = $admin_states->{$port};
 | |
| 
 | |
|         if ( $state =~ /enable/ ) {
 | |
|             $peth_port_status->{$i} = 'deliveringPower';
 | |
|         }
 | |
|         else {
 | |
|             $peth_port_status->{$i} = 'disabled';
 | |
|         }
 | |
|     }
 | |
|     return $peth_port_status;
 | |
| }
 | |
| 
 | |
| sub peth_power_status {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $watts = $foundry->snAgentPoeUnitPowerCapacityTotal($partial) || {};
 | |
| 
 | |
|     my $peth_power_status = {};
 | |
|     foreach my $i ( keys %$watts ) {
 | |
|         $peth_power_status->{$i} = 'on';
 | |
|     }
 | |
|     return $peth_power_status;
 | |
| }
 | |
| 
 | |
| sub peth_power_watts {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $watts_total = $foundry->snAgentPoeUnitPowerCapacityTotal($partial)
 | |
|         || {};
 | |
| 
 | |
|     my $peth_power_watts = {};
 | |
|     foreach my $i ( keys %$watts_total ) {
 | |
|         my $total = $watts_total->{$i};
 | |
|         next unless $total;
 | |
| 
 | |
|         $peth_power_watts->{$i} = $total / 1000;
 | |
|     }
 | |
|     return $peth_power_watts;
 | |
| }
 | |
| 
 | |
| sub peth_power_consumption {
 | |
|     my $foundry = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $watts_total = $foundry->snAgentPoeUnitPowerCapacityTotal($partial)
 | |
|         || {};
 | |
|     my $watts_free = $foundry->snAgentPoeUnitPowerCapacityFree($partial)
 | |
|         || {};
 | |
| 
 | |
|     my $peth_power_consumed = {};
 | |
|     foreach my $i ( keys %$watts_total ) {
 | |
|         my $total = $watts_total->{$i};
 | |
|         next unless $total;
 | |
|         my $free = $watts_free->{$i} || 0;
 | |
| 
 | |
|         $peth_power_consumed->{$i} = ( $total - $free ) / 1000;
 | |
|     }
 | |
|     return $peth_power_consumed;
 | |
| }
 | |
| 
 | |
| sub agg_ports {
 | |
|   my $dev = shift;
 | |
| 
 | |
|   # TODO: implement partial
 | |
|   my $trunks = $dev->snMSTrunkPortList;
 | |
|   my $ports  = $dev->snSwPortIfIndex; # sw_index()
 | |
| 
 | |
|   return {} unless
 | |
|     ref {} eq ref $trunks and scalar keys %$trunks
 | |
|     and ref {} eq ref $ports and scalar keys %$ports;
 | |
| 
 | |
|   my $ret = {};
 | |
|   foreach my $m (keys %$trunks) {
 | |
|       my $skip = 0;
 | |
|       while (my $s = unpack("x${skip}n2", $trunks->{$m})) {
 | |
|           $ret->{ $ports->{$s} } = $ports->{$m};
 | |
|           $skip += 2;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   return $ret;
 | |
| }
 | |
| 
 | |
| sub i_stp_state {
 | |
|     my $foundry  = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $bp_index    = $foundry->bp_index($partial);
 | |
|     my $stp_p_state = $foundry->dot1dStpPortState($partial);
 | |
| 
 | |
|     my %i_stp_state;
 | |
| 
 | |
|     foreach my $index ( keys %$stp_p_state ) {
 | |
|         my $state = $stp_p_state->{$index};
 | |
|         my $iid   = $bp_index->{$index};
 | |
|         next unless defined $iid;
 | |
|         next unless defined $state;
 | |
|         $i_stp_state{$iid} = $state;
 | |
|     }
 | |
| 
 | |
|     return \%i_stp_state;
 | |
| }
 | |
| 
 | |
| 1;
 | |
| __END__
 | |
| 
 | |
| =head1 NAME
 | |
| 
 | |
| SNMP::Info::Layer3::Foundry - SNMP Interface to Brocade (Foundry) Network
 | |
| Devices
 | |
| 
 | |
| =head1 AUTHOR
 | |
| 
 | |
| Max Baker
 | |
| 
 | |
| =head1 SYNOPSIS
 | |
| 
 | |
|  # Let SNMP::Info determine the correct subclass for you.
 | |
|  my $foundry = new SNMP::Info(
 | |
|                           AutoSpecify => 1,
 | |
|                           Debug       => 1,
 | |
|                           DestHost    => 'myswitch',
 | |
|                           Community   => 'public',
 | |
|                           Version     => 1
 | |
|                         )
 | |
|     or die "Can't connect to DestHost.\n";
 | |
| 
 | |
|  my $class = $foundry->class();
 | |
| 
 | |
|  print "SNMP::Info determined this device to fall under subclass : $class\n";
 | |
| 
 | |
| =head1 DESCRIPTION
 | |
| 
 | |
| Abstraction subclass for Brocade (Foundry) Networks 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 $foundry = new SNMP::Info::Layer3::Foundry(...);
 | |
| 
 | |
| =head2 Inherited Classes
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item SNMP::Info::Layer3;
 | |
| 
 | |
| =item SNMP::Info::FDP;
 | |
| 
 | |
| =item SNMP::Info::LLDP;
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Required MIBs
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item F<FOUNDRY-SN-ROOT-MIB>
 | |
| 
 | |
| =item F<FOUNDRY-SN-AGENT-MIB>
 | |
| 
 | |
| =item F<FOUNDRY-SN-SWITCH-GROUP-MIB>
 | |
| 
 | |
| =item F<FOUNDRY-SN-STACKING-MIB>
 | |
| 
 | |
| =item F<FOUNDRY-POE-MIB>
 | |
| 
 | |
| =item F<FOUNDRY-SN-SWITCH-GROUP-MIB>
 | |
| 
 | |
| =item Inherited Classes' MIBs
 | |
| 
 | |
| See L<SNMP::Info::Layer3/"Required MIBs"> for its own MIB requirements.
 | |
| 
 | |
| See L<SNMP::Info::FDP/"Required MIBs"> for its own MIB requirements.
 | |
| 
 | |
| See L<SNMP::Info::LLDP/"Required MIBs"> for its own MIB requirements.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 GLOBALS
 | |
| 
 | |
| These are methods that return scalar value from SNMP
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $foundry->model()
 | |
| 
 | |
| Returns model type.  Checks $foundry->id() against the F<FOUNDRY-SN-ROOT-MIB>
 | |
| and removes 'C<sn>' and 'C<Switch>'.  EdgeIron models determined
 | |
| through F<ENTITY-MIB>.
 | |
| 
 | |
| =item $foundry->vendor()
 | |
| 
 | |
| Returns 'brocade'
 | |
| 
 | |
| =item $foundry->os()
 | |
| 
 | |
| Returns 'brocade'
 | |
| 
 | |
| =item $foundry->os_ver()
 | |
| 
 | |
| Returns the software version
 | |
| 
 | |
| =item $foundry->mac()
 | |
| 
 | |
| Returns MAC Address of root port.
 | |
| 
 | |
| (C<ifPhysAddress.1>)
 | |
| 
 | |
| =item $foundry->chassis()
 | |
| 
 | |
| Returns Chassis type.
 | |
| 
 | |
| (C<entPhysicalDescr.1>)
 | |
| 
 | |
| =item $foundry->serial()
 | |
| 
 | |
| Returns serial number of device.
 | |
| 
 | |
| =item $foundry->temp()
 | |
| 
 | |
| Returns the chassis temperature
 | |
| 
 | |
| (C<snChasActualTemperature>)
 | |
| 
 | |
| =item $foundry->ps1_type()
 | |
| 
 | |
| Returns the Description for the power supply
 | |
| 
 | |
| (C<snChasPwrSupplyDescription.1>)
 | |
| 
 | |
| =item $foundry->ps1_status()
 | |
| 
 | |
| Returns the status of the power supply.
 | |
| 
 | |
| (C<snChasPwrSupplyOperStatus.1>)
 | |
| 
 | |
| =item $foundry->fan()
 | |
| 
 | |
| Returns the status of the chassis fan.
 | |
| 
 | |
| (C<snChasFanOperStatus.1>)
 | |
| 
 | |
| =item $foundry->img_ver()
 | |
| 
 | |
| Returns device image version.
 | |
| 
 | |
| (C<snAgImgVer.0>)
 | |
| 
 | |
| =item $foundry->ch_serial()
 | |
| 
 | |
| Returns chassis serial number.
 | |
| 
 | |
| (C<snChasSerNum.0>)
 | |
| 
 | |
| =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::FDP
 | |
| 
 | |
| See documentation in L<SNMP::Info::FDP/"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 $foundry->interfaces()
 | |
| 
 | |
| Returns reference to hash of interface names to iids.
 | |
| 
 | |
| =item $foundry->i_ignore()
 | |
| 
 | |
| Returns reference to hash of interfaces to be ignored.
 | |
| 
 | |
| Ignores interfaces with descriptions of  tunnel,loopback,null
 | |
| 
 | |
| =item $foundry->i_duplex()
 | |
| 
 | |
| Returns reference to hash of interface link duplex status.
 | |
| 
 | |
| Crosses $foundry->sw_duplex() with $foundry->sw_index()
 | |
| 
 | |
| =item $foundry->i_stp_state()
 | |
| 
 | |
| Returns the mapping of (C<dot1dStpPortState>) to the interface
 | |
| index (iid).
 | |
| 
 | |
| =item $foundry->agg_ports()
 | |
| 
 | |
| Returns a HASH reference mapping from slave to master port for each member of
 | |
| a port bundle on the device. Keys are ifIndex of the slave ports, Values are
 | |
| ifIndex of the corresponding master ports.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 F<ENTITY-MIB> Information
 | |
| 
 | |
| F<ENTITY-MIB> is supported on the Brocade NetIron XMR, NetIron MLX, MLXe,
 | |
| NetIron CES, NetIron CER, and older EdgeIron series devices.  For other
 | |
| devices which do not support it, these methods emulate Physical Table methods
 | |
| using F<FOUNDRY-SN-AGENT-MIB>.  See Pseudo F<ENTITY-MIB> information below
 | |
| for details on brcd_e_* methods.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $foundry->e_index()
 | |
| 
 | |
| If the device doesn't support C<entPhysicalDescr>, this will
 | |
| try brcd_e_index().
 | |
| 
 | |
| Note that this is based on C<entPhysicalDescr> due to implementation
 | |
| details of SNMP::Info::Entity::e_index().
 | |
| 
 | |
| =item $foundry->e_class()
 | |
| 
 | |
| If the device doesn't support C<entPhysicalClass>, this will try
 | |
| brcd_e_class().
 | |
| 
 | |
| =item $foundry->e_descr()
 | |
| 
 | |
| If the device doesn't support C<entPhysicalDescr>, this will try
 | |
| brcd_e_descr().
 | |
| 
 | |
| =item $foundry->e_name()
 | |
| 
 | |
| If the device doesn't support C<entPhysicalName>, this will try
 | |
| brcd_e_name().
 | |
| 
 | |
| =item $foundry->e_parent()
 | |
| 
 | |
| If the device doesn't support C<entPhysicalContainedIn>, this will try
 | |
| brcd_e_parent().
 | |
| 
 | |
| =item $foundry->e_pos()
 | |
| 
 | |
| If the device doesn't support C<entPhysicalParentRelPos>, this will try
 | |
| brcd_e_pos().
 | |
| 
 | |
| =item $foundry->e_serial()
 | |
| 
 | |
| If the device doesn't support C<entPhysicalSerialNum>, this will try
 | |
| brcd_e_serial().
 | |
| 
 | |
| =item $foundry->e_type()
 | |
| 
 | |
| If the device doesn't support C<entPhysicalVendorType>, this will try
 | |
| brcd_e_type().
 | |
| 
 | |
| =item $foundry->e_vendor()
 | |
| 
 | |
| If the device doesn't support C<entPhysicalMfgName>, this will try
 | |
| brcd_e_vendor().
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Pseudo F<ENTITY-MIB> information
 | |
| 
 | |
| These methods emulate F<ENTITY-MIB> Physical Table methods using
 | |
| F<FOUNDRY-SN-AGENT-MIB>.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $foundry->brcd_e_index()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Integer, Indices are combined
 | |
| into an integer, each index is two digits padded with leading zero if
 | |
| required.
 | |
| 
 | |
| =item $foundry->brcd_e_class()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: General hardware type.
 | |
| 
 | |
| Returns 'stack' for the stack master in an active stack, 'chassis' for
 | |
| base switches that contain modules, and 'module' for others.
 | |
| 
 | |
| =item $foundry->brcd_e_descr()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Human friendly name
 | |
| 
 | |
| (C<snAgentConfigModule2Description>) or
 | |
| (C<snAgentConfigModuleDescription>)
 | |
| 
 | |
| =item $foundry->brcd_e_name()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Human friendly name
 | |
| 
 | |
| =item $foundry->brcd_e_vendor()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: brocade
 | |
| 
 | |
| =item $foundry->brcd_e_serial()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Serial number
 | |
| 
 | |
| Serial number is $foundry->serial() for a stack master unit and
 | |
| (C<snAgentConfigModule2SerialNumber>) or
 | |
| (C<snAgentConfigModuleSerialNumber>) for all others.
 | |
| 
 | |
| =item $foundry->brcd_e_type()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Type of component/sub-component
 | |
| as defined under C<snAgentConfigModule2Type> or C<snAgentConfigModule2Type>
 | |
| in F<FOUNDRY-SN-AGENT-MIB>.
 | |
| 
 | |
| =item $foundry->brcd_e_pos()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: The relative position among all
 | |
| entities sharing the same parent.
 | |
| 
 | |
| (C<s5ChasComSubIndx>)
 | |
| 
 | |
| =item $foundry->brcd_e_parent()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: The value of brcd_e_index()
 | |
| for the entity which 'contains' this entity.  A value of zero indicates
 | |
| this entity is not contained in any other entity.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Foundry Switch Port Information Table (C<snSwPortIfTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $foundry->sw_index()
 | |
| 
 | |
| Returns reference to hash.  Maps Table to Interface IID.
 | |
| 
 | |
| (C<snSwPortIfIndex>)
 | |
| 
 | |
| =item $foundry->sw_duplex()
 | |
| 
 | |
| Returns reference to hash.   Current duplex status for switch ports.
 | |
| 
 | |
| (C<snSwPortInfoChnMode>)
 | |
| 
 | |
| =item $foundry->sw_type()
 | |
| 
 | |
| Returns reference to hash.  Current Port Type .
 | |
| 
 | |
| (C<snSwPortInfoMediaType>)
 | |
| 
 | |
| =item $foundry->sw_speed()
 | |
| 
 | |
| Returns reference to hash.  Current Port Speed.
 | |
| 
 | |
| (C<snSwPortInfoSpeed>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Power Over Ethernet Port Table
 | |
| 
 | |
| These methods emulate the F<POWER-ETHERNET-MIB> Power Source Entity (PSE)
 | |
| Port Table C<pethPsePortTable> methods using the F<FOUNDRY-POE-MIB> Power
 | |
| over Ethernet Port Table C<snAgentPoePortTable>.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $foundry->peth_port_ifindex()
 | |
| 
 | |
| Creates an index of module.port to align with the indexing of the
 | |
| C<pethPsePortTable> with a value of C<ifIndex>.  The module defaults 1
 | |
| if otherwise unknown.
 | |
| 
 | |
| =item $foundry->peth_port_admin()
 | |
| 
 | |
| Administrative status: is this port permitted to deliver power?
 | |
| 
 | |
| C<pethPsePortAdminEnable>
 | |
| 
 | |
| =item $foundry->peth_port_status()
 | |
| 
 | |
| Current status: is this port delivering power.
 | |
| 
 | |
| =item $foundry->peth_port_class()
 | |
| 
 | |
| Device class: if status is delivering power, this represents the 802.3af
 | |
| class of the device being powered.
 | |
| 
 | |
| =item $foundry->peth_port_neg_power()
 | |
| 
 | |
| The power, in milliwatts, that has been committed to this port.
 | |
| This value is derived from the 802.3af class of the device being
 | |
| powered.
 | |
| 
 | |
| =item $foundry->peth_port_power()
 | |
| 
 | |
| The power, in milliwatts, that the port is delivering.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Power Over Ethernet Module Table
 | |
| 
 | |
| These methods emulate the F<POWER-ETHERNET-MIB> Main Power Source Entity
 | |
| (PSE) Table C<pethMainPseTable> methods using the F<FOUNDRY-POE-MIB> Power
 | |
| over Ethernet Port Table C<snAgentPoeModuleTable >.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $foundry->peth_power_watts()
 | |
| 
 | |
| The power supply's capacity, in watts.
 | |
| 
 | |
| =item $foundry->peth_power_status()
 | |
| 
 | |
| The power supply's operational status.
 | |
| 
 | |
| =item $foundry->peth_power_consumption()
 | |
| 
 | |
| How much power, in watts, this power supply has been committed to
 | |
| deliver.
 | |
| 
 | |
| =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::FDP
 | |
| 
 | |
| See documentation in L<SNMP::Info::FDP/"TABLE METHODS"> for details.
 | |
| 
 | |
| =head2 Table Methods imported from SNMP::Info::LLDP
 | |
| 
 | |
| See documentation in L<SNMP::Info::LLDP/"TABLE METHODS"> for details.
 | |
| 
 | |
| =cut
 |