757 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			757 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
# SNMP::Info::Layer3::Huawei
 | 
						|
#
 | 
						|
# Copyright (c) 2018 Jeroen van Ingen and 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::Huawei;
 | 
						|
 | 
						|
use strict;
 | 
						|
use Exporter;
 | 
						|
use SNMP::Info::Layer3;
 | 
						|
use SNMP::Info::IEEE802dot3ad;
 | 
						|
 | 
						|
@SNMP::Info::Layer3::Huawei::ISA = qw/
 | 
						|
    SNMP::Info::IEEE802dot3ad
 | 
						|
    SNMP::Info::Layer3
 | 
						|
    Exporter
 | 
						|
    /;
 | 
						|
@SNMP::Info::Layer3::Huawei::EXPORT_OK = qw//;
 | 
						|
 | 
						|
our ($VERSION, %GLOBALS, %MIBS, %FUNCS, %MUNGE);
 | 
						|
 | 
						|
$VERSION = '3.67';
 | 
						|
 | 
						|
%MIBS = (
 | 
						|
    %SNMP::Info::Layer3::MIBS,
 | 
						|
    %SNMP::Info::IEEE802dot3ad::MIBS,
 | 
						|
    'HUAWEI-MIB'               => 'quidway',
 | 
						|
    'HUAWEI-PORT-MIB'          => 'hwEthernetDuplex',
 | 
						|
    'HUAWEI-IF-EXT-MIB'        => 'hwTrunkIfIndex',
 | 
						|
    'HUAWEI-L2IF-MIB'          => 'hwL2IfPortIfIndex',
 | 
						|
    'HUAWEI-POE-MIB'           => 'hwPoePower',
 | 
						|
    'HUAWEI-ENTITY-EXTENT-MIB' => 'hwEntityFanState',
 | 
						|
);
 | 
						|
 | 
						|
%GLOBALS = ( %SNMP::Info::Layer3::GLOBALS, );
 | 
						|
 | 
						|
%FUNCS = (
 | 
						|
    %SNMP::Info::Layer3::FUNCS,
 | 
						|
    %SNMP::Info::IEEE802dot3ad::FUNCS,
 | 
						|
 | 
						|
    # HUAWEI-PORT-MIB::hwEthernetTable
 | 
						|
    'hw_eth_speed_admin' => 'hwEthernetSpeedSet',
 | 
						|
    'hw_eth_duplex'      => 'hwEthernetDuplex',
 | 
						|
    'hw_eth_auto'        => 'hwEthernetNegotiation',
 | 
						|
    'hw_eth_frame_len'   => 'hwEthernetJumboframeMaxLength',
 | 
						|
 | 
						|
    # HUAWEI-PORT-MIB::hwPhysicalPortTable
 | 
						|
    'hw_phy_port_slot' => 'hwPhysicalPortInSlot',
 | 
						|
 | 
						|
    # HUAWEI-IF-EXT-MIB::hwTrunkIfTable
 | 
						|
    'hw_trunk_if_idx' => 'hwTrunkIfIndex',
 | 
						|
    'hw_trunk_entry'  => 'hwTrunkValidEntry',
 | 
						|
 | 
						|
    # HUAWEI-L2IF-MIB::hwL2IfTable
 | 
						|
    'hw_l2if_port_idx' => 'hwL2IfPortIfIndex',
 | 
						|
 | 
						|
    # HUAWEI-POE-MIB::hwPoePortTable
 | 
						|
    'hw_peth_port_admin'  => 'hwPoePortEnable',
 | 
						|
    'hw_peth_port_status' => 'hwPoePortPowerStatus',
 | 
						|
    'hw_peth_port_class'  => 'hwPoePortPdClass',
 | 
						|
    'hw_peth_port_power'  => 'hwPoePortConsumingPower',
 | 
						|
 | 
						|
    # HUAWEI-POE-MIB::hwPoeSlotTable
 | 
						|
    'peth_power_watts'       => 'hwPoeSlotMaximumPower',
 | 
						|
    'peth_power_consumption' => 'hwPoeSlotConsumingPower',
 | 
						|
    'peth_power_threshold'   => 'hwPoeSlotPowerUtilizationThreshold',
 | 
						|
 | 
						|
    # HUAWEI-ENTITY-EXTENT-MIB::hwFanStatusTable
 | 
						|
    'hw_fan_state' => 'hwEntityFanState',
 | 
						|
    'hw_fan_descr' => 'hwEntityFanDesc',
 | 
						|
 | 
						|
    # HUAWEI-ENTITY-EXTENT-MIB::hwPwrStatusTable
 | 
						|
    'hw_pwr_state' => 'hwEntityPwrState',
 | 
						|
    'hw_pwr_descr' => 'hwEntityPwrDesc',
 | 
						|
);
 | 
						|
 | 
						|
%MUNGE = (
 | 
						|
    %SNMP::Info::Layer3::MUNGE,
 | 
						|
    %SNMP::Info::IEEE802dot3ad::MUNGE,
 | 
						|
    'hw_peth_port_admin' => \&SNMP::Info::Layer3::Huawei::munge_hw_peth_admin,
 | 
						|
    'peth_power_watts'   => \&SNMP::Info::Layer3::Huawei::munge_hw_peth_power,
 | 
						|
    'peth_power_consumption' =>
 | 
						|
        \&SNMP::Info::Layer3::Huawei::munge_hw_peth_power,
 | 
						|
    'hw_peth_port_status' =>
 | 
						|
        \&SNMP::Info::Layer3::Huawei::munge_hw_peth_status,
 | 
						|
    'hw_peth_port_class' => \&SNMP::Info::Layer3::Huawei::munge_hw_peth_class,
 | 
						|
);
 | 
						|
 | 
						|
sub vendor {
 | 
						|
    return "Huawei";
 | 
						|
}
 | 
						|
 | 
						|
sub os {
 | 
						|
    my $huawei = shift;
 | 
						|
    my $descr  = $huawei->description();
 | 
						|
 | 
						|
    if ( $descr =~ /\b(VRP)\b/ ) {
 | 
						|
        return $1;
 | 
						|
    }
 | 
						|
    return "huawei";
 | 
						|
}
 | 
						|
 | 
						|
sub os_ver {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $entity_os = $huawei->entity_derived_os_ver();
 | 
						|
    if ( defined $entity_os and $entity_os !~ /^\s*$/ ) {
 | 
						|
        return $entity_os;
 | 
						|
    }
 | 
						|
 | 
						|
    my $descr  = $huawei->description();
 | 
						|
    my $os_ver = undef;
 | 
						|
 | 
						|
    if ($descr =~ /Version\s            # Start match on Version string
 | 
						|
                   ([\d\.]+)            # Capture the primary version in 1
 | 
						|
                   ,?                   # There may be a comma
 | 
						|
                   \s                   # Always a space
 | 
						|
                   (?:Release|Feature)? # Don't capture stanza if present
 | 
						|
                   (?:\(\w+)?           # If paren & model don't capture
 | 
						|
                   \s                   # Always a space
 | 
						|
                   (\w+)                # If 2nd part of version capture in 2
 | 
						|
                   /xi
 | 
						|
        )
 | 
						|
    {
 | 
						|
        $os_ver = $2 ? "$1 $2" : $1;
 | 
						|
    }
 | 
						|
 | 
						|
    return $os_ver;
 | 
						|
}
 | 
						|
 | 
						|
sub mac {
 | 
						|
    my $huawei  = shift;
 | 
						|
 | 
						|
    return $huawei->b_mac();
 | 
						|
}
 | 
						|
 | 
						|
sub i_ignore {
 | 
						|
    my $huawei  = shift;
 | 
						|
    my $partial = shift;
 | 
						|
 | 
						|
    my $interfaces = $huawei->interfaces($partial) || {};
 | 
						|
 | 
						|
    my %i_ignore;
 | 
						|
    foreach my $if ( keys %$interfaces ) {
 | 
						|
 | 
						|
        # lo0 etc
 | 
						|
        if ( $interfaces->{$if} =~ /\b(inloopback|console)\d*\b/ix ) {
 | 
						|
            $i_ignore{$if}++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return \%i_ignore;
 | 
						|
}
 | 
						|
 | 
						|
sub bp_index {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $hw_index = $huawei->hw_l2if_port_idx();
 | 
						|
    return $hw_index
 | 
						|
        if ( ref {} eq ref $hw_index and scalar keys %$hw_index );
 | 
						|
 | 
						|
    return $huawei->SUPER::bp_index();
 | 
						|
}
 | 
						|
 | 
						|
sub i_duplex {
 | 
						|
    my $huawei  = shift;
 | 
						|
    my $partial = shift;
 | 
						|
 | 
						|
    my $hw_duplex = $huawei->hw_eth_duplex($partial);
 | 
						|
    return $hw_duplex
 | 
						|
        if ( ref {} eq ref $hw_duplex and scalar keys %$hw_duplex );
 | 
						|
 | 
						|
    return $huawei->SUPER::i_duplex($partial);
 | 
						|
}
 | 
						|
 | 
						|
sub i_duplex_admin {
 | 
						|
    my $huawei  = shift;
 | 
						|
    my $partial = shift;
 | 
						|
 | 
						|
    my $hw_duplex_admin = $huawei->hw_eth_duplex($partial) || {};
 | 
						|
    my $hw_auto         = $huawei->hw_eth_auto($partial)   || {};
 | 
						|
 | 
						|
    my %i_duplex_admin;
 | 
						|
    foreach my $if ( keys %$hw_duplex_admin ) {
 | 
						|
        my $duplex = $hw_duplex_admin->{$if};
 | 
						|
        next unless defined $duplex;
 | 
						|
        my $auto = $hw_auto->{$if} || 'disabled';
 | 
						|
 | 
						|
        my $string = 'other';
 | 
						|
        $string = 'half' if ( $duplex =~ /half/i and $auto =~ /disabled/i );
 | 
						|
        $string = 'full' if ( $duplex =~ /full/i and $auto =~ /disabled/i );
 | 
						|
        $string = 'auto' if $auto =~ /enabled/i;
 | 
						|
 | 
						|
        $i_duplex_admin{$if} = $string;
 | 
						|
    }
 | 
						|
    return \%i_duplex_admin;
 | 
						|
}
 | 
						|
 | 
						|
sub agg_ports {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    # First use proprietary MIB for broader implementation across
 | 
						|
    # devices type / os and no xref of hwL2IfPortIfIndex
 | 
						|
    my $masters = $huawei->hw_trunk_if_idx();
 | 
						|
    my $slaves  = $huawei->hw_trunk_entry();
 | 
						|
 | 
						|
    my $ret = {};
 | 
						|
 | 
						|
    if (    ref {} eq ref $masters
 | 
						|
        and scalar keys %$masters
 | 
						|
        and ref {} eq ref $slaves
 | 
						|
        and scalar keys %$slaves )
 | 
						|
    {
 | 
						|
        foreach my $s ( keys %$slaves ) {
 | 
						|
            next if $slaves->{$s} ne 'valid';
 | 
						|
            my ( $trunk, $sl_idx ) = split( /\./, $s );
 | 
						|
            foreach my $m ( keys %$masters ) {
 | 
						|
                next unless $m == $trunk;
 | 
						|
                next unless defined $masters->{$m};
 | 
						|
                $ret->{$sl_idx} = $masters->{$m};
 | 
						|
                last;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return $ret;
 | 
						|
    }
 | 
						|
 | 
						|
    # If for some reason we don't get the info, try IEEE8023-LAG-MIB
 | 
						|
    return $huawei->agg_ports_lag();
 | 
						|
}
 | 
						|
 | 
						|
# The standard IEEE 802.af POWER-ETHERNET-MIB has an index of module.port
 | 
						|
# The HUAWEI-POE-MIB only indexes by ifIndex, we need to match the standard
 | 
						|
# for so method calls across classes work the same
 | 
						|
#
 | 
						|
sub peth_port_ifindex {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $peth_port_status = $huawei->hw_peth_port_status() || {};
 | 
						|
    my $peth_port_slot   = $huawei->hw_phy_port_slot()    || {};
 | 
						|
    my $i_descr          = $huawei->i_description()       || {};
 | 
						|
 | 
						|
    my $peth_port_ifindex = {};
 | 
						|
 | 
						|
    foreach my $i ( keys %$peth_port_status ) {
 | 
						|
        my $slot = 0;
 | 
						|
        if ( exists $peth_port_slot->{$i}
 | 
						|
            && defined $peth_port_slot->{$i} )
 | 
						|
        {
 | 
						|
            $slot = $peth_port_slot->{$i};
 | 
						|
        }
 | 
						|
        elsif ( exists $i_descr->{$i}
 | 
						|
            && $i_descr->{$i} =~ /(\d+)(?:\/\d+){2,3}$/x )
 | 
						|
        {
 | 
						|
            $slot = $1;
 | 
						|
        }
 | 
						|
        $peth_port_ifindex->{"$slot.$i"} = $i;
 | 
						|
    }
 | 
						|
    return $peth_port_ifindex;
 | 
						|
}
 | 
						|
 | 
						|
sub peth_port_admin {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $port_admin   = $huawei->hw_peth_port_admin() || {};
 | 
						|
    my $port_ifindex = $huawei->peth_port_ifindex()  || {};
 | 
						|
 | 
						|
    my $peth_port_admin = {};
 | 
						|
 | 
						|
    foreach my $idx ( keys %$port_ifindex ) {
 | 
						|
        my $ifindex = $port_ifindex->{$idx};
 | 
						|
        my $admin   = $port_admin->{$ifindex};
 | 
						|
        next unless $admin;
 | 
						|
 | 
						|
        $peth_port_admin->{$idx} = $admin;
 | 
						|
    }
 | 
						|
    return $peth_port_admin;
 | 
						|
}
 | 
						|
 | 
						|
sub peth_port_status {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $port_status  = $huawei->hw_peth_port_status() || {};
 | 
						|
    my $port_ifindex = $huawei->peth_port_ifindex()   || {};
 | 
						|
 | 
						|
    my $peth_port_status = {};
 | 
						|
 | 
						|
    foreach my $idx ( keys %$port_ifindex ) {
 | 
						|
        my $ifindex = $port_ifindex->{$idx};
 | 
						|
        my $status  = $port_status->{$ifindex};
 | 
						|
        next unless $status;
 | 
						|
 | 
						|
        $peth_port_status->{$idx} = $status;
 | 
						|
    }
 | 
						|
    return $peth_port_status;
 | 
						|
}
 | 
						|
 | 
						|
sub peth_port_class {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $port_class   = $huawei->hw_peth_port_class() || {};
 | 
						|
    my $port_ifindex = $huawei->peth_port_ifindex()  || {};
 | 
						|
 | 
						|
    my $peth_port_class = {};
 | 
						|
 | 
						|
    foreach my $idx ( keys %$port_ifindex ) {
 | 
						|
        my $ifindex = $port_ifindex->{$idx};
 | 
						|
        my $class   = $port_class->{$ifindex};
 | 
						|
        next unless $class;
 | 
						|
 | 
						|
        $peth_port_class->{$idx} = $class;
 | 
						|
    }
 | 
						|
    return $peth_port_class;
 | 
						|
}
 | 
						|
 | 
						|
sub peth_port_power {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $port_power   = $huawei->hw_peth_port_power() || {};
 | 
						|
    my $port_ifindex = $huawei->peth_port_ifindex()  || {};
 | 
						|
 | 
						|
    my $peth_port_power = {};
 | 
						|
 | 
						|
    foreach my $idx ( keys %$port_ifindex ) {
 | 
						|
        my $ifindex = $port_ifindex->{$idx};
 | 
						|
        my $power   = $port_power->{$ifindex};
 | 
						|
        next unless defined $power;
 | 
						|
 | 
						|
        $peth_port_power->{$idx} = $power;
 | 
						|
    }
 | 
						|
    return $peth_port_power;
 | 
						|
}
 | 
						|
 | 
						|
sub peth_port_neg_power {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $peth_port_status = $huawei->peth_port_status()  || {};
 | 
						|
    my $peth_port_class  = $huawei->peth_port_class()   || {};
 | 
						|
    my $port_ifindex     = $huawei->peth_port_ifindex() || {};
 | 
						|
 | 
						|
    my $huaweimax = {
 | 
						|
        'class0' => 12950,
 | 
						|
        'class1' => 3840,
 | 
						|
        'class2' => 6490,
 | 
						|
        'class3' => 12950,
 | 
						|
        'class4' => 25500
 | 
						|
    };
 | 
						|
 | 
						|
    my $peth_port_neg_power = {};
 | 
						|
 | 
						|
    foreach my $idx ( keys %$port_ifindex ) {
 | 
						|
        if ( $peth_port_status->{$idx} eq 'deliveringPower' ) {
 | 
						|
            $peth_port_neg_power->{$idx}
 | 
						|
                = $huaweimax->{ $peth_port_class->{$idx} };
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return $peth_port_neg_power;
 | 
						|
}
 | 
						|
 | 
						|
sub fan {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $fan   = $huawei->hw_fan_descr() || {};
 | 
						|
    my $state = $huawei->hw_fan_state() || {};
 | 
						|
 | 
						|
    if ( scalar keys %$state ) {
 | 
						|
        my @messages = ();
 | 
						|
 | 
						|
        foreach my $k ( keys %$state ) {
 | 
						|
            next if $state->{$k} and $state->{$k} eq 'normal';
 | 
						|
            my ($slot, $num) = split(/\./, $k);
 | 
						|
            my $descr = "Slot $slot,Fan $num";
 | 
						|
            $descr = $fan->{$k} if ($fan->{$k});
 | 
						|
 | 
						|
            push @messages, "$descr: $state->{$k}";
 | 
						|
        }
 | 
						|
 | 
						|
        push @messages, ( ( scalar keys %$state ) . " fans OK" )
 | 
						|
            if scalar @messages == 0;
 | 
						|
 | 
						|
        return ( join ", ", @messages );
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
sub ps1_status {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $pwr_state = $huawei->hw_pwr_state() || {};
 | 
						|
    my $pwr_descr = $huawei->hw_pwr_descr() || {};
 | 
						|
 | 
						|
    my $ret = "";
 | 
						|
    my $s   = "";
 | 
						|
    foreach my $i ( sort keys %$pwr_state ) {
 | 
						|
        my ( $slot, $num ) = split( /\./, $i );
 | 
						|
        next unless $num == 1;
 | 
						|
        my $descr = "Slot $slot,PS $num";
 | 
						|
        $descr = $pwr_descr->{$i} if ($pwr_descr->{$i});
 | 
						|
 | 
						|
        $ret .= $s . $descr . ": " . $pwr_state->{$i};
 | 
						|
        $s = ", ";
 | 
						|
    }
 | 
						|
    return if ( $s eq "" );
 | 
						|
    return $ret;
 | 
						|
}
 | 
						|
 | 
						|
sub ps2_status {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $pwr_state = $huawei->hw_pwr_state() || {};
 | 
						|
    my $pwr_descr = $huawei->hw_pwr_descr() || {};
 | 
						|
 | 
						|
    my $ret = "";
 | 
						|
    my $s   = "";
 | 
						|
    foreach my $i ( sort keys %$pwr_state ) {
 | 
						|
        my ( $slot, $num ) = split( /\./, $i );
 | 
						|
        next unless $num == 2;
 | 
						|
        my $descr = "Slot $slot,PS $num";
 | 
						|
        $descr = $pwr_descr->{$i} if ($pwr_descr->{$i});
 | 
						|
 | 
						|
        $ret .= $s . $descr . ": " . $pwr_state->{$i};
 | 
						|
        $s = ", ";
 | 
						|
    }
 | 
						|
    return if ( $s eq "" );
 | 
						|
    return $ret;
 | 
						|
}
 | 
						|
 | 
						|
sub i_mtu {
 | 
						|
    my $huawei = shift;
 | 
						|
 | 
						|
    my $mtus   = $huawei->SUPER::i_mtu()     || {};
 | 
						|
    my $frames = $huawei->hw_eth_frame_len() || {};
 | 
						|
 | 
						|
    foreach my $idx ( keys %$mtus ) {
 | 
						|
        my $frame_sz = $frames->{$idx};
 | 
						|
        next unless $frame_sz;
 | 
						|
 | 
						|
        $mtus->{$idx} = $frame_sz;
 | 
						|
    }
 | 
						|
    return $mtus;
 | 
						|
}
 | 
						|
 | 
						|
sub munge_hw_peth_admin {
 | 
						|
    my $admin = shift;
 | 
						|
 | 
						|
    $admin =~ s/enabled/true/;
 | 
						|
    $admin =~ s/disabled/false/;
 | 
						|
    return $admin;
 | 
						|
}
 | 
						|
 | 
						|
sub munge_hw_peth_power {
 | 
						|
    my $pwr = shift;
 | 
						|
 | 
						|
    $pwr = $pwr / 1000;
 | 
						|
    return sprintf( "%.0f", $pwr );
 | 
						|
}
 | 
						|
 | 
						|
sub munge_hw_peth_class {
 | 
						|
    my $pwr = shift;
 | 
						|
 | 
						|
    return "class$pwr";
 | 
						|
}
 | 
						|
 | 
						|
# The values are from the MIB reference guide
 | 
						|
sub munge_hw_peth_status {
 | 
						|
    my $pwr = shift;
 | 
						|
 | 
						|
    # The status is an octet string rather than enum
 | 
						|
    # so use regex rather than hash lookup
 | 
						|
    $pwr = 'disabled'        if $pwr =~ /Disabled/i;
 | 
						|
    $pwr = 'searching'       if $pwr =~ /(Powering|Power-ready|Detecting)/ix;
 | 
						|
    $pwr = 'deliveringPower' if $pwr =~ /Powered/i;
 | 
						|
    $pwr = 'fault'           if $pwr =~ /fault/i;
 | 
						|
 | 
						|
    return $pwr;
 | 
						|
}
 | 
						|
 | 
						|
1;
 | 
						|
 | 
						|
__END__
 | 
						|
 | 
						|
=head1 NAME
 | 
						|
 | 
						|
SNMP::Info::Layer3::Huawei - SNMP Interface to Huawei switches and routers.
 | 
						|
 | 
						|
=head1 AUTHORS
 | 
						|
 | 
						|
Jeroen van Ingen and Eric Miller
 | 
						|
 | 
						|
=head1 SYNOPSIS
 | 
						|
 | 
						|
 # Let SNMP::Info determine the correct subclass for you.
 | 
						|
 my $huawei = new SNMP::Info(
 | 
						|
                          AutoSpecify => 1,
 | 
						|
                          Debug       => 1,
 | 
						|
                          DestHost    => 'myrouter',
 | 
						|
                          Community   => 'public',
 | 
						|
                          Version     => 2
 | 
						|
                        )
 | 
						|
    or die "Can't connect to DestHost.\n";
 | 
						|
 | 
						|
 my $class      = $huawei->class();
 | 
						|
 print "SNMP::Info determined this device to fall under subclass : $class\n";
 | 
						|
 | 
						|
=head1 DESCRIPTION
 | 
						|
 | 
						|
Subclass for Huawei switches
 | 
						|
 | 
						|
=head2 Inherited Classes
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item SNMP::Info::Layer3
 | 
						|
 | 
						|
=item SNMP::Info::IEEE802dot3ad
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 Required MIBs
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item F<HUAWEI-MIB>
 | 
						|
 | 
						|
=item F<HUAWEI-PORT-MIB>
 | 
						|
 | 
						|
=item F<HUAWEI-IF-EXT-MIB>
 | 
						|
 | 
						|
=item F<HUAWEI-L2IF-MIB>
 | 
						|
 | 
						|
=item F<HUAWEI-POE-MIB>
 | 
						|
 | 
						|
=item F<HUAWEI-ENTITY-EXTENT-MIB>
 | 
						|
 | 
						|
=item Inherited Classes' MIBs
 | 
						|
 | 
						|
See L<SNMP::Info::Layer3> for its own MIB requirements.
 | 
						|
 | 
						|
See L<SNMP::Info::IEEE802dot3ad> for its own MIB requirements.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head1 GLOBALS
 | 
						|
 | 
						|
These are methods that return scalar value from SNMP
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item $huawei->vendor()
 | 
						|
 | 
						|
Returns 'Huawei'.
 | 
						|
 | 
						|
=item $huawei->os()
 | 
						|
 | 
						|
Returns 'VRP' if contained in C<sysDescr>, 'huawei' otherwise.
 | 
						|
 | 
						|
=item $huawei->os_ver()
 | 
						|
 | 
						|
Returns the software version derived from the C<ENTITY-MIB> or
 | 
						|
extracted from C<sysDescr>.
 | 
						|
 | 
						|
=item $huawei->mac()
 | 
						|
 | 
						|
Base MAC of the device.
 | 
						|
 | 
						|
(C<dot1dBaseBridgeAddress>)
 | 
						|
 | 
						|
=item $huawei->fan()
 | 
						|
 | 
						|
Return the status of all fans from the F<HUAWEI-ENTITY-EXTENT-MIB>. Returns
 | 
						|
a string indicating the number of fans 'OK' or identification of any fan without
 | 
						|
a 'normal' operating status
 | 
						|
 | 
						|
=item $huawei->ps1_status()
 | 
						|
 | 
						|
Return the status of the first power supply in each chassis or switch from
 | 
						|
the F<HUAWEI-ENTITY-EXTENT-MIB>
 | 
						|
 | 
						|
=item $huawei->ps2_status()
 | 
						|
 | 
						|
Return the status of the second power supply in each chassis or switch from
 | 
						|
the F<HUAWEI-ENTITY-EXTENT-MIB>
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 Globals imported from SNMP::Info::Layer3
 | 
						|
 | 
						|
See documentation in L<SNMP::Info::Layer3> for details.
 | 
						|
 | 
						|
=head1 TABLE ENTRIES
 | 
						|
 | 
						|
These are methods that return tables of information in the form of a reference
 | 
						|
to a hash.
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item $huawei->i_duplex()
 | 
						|
 | 
						|
Returns reference to map of IIDs to current link duplex.
 | 
						|
 | 
						|
=item $huawei->i_duplex_admin()
 | 
						|
 | 
						|
Returns reference to hash of IIDs to admin duplex setting.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 POE Slot Table
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item $huawei->peth_power_watts()
 | 
						|
 | 
						|
The slot's power supply's capacity, in watts.
 | 
						|
 | 
						|
C<hwPoeSlotMaximumPower>
 | 
						|
 | 
						|
=item $huawei->peth_power_consumption()
 | 
						|
 | 
						|
How much power, in watts, this power supply has been committed to
 | 
						|
deliver.
 | 
						|
 | 
						|
C<hwPoeSlotConsumingPower>
 | 
						|
 | 
						|
=item $huawei->peth_power_threshold()
 | 
						|
 | 
						|
The threshold (in percent) of consumption required to raise an
 | 
						|
alarm.
 | 
						|
 | 
						|
C<hwPoeSlotPowerUtilizationThreshold>
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 Overrides
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item $huawei->i_ignore()
 | 
						|
 | 
						|
Returns reference to hash.  Increments value of IID if port is to be ignored.
 | 
						|
 | 
						|
Ignores InLoopback and Console interfaces
 | 
						|
 | 
						|
=item $huawei->bp_index()
 | 
						|
 | 
						|
Returns a mapping between C<ifIndex> and the Bridge Table. Uses
 | 
						|
C<hwL2IfPortIfIndex> for the most complete mapping and falls back to
 | 
						|
C<dot1dBasePortIfIndex> if not available.
 | 
						|
 | 
						|
=item C<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. Attempts to use C<hwTrunkIfTable>
 | 
						|
first and then C<dot3adAggPortListPorts> if that is unavailable.
 | 
						|
 | 
						|
=item C<i_mtu>
 | 
						|
 | 
						|
Interface MTU value. Overridden with corresponding frame size entry from
 | 
						|
C<hwEthernetJumboframeMaxLength> if one exists.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 Power Port Table
 | 
						|
 | 
						|
The index of these methods have been normalized to slot.port and values
 | 
						|
munged to provide compatibility with the IEEE 802.3af F<POWER-ETHERNET-MIB>
 | 
						|
and equivalent L<SNMP::Info::PowerEthernet> methods.
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item $huawei->peth_port_admin()
 | 
						|
 | 
						|
Administrative status: is this port permitted to deliver power?
 | 
						|
 | 
						|
=item $huawei->peth_port_status()
 | 
						|
 | 
						|
Current status: is this port delivering power, searching, disabled, etc?
 | 
						|
 | 
						|
=item $huawei->peth_port_class()
 | 
						|
 | 
						|
Device class: if status is delivering power, this represents the 802.3af
 | 
						|
class of the device being powered.
 | 
						|
 | 
						|
=item $huawei->peth_port_power()
 | 
						|
 | 
						|
Power supplied the port, in milliwatts
 | 
						|
 | 
						|
=item $huawei->peth_port_ifindex()
 | 
						|
 | 
						|
Returns an index of slot.port to an C<ifIndex>. Slot defaults to zero
 | 
						|
meaning chassis or box if there is no C<ifIndex> to slot mapping available in
 | 
						|
C<hwPhysicalPortInSlot>. Mapping the index to slot.port is a normalization
 | 
						|
function to provide compatibility with the IEEE 802.3af F<POWER-ETHERNET-MIB>.
 | 
						|
 | 
						|
=item $huawei->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.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 Table Methods imported from SNMP::Info::Layer3
 | 
						|
 | 
						|
See documentation in L<SNMP::Info::Layer3> for details.
 | 
						|
 | 
						|
=head2 Table Methods imported from SNMP::Info::IEEE802dot3ad
 | 
						|
 | 
						|
See documentation in L<SNMP::Info::IEEE802dot3ad> for details.
 | 
						|
 | 
						|
=head1 Data Munging Callback Subroutines
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item $huawei->munge_hw_peth_admin()
 | 
						|
 | 
						|
Normalizes C<hwPoePortEnable> values to 'true' or 'false'.
 | 
						|
 | 
						|
=item $huawei->munge_hw_peth_class()
 | 
						|
 | 
						|
Normalizes C<hwPoePortPdClass> values by prepending 'class'.
 | 
						|
 | 
						|
=item $huawei->munge_hw_peth_power()
 | 
						|
 | 
						|
Converts and rounds to a whole number milliwatts to watts.
 | 
						|
 | 
						|
=item $huawei->munge_hw_peth_status()
 | 
						|
 | 
						|
Normalizes C<hwPoePortPowerStatus> values to those that would be returned by
 | 
						|
the the IEEE 802.3af F<POWER-ETHERNET-MIB>.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=cut
 |