450 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			450 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| # SNMP::Info::MAU - Media Access Unit - RFC 2668
 | |
| # Max Baker
 | |
| #
 | |
| # Copyright (c) 2004,2005 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::MAU;
 | |
| $VERSION = 1.0;
 | |
| # $Id$
 | |
| 
 | |
| use strict;
 | |
| 
 | |
| use Exporter;
 | |
| use SNMP::Info;
 | |
| 
 | |
| use vars qw/$VERSION $DEBUG %MIBS %FUNCS %GLOBALS %MUNGE $INIT/;
 | |
| @SNMP::Info::MAU::ISA = qw/SNMP::Info Exporter/;
 | |
| @SNMP::Info::MAU::EXPORT_OK = qw//;
 | |
| 
 | |
| %MIBS = ('MAU-MIB' => 'mauMod');
 | |
| 
 | |
| %GLOBALS = (
 | |
|            );
 | |
| 
 | |
| %FUNCS = (
 | |
|           # Interface MAU Table
 | |
|           'mau_index'    => 'ifMauIfIndex',
 | |
|           'mau_link'     => 'ifMauType',
 | |
|           'mau_status'   => 'ifMauStatus',
 | |
|           'mau_up'       => 'ifMauMediaAvailable',
 | |
|           'mau_type'     => 'ifMauTypeList',
 | |
|           'mau_type_admin'     => 'ifMauDefaultType',
 | |
|           # Interface Auto-Negotiation Table
 | |
|           'mau_auto'     => 'ifMauAutoNegSupported',
 | |
|           'mau_autostat' => 'ifMauAutoNegAdminStatus',
 | |
|           'mau_autosent' => 'ifMauAutoNegCapAdvertised',
 | |
|           'mau_autorec'  => 'ifMauAutoNegCapReceived',
 | |
|           );
 | |
| 
 | |
| %MUNGE = (
 | |
|           # Inherit all the built in munging
 | |
|           %SNMP::Info::MUNGE,
 | |
|           # Add ones for our class
 | |
|           'mau_type' => \&munge_int2bin,
 | |
|           'mau_autosent' => \&munge_int2bin,
 | |
|           'mau_autorec' => \&munge_int2bin,
 | |
|          );
 | |
| 
 | |
| 
 | |
| sub munge_int2bin {
 | |
|     my $int = shift;
 | |
|     return undef unless defined $int;
 | |
|     return unpack("B32", pack("N", $int));
 | |
| }
 | |
| 
 | |
| sub _isfullduplex{
 | |
|     my $mau = shift;
 | |
|     my $mautype = shift;
 | |
| 
 | |
|     my @full_types = qw/11 13 16 18 20/;
 | |
|     foreach my $type ( @full_types ) {
 | |
|         return 1 if (substr($mautype,32-$type,1) eq '1')
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| sub _ishalfduplex{
 | |
|     my $mau = shift;
 | |
|     my $mautype = shift;
 | |
| 
 | |
|     my @half_types = qw/10 12 15 17 19/;
 | |
|     foreach my $type ( @half_types ) {
 | |
|         return 1 if (substr($mautype,32-$type,1) eq '1')
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| my %_mau_i_speed_map = (
 | |
|  '10' => '10 Mbps',
 | |
|  '100' => '100 Mbps',
 | |
|  '1000' => '1.0 Gbps',
 | |
|  '10Gig' => '10 Gbps',
 | |
| );
 | |
| 
 | |
| sub mau_i_speed_admin {
 | |
|     my $mau = shift;
 | |
| 
 | |
|     my $mau_index = $mau->mau_index();
 | |
|     my $mau_type_admin = $mau->mau_type_admin();
 | |
| 
 | |
|     my %i_speed_admin;
 | |
|     foreach my $mau_port (keys %$mau_type_admin){
 | |
|         my $iid = $mau_index->{$mau_port};
 | |
|         next unless defined $iid;
 | |
| 
 | |
|         my $type_adminoid = $mau_type_admin->{$mau_port};
 | |
|         my $type_admin = &SNMP::translateObj($type_adminoid);
 | |
|         next unless defined $type_admin;
 | |
| 
 | |
| 	if ($type_adminoid eq '.0.0') {
 | |
| 		$i_speed_admin{$iid} = 'auto';
 | |
| 	} elsif ($type_admin =~ /^dot3MauType(.*)Base/ && $_mau_i_speed_map{$1}) {
 | |
| 		$i_speed_admin{$iid} = $_mau_i_speed_map{$1};
 | |
| 	}
 | |
|     }
 | |
|     return \%i_speed_admin;
 | |
| }
 | |
| 
 | |
| sub mau_i_duplex {
 | |
|     my $mau = shift;
 | |
| 
 | |
|     my $mau_index = $mau->mau_index();
 | |
|     my $mau_link = $mau->mau_link();
 | |
| 
 | |
|     my %i_duplex;
 | |
|     foreach my $mau_port (keys %$mau_link){
 | |
|         my $iid = $mau_index->{$mau_port};
 | |
|         next unless defined $iid;
 | |
| 
 | |
|         my $linkoid = $mau_link->{$mau_port};
 | |
|         my $link = &SNMP::translateObj($linkoid);
 | |
|         next unless defined $link;
 | |
| 
 | |
|         my $duplex = undef;
 | |
| 
 | |
|         if ($link =~ /fd$/i) {
 | |
|             $duplex = 'full';
 | |
|         } elsif ($link =~ /hd$/i){
 | |
|             $duplex = 'half';
 | |
|         }
 | |
| 
 | |
|         $i_duplex{$iid} = $duplex if defined $duplex;
 | |
|     }
 | |
|     return \%i_duplex;
 | |
| }
 | |
| 
 | |
| sub mau_i_duplex_admin {
 | |
|     my $mau = shift;
 | |
| 
 | |
|     my $mau_index = $mau->mau_index();
 | |
|     my $mau_autostat = $mau->mau_autostat();
 | |
|     my $mau_type_admin = $mau->mau_type_admin();
 | |
| 
 | |
|     # Older HP4000's don't implement ifMauDefaultType, but we can
 | |
|     # figure out from ifMauAutoNegCapAdvertised what we'd like.
 | |
|     if (!defined($mau_type_admin)) {
 | |
|         return mau_i_duplex_admin_old($mau,$mau_index,$mau_autostat);
 | |
|     }
 | |
| 
 | |
|     my %i_duplex_admin;
 | |
|     foreach my $mau_port (keys %$mau_type_admin){
 | |
|         my $iid = $mau_index->{$mau_port};
 | |
|         next unless defined $iid;
 | |
| 
 | |
|         my $autostat = $mau_autostat->{$mau_port};
 | |
|         if (defined $autostat and $autostat =~ /enabled/i){
 | |
|             $i_duplex_admin{$iid} = 'auto';
 | |
|             next;
 | |
|         } 
 | |
| 
 | |
|         my $type_adminoid = $mau_type_admin->{$mau_port};
 | |
|         my $type_admin = &SNMP::translateObj($type_adminoid);
 | |
|         next unless defined $type_admin;
 | |
| 
 | |
|         my $duplex = undef;
 | |
| 
 | |
|         if ($type_admin =~ /fd$/i) {
 | |
|             $duplex = 'full';
 | |
|         } elsif ($type_admin =~ /hd$/i){
 | |
|             $duplex = 'half';
 | |
|         }
 | |
| 
 | |
|         $i_duplex_admin{$iid} = $duplex if defined $duplex;
 | |
|     }
 | |
|     return \%i_duplex_admin;
 | |
| }
 | |
| 
 | |
| sub mau_i_duplex_admin_old {
 | |
|     my $mau = shift;
 | |
|     my $mau_index = shift;
 | |
|     my $mau_autostat = shift;
 | |
| 
 | |
|     my $interfaces   = $mau->interfaces();
 | |
|     my $mau_autosent = $mau->mau_autosent();
 | |
| 
 | |
|     my %mau_reverse = reverse %$mau_index;
 | |
| 
 | |
|     my %i_duplex_admin;
 | |
|     foreach my $iid (keys %$interfaces){
 | |
|         my $mau_index = $mau_reverse{$iid};
 | |
|         next unless defined $mau_index;
 | |
| 
 | |
|         my $autostat = $mau_autostat->{$mau_index};
 | |
|         
 | |
|         # HP25xx has this value
 | |
|         if (defined $autostat and $autostat =~ /enabled/i){
 | |
|             $i_duplex_admin{$iid} = 'auto';
 | |
|             next;
 | |
|         } 
 | |
|         
 | |
|         my $type = $mau_autosent->{$mau_index};
 | |
|     
 | |
|         next unless defined $type;
 | |
| 
 | |
|         if ($type == 0) {
 | |
|             $i_duplex_admin{$iid} = 'none';
 | |
|             next;
 | |
|         }
 | |
| 
 | |
|         my $full = $mau->_isfullduplex($type);
 | |
|         my $half = $mau->_ishalfduplex($type);
 | |
| 
 | |
|         if ($full and !$half){
 | |
|             $i_duplex_admin{$iid} = 'full';
 | |
|         } elsif ($half) {
 | |
|             $i_duplex_admin{$iid} = 'half';
 | |
|         } 
 | |
|     } 
 | |
|     
 | |
|     return \%i_duplex_admin;
 | |
| }
 | |
| 
 | |
| 1;
 | |
| __END__
 | |
| 
 | |
| 
 | |
| =head1 NAME
 | |
| 
 | |
| SNMP::Info::MAU - Perl5 Interface to Medium Access Unit (MAU) MIB (RFC 2668) via SNMP
 | |
| 
 | |
| =head1 AUTHOR
 | |
| 
 | |
| Max Baker
 | |
| 
 | |
| =head1 SYNOPSIS
 | |
| 
 | |
|  my $mau = new SNMP::Info ( 
 | |
|                              AutoSpecify => 1,
 | |
|                              Debug       => 1,
 | |
|                              DestHost    => 'hpswitch', 
 | |
|                              Community   => 'public',
 | |
|                              Version     => 2
 | |
|                            );
 | |
|  
 | |
|  my $class = $mau->class();
 | |
|  print " Using device sub class : $class\n";
 | |
| 
 | |
| =head1 DESCRIPTION
 | |
| 
 | |
| SNMP::Info::MAU is a sublcass of SNMP::Info that supplies access to the
 | |
| MAU-MIB (RFC 2668). This MIB is sometimes implemented on Layer 2 network devices like HP Switches.
 | |
| MAU = Media Access Unit.
 | |
| 
 | |
| The MAU table contains link and duplex info for the port itself and the device
 | |
| connected to that port.
 | |
| 
 | |
| Normally you use or create a subclass of SNMP::Info that inherits this one.  Do not use directly.
 | |
| 
 | |
| For debugging purposes call the class directly as you would SNMP::Info
 | |
| 
 | |
|  my $mau = new SNMP::Info::MAU(...);
 | |
| 
 | |
| =head2 Inherited Classes
 | |
| 
 | |
| None.
 | |
| 
 | |
| =head2 Required MIBs
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item MAU-MIB
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 GLOBALS
 | |
| 
 | |
| These are methods that return scalar value from SNMP
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item None
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 TABLE METHODS
 | |
| 
 | |
| These are methods that return tables of information in the form of a reference
 | |
| to a hash.
 | |
| 
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $mau->mau_i_duplex()
 | |
| 
 | |
| Parses mau_index and mau_link to return the duplex information for
 | |
| interfaces.
 | |
| 
 | |
| =item $mau->mau_i_duplex_admin()
 | |
| 
 | |
| Parses C<mac_index>,C<mau_autostat>,C<mau_type_admin> in
 | |
| order to find the admin duplex setting for all the interfaces.
 | |
| 
 | |
| Returns either (auto,full,half).
 | |
| 
 | |
| =item $mau->mau_i_duplex_admin_old()
 | |
| 
 | |
| Called by mau_i_duplex_admin() if C<mau_type_admin> is empty.
 | |
| Parses C<mau_index>,C<mau_autostat>,C<mau_autosent> in
 | |
| order to find the admin duplex setting for all the interfaces.
 | |
| 
 | |
| Returns either (auto,none,full,half).
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 MAU INTERFACE TABLE ENTRIES
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $mau->mau_index() -  Returns a list of interfaces
 | |
| and their index in the MAU IF Table.
 | |
| 
 | |
| (B<ifMauIfIndex>)
 | |
| 
 | |
| =item $mau->mau_link() - Returns the type of Media Access used.  
 | |
| 
 | |
|     This is essentially the type of link in use.  
 | |
|     eg. dot3MauType100BaseTXFD - 100BaseT at Full Duplex
 | |
| 
 | |
| (B<ifMauType>)
 | |
| 
 | |
| =item $mau->mau_status() - Returns the admin link condition as 
 | |
| 
 | |
|     1 - other
 | |
|     2 - unknown
 | |
|     3 - operational
 | |
|     4 - standby
 | |
|     5 - shutdown
 | |
|     6 - reset
 | |
| 
 | |
| Use 5 and !5 to see if the link is up or down on the admin side.
 | |
| 
 | |
| (B<ifMauStatus>)
 | |
| 
 | |
| =item $mau->mau_up() -  Returns the current link condition
 | |
| 
 | |
|  (B<ifMauMediaAvailable>)
 | |
| 
 | |
| =item $mau->mau_type() - Returns a 32bit string reporting the capabilities
 | |
| of the port from a MAU POV. 
 | |
| 
 | |
|   Directly from the MAU-MIB : 
 | |
|           Bit   Capability
 | |
|             0      other or unknown
 | |
|             1      AUI
 | |
|             2      10BASE-5
 | |
|             3      FOIRL
 | |
|             4      10BASE-2
 | |
|             5      10BASE-T duplex mode unknown
 | |
|             6      10BASE-FP
 | |
|             7      10BASE-FB
 | |
|             8      10BASE-FL duplex mode unknown
 | |
|             9      10BROAD36
 | |
|            10      10BASE-T  half duplex mode
 | |
|            11      10BASE-T  full duplex mode
 | |
|            12      10BASE-FL half duplex mode
 | |
|            13      10BASE-FL full duplex mode
 | |
|            14      100BASE-T4
 | |
|            15      100BASE-TX half duplex mode
 | |
|            16      100BASE-TX full duplex mode
 | |
|            17      100BASE-FX half duplex mode
 | |
|            18      100BASE-FX full duplex mode
 | |
|            19      100BASE-T2 half duplex mode
 | |
|            20      100BASE-T2 full duplex mode
 | |
| 
 | |
| (B<ifMauTypeList>)
 | |
| 
 | |
| =item $mau->mau_type_admin()
 | |
| 
 | |
| (C<ifMauDefaultType>)
 | |
| 
 | |
| =item $mau->mau_auto() - Returns status of auto-negotiation mode for ports.
 | |
| 
 | |
| (B<ifMauAutoNegAdminStatus>)
 | |
| 
 | |
| =item $mau->mau_autostat()
 | |
| 
 | |
| (C<ifMauAutoNegAdminStatus>)
 | |
| 
 | |
| =item $mau->mau_autosent() - Returns a 32 bit bit-string representing the
 | |
| capabilities we are broadcasting on that port 
 | |
| 
 | |
|     Uses the same decoder as $mau->mau_type().
 | |
| 
 | |
| (B<ifMauAutoNegCapAdvertised>)
 | |
| 
 | |
| 
 | |
| =item $mau->mau_autorec() - Returns a 32 bit bit-string representing the 
 | |
| capabilities of the device on the other end. 
 | |
| 
 | |
|     Uses the same decoder as $mau->mau_type().
 | |
| 
 | |
| (B<ifMauAutoNegCapReceived>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 Utility Functions
 | |
| 
 | |
| =over 
 | |
| 
 | |
| =item munge_int2bin() - Unpacks an integer into a 32bit bit string.
 | |
| 
 | |
| =item $mau->_isfullduplex(bitstring)
 | |
| 
 | |
|     Boolean. Checks to see if any of the full_duplex types from mau_type() are
 | |
|     high.  Currently bits 11,13,16,18,20.
 | |
| 
 | |
| =item $mau->_ishalfduplex(bitstring)
 | |
|     
 | |
|     Boolean.  Checks to see if any of the half_duplex types from mau_type() are
 | |
|     high.  Currently bits 10,12,15,17,19.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =cut
 | 
