Files
snmp-info/Info/Layer2/HP.pm
2003-08-14 18:24:56 +00:00

536 lines
13 KiB
Perl

# SNMP::Info::Layer2::HP - SNMP Interface to HP ProCurve Switches
# Max Baker <max@warped.org>
#
# 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::Layer2::HP;
$VERSION = 0.7;
# $Id$
use strict;
use Exporter;
use SNMP::Info::Layer2;
use SNMP::Info::MAU;
use SNMP::Info::Entity;
use vars qw/$VERSION $DEBUG %GLOBALS %MIBS %FUNCS %PORTSTAT %MODEL_MAP %MUNGE $INIT/ ;
@SNMP::Info::Layer2::HP::ISA = qw/SNMP::Info::Layer2 SNMP::Info::MAU SNMP::Info::Entity Exporter/;
@SNMP::Info::Layer2::HP::EXPORT_OK = qw//;
# See SNMP::Info for the details of these data structures and interworkings.
$INIT = 0;
%MIBS = ( %SNMP::Info::Layer2::MIBS,
%SNMP::Info::MAU::MIBS,
%SNMP::Info::Entity::MIBS,
'RFC1271-MIB' => 'logDescription',
'HP-ICF-OID' => 'hpSwitch4000',
'STATISTICS-MIB' => 'hpSwitchCpuStat',
'NETSWITCH-MIB' => 'hpMsgBufFree'
);
%GLOBALS = (
%SNMP::Info::Layer2::GLOBALS,
%SNMP::Info::MAU::GLOBALS,
%SNMP::Info::Entity::GLOBALS,
'serial1' => 'entPhysicalSerialNum.1',
'hp_cpu' => 'hpSwitchCpuStat.0',
'hp_mem_total' => 'hpGlobalMemTotalBytes.1',
'mem_free' => 'hpGlobalMemFreeBytes.1',
'mem_used' => 'hpGlobalMemAllocBytes.1',
'os_version' => 'hpSwitchOsVersion.0',
'os_bin' => 'hpSwitchRomVersion.0',
'mac' => 'hpSwitchBaseMACAddress.0'
);
%FUNCS = (
%SNMP::Info::Layer2::FUNCS,
%SNMP::Info::MAU::FUNCS,
%SNMP::Info::Entity::FUNCS,
'i_type2' => 'ifType',
# RFC1271
'l_descr' => 'logDescription'
);
%MUNGE = (
# Inherit all the built in munging
%SNMP::Info::Layer2::MUNGE,
%SNMP::Info::MAU::MUNGE,
%SNMP::Info::Entity::MUNGE
);
%MODEL_MAP = (
'J4812A' => '2512',
'J4819A' => '5308XL',
'J4813A' => '2524',
'J4805A' => '5304XL',
'J4815A' => '3324XL',
'J4865A' => '4108GL',
'J4887A' => '4104GL',
'J4874A' => '9315',
);
# Method Overrides
sub cpu {
my $hp = shift;
return $hp->hp_cpu();
}
sub mem_total {
my $hp = shift;
return $hp->hp_mem_total();
}
sub os {
return 'hp';
}
sub os_ver {
my $hp = shift;
my $os_version = $hp->os_version();
return $os_version if defined $os_version;
# Some older ones don't have this value,so we cull it from the description
my $descr = $hp->description();
if ($descr =~ m/revision ([A-Z]{1}\.\d{2}\.\d{2})/) {
return $1;
}
return undef;
}
# Lookup model number, and translate the part number to the common number
sub model {
my $hp = shift;
my $id = $hp->id();
my $model = &SNMP::translateObj($id);
$model =~ s/^hpswitch//i;
return defined $MODEL_MAP{$model} ? $MODEL_MAP{$model} : $model;
}
# Some have the serial num in entity mib, some dont.
sub serial {
my $hp = shift;
# procurve 2xxx have this
my $serial = $hp->serial1();
return undef unless defined $serial;
# 4xxx dont
return undef if $serial =~ /nosuchobject/i;
return $serial;
}
sub interfaces {
my $hp = shift;
my $interfaces = $hp->i_index();
my $i_descr = $hp->i_description();
my %if;
foreach my $iid (keys %$interfaces){
my $descr = $i_descr->{$iid};
next unless defined $descr;
$if{$iid} = $descr if (defined $descr and length $descr);
}
return \%if
}
sub i_type {
my $hp = shift;
my $e_descr = $hp->e_descr();
my $e_port = $hp->e_port();
# Grab default values to pass through
my $i_type = $hp->i_type2();
# Now Stuff in the entity-table values
foreach my $port (keys %$e_descr){
my $iid = $e_port->{$port};
next unless defined $iid;
my $type = $e_descr->{$port};
$type =~ s/^HP ?//;
$i_type->{$iid} = $type;
}
return $i_type;
}
sub i_name {
my $hp = shift;
my $i_alias = $hp->i_alias();
my $e_name = $hp->e_name();
my $e_port = $hp->e_port();
my %i_name;
foreach my $port (keys %$e_name){
my $iid = $e_port->{$port};
next unless defined $iid;
my $alias = $i_alias->{$iid};
next unless defined $iid;
$i_name{$iid} = $e_name->{$port};
# Check for alias
$i_name{$iid} = $alias if (defined $alias and length($alias));
}
return \%i_name;
}
sub vendor {
return 'hp';
}
sub log {
my $hp=shift;
my $log = $hp->l_descr();
my $logstring = undef;
foreach my $val (values %$log){
next if $val =~ /^Link\s+(Up|Down)/;
$logstring .= "$val\n";
}
return $logstring;
}
sub slots {
my $hp=shift;
my $e_name = $hp->e_name();
return undef unless defined $e_name;
my $slots;
foreach my $slot (keys %$e_name) {
$slots++ if $e_name->{$slot} =~ /slot/i;
}
return $slots;
}
#sub fan {
# my $hp = shift;
#
# my %ents = reverse %{$hp->e_name()};
#
# my $fan = $ents{'Fan'};
#
#}
sub i_duplex {
my $hp = shift;
my $mau_index = $hp->mau_index();
my $mau_link = $hp->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 i_duplex_admin {
my $hp = shift;
my $interfaces = $hp->interfaces();
my $mau_index = $hp->mau_index();
my $mau_auto = $hp->mau_auto();
my $mau_autostat = $hp->mau_autostat();
my $mau_typeadmin = $hp->mau_type_admin();
my $mau_autosent = $hp->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 = $hp->_isfullduplex($type);
my $half = $hp->_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::Layer2::HP - SNMP Interface to HP Procurve Switches
=head1 AUTHOR
Max Baker (C<max@warped.org>)
=head1 SYNOPSIS
# Let SNMP::Info determine the correct subclass for you.
my $hp = new SNMP::Info(
AutoSpecify => 1,
Debug => 1,
# These arguments are passed directly on to SNMP::Session
DestHost => 'myswitch',
Community => 'public',
Version => 2
)
or die "Can't connect to DestHost.\n";
my $class = $hp->class();
print "SNMP::Info determined this device to fall under subclass : $class\n";
=head1 DESCRIPTION
Provides abstraction to the configuration information obtainable from a
HP ProCurve Switch via SNMP.
Note: Some HP Switches will connect via SNMP version 1, but a lot of config data will
not be available. Make sure you try and connect with Version 2 first, and then fail back
to version 1.
For speed or debugging purposes you can call the subclass directly, but not after determining
a more specific class using the method above.
my $hp = new SNMP::Info::Layer2::HP(...);
=head2 Inherited Classes
=over
=item SNMP::Info::Layer2
=item SNMP::Info::Entity
=item SNMP::Info::MAU
=back
=head2 Required MIBs
=over
=item RFC1271-MIB
Included in V2 mibs from Cisco
=item HP-ICF-OID
=item STATISTICS-MIB
=item NETSWITCH-MIB
=back
The last three MIBs listed are from HP and can be found at http://www.hp.com/rnd/software
=head1 ChangeLog
Version 0.4 - Removed ENTITY-MIB e_*() methods to separate sub-class - SNMP::Info::Entity
=head1 GLOBALS
These are methods that return scalar value from SNMP
=over
=item $hp->cpu()
Returns CPU Utilization in percentage.
=item $hp->log()
Returns all the log entries from the switch's log that are not Link up or down messages.
=item $hp->mem_free()
Returns bytes of free memory
=item $hp->mem_total()
Return bytes of total memory
=item $hp->mem_used()
Returns bytes of used memory
=item $hp->model()
Returns the model number of the HP Switch. Will translate between the HP Part number and
the common model number with this map :
%MODEL_MAP = (
'J4812A' => '2512',
'J4819A' => '5308XL',
'J4813A' => '2524',
'J4805A' => '5304XL',
'J4815A' => '3324XL',
'J4865A' => '4108GL',
'J4887A' => '4104GL',
'J4874A' => '9315',
);
=item $hp->os()
Returns hp
=item $hp->os_bin()
B<hpSwitchRomVersion.0>
=item $hp->os_ver()
Tries to use os_version() and if that fails will try and cull the version from
the description field.
=item $hp->os_version()
B<hpSwitchOsVersion.0>
=item $hp->serial()
Returns serial number if available through SNMP
=item $hp->slots()
Returns number of entries in $hp->e_name that have 'slot' in them.
=item $hp->vendor()
hp
=back
=head2 Globals imported from SNMP::Info::Layer2
See documentation in SNMP::Info::Layer2 for details.
=head2 Globals imported from SNMP::Info::Entity
See documentation in SNMP::Info::Entity for details.
=head2 Globals imported from SNMP::Info::MAU
See documentation in SNMP::Info::MAU 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 $hp->interfaces()
Uses $hp->i_description()
=item $hp->i_duplex()
Maps $hp->mau_index() with $hp->mau_link(). Methods inherited from
SNMP::Info::MAU.
=item $hp->i_duplex_admin()
Maps $hp->mau_index() with $hp->mau_auto(), $hp->mau_autostat(),
$hp->typeadmin(), and $mau_autosent(). Methods inherited from
SNMP::Info::MAU.
=item $hp->i_name()
Crosses i_name() with $hp->e_name() using $hp->e_port() and i_alias()
=item $hp->i_type()
Crosses i_type() with $hp->e_descr() using $hp->e_port()
=back
=head2 Table Methods imported from SNMP::Info::Layer2
See documentation in SNMP::Info::Layer2 for details.
=head2 Table Methods imported from SNMP::Info::Entity
See documentation in SNMP::Info::Entity for details.
=head2 Table Methods imported from SNMP::Info::MAU
See documentation in SNMP::Info::MAU for details.
=cut