migrate from EUMM to Module::Build
This commit is contained in:
		
							
								
								
									
										173
									
								
								lib/SNMP/Info/Layer2/3Com.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								lib/SNMP/Info/Layer2/3Com.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| package SNMP::Info::Layer2::3Com; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2; | ||||
| use SNMP::Info::LLDP; | ||||
| use SNMP::Info::CDP; | ||||
|  | ||||
| @SNMP::Info::Layer2::3Com::ISA       = qw/SNMP::Info::LLDP SNMP::Info::Layer2 Exporter/; | ||||
| @SNMP::Info::Layer2::3Com::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::LLDP::MIBS, | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     'A3Com-products-MIB' => 'wlanAP7760', | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::GLOBALS, | ||||
|     %SNMP::Info::LLDP::GLOBALS, | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     %SNMP::Info::LLDP::FUNCS, | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::Layer2::MUNGE, | ||||
|     %SNMP::Info::LLDP::MUNGE, | ||||
| ); | ||||
|  | ||||
|  | ||||
| sub os { | ||||
|     return '3Com'; | ||||
| } | ||||
|  | ||||
| sub serial { | ||||
|     my $dev  = shift; | ||||
|     my $e_serial = $dev->e_serial(); | ||||
|  | ||||
|     # Find entity table entry for this unit | ||||
|     foreach my $e ( sort keys %$e_serial ) { | ||||
|         if (defined $e_serial->{$e} and $e_serial->{$e} !~ /^\s*$/) { | ||||
|             return $e_serial->{$e}; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|  | ||||
|     my $dev = shift; | ||||
|     my $e_swver  = $dev->e_swver(); | ||||
|     # Find entity table entry for this unit | ||||
|     foreach my $e ( sort keys %$e_swver ) { | ||||
|         if (defined $e_swver->{$e} and $e_swver->{$e} !~ /^\s*$/) { | ||||
|             return $e_swver->{$e}; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return '3Com'; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|  | ||||
|     my $dsmodel = shift; | ||||
|     my $descr = $dsmodel->description(); | ||||
|     if ( $descr =~ /^([\S ]+) Software.*/){ | ||||
|         return $1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::3Com - SNMP Interface to L2 3Com Switches | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Kosmach | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you. | ||||
|  my $router = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myrouter', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 1 | ||||
|                         ) | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $router->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Subclass for 3Com L2 devices | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<A3Com-products-MIB> | ||||
|  | ||||
| =item Inherited Classes' MIBs | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $device->vendor() | ||||
|  | ||||
| Returns '3Com' | ||||
|  | ||||
| =item $device->os() | ||||
|  | ||||
| Returns '3Com' | ||||
|  | ||||
| =item $device->os_ver() | ||||
|  | ||||
| Return os version | ||||
|  | ||||
| =item $device->model() | ||||
|  | ||||
| Returns device model extracted from description | ||||
|  | ||||
| =item $device->serial() | ||||
|  | ||||
| Returns serial number | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head1 TABLE METHODS | ||||
|  | ||||
| These are methods that return tables of information in the form of a reference | ||||
| to a hash. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
|  | ||||
							
								
								
									
										385
									
								
								lib/SNMP/Info/Layer2/Airespace.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										385
									
								
								lib/SNMP/Info/Layer2/Airespace.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,385 @@ | ||||
| # SNMP::Info::Layer2::Airespace | ||||
| # | ||||
| # Copyright (c) 2008 Eric Miller | ||||
| # | ||||
| # 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::Airespace; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Bridge; | ||||
| use SNMP::Info::CDP; | ||||
| use SNMP::Info::Airespace; | ||||
|  | ||||
| @SNMP::Info::Layer2::Airespace::ISA | ||||
|     = qw/SNMP::Info::Airespace SNMP::Info::CDP SNMP::Info::Bridge Exporter/; | ||||
| @SNMP::Info::Layer2::Airespace::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::MIBS,      %SNMP::Info::Bridge::MIBS, | ||||
|     %SNMP::Info::CDP::MIBS, %SNMP::Info::Airespace::MIBS, | ||||
|     'CISCO-LWAPP-DOT11-CLIENT-MIB' => 'cldcClientCurrentTxRateSet', | ||||
|     'CISCO-LWAPP-DOT11-MIB'        => 'cldHtDot11nChannelBandwidth', | ||||
|     'CISCO-LWAPP-AP-MIB'           => 'cLApIfMacAddress', | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::GLOBALS,      %SNMP::Info::Bridge::GLOBALS, | ||||
|     %SNMP::Info::CDP::GLOBALS, %SNMP::Info::Airespace::GLOBALS, | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::FUNCS,      %SNMP::Info::Bridge::FUNCS, | ||||
|     %SNMP::Info::CDP::FUNCS, %SNMP::Info::Airespace::FUNCS, | ||||
|     # CISCO-LWAPP-AP-MIB::cLApTable | ||||
|     'ap_if_mac'        => 'cLApIfMacAddress', | ||||
|     # CISCO-LWAPP-DOT11-CLIENT-MIB::cldcClientTable | ||||
|     'client_txrate'    => 'cldcClientCurrentTxRateSet', | ||||
|     'cd11_proto'       => 'cldcClientProtocol', | ||||
|     'cd11_rateset'     => 'cldcClientDataRateSet', | ||||
|     # CISCO-LWAPP-DOT11-MIB::cldHtMacOperationsTable | ||||
|     'cd11n_ch_bw'      => 'cldHtDot11nChannelBandwidth', | ||||
|  | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::MUNGE,      %SNMP::Info::Bridge::MUNGE, | ||||
|     %SNMP::Info::CDP::MUNGE, %SNMP::Info::Airespace::MUNGE, | ||||
|     'ap_if_mac'         => \&SNMP::Info::munge_mac, | ||||
|     'cd11n_ch_bw'       => \&munge_cd11n_ch_bw, | ||||
|     'cd11_rateset'      => \&munge_cd11_rateset, | ||||
|     'cd11_proto'        => \&munge_cd11_proto, | ||||
| ); | ||||
|  | ||||
| # 802.11n Modulation and Coding Scheme (MCS) | ||||
| my $mcs_index = { | ||||
|     20 => { | ||||
| 	m0  => '6.5', | ||||
| 	m1  => '13', | ||||
| 	m2  => '19.5', | ||||
| 	m3  => '26', | ||||
| 	m4  => '39', | ||||
| 	m5  => '52', | ||||
| 	m6  => '58.5', | ||||
| 	m7  => '65', | ||||
| 	m8  => '13', | ||||
| 	m9  => '26', | ||||
| 	m10 => '39', | ||||
| 	m11 => '52', | ||||
| 	m12 => '78', | ||||
| 	m13 => '104', | ||||
| 	m14 => '117', | ||||
| 	m15 => '130', | ||||
| 	# This is a cheat for 802.11a bonded | ||||
| 	m108 => '108', | ||||
|     }, | ||||
|     40 => { | ||||
| 	m0  => '15', | ||||
| 	m1  => '30', | ||||
| 	m2  => '45', | ||||
| 	m3  => '60', | ||||
| 	m4  => '90', | ||||
| 	m5  => '120', | ||||
| 	m6  => '135', | ||||
| 	m7  => '157.5', | ||||
| 	m8  => '30', | ||||
| 	m9  => '60', | ||||
| 	m10 => '90', | ||||
| 	m11 => '120', | ||||
| 	m12 => '180', | ||||
| 	m13 => '240', | ||||
| 	m14 => '270', | ||||
| 	m15 => '300', | ||||
|     } | ||||
| }; | ||||
|  | ||||
| sub os { | ||||
|     return 'cisco'; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'cisco'; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $airespace = shift; | ||||
|     my $model     = $airespace->airespace_model(); | ||||
|     return unless defined $model; | ||||
|  | ||||
|     return $model; | ||||
| } | ||||
|  | ||||
| sub cd11_mac { | ||||
|     my $airespace = shift; | ||||
|     my $cd11_sigstrength = $airespace->cd11_sigstrength(); | ||||
|  | ||||
|     my $ret = {}; | ||||
|     foreach my $idx ( keys %$cd11_sigstrength ) { | ||||
| 	my $mac = join( ":", map { sprintf "%02x", $_ } split /\./, $idx ); | ||||
| 	$ret->{$idx} = $mac | ||||
|     } | ||||
|     return $ret; | ||||
| } | ||||
|  | ||||
| sub cd11_txrate { | ||||
|     my $airespace = shift; | ||||
|      | ||||
|     my $rates  = $airespace->client_txrate() || {}; | ||||
|     my $protos = $airespace->cd11_proto()    || {}; | ||||
|     my $bws    = $airespace->cd11n_ch_bw()   || {}; | ||||
|      | ||||
|     my $cd11_txrate = {}; | ||||
|     foreach my $idx ( keys %$rates ) { | ||||
| 	my $rate = $rates->{$idx} || '0.0'; | ||||
| 	 | ||||
| 	if ( $rate =~ /^\d+/ ) { | ||||
|             $cd11_txrate->{$idx} = [ $rate * 1.0 ]; | ||||
| 	} | ||||
| 	elsif ( $rate =~ /^m/ ) { | ||||
| 	    my $band = $protos->{$idx}; | ||||
| 	    my $bw   = $bws->{$band}; | ||||
| 	    $cd11_txrate->{$idx} = [ $mcs_index->{$bw}->{$rate} || '0.0' ]; | ||||
| 	} | ||||
| 	else { | ||||
| 	    $cd11_txrate->{$idx} = [ $rate ]; | ||||
| 	} | ||||
|     } | ||||
|     return $cd11_txrate; | ||||
| } | ||||
|  | ||||
| sub munge_cd11n_ch_bw { | ||||
|     my $bw = shift; | ||||
|      | ||||
|     if ( $bw =~ /forty/ ) { | ||||
| 	return 40; | ||||
|     } | ||||
|     return 20; | ||||
| } | ||||
|  | ||||
| sub munge_cd11_proto { | ||||
|     my $bw = shift; | ||||
|      | ||||
|     return 2 if ( $bw eq 'dot11n5' ); | ||||
|  | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| sub munge_cd11_rateset { | ||||
|     my $rates = shift; | ||||
|     return [ map { $_ * 1.0 } split /,/, $rates ]; | ||||
| } | ||||
|  | ||||
| # Cisco provides the AP's Ethernet MAC via | ||||
| # CISCO-LWAPP-AP-MIB::cLApIfMacAddress this was not available pre-Cisco | ||||
| sub i_mac { | ||||
|     my $airespace = shift; | ||||
|     my $partial   = shift; | ||||
|  | ||||
|     my $i_index = $airespace->i_index($partial)  || {}; | ||||
|     my $ap_mac  = $airespace->ap_if_mac()        || {}; | ||||
|  | ||||
|     my $i_mac = $airespace->SUPER::i_mac() || {}; | ||||
|     foreach my $iid ( keys %$i_index ) { | ||||
| 	my $index = $i_index->{$iid}; | ||||
| 	next unless defined $index; | ||||
|  | ||||
| 	if ( $index =~ /(?:[0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}/ ) { | ||||
| 	    $index =~ s/\.\d+$//; | ||||
| 	    next unless defined $index; | ||||
| 	    my $sys_mac = join( '.', map { hex($_) } split( ':', $index ) ); | ||||
| 	    my $mac = $ap_mac->{$sys_mac}; | ||||
| 	    $i_mac->{$iid} = $mac; | ||||
| 	} | ||||
|     } | ||||
|     return $i_mac; | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Airespace - SNMP Interface to Cisco (Airespace) Wireless | ||||
| Controllers | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Eric Miller | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|     #Let SNMP::Info determine the correct subclass for you. | ||||
|  | ||||
|     my $airespace = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|     my $class = $airespace->class(); | ||||
|     print " Using device sub class : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from  | ||||
| Cisco (Airespace) Wireless Controllers through SNMP. | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
| my $airespace = new SNMP::Info::Layer2::Airespace(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Airespace | ||||
|  | ||||
| =item SNMP::Info::CDP | ||||
|  | ||||
| =item SNMP::Info::Bridge | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<CISCO-LWAPP-DOT11-CLIENT-MIB> | ||||
|  | ||||
| =item F<CISCO-LWAPP-DOT11-MIB> | ||||
|  | ||||
| =item F<CISCO-LWAPP-AP-MIB> | ||||
|  | ||||
| =item Inherited Classes' MIBs | ||||
|  | ||||
| See L<SNMP::Info::Airespace/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CDP/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::Bridge/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $airespace->vendor() | ||||
|  | ||||
| Returns 'cisco' | ||||
|  | ||||
| =item $airespace->os() | ||||
|  | ||||
| Returns 'cisco' | ||||
|  | ||||
| =item $airespace->model() | ||||
|  | ||||
| (C<agentInventoryMachineModel>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::Airespace | ||||
|  | ||||
| See documentation in L<SNMP::Info::Airespace/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::CDP | ||||
|  | ||||
| See documentation in L<SNMP::Info::CDP/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Bridge | ||||
|  | ||||
| See documentation in L<SNMP::Info::Bridge/"GLOBALS"> for details. | ||||
|  | ||||
| =head1 TABLE METHODS | ||||
|  | ||||
| These are methods that return tables of information in the form of a reference | ||||
| to a hash. | ||||
|  | ||||
| =over  | ||||
|  | ||||
| =item cd11_mac() | ||||
|  | ||||
| Returns client radio interface MAC addresses. | ||||
|  | ||||
| =item cd11_txrate() | ||||
|  | ||||
| Returns client transmission speed in Mbs. | ||||
|  | ||||
| =back  | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item i_mac() | ||||
|  | ||||
| Adds AP Ethernet MAC as port mac on radio ports from C<CISCO-LWAPP-AP-MIB>. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Airespace | ||||
|  | ||||
| See documentation in L<SNMP::Info::Airespace/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CDP | ||||
|  | ||||
| See documentation in L<SNMP::Info::CDP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Bridge | ||||
|  | ||||
| See documentation in L<SNMP::Info::Bridge/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head1 Data Munging Callback Subroutines | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item munge_cd11n_ch_bw() | ||||
|  | ||||
| Converts 802.11n channel bandwidth to either 20 or 40. | ||||
|  | ||||
| =item munge_cd11_proto() | ||||
|  | ||||
| Converts 802.11n 2.4Ghz to 1 and 5Ghz to 2 to correspond to the | ||||
| (C<cldHtMacOperationsTable>) index. | ||||
|  | ||||
| =item munge_cd11_rateset() | ||||
|  | ||||
| Converts rate set to array. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										690
									
								
								lib/SNMP/Info/Layer2/Aironet.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										690
									
								
								lib/SNMP/Info/Layer2/Aironet.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,690 @@ | ||||
| # SNMP::Info::Layer2::Aironet | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008-2009 Max Baker changes from version 0.8 and beyond. | ||||
| # | ||||
| # Copyright (c) 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::Aironet; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2; | ||||
| use SNMP::Info::Entity; | ||||
| use SNMP::Info::EtherLike; | ||||
| use SNMP::Info::CiscoStats; | ||||
| use SNMP::Info::CiscoConfig; | ||||
| use SNMP::Info::CDP; | ||||
| use SNMP::Info::IEEE802dot11; | ||||
|  | ||||
| @SNMP::Info::Layer2::Aironet::ISA | ||||
|     = qw/SNMP::Info::Layer2 SNMP::Info::Entity SNMP::Info::EtherLike | ||||
|     SNMP::Info::CiscoStats SNMP::Info::CiscoConfig SNMP::Info::CDP Exporter/; | ||||
| @SNMP::Info::Layer2::Aironet::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::IEEE802dot11::GLOBALS, | ||||
|     %SNMP::Info::Layer2::GLOBALS, | ||||
|     %SNMP::Info::Entity::GLOBALS, | ||||
|     %SNMP::Info::EtherLike::GLOBALS, | ||||
|     %SNMP::Info::CiscoStats::GLOBALS, | ||||
|     %SNMP::Info::CiscoConfig::GLOBALS, | ||||
|     %SNMP::Info::CDP::GLOBALS, | ||||
|     'serial' => 'entPhysicalSerialNum.1', | ||||
|     'descr'  => 'sysDescr', | ||||
|     'ps1_type' => 'cpoePdCurrentPowerSource' | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::IEEE802dot11::FUNCS, | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     %SNMP::Info::Entity::FUNCS, | ||||
|     %SNMP::Info::EtherLike::FUNCS, | ||||
|     %SNMP::Info::CiscoStats::FUNCS, | ||||
|     %SNMP::Info::CiscoConfig::FUNCS, | ||||
|     %SNMP::Info::CDP::FUNCS, | ||||
|     'i_80211channel'   => 'cd11IfPhyDsssCurrentChannel', | ||||
|     'c_dot11subif'     => 'cDot11ClientSubIfIndex', | ||||
|     'cd11_rateset'     => 'cDot11ClientDataRateSet', | ||||
|     'cd11_txrate'      => 'cDot11ClientCurrentTxRateSet', | ||||
|     'cd11_uptime'      => 'cDot11ClientUpTime', | ||||
|     'cd11_sigstrength' => 'cDot11ClientSignalStrength', | ||||
|     'cd11_sigqual'     => 'cDot11ClientSigQuality', | ||||
|     'cd11_rxpkt'       => 'cDot11ClientPacketsReceived', | ||||
|     'cd11_txpkt'       => 'cDot11ClientPacketsSent', | ||||
|     'cd11_rxbyte'      => 'cDot11ClientBytesReceived', | ||||
|     'cd11_txbyte'      => 'cDot11ClientBytesSent', | ||||
|     'mbss_mac_addr'    => 'cdot11MbssidIfMacAddress', | ||||
| ); | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::IEEE802dot11::MIBS, | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     %SNMP::Info::Entity::MIBS, | ||||
|     %SNMP::Info::EtherLike::MIBS, | ||||
|     %SNMP::Info::CiscoStats::MIBS, | ||||
|     %SNMP::Info::CiscoConfig::MIBS, | ||||
|     %SNMP::Info::CDP::MIBS, | ||||
|     'CISCO-DOT11-IF-MIB'                  => 'cd11IfAuxSsid', | ||||
|     'CISCO-DOT11-ASSOCIATION-MIB'         => 'cDot11ClientSubIfIndex', | ||||
|     'CISCO-DOT11-SSID-SECURITY-MIB'       => 'cdot11SecVlanNameId', | ||||
|     'CISCO-VLAN-IFTABLE-RELATIONSHIP-MIB' => 'cviRoutedVlanIfIndex', | ||||
|     'CISCO-POE-PD-MIB'                    => 'cpoePdCurrentPowerSource', | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::IEEE802dot11::MUNGE, | ||||
|     %SNMP::Info::Layer2::MUNGE, | ||||
|     %SNMP::Info::Entity::MUNGE, | ||||
|     %SNMP::Info::EtherLike::MUNGE, | ||||
|     %SNMP::Info::CiscoStats::MUNGE, | ||||
|     %SNMP::Info::CiscoConfig::MUNGE, | ||||
|     %SNMP::Info::CDP::MUNGE, | ||||
|     'cd11_txrate'   => \&munge_cd11_txrate, | ||||
|     'cd11_rateset'  => \&munge_cd11_txrate, | ||||
|     'mbss_mac_addr' => \&SNMP::Info::munge_mac, | ||||
| ); | ||||
|  | ||||
| # Use 802.11 power level without putting IEEE802dot11 in @ISA | ||||
| *SNMP::Info::Layer2::Aironet::dot11_cur_tx_pwr_mw | ||||
|     = \&SNMP::Info::IEEE802dot11::dot11_cur_tx_pwr_mw; | ||||
|  | ||||
| sub vendor { | ||||
|  | ||||
|     # Sorry, but it's true. | ||||
|     return 'cisco'; | ||||
| } | ||||
|  | ||||
| sub interfaces { | ||||
|     my $aironet = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $i_description = $aironet->i_description($partial); | ||||
|  | ||||
|     return $i_description; | ||||
| } | ||||
|  | ||||
| # Tag on e_descr.1 | ||||
| sub description { | ||||
|     my $aironet = shift; | ||||
|     my $descr   = $aironet->descr(); | ||||
|     my $e_descr = $aironet->e_descr(); | ||||
|  | ||||
|     $descr = "$e_descr->{1}  $descr" if defined $e_descr->{1}; | ||||
|  | ||||
|     return $descr; | ||||
| } | ||||
|  | ||||
| # Fetch duplex from EtherLike | ||||
| sub i_duplex { | ||||
|     my $aironet = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $el_duplex = $aironet->el_duplex($partial); | ||||
|  | ||||
|     my %i_duplex; | ||||
|     foreach my $d ( keys %$el_duplex ) { | ||||
|         my $val = $el_duplex->{$d}; | ||||
|         next unless defined $val; | ||||
|         $i_duplex{$d} = 'full' if $val =~ /full/i; | ||||
|         $i_duplex{$d} = 'half' if $val =~ /half/i; | ||||
|     } | ||||
|  | ||||
|     return \%i_duplex; | ||||
| } | ||||
|  | ||||
| # | ||||
| # IOS 12.3 introduces the cDot11ClientSubIfIndex in the | ||||
| # cDot11ClientConfigInfoTable, which supplies the ifIndex | ||||
| # of the VLAN Subinterface if one exists, or of the primary | ||||
| # interface if there are not subinterfaces.  12.2 used the | ||||
| # Q-BRIDGE-MIB dot1qTpFdbTable but that was removed in 12.3. | ||||
| sub _aironet_special { | ||||
|     my $aironet = shift; | ||||
|     my $os_ver  = $aironet->os_ver(); | ||||
|     if (   defined($os_ver) | ||||
|         && $os_ver =~ /^(\d+)\.(\d+)(\D|$)/ | ||||
|         && ( ( $1 == 12 && $2 >= 3 ) || $1 > 12 ) ) | ||||
|     { | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| # | ||||
| # INDEX      { ifIndex, cd11IfAuxSsid, cDot11ClientAddress } | ||||
| sub _aironet_breakout_dot11idx { | ||||
|     my $oid = shift; | ||||
|  | ||||
|     my @parts   = split( /\./, $oid ); | ||||
|     my $ifindex = shift(@parts); | ||||
|     my $ssidlen = shift(@parts); | ||||
|     my $ssid    = pack( "C*", splice( @parts, 0, $ssidlen ) ); | ||||
|     my $mac     = join( ":", map { sprintf "%02x", $_ } @parts ); | ||||
|     return ( $ifindex, $ssid, $mac ); | ||||
| } | ||||
|  | ||||
| sub fw_mac { | ||||
|     my $aironet = shift; | ||||
|  | ||||
|     return $aironet->qb_fw_mac() unless _aironet_special($aironet); | ||||
|     my $c_dot11subif = $aironet->c_dot11subif(); | ||||
|     my $fw_mac       = {}; | ||||
|  | ||||
|     foreach my $i ( keys %$c_dot11subif ) { | ||||
|         my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($i); | ||||
|         $fw_mac->{$i} = $mac; | ||||
|     } | ||||
|     return $fw_mac; | ||||
| } | ||||
|  | ||||
| sub fw_port { | ||||
|     my $aironet = shift; | ||||
|  | ||||
|     return $aironet->qb_fw_port() unless _aironet_special($aironet); | ||||
|     my $c_dot11subif = $aironet->c_dot11subif(); | ||||
|     my $fw_port      = {}; | ||||
|  | ||||
|     foreach my $i ( keys %$c_dot11subif ) { | ||||
|         my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($i); | ||||
|         $fw_port->{$i} = $c_dot11subif->{$i} || $ifindex; | ||||
|     } | ||||
|     return $fw_port; | ||||
| } | ||||
|  | ||||
| sub bp_index { | ||||
|     my $aironet = shift; | ||||
|  | ||||
|     return $aironet->orig_bp_index() unless _aironet_special($aironet); | ||||
|     my $c_dot11subif = $aironet->c_dot11subif(); | ||||
|     my $bp_index     = {}; | ||||
|  | ||||
|     foreach my $i ( keys %$c_dot11subif ) { | ||||
|         my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($i); | ||||
|         my ($i) = $c_dot11subif->{$i} || $ifindex; | ||||
|         $bp_index->{$i} = $i; | ||||
|     } | ||||
|     return $bp_index; | ||||
| } | ||||
|  | ||||
| ### | ||||
| # | ||||
| # VLAN support | ||||
| # | ||||
| sub v_name { | ||||
|     my $aironet = shift; | ||||
|  | ||||
|     my $v_name      = {}; | ||||
|     my $vlan_nameid = $aironet->cdot11SecVlanNameId(); | ||||
|     foreach my $i ( keys %$vlan_nameid ) { | ||||
|         my @parts = split( /\./, $i ); | ||||
|         my $namelen = shift(@parts); | ||||
|  | ||||
|         my $name = pack( "C*", @parts ); | ||||
|         $v_name->{$i} = $name; | ||||
|     } | ||||
|     return $v_name; | ||||
| } | ||||
|  | ||||
| sub v_index { | ||||
|     my $aironet = shift; | ||||
|  | ||||
|     return $aironet->cdot11SecVlanNameId(); | ||||
| } | ||||
|  | ||||
| sub i_vlan { | ||||
|     my $aironet = shift; | ||||
|  | ||||
|     my $i_vlan = {}; | ||||
|     my $idxmap = $aironet->cviRoutedVlanIfIndex(); | ||||
|     foreach my $i ( keys %$idxmap ) { | ||||
|         my @parts = split( /\./, $i ); | ||||
|         $i_vlan->{ $idxmap->{$i} } = $parts[0]; | ||||
|     } | ||||
|     return $i_vlan; | ||||
| } | ||||
|  | ||||
| # The MIB reports in units of half a megabit, e.g., | ||||
| # 5.5Mbps is reported as 11. | ||||
| sub munge_cd11_txrate { | ||||
|     my $txrates = shift; | ||||
|     my @units   = unpack( "C*", $txrates ); | ||||
|     my @rates   = map { | ||||
|         my $unit = $_; | ||||
|         $unit *= 0.5; | ||||
|     } @units; | ||||
|  | ||||
|     return \@rates; | ||||
| } | ||||
|  | ||||
| # cd11 INDEX | ||||
| sub cd11_port { | ||||
|     my $aironet          = shift; | ||||
|     my $cd11_sigstrength = $aironet->cd11_sigstrength(); | ||||
|     my $interfaces       = $aironet->interfaces(); | ||||
|     my %ret; | ||||
|     foreach ( keys %$cd11_sigstrength ) { | ||||
|         my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($_); | ||||
|         $ret{$_} = $interfaces->{$ifindex}; | ||||
|     } | ||||
|     return \%ret; | ||||
| } | ||||
|  | ||||
| sub cd11_ssid { | ||||
|     my $aironet          = shift; | ||||
|     my $cd11_sigstrength = $aironet->cd11_sigstrength(); | ||||
|     my %ret; | ||||
|     foreach ( keys %$cd11_sigstrength ) { | ||||
|         my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($_); | ||||
|         $ret{$_} = $ssid; | ||||
|     } | ||||
|     return \%ret; | ||||
| } | ||||
|  | ||||
| sub cd11_mac { | ||||
|     my $aironet          = shift; | ||||
|     my $cd11_sigstrength = $aironet->cd11_sigstrength(); | ||||
|     my %ret; | ||||
|     foreach ( keys %$cd11_sigstrength ) { | ||||
|         my ( $ifindex, $ssid, $mac ) = _aironet_breakout_dot11idx($_); | ||||
|         $ret{$_} = $mac; | ||||
|     } | ||||
|     return \%ret; | ||||
| } | ||||
|  | ||||
| # Map VLAN N on interface I to its actual ifIndex. | ||||
| sub _vlan_map_n_stack { | ||||
|     my $aironet  = shift; | ||||
|     my $vlan_idx = $aironet->cviRoutedVlanIfIndex(); | ||||
|  | ||||
|     my $vlan_map = {}; | ||||
|     foreach my $idx ( keys %$vlan_idx ) { | ||||
|         my ( $vlan, $num ) = split( /\./, $idx ); | ||||
|         $vlan_map->{$vlan}->{$num} = $vlan_idx->{$idx}; | ||||
|     } | ||||
|     return $vlan_map; | ||||
| } | ||||
|  | ||||
| # When using MBSS, the ifTable reports the | ||||
| # base MAC address, but the actual association is | ||||
| # with a different MAC address for MBSS. | ||||
| # This convoluted path seems to be necessary | ||||
| # to get the right overrides. | ||||
| sub i_mac { | ||||
|     my $aironet = shift; | ||||
|  | ||||
|     # no partial is possible due to the levels | ||||
|     # of indirection. | ||||
|  | ||||
|     # Start with the ifPhysAddress, and override | ||||
|     my $mbss_mac = $aironet->orig_i_mac(); | ||||
|  | ||||
|     my $mbss_mac_addr = $aironet->mbss_mac_addr(); | ||||
|     my $ssid_vlan     = $aironet->cdot11SecAuxSsidVlan(); | ||||
|     my $vlan_map      = $aironet->cviRoutedVlanIfIndex(); | ||||
|     my $ifstack       = $aironet->ifStackStatus(); | ||||
|  | ||||
|     my $vlan_list = {}; | ||||
|     foreach my $idx ( keys %$vlan_map ) { | ||||
|         my ( $vlan, $num ) = split( /\./, $idx ); | ||||
|         push( @{ $vlan_list->{$vlan} }, $vlan_map->{$idx} ); | ||||
|     } | ||||
|  | ||||
|     my $stack = {}; | ||||
|     foreach my $idx ( keys %$ifstack ) { | ||||
|         my ( $upper, $lower ) = split( /\./, $idx ); | ||||
|         $stack->{$upper}->{$lower} = $ifstack->{$idx}; | ||||
|     } | ||||
|  | ||||
|     # mbss_mac_addr index is (radio, ssid). | ||||
|     # ssid_vlan maps ssid->vlan. | ||||
|     # vlan_map maps vlan->[list of interfaces] | ||||
|     # ifstack allows us to pick the right interface | ||||
|     foreach my $idx ( keys %$mbss_mac_addr ) { | ||||
|         my ( $interface, @ssid ) = split( /\./, $idx ); | ||||
|         my $vlan = $ssid_vlan->{ join( ".", scalar(@ssid), @ssid ) }; | ||||
|         next unless defined($vlan); | ||||
|         foreach my $vlanif ( @{ $vlan_list->{$vlan} } ) { | ||||
|             if ( defined( $stack->{$vlanif}->{$interface} ) ) { | ||||
|                 $mbss_mac->{$vlanif} = $mbss_mac_addr->{$idx}; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return $mbss_mac; | ||||
| } | ||||
|  | ||||
| sub i_ssidlist { | ||||
|     my $aironet = shift; | ||||
|  | ||||
|     # no partial is possible due to the levels | ||||
|     # of indirection. | ||||
|     my $ssid_row  = $aironet->cdot11SecInterfSsidRowStatus(); | ||||
|     my $ssid_vlan = $aironet->cdot11SecAuxSsidVlan(); | ||||
|     if ( !defined($ssid_row) || !defined($ssid_vlan) ) { | ||||
|         return $aironet->cd11IfAuxSsid(); | ||||
|     } | ||||
|     my $ssidlist     = {}; | ||||
|     my $if_ssidcount = {}; | ||||
|     my $vlan_map     = $aironet->_vlan_map_n_stack(); | ||||
|     foreach my $idx ( keys %$ssid_row ) { | ||||
|         next unless $ssid_row->{$idx} eq 'active'; | ||||
|  | ||||
|         # ssid_row index is radio.ssid | ||||
|         my ( $interface, $ssid ) = split( /\./, $idx, 2 ); | ||||
|         my ( $len, @ssidt ) = split( /\./, $ssid ); | ||||
|         my $mappedintf = $vlan_map->{ $ssid_vlan->{$ssid} }->{$interface}; | ||||
|         next unless $mappedintf; | ||||
|         if ( !$if_ssidcount->{$mappedintf} ) { | ||||
|             $if_ssidcount->{$mappedintf} = 1; | ||||
|         } | ||||
|         my $ssidlist_idx | ||||
|             = sprintf( "%s.%d", $mappedintf, $if_ssidcount->{$mappedintf} ); | ||||
|         $ssidlist->{$ssidlist_idx} = pack( "C*", @ssidt ); | ||||
|         $if_ssidcount->{$mappedintf}++; | ||||
|     } | ||||
|     return $ssidlist; | ||||
| } | ||||
|  | ||||
| sub i_ssidbcast { | ||||
|     my $aironet    = shift; | ||||
|     my $partial    = shift; | ||||
|     my $mbss_bcast = $aironet->cdot11SecAuxSsidMbssidBroadcast(); | ||||
|     if ( !defined($mbss_bcast) ) { | ||||
|         return $aironet->cd11IfAuxSsidBroadcastSsid($partial); | ||||
|     } | ||||
|     my $map = {}; | ||||
|     foreach my $key ( keys %$mbss_bcast ) { | ||||
|         my (@idx) = split( /\./, $key ); | ||||
|         my $len = shift(@idx); | ||||
|         $map->{ pack( "C*", @idx ) } = $mbss_bcast->{$key}; | ||||
|     } | ||||
|  | ||||
|     # This needs to return the same indexes as i_ssidlist. | ||||
|     # mbss_bcast maps ssid -> broadcasting | ||||
|     #  so we just replace the i_ssidlist values with the mbss_bcast ones. | ||||
|     my $i_ssidlist  = $aironet->i_ssidlist(); | ||||
|     my $i_ssidbcast = {}; | ||||
|     foreach my $key ( keys %$i_ssidlist ) { | ||||
|         $i_ssidbcast->{$key} = $map->{ $i_ssidlist->{$key} }; | ||||
|     } | ||||
|     return $i_ssidbcast; | ||||
| } | ||||
|  | ||||
| sub i_ssidmac { | ||||
|     my $aironet    = shift; | ||||
|     my $partial    = shift; | ||||
|     my $mbss_mac_addr = $aironet->mbss_mac_addr(); | ||||
|  | ||||
|     # Same logic as i_ssidbcast to return same indexes as i_ssidlist  | ||||
|     my $map = {}; | ||||
|     foreach my $key ( keys %$mbss_mac_addr ) { | ||||
|         my ( $interface, @idx ) = split( /\./, $key ); | ||||
|         $map->{ pack( "C*", @idx ) } = $mbss_mac_addr->{$key}; | ||||
|     } | ||||
|  | ||||
|     my $i_ssidlist  = $aironet->i_ssidlist(); | ||||
|     my $i_ssidmac = {}; | ||||
|     foreach my $key ( keys %$i_ssidlist ) { | ||||
|         $i_ssidmac->{$key} = $map->{ $i_ssidlist->{$key} }; | ||||
|     } | ||||
|     return $i_ssidmac; | ||||
| } | ||||
|  | ||||
| ### | ||||
| # PoE status.  The ps1_type is the PoE injector type, which is just | ||||
| # a scalar; the status is a little more complex. | ||||
| sub ps1_status { | ||||
|     my $aironet = shift; | ||||
|     my $idx = $aironet->cpoePdCurrentPowerLevel(); | ||||
|     my $mw = $aironet->cpoePdSupportedPower( $idx ); | ||||
|     my $descr = $aironet->cpoePdSupportedPowerMode( $idx ); | ||||
|  | ||||
|     return sprintf( "%.2fW (%s)", $mw->{$idx} * 0.001, $descr->{$idx} ); | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Aironet - SNMP Interface to Cisco Aironet devices running | ||||
| IOS. | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Baker | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $aironet = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $aironet->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides interface to SNMP Data available on newer Aironet devices running | ||||
| Cisco IOS. | ||||
|  | ||||
| Note there are two classes for Aironet devices : | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer3::Aironet | ||||
|  | ||||
| This class is for devices running Aironet software (older) | ||||
|  | ||||
| =item SNMP::Info::Layer2::Aironet | ||||
|  | ||||
| This class is for devices running Cisco IOS software (newer) | ||||
|  | ||||
| =back | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
| my $aironet = new SNMP::Info::Layer2::Aironet(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =item SNMP::Info::Entity | ||||
|  | ||||
| =item SNMP::Info::EtherLike | ||||
|  | ||||
| =item SNMP::Info::CiscoStats | ||||
|  | ||||
| =item SNMP::Info::CiscoConfig | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item Inherited Classes | ||||
|  | ||||
| MIBs required by the inherited classes listed above. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $aironet->vendor() | ||||
|  | ||||
| Returns 'cisco' | ||||
|  | ||||
| =item $aironet->description() | ||||
|  | ||||
| System description. Adds info from method e_descr() from SNMP::Info::Entity | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Entity | ||||
|  | ||||
| See documentation in L<SNMP::Info::Entity/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::EtherLike | ||||
|  | ||||
| See documentation in L<SNMP::Info::EtherLike/"GLOBALS"> for details. | ||||
|  | ||||
| =head1 TABLE METHODS | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $aironet->cd11_port() | ||||
|  | ||||
| Returns radio interfaces. | ||||
|  | ||||
| =item $aironet->cd11_mac() | ||||
|  | ||||
| Returns client radio interface MAC addresses. | ||||
|  | ||||
| =item $aironet->cd11_ssid() | ||||
|  | ||||
| Returns radio interface ssid. | ||||
|  | ||||
| =item $aironet->dot11_cur_tx_pwr_mw() | ||||
|  | ||||
| Current transmit power, in milliwatts, of the radio interface. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $aironet->interfaces() | ||||
|  | ||||
| Uses the i_description() field. | ||||
|  | ||||
| =item $aironet->i_mac() | ||||
|  | ||||
| MAC address of the interface. Note this is just the MAC of the port, not | ||||
| anything connected to it. | ||||
|  | ||||
| =item $aironet->i_duplex() | ||||
|  | ||||
| Crosses information from SNMP::Info::EtherLike to get duplex info for | ||||
| interfaces. | ||||
|  | ||||
| =item $aironet->bp_index() | ||||
|  | ||||
| Returns reference to hash of bridge port table entries map back to interface | ||||
| identifier (iid) | ||||
|  | ||||
| =item $aironet->fw_mac() | ||||
|  | ||||
| Returns reference to hash of forwarding table MAC Addresses | ||||
|  | ||||
| =item $aironet->fw_port() | ||||
|  | ||||
| Returns reference to hash of forwarding table entries port interface | ||||
| identifier (iid) | ||||
|  | ||||
| =item $aironet->i_vlan() | ||||
|  | ||||
| Returns a mapping between C<ifIndex> and the PVID or default VLAN. | ||||
|  | ||||
| =item $aironet->v_index() | ||||
|  | ||||
| Returns VLAN IDs | ||||
|  | ||||
| =item $aironet->v_name() | ||||
|  | ||||
| Returns VLAN names | ||||
|  | ||||
| =item $aironet->i_ssidlist() | ||||
|  | ||||
| Returns a list of SSIDs associated with interfaces.  This function | ||||
| is C<MBSSID> aware, so when using C<MBSSID> can map SSIDs to the sub-interface | ||||
| to which they belong. | ||||
|  | ||||
| =item $aironet->i_ssidbcast() | ||||
|  | ||||
| With the same keys as i_ssidlist, returns whether the given SSID is | ||||
| being broadcast. | ||||
|  | ||||
| =item $aironet->i_ssidmac() | ||||
|  | ||||
| With the same keys as i_ssidlist, returns the Basic service set | ||||
| identification (BSSID), MAC address, the AP is using for the SSID.  | ||||
|  | ||||
| =item $aironet ps1_status() | ||||
|  | ||||
| Returns the PoE injector status based on C<cpoePdSupportedPower> and  | ||||
| C<cpoePdSupportedPowerMode>. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Entity | ||||
|  | ||||
| See documentation in L<SNMP::Info::Entity/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::EtherLike | ||||
|  | ||||
| See documentation in L<SNMP::Info::EtherLike/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head1 Data Munging Callback Subroutines | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $aironet->munge_cd11_txrate() | ||||
|  | ||||
| Converts units of half a megabit to human readable string. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										240
									
								
								lib/SNMP/Info/Layer2/Allied.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								lib/SNMP/Info/Layer2/Allied.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,240 @@ | ||||
| # SNMP::Info::Layer2::Allied | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008 Max Baker | ||||
| # 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::Allied; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2; | ||||
| use SNMP::Info::Layer1; | ||||
|  | ||||
| @SNMP::Info::Layer2::Allied::ISA       = qw/SNMP::Info::Layer2 Exporter/; | ||||
| @SNMP::Info::Layer2::Allied::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     'ip_adresses' => 'atNetAddress', | ||||
|     'ip_mac'      => 'atPhysAddress', | ||||
| ); | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     'AtiSwitch-MIB'    => 'atiswitchProductType', | ||||
|     'AtiStackInfo-MIB' => 'atiswitchEnhancedStacking', | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( %SNMP::Info::Layer2::MUNGE, ); | ||||
|  | ||||
| sub vendor { | ||||
|     return 'allied'; | ||||
| } | ||||
|  | ||||
| sub os { | ||||
|     return 'allied'; | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|     my $allied = shift; | ||||
|     my $descr  = $allied->description(); | ||||
|  | ||||
|     if ( $descr =~ m/version (\d+\.\d+)/ ) { | ||||
|         return $1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $allied = shift; | ||||
|  | ||||
|     my $desc = $allied->description(); | ||||
|  | ||||
|     if ( $desc =~ /(AT-80\d{2}\S*)/ ) { | ||||
|         return $1; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub root_ip { | ||||
|     my $allied  = shift; | ||||
|     my $ip_hash = $allied->ip_addresses(); | ||||
|     my $found_ip; | ||||
|  | ||||
|     foreach my $ip ( values %{$ip_hash} ) { | ||||
|         $found_ip = SNMP::Info::munge_ip($ip) if ( defined $ip ); | ||||
|         last;    # this is only one IP address | ||||
|     } | ||||
|     return $found_ip; | ||||
| } | ||||
|  | ||||
| sub mac { | ||||
|     my $allied   = shift; | ||||
|     my $mac_hash = $allied->ip_mac(); | ||||
|     my $found_mac; | ||||
|  | ||||
|     foreach my $mac ( values %{$mac_hash} ) { | ||||
|         $found_mac = SNMP::Info::munge_mac($mac); | ||||
|         last;    # this is only one MAC address | ||||
|     } | ||||
|     return $found_mac; | ||||
| } | ||||
|  | ||||
| sub i_up { | ||||
|     my $allied  = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $i_up = SNMP::Info::Layer1::i_up( $allied, $partial ); | ||||
|  | ||||
|     foreach my $port ( keys %$i_up ) { | ||||
|         my $up = $i_up->{$port}; | ||||
|         $i_up->{$port} = 'down' if $up eq 'linktesterror'; | ||||
|         $i_up->{$port} = 'up'   if $up eq 'nolinktesterror'; | ||||
|     } | ||||
|  | ||||
|     return $i_up; | ||||
| } | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Allied - SNMP Interface to Allied Telesis switches | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Baker, Dmitry Sergienko <dmitry@trifle.net> | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $allied = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myhub', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 1 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class = $allied->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from a  | ||||
| Allied device through SNMP. See inherited classes' documentation for  | ||||
| inherited methods. | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<AtiSwitch-MIB> | ||||
|  | ||||
| =item F<AtiStackInfo-MIB> | ||||
|  | ||||
| Download for your device from ftp://ftp.allied-telesyn.com/pub/switches/mibs/ | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Inherited MIBs | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $allied->vendor() | ||||
|  | ||||
| Returns 'allied' :) | ||||
|  | ||||
| =item $allied->os() | ||||
|  | ||||
| Returns 'allied'  | ||||
|  | ||||
| =item $allied->os_ver() | ||||
|  | ||||
| Culls Version from description() | ||||
|  | ||||
| =item $allied->root_ip() | ||||
|  | ||||
| Returns IP Address of Managed Device. | ||||
|  | ||||
| (C<actualIpAddr>) | ||||
|  | ||||
| =item $allied->model() | ||||
|  | ||||
| Tries to cull out C<AT-nnnnX> out of the description field. | ||||
|  | ||||
| =item $allied->mac() | ||||
|  | ||||
| Returns device MAC.  | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head1 TABLE METHODS | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $allied->i_up() | ||||
|  | ||||
| Returns reference to map of IIDs to link status.  Changes | ||||
| the values of ati_up() to 'up' and 'down'. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										711
									
								
								lib/SNMP/Info/Layer2/Baystack.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										711
									
								
								lib/SNMP/Info/Layer2/Baystack.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,711 @@ | ||||
| # SNMP::Info::Layer2::Baystack | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond. | ||||
| # 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::Baystack; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::SONMP; | ||||
| use SNMP::Info::NortelStack; | ||||
| use SNMP::Info::RapidCity; | ||||
| use SNMP::Info::LLDP; | ||||
| use SNMP::Info::Layer3; | ||||
|  | ||||
| @SNMP::Info::Layer2::Baystack::ISA | ||||
|     = qw/SNMP::Info::SONMP SNMP::Info::NortelStack | ||||
|     SNMP::Info::RapidCity SNMP::Info::LLDP | ||||
|     SNMP::Info::Layer3 Exporter/; | ||||
| @SNMP::Info::Layer2::Baystack::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer3::MIBS,    %SNMP::Info::LLDP::MIBS, | ||||
|     %SNMP::Info::RapidCity::MIBS, %SNMP::Info::NortelStack::MIBS, | ||||
|     %SNMP::Info::SONMP::MIBS, | ||||
|     'BAY-STACK-PETH-EXT-MIB' => 'bspePethPsePortExtMeasuredPower', | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer3::GLOBALS,    %SNMP::Info::LLDP::GLOBALS, | ||||
|     %SNMP::Info::RapidCity::GLOBALS, %SNMP::Info::NortelStack::GLOBALS, | ||||
|     %SNMP::Info::SONMP::GLOBALS, | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer3::FUNCS,    %SNMP::Info::LLDP::FUNCS, | ||||
|     %SNMP::Info::RapidCity::FUNCS, %SNMP::Info::NortelStack::FUNCS, | ||||
|     %SNMP::Info::SONMP::FUNCS, | ||||
|     'peth_port_power' => 'bspePethPsePortExtMeasuredPower', | ||||
| ); | ||||
|  | ||||
| # 450's report full duplex as speed = 20mbps?! | ||||
| $SNMP::Info::SPEED_MAP{20_000_000}    = '10 Mbps'; | ||||
| $SNMP::Info::SPEED_MAP{200_000_000}   = '100 Mbps'; | ||||
| $SNMP::Info::SPEED_MAP{2_000_000_000} = '1.0 Gbps'; | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::Layer3::MUNGE,    %SNMP::Info::LLDP::MUNGE, | ||||
|     %SNMP::Info::RapidCity::MUNGE, %SNMP::Info::NortelStack::MUNGE, | ||||
|     %SNMP::Info::SONMP::MUNGE, | ||||
| ); | ||||
|  | ||||
| sub os { | ||||
|     my $baystack = shift; | ||||
|     my $descr    = $baystack->description() || ""; | ||||
|     my $model    = $baystack->model() || ""; | ||||
|  | ||||
|     if ( $descr =~ /Business Ethernet Switch.*SW:v/i ) { | ||||
|         return 'bes'; | ||||
|     } | ||||
|     if (   ( ( $model =~ /(420|425|BPS)/ ) and ( $descr =~ m/SW:v[1-2]/i ) ) | ||||
|         or ( ( $model =~ /(410|450|380)/ ) ) ) | ||||
|     { | ||||
|         return 'baystack'; | ||||
|     } | ||||
|     if ( $model =~ /VSP/ ) { | ||||
|         return 'vsp'; | ||||
|     } | ||||
|  | ||||
|     return 'boss'; | ||||
| } | ||||
|  | ||||
| sub os_bin { | ||||
|     my $baystack = shift; | ||||
|     my $descr    = $baystack->description(); | ||||
|     return unless defined $descr; | ||||
|  | ||||
|     # 303 / 304 | ||||
|     if ( $descr =~ m/Rev: \d+\.(\d+\.\d+\.\d+)-\d+\.\d+\.\d+\.\d+/ ) { | ||||
|         return $1; | ||||
|     } | ||||
|  | ||||
|     # 450 | ||||
|     if ( $descr =~ m/FW:V(\d+\.\d+)/ ) { | ||||
|         return $1; | ||||
|     } | ||||
|  | ||||
|     if ( $descr =~ m/FW:(\d+\.\d+\.\d+\.\d+)/i ) { | ||||
|         return $1; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'avaya'; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $baystack = shift; | ||||
|     my $id       = $baystack->id(); | ||||
|     return unless defined $id; | ||||
|     my $model = &SNMP::translateObj($id); | ||||
|     return $id unless defined $model; | ||||
|  | ||||
|     my $descr = $baystack->description(); | ||||
|  | ||||
|     return '303' if ( defined $descr and $descr =~ /\D303\D/ ); | ||||
|     return '304' if ( defined $descr and $descr =~ /\D304\D/ ); | ||||
|     return 'BPS' if ( $model =~ /BPS2000/i ); | ||||
|      | ||||
|     # Pull sreg- from all | ||||
|     $model =~ s/^sreg-//; | ||||
|     # Strip ES/ERS/BayStack etc. from those families | ||||
|     $model =~ s/^(E(R)?S|BayStack|Ethernet(Routing)?Switch)-?//; | ||||
|     $model =~ s/-ethSwitchNMM//; | ||||
|  | ||||
|     return $model; | ||||
| } | ||||
|  | ||||
| sub interfaces { | ||||
|     my $baystack = shift; | ||||
|     my $partial  = shift; | ||||
|  | ||||
|     my $i_index      = $baystack->i_index($partial) || {}; | ||||
|     my $index_factor = $baystack->index_factor(); | ||||
|     my $slot_offset  = $baystack->slot_offset(); | ||||
|  | ||||
|     my %if; | ||||
|     foreach my $iid ( keys %$i_index ) { | ||||
|         my $index = $i_index->{$iid}; | ||||
|         next unless defined $index; | ||||
|  | ||||
|         # Ignore cascade ports | ||||
|         next if $index > $index_factor * 8; | ||||
|  | ||||
|         my $port = ( $index % $index_factor ); | ||||
|         my $slot = ( int( $index / $index_factor ) ) + $slot_offset; | ||||
|  | ||||
|         my $slotport = "$slot.$port"; | ||||
|         $if{$iid} = $slotport; | ||||
|     } | ||||
|     return \%if; | ||||
| } | ||||
|  | ||||
| sub i_mac { | ||||
|     my $baystack = shift; | ||||
|     my $partial  = shift; | ||||
|  | ||||
|     my $i_mac = $baystack->orig_i_mac($partial) || {}; | ||||
|  | ||||
|     my %i_mac; | ||||
|  | ||||
|     # Baystack 303's with a hw rev < 2.11.4.5 report the mac as all zeros | ||||
|     foreach my $iid ( keys %$i_mac ) { | ||||
|         my $mac = $i_mac->{$iid}; | ||||
|         next unless defined $mac; | ||||
|         next if $mac eq '00:00:00:00:00:00'; | ||||
|         $i_mac{$iid} = $mac; | ||||
|     } | ||||
|     return \%i_mac; | ||||
| } | ||||
|  | ||||
| sub i_name { | ||||
|     my $baystack = shift; | ||||
|     my $partial  = shift; | ||||
|  | ||||
|     my $i_index = $baystack->i_index($partial)     || {}; | ||||
|     my $i_alias = $baystack->i_alias($partial)     || {}; | ||||
|     my $i_name2 = $baystack->orig_i_name($partial) || {}; | ||||
|  | ||||
|     my %i_name; | ||||
|     foreach my $iid ( keys %$i_name2 ) { | ||||
|         my $name  = $i_name2->{$iid}; | ||||
|         my $alias = $i_alias->{$iid}; | ||||
|         $i_name{$iid} | ||||
|             = ( defined $alias and $alias !~ /^\s*$/ ) | ||||
|             ? $alias | ||||
|             : $name; | ||||
|     } | ||||
|  | ||||
|     return \%i_name; | ||||
| } | ||||
|  | ||||
| sub index_factor { | ||||
|     my $baystack = shift; | ||||
|     my $model    = $baystack->model() || ""; | ||||
|     my $os       = $baystack->os(); | ||||
|     my $os_ver   = $baystack->os_ver(); | ||||
|     my $op_mode  = $baystack->ns_op_mode(); | ||||
|  | ||||
|     $op_mode = 'pure' unless defined $op_mode; | ||||
|     if ( $os_ver =~ m/^(\d+)\./ ) { | ||||
|         $os_ver = $1; | ||||
|     } else { | ||||
|         $os_ver = 1; | ||||
|     } | ||||
|  | ||||
|     my $index_factor = 32; | ||||
|     $index_factor = 64 | ||||
|         if ( ( $model =~ /(470)/ ) | ||||
|         or ( $os =~ m/(boss|bes)/ ) and ( $op_mode eq 'pure' ) ); | ||||
|     $index_factor = 128 | ||||
|         if ( ( $model =~ /(5[56]\d\d)|VSP/ ) | ||||
|         and ( $os_ver >= 6 ) ); | ||||
|  | ||||
|     return $index_factor; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| # Newer devices support ENTITY-MIB, use if available otherwise use proprietary | ||||
| # methods. | ||||
|  | ||||
| sub e_index { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_index($partial) || $stack->ns_e_index($partial); | ||||
| } | ||||
|  | ||||
| sub e_class { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_class($partial) || $stack->ns_e_class($partial); | ||||
| } | ||||
|  | ||||
| sub e_descr { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_descr($partial) || $stack->ns_e_descr($partial); | ||||
| } | ||||
|  | ||||
| sub e_name { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_name($partial) || $stack->ns_e_name($partial); | ||||
| } | ||||
|  | ||||
| sub e_fwver { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_fwver($partial) || $stack->ns_e_fwver($partial); | ||||
| } | ||||
|  | ||||
| sub e_hwver { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_hwver($partial) || $stack->ns_e_hwver($partial); | ||||
| } | ||||
|  | ||||
| sub e_parent { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_parent($partial) || $stack->ns_e_parent($partial); | ||||
| } | ||||
|  | ||||
| sub e_pos { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_pos($partial) || $stack->ns_e_pos($partial); | ||||
| } | ||||
|  | ||||
| sub e_serial { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_serial($partial) || $stack->ns_e_serial($partial); | ||||
| } | ||||
|  | ||||
| sub e_swver { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_swver($partial) || $stack->ns_e_swver($partial); | ||||
| } | ||||
|  | ||||
| sub e_type { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_type($partial) || $stack->ns_e_type($partial); | ||||
| } | ||||
|  | ||||
| sub e_vendor { | ||||
|     my $stack   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $stack->SUPER::e_vendor($partial) || $stack->ns_e_vendor($partial); | ||||
| } | ||||
|  | ||||
| # fix for stack of switches without POE on module 1 | ||||
| # https://sourceforge.net/tracker/?func=detail&aid=3317739&group_id=70362&atid=527529 | ||||
| sub peth_port_ifindex { | ||||
|     my $stack = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my %peth_port_ifindex = (); | ||||
|     my $poe_port_st = $stack->peth_port_status($partial); | ||||
|     my $if_index = $stack->interfaces($partial); | ||||
|  | ||||
|     foreach my $i (keys %$if_index) { | ||||
|         next unless defined $poe_port_st->{$if_index->{$i}}; | ||||
|         $peth_port_ifindex{$if_index->{$i}} = $i; | ||||
|     } | ||||
|     return \%peth_port_ifindex; | ||||
| } | ||||
|  | ||||
| # Currently only ERS 4800 v5.8+ support the rcBridgeSpbmMacTable  | ||||
| # which holds the FDB for a SPBM edge deployment. | ||||
| # | ||||
| # Q-BRIDGE still holds some entries when the rcBridgeSpbmMacTable is in use | ||||
| # so we merge hash entries. | ||||
|  | ||||
| sub fw_mac { | ||||
|     my $rapidcity = shift; | ||||
|  | ||||
|     my $qb = $rapidcity->SUPER::fw_mac() || {}; | ||||
|     my $spbm = $rapidcity->rc_spbm_fw_mac() || {}; | ||||
|     my $fw_mac = { %$qb, %$spbm }; | ||||
|      | ||||
|     return $fw_mac; | ||||
| } | ||||
|  | ||||
| sub fw_port { | ||||
|     my $rapidcity = shift; | ||||
|  | ||||
|     my $qb = $rapidcity->SUPER::fw_port() || {}; | ||||
|     my $spbm = $rapidcity->rc_spbm_fw_port() || {}; | ||||
|     my $fw_port = { %$qb, %$spbm }; | ||||
|      | ||||
|     return $fw_port; | ||||
| } | ||||
|  | ||||
| sub fw_status { | ||||
|     my $rapidcity = shift; | ||||
|  | ||||
|     my $qb = $rapidcity->SUPER::fw_status() || {};     | ||||
|     my $spbm = $rapidcity->rc_spbm_fw_status() || {}; | ||||
|     my $fw_status = { %$qb, %$spbm }; | ||||
|      | ||||
|     return $fw_status; | ||||
| } | ||||
|  | ||||
| sub qb_fw_vlan { | ||||
|     my $rapidcity = shift; | ||||
|  | ||||
|     my $qb = $rapidcity->SUPER::qb_fw_vlan() || {}; | ||||
|     my $spbm = $rapidcity->rc_spbm_fw_vlan() || {}; | ||||
|     my $qb_fw_vlan = { %$qb, %$spbm }; | ||||
|      | ||||
|     return $qb_fw_vlan; | ||||
| } | ||||
|  | ||||
| # Baystack uses S5-AGENT-MIB (loaded in NortelStack) versus RAPID-CITY | ||||
| sub stp_ver { | ||||
|     my $rapidcity = shift; | ||||
|  | ||||
|     return $rapidcity->s5AgSysSpanningTreeOperMode() | ||||
|       || $rapidcity->SUPER::stp_ver(); | ||||
| } | ||||
|  | ||||
| 1; | ||||
|  | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Baystack - SNMP Interface to Avaya Ethernet Switch | ||||
| (Baystack) and VSP 7000 series switches | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Eric Miller | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you. | ||||
|  my $baystack = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|   or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class = $baystack->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from an | ||||
| Avaya Ethernet Switch (formerly Nortel/Bay Baystack) and VSP 7000 series | ||||
| through SNMP.  | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
| my $baystack = new SNMP::Info::Layer2::Baystack(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::SONMP | ||||
|  | ||||
| =item SNMP::Info::NortelStack | ||||
|  | ||||
| =item SNMP::Info::RapidCity | ||||
|  | ||||
| =item SNMP::Info::LLDP | ||||
|  | ||||
| =item SNMP::Info::Layer3 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<BAY-STACK-PETH-EXT-MIBB> | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Inherited MIBs | ||||
|  | ||||
| See L<SNMP::Info::SONMP/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::NortelStack/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::RapidCity/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::LLDP/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::Layer3/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $baystack->vendor() | ||||
|  | ||||
| Returns 'avaya' | ||||
|  | ||||
| =item $baystack->model() | ||||
|  | ||||
| Cross references $baystack->id() to the F<SYNOPTICS-MIB> and returns | ||||
| the results.  303s and 304s have the same ID, so we have a hack | ||||
| to return depending on which it is. | ||||
|  | ||||
| Returns BPS for Business Policy Switch | ||||
|  | ||||
| For others extracts and returns the switch numeric designation. | ||||
|  | ||||
| =item $baystack->os() | ||||
|  | ||||
| Returns 'baystack' or 'boss' depending on software version. | ||||
|  | ||||
| =item $baystack->os_bin() | ||||
|  | ||||
| Returns the firmware version extracted from C<sysDescr>. | ||||
|  | ||||
| =item $baystack->stp_ver() | ||||
|  | ||||
| Returns the particular STP version running on this device.   | ||||
|  | ||||
| Values: C<nortelStpg>, C<pvst>, C<rstp>, C<mstp>, C<ieee8021d> | ||||
|  | ||||
| (C<s5AgSysSpanningTreeOperMode>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item  $baystack->index_factor() | ||||
|  | ||||
| Required by SNMP::Info::SONMP.  Number representing the number of ports | ||||
| reserved per slot within the device MIB. | ||||
|  | ||||
| Index factor on the Baystack switches are determined by the formula: Index | ||||
| Factor = 64 if (model = 470 or (os eq 'boss' and operating in pure mode)) | ||||
| or else Index factor = 32. | ||||
|  | ||||
| Returns either 32 or 64 based upon the formula. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::SONMP | ||||
|  | ||||
| See L<SNMP::Info::SONMP/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::NortelStack | ||||
|  | ||||
| See L<SNMP::Info::NortelStack/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::RapidCity | ||||
|  | ||||
| See L<SNMP::Info::RapidCity/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::LLDP | ||||
|  | ||||
| See documentation in L<SNMP::Info::LLDP/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer3 | ||||
|  | ||||
| See L<SNMP::Info::Layer3/"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 $baystack->interfaces() | ||||
|  | ||||
| Returns reference to the map between IID and physical Port. | ||||
|  | ||||
|   Slot and port numbers on the Baystack switches are determined by the | ||||
|   formula: | ||||
|    | ||||
|   port = (Interface index % Index factor) | ||||
|   slot = (int(Interface index / Index factor)) + Slot offset | ||||
|   | ||||
|   The physical port name is returned as slot.port. | ||||
|  | ||||
| =item $baystack->i_ignore() | ||||
|  | ||||
| Returns reference to hash of IIDs to ignore. | ||||
|  | ||||
| =item $baystack->i_mac() | ||||
|  | ||||
| Returns the C<ifPhysAddress> table entries.  | ||||
|  | ||||
| Removes all entries matching '00:00:00:00:00:00' -- Certain  | ||||
| revisions of Baystack firmware report all zeros for each port mac. | ||||
|  | ||||
| =item $baystack->i_name() | ||||
|  | ||||
| Crosses C<ifName> with C<ifAlias> and returns the human set port name if | ||||
| exists. | ||||
|  | ||||
| =item $baystack->peth_port_ifindex() | ||||
|  | ||||
| Maps the C<pethPsePortTable> to C<ifIndex> by way of the F<ENTITY-MIB>. | ||||
|  | ||||
| =item $baystack->peth_port_power() | ||||
|  | ||||
| Power supplied by PoE ports, in milliwatts | ||||
|  | ||||
| (C<bspePethPsePortExtMeasuredPower>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 F<ENTITY-MIB> Information | ||||
|  | ||||
| For older devices which do not support F<ENTITY-MIB>, these methods emulate | ||||
| Physical Table methods using F<S5-CHASSIS-MIB>.  See | ||||
| L<SNMP::Info::NortelStack/"TABLE METHODS"> for details on ns_e_* methods. | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $baystack->e_index()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalDescr>, this will try ns_e_index(). | ||||
| Note that this is based on C<entPhysicalDescr> due to implementation | ||||
| details of SNMP::Info::Entity::e_index(). | ||||
|  | ||||
| =item $baystack->e_class()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalClass>, this will try ns_e_class(). | ||||
|  | ||||
| =item $baystack->e_descr()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalDescr>, this will try ns_e_descr(). | ||||
|  | ||||
| =item $baystack->e_name()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalName>, this will try ns_e_name(). | ||||
|  | ||||
| =item $baystack->e_fwver()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalFirmwareRev>, this will try | ||||
| ns_e_fwver(). | ||||
|  | ||||
| =item $baystack->e_hwver()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalHardwareRev>, this will try | ||||
| ns_e_hwver(). | ||||
|  | ||||
| =item $baystack->e_parent()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalContainedIn>, this will try | ||||
| ns_e_parent(). | ||||
|  | ||||
| =item $baystack->e_pos()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalParentRelPos>, this will try | ||||
| ns_e_pos(). | ||||
|  | ||||
| =item $baystack->e_serial()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalSerialNum>, this will try | ||||
| ns_e_serial(). | ||||
|  | ||||
| =item $baystack->e_swver()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalSoftwareRev>, this will try | ||||
| ns_e_swver(). | ||||
|  | ||||
| =item $baystack->e_type()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalVendorType>, this will try | ||||
| ns_e_type(). | ||||
|  | ||||
| =item $baystack->e_vendor()  | ||||
|  | ||||
| If the device doesn't support C<entPhysicalMfgName>, this will try | ||||
| ns_e_vendor(). | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Layer 2 Forwarding Database | ||||
|  | ||||
| These methods try to obtain the layer 2 forwarding database entries via the | ||||
| normal bridge methods as well as SPBM entries via rapid city methods. | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $baystack->fw_mac() | ||||
|  | ||||
| Returns reference to hash of forwarding table MAC Addresses | ||||
|  | ||||
| =item $baystack->fw_port() | ||||
|  | ||||
| Returns reference to hash of forwarding table entries port interface | ||||
| identifier (iid) | ||||
|  | ||||
| =item $baystack->qb_fw_vlan() | ||||
|  | ||||
| Returns reference to hash of forwarding table entries VLAN ID | ||||
|  | ||||
| =item $baystack->fw_status() | ||||
|  | ||||
| Returns reference to hash of forwarding table entries status | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::SONMP | ||||
|  | ||||
| See L<SNMP::Info::SONMP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::NortelStack | ||||
|  | ||||
| See L<SNMP::Info::NortelStack/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::RapidCity | ||||
|  | ||||
| See L<SNMP::Info::RapidCity/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::LLDP | ||||
|  | ||||
| See documentation in L<SNMP::Info::LLDP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer3 | ||||
|  | ||||
| See L<SNMP::Info::Layer3/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										580
									
								
								lib/SNMP/Info/Layer2/C1900.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										580
									
								
								lib/SNMP/Info/Layer2/C1900.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,580 @@ | ||||
| # SNMP::Info::Layer2::C1900 | ||||
| # $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::Layer2::C1900; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::CDP; | ||||
| use SNMP::Info::CiscoStats; | ||||
| use SNMP::Info::CiscoConfig; | ||||
| use SNMP::Info::CiscoStpExtensions; | ||||
| use SNMP::Info::CiscoAgg; | ||||
| use SNMP::Info::Layer2; | ||||
|  | ||||
| @SNMP::Info::Layer2::C1900::ISA = qw/SNMP::Info::CDP SNMP::Info::CiscoStats | ||||
|     SNMP::Info::CiscoConfig SNMP::Info::CiscoStpExtensions SNMP::Info::CiscoAgg SNMP::Info::Layer2 | ||||
|     Exporter/; | ||||
| @SNMP::Info::Layer2::C1900::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::GLOBALS, | ||||
|     %SNMP::Info::CiscoAgg::GLOBALS, | ||||
|     %SNMP::Info::CiscoStpExtensions::GLOBALS, | ||||
|     %SNMP::Info::CiscoConfig::GLOBALS, | ||||
|     %SNMP::Info::CiscoStats::GLOBALS, | ||||
|     %SNMP::Info::CDP::GLOBALS, | ||||
|     'c1900_flash_status' => 'upgradeFlashBankStatus', | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     %SNMP::Info::CiscoAgg::FUNCS, | ||||
|     %SNMP::Info::CiscoStpExtensions::FUNCS, | ||||
|     %SNMP::Info::CiscoConfig::FUNCS, | ||||
|     %SNMP::Info::CiscoStats::FUNCS, | ||||
|     %SNMP::Info::CDP::FUNCS, | ||||
|  | ||||
|     # ESSWITCH-MIB | ||||
|     'c1900_p_index'        => 'swPortIndex', | ||||
|     'c1900_p_ifindex'      => 'swPortIfIndex', | ||||
|     'c1900_p_duplex'       => 'swPortDuplexStatus', | ||||
|     'c1900_p_duplex_admin' => 'swPortFullDuplex', | ||||
|     'c1900_p_name'         => 'swPortName', | ||||
|     'c1900_p_up_admin'     => 'swPortAdminStatus', | ||||
|     'c1900_p_type'         => 'swPortMediaCapability', | ||||
|     'c1900_p_media'        => 'swPortConnectorType', | ||||
| ); | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     %SNMP::Info::CiscoAgg::MIBS, | ||||
|     %SNMP::Info::CiscoStpExtensions::MIBS, | ||||
|     %SNMP::Info::CiscoConfig::MIBS, | ||||
|     %SNMP::Info::CiscoStats::MIBS, | ||||
|     %SNMP::Info::CDP::MIBS, | ||||
|  | ||||
|     # Also known as the ESSWITCH-MIB | ||||
|     'STAND-ALONE-ETHERNET-SWITCH-MIB' => 'series2000' | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::Layer2::MUNGE,             %SNMP::Info::CiscoAgg::MUNGE, | ||||
|     %SNMP::Info::CiscoStpExtensions::MUNGE, %SNMP::Info::CiscoConfig::MUNGE, | ||||
|     %SNMP::Info::CiscoStats::MUNGE,         %SNMP::Info::CDP::MUNGE, | ||||
| ); | ||||
|  | ||||
| sub bulkwalk_no         { return 1; } | ||||
| sub cisco_comm_indexing { return 1; } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'cisco'; | ||||
| } | ||||
|  | ||||
| sub os { | ||||
|     return 'catalyst'; | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|     my $c1900 = shift; | ||||
|  | ||||
|     # Check for superclass one | ||||
|     my $os_ver = $c1900->SUPER::os_ver(); | ||||
|     return $os_ver if defined $os_ver; | ||||
|  | ||||
|     my $c1900_flash_status = $c1900->c1900_flash_status(); | ||||
|     return unless defined $c1900_flash_status; | ||||
|  | ||||
|     if ( $c1900_flash_status =~ m/V(\d+\.\d+(\.\d+)?)/ ) { | ||||
|         return $1; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub interfaces { | ||||
|     my $c1900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $i_descr = $c1900->i_description($partial) || {}; | ||||
|  | ||||
|     foreach my $iid ( keys %$i_descr ) { | ||||
|         $i_descr->{$iid} =~ s/\s*$//; | ||||
|     } | ||||
|     return $i_descr; | ||||
| } | ||||
|  | ||||
| sub i_duplex { | ||||
|     my $c1900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $c1900_p_duplex = $c1900->c1900_p_duplex($partial) || {}; | ||||
|  | ||||
|     my %i_duplex; | ||||
|     foreach my $if ( keys %$c1900_p_duplex ) { | ||||
|         my $duplex = $c1900_p_duplex->{$if}; | ||||
|         next unless defined $duplex; | ||||
|  | ||||
|         $duplex = 'half' if $duplex =~ /half/i; | ||||
|         $duplex = 'full' if $duplex =~ /full/i; | ||||
|         $i_duplex{$if} = $duplex; | ||||
|     } | ||||
|     return \%i_duplex; | ||||
| } | ||||
|  | ||||
| sub i_duplex_admin { | ||||
|     my $c1900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $c1900_p_admin = $c1900->c1900_p_duplex_admin($partial) || {}; | ||||
|  | ||||
|     my %i_duplex_admin; | ||||
|     foreach my $if ( keys %$c1900_p_admin ) { | ||||
|         my $duplex = $c1900_p_admin->{$if}; | ||||
|         next unless defined $duplex; | ||||
|  | ||||
|         $duplex = 'half' if $duplex =~ /disabled/i; | ||||
|         $duplex = 'full' if $duplex =~ /flow control/i; | ||||
|         $duplex = 'full' if $duplex =~ /enabled/i; | ||||
|         $duplex = 'auto' if $duplex =~ /auto/i; | ||||
|         $i_duplex_admin{$if} = $duplex; | ||||
|     } | ||||
|     return \%i_duplex_admin; | ||||
| } | ||||
|  | ||||
| sub i_name { | ||||
|     my $c1900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $i_name       = $c1900->orig_i_name($partial)  || {}; | ||||
|     my $c1900_p_name = $c1900->c1900_p_name($partial) || {}; | ||||
|  | ||||
|     foreach my $port ( keys %$c1900_p_name ) { | ||||
|         my $name = $c1900_p_name->{$port}; | ||||
|         next unless defined $name; | ||||
|         next unless $name !~ /^\s*$/; | ||||
|         $i_name->{$port} = $name; | ||||
|     } | ||||
|  | ||||
|     return $i_name; | ||||
| } | ||||
|  | ||||
| sub set_i_duplex_admin { | ||||
|     my $c1900 = shift; | ||||
|     my ( $duplex, $port ) = @_; | ||||
|  | ||||
|     # map a textual duplex to an integer one the switch understands | ||||
|     my %duplexes = qw/full 1 half 2 auto 3/; | ||||
|  | ||||
|     my $iid = $c1900->c1900_p_ifindex($port); | ||||
|  | ||||
|     $duplex = lc($duplex); | ||||
|  | ||||
|     return 0 unless defined $duplexes{$duplex}; | ||||
|  | ||||
|     return $c1900->set_c1900_p_duplex_admin( $duplexes{$duplex}, $iid ); | ||||
| } | ||||
|  | ||||
| sub i_vlan { | ||||
|     my $c1900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     # Overlap allows more than one VLAN per port.  Unable to determine default | ||||
|     my $overlap  | ||||
|         = $c1900->bridgeGroupAllowMembershipOverlap() | ||||
|         || $c1900->vlanAllowMembershipOverlap() | ||||
|         || 'disabled'; | ||||
|  | ||||
|     if ( $overlap eq 'enabled' ) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     my $member_of = $c1900->bridgeGroupMemberPortOfBridgeGroup() | ||||
|         || $c1900->vlanMemberPortOfVlan(); | ||||
|  | ||||
|     my $i_pvid = {}; | ||||
|     foreach my $idx ( keys %$member_of ) { | ||||
|         my @values = split( /\./, $idx ); | ||||
|         my ( $vlan, $port ) = @values; | ||||
|         next unless $vlan; | ||||
|         next unless $port; | ||||
|         next if ( defined $partial and $port !~ /^$partial$/ ); | ||||
|         my $value = $member_of->{$idx}; | ||||
|         next if ( $value eq 'false' ); | ||||
|  | ||||
|         $i_pvid->{$port} = $vlan; | ||||
|     } | ||||
|     return $i_pvid; | ||||
| } | ||||
|  | ||||
| sub i_vlan_membership { | ||||
|     my $c1900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $member_of = $c1900->bridgeGroupMemberPortOfBridgeGroup() | ||||
|         || $c1900->vlanMemberPortOfVlan(); | ||||
|  | ||||
|     my $i_vlan_membership = {}; | ||||
|     foreach my $idx ( keys %$member_of ) { | ||||
|         my @values = split( /\./, $idx ); | ||||
|         my ( $vlan, $port ) = @values; | ||||
|         next unless $vlan; | ||||
|         next unless $port; | ||||
|         next if ( defined $partial and $port !~ /^$partial$/ ); | ||||
|         my $value = $member_of->{$idx}; | ||||
|         next if ( $value eq 'false' ); | ||||
|  | ||||
|         push( @{ $i_vlan_membership->{$port} }, $vlan ); | ||||
|     } | ||||
|     return $i_vlan_membership; | ||||
| } | ||||
|  | ||||
| sub i_vlan_membership_untagged { return; } | ||||
|  | ||||
| sub bp_index { | ||||
|     my $c1900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $if_index = $c1900->i_index($partial); | ||||
|     my $index = $c1900->orig_bp_index($partial) || {}; | ||||
|     foreach my $iid ( keys %$if_index ) { | ||||
|         $index->{$iid} = $iid if ( !defined $index->{$iid} ); | ||||
|     } | ||||
|     return $index; | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::C1900 - SNMP Interface to data from Cisco Catalyst 1900 | ||||
| Network Switches running CatOS | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Baker | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $c1900 = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 1 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $c1900->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from a | ||||
| Catalyst 1900 device through SNMP.  See SNMP::Info for full documentation | ||||
|  | ||||
| Note that most of these devices only talk SNMP version 1, but not all. | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
|  my $c1900 = new SNMP::Info::Layer2::C1900(...); | ||||
|  | ||||
| =head2 Inherited classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::CDP | ||||
|  | ||||
| =item SNMP::Info::CiscoStats | ||||
|  | ||||
| =item SNMP::Info::CiscoConfig | ||||
|  | ||||
| =item SNMP::Info::CiscoStpExtensions | ||||
|  | ||||
| =item SNMP::Info::CiscoAgg | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<STAND-ALONE-ETHERNET-SWITCH-MIB (ESSWITCH-MIB)> | ||||
|  | ||||
| F<ESSWITCH-MIB> is included in the Version 1 MIBs from Cisco. | ||||
|  | ||||
| They can be found at ftp://ftp.cisco.com/pub/mibs/v1/v1.tar.gz | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Inherited MIBs | ||||
|  | ||||
| See L<SNMP::Info::CDP/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoStats/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoConfig/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoStpExtensions/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoAgg/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $c1900->c1900_flash_status() | ||||
|  | ||||
| Usually contains the version of the software loaded in flash. | ||||
| Used by os_ver() | ||||
|  | ||||
| C<STAND-ALONE-ETHERNET-SWITCH-MIB::upgradeFlashBankStatus> | ||||
|  | ||||
| =item $c1900->os() | ||||
|  | ||||
| Returns 'catalyst' | ||||
|  | ||||
| =item $c1900->os_ver() | ||||
|  | ||||
| Returns CatOS version if obtainable.  First tries to use  | ||||
| SNMP::Info::CiscoStats->os_ver() .  If that fails then it  | ||||
| checks for the presence of $c1900->c1900_flash_status() and culls | ||||
| the version from there. | ||||
|  | ||||
| =item $c1900->vendor() | ||||
|  | ||||
| Returns 'cisco' :) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $c1900->cisco_comm_indexing() | ||||
|  | ||||
| Returns 1.  Use vlan indexing. | ||||
|  | ||||
| =item $c1900->bulkwalk_no | ||||
|  | ||||
| Return C<1>.  Bulkwalk is turned off for this class. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CDP | ||||
|  | ||||
| See L<SNMP::Info::CDP/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoStats | ||||
|  | ||||
| See L<SNMP::Info::CiscoStats/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoConfig | ||||
|  | ||||
| See L<SNMP::Info::CiscoConfig/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoStpExtensions | ||||
|  | ||||
| See L<SNMP::Info::CiscoStpExtensions/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoAgg | ||||
|  | ||||
| See L<SNMP::Info::CiscoAgg/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"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 $c1900->interfaces() | ||||
|  | ||||
| Returns reference to the map between IID and physical Port. | ||||
|  | ||||
| =item $c1900->i_duplex() | ||||
|  | ||||
| Returns reference to map of IIDs to current link duplex | ||||
|  | ||||
| =item $c1900->i_duplex_admin() | ||||
|  | ||||
| Returns reference to hash of IIDs to admin duplex setting | ||||
|  | ||||
| =item $c1900->i_name() | ||||
|  | ||||
| Crosses C<ifName> with $c1900->c1900_p_name() and returns the human set port | ||||
| name if exists. | ||||
|  | ||||
| =item $c1900->i_vlan() | ||||
|  | ||||
| Returns a mapping between the interface and the VLAN / bridge group if overlap | ||||
| is not enabled. | ||||
|  | ||||
| =item $c1900->i_vlan_membership() | ||||
|  | ||||
| Returns reference to hash of arrays: key = interface, value = array of VLAN / | ||||
| bridge group IDs. | ||||
|  | ||||
|   Example: | ||||
|   my $interfaces = $c1900->interfaces(); | ||||
|   my $vlans      = $c1900->i_vlan_membership(); | ||||
|    | ||||
|   foreach my $iid (sort keys %$interfaces) { | ||||
|     my $port = $interfaces->{$iid}; | ||||
|     my $vlan = join(',', sort(@{$vlans->{$iid}})); | ||||
|     print "Port: $port VLAN: $vlan\n"; | ||||
|   } | ||||
|  | ||||
| =item $c1900->i_vlan_membership_untagged() | ||||
|  | ||||
| Unsupported, returns nothing. | ||||
|  | ||||
| =item $c1900->bp_index() | ||||
|  | ||||
| Returns a bp_index that contains the original bp_index entries and extra | ||||
| entries for those interfaces listed in if_index, as some C1900 devices do not | ||||
| return complete bp_indexes. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 F<STAND-ALONE-ETHERNET-SWITCH-MIB> Switch Port Table Entries: | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $c1900->c1900_p_index() | ||||
|  | ||||
| Maps the Switch Port Table to the IID | ||||
|  | ||||
| C<swPortIfIndex> | ||||
|  | ||||
| =item $c1900->c1900_p_duplex() | ||||
|  | ||||
| Gives Port Duplex Info | ||||
|  | ||||
| (C<swPortDuplexStatus>) | ||||
|  | ||||
| =item $c1900->c1900_p_duplex_admin() | ||||
|  | ||||
| Gives admin setting for Duplex Info | ||||
|  | ||||
| (C<swPortFullDuplex>) | ||||
|  | ||||
| =item $c1900->c1900_p_name() | ||||
|  | ||||
| Gives human set name for port  | ||||
|  | ||||
| (C<swPortName>) | ||||
|  | ||||
| =item $c1900->c1900_p_up_admin() | ||||
|  | ||||
| Gives Admin status of port enabled. | ||||
|  | ||||
| (C<swPortAdminStatus>) | ||||
|  | ||||
| =item $c1900->c1900_p_type() | ||||
|  | ||||
| Gives Type of port, i.e. C<"general-ethernet"> | ||||
|  | ||||
| (C<swPortMediaCapability>) | ||||
|  | ||||
| =item $c1900->c1900_p_media() | ||||
|  | ||||
| Gives the media of the port , i.e. "C<fiber-sc>" | ||||
|  | ||||
| (C<swPortConnectorType>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CDP | ||||
|  | ||||
| See L<SNMP::Info::CDP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoStats | ||||
|  | ||||
| See L<SNMP::Info::CiscoStats/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoConfig | ||||
|  | ||||
| See L<SNMP::Info::CiscoConfig/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoStpExtensions | ||||
|  | ||||
| See L<SNMP::Info::CiscoStpExtensions/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoAgg | ||||
|  | ||||
| See L<SNMP::Info::CiscoAgg/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head1 SET METHODS | ||||
|  | ||||
| These are methods that provide SNMP set functionality for overridden methods | ||||
| or provide a simpler interface to complex set operations.  See | ||||
| L<SNMP::Info/"SETTING DATA VIA SNMP"> for general information on set | ||||
| operations.  | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $c1900->set_i_duplex_admin(duplex, ifIndex) | ||||
|  | ||||
| Sets port duplex, must be supplied with duplex and port C<ifIndex>.  Speed | ||||
| choices are 'auto', 'half', 'full'. | ||||
|  | ||||
|   Example: | ||||
|   my %if_map = reverse %{$c1900->interfaces()}; | ||||
|   $c1900->set_i_duplex_admin('auto', $if_map{'1'})  | ||||
|     or die "Couldn't change port duplex. ",$c1900->error(1); | ||||
|  | ||||
| =back | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										410
									
								
								lib/SNMP/Info/Layer2/C2900.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										410
									
								
								lib/SNMP/Info/Layer2/C2900.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,410 @@ | ||||
| # SNMP::Info::Layer2::C2900 | ||||
| # $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::Layer2::C2900; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2::Cisco; | ||||
|  | ||||
| @SNMP::Info::Layer2::C2900::ISA = qw/SNMP::Info::Layer2::Cisco Exporter/; | ||||
| @SNMP::Info::Layer2::C2900::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::Cisco::GLOBALS, | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::Cisco::FUNCS, | ||||
|     'i_name' => 'ifAlias', | ||||
|  | ||||
|     # C2900PortEntry | ||||
|     'c2900_p_index'        => 'c2900PortIfIndex', | ||||
|     'c2900_p_duplex'       => 'c2900PortDuplexStatus', | ||||
|     'c2900_p_duplex_admin' => 'c2900PortDuplexState', | ||||
|     'c2900_p_speed_admin'  => 'c2900PortAdminSpeed', | ||||
| ); | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::Cisco::MIBS, | ||||
|     'CISCO-C2900-MIB' => 'ciscoC2900MIB', | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::Layer2::Cisco::MUNGE, | ||||
| ); | ||||
|  | ||||
| sub vendor { | ||||
|     return 'cisco'; | ||||
| } | ||||
|  | ||||
| sub cisco_comm_indexing { | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| sub i_duplex { | ||||
|     my $c2900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $interfaces     = $c2900->interfaces($partial); | ||||
|     my $c2900_p_index  = $c2900->c2900_p_index() || {}; | ||||
|     my $c2900_p_duplex = $c2900->c2900_p_duplex(); | ||||
|  | ||||
|     my %reverse_2900 = reverse %$c2900_p_index; | ||||
|  | ||||
|     my %i_duplex; | ||||
|     foreach my $if ( keys %$interfaces ) { | ||||
|         my $port_2900 = $reverse_2900{$if}; | ||||
|         next unless defined $port_2900; | ||||
|         my $duplex = $c2900_p_duplex->{$port_2900}; | ||||
|         next unless defined $duplex; | ||||
|  | ||||
|         $duplex = 'half' if $duplex =~ /half/i; | ||||
|         $duplex = 'full' if $duplex =~ /full/i; | ||||
|         $i_duplex{$if} = $duplex; | ||||
|     } | ||||
|     return \%i_duplex; | ||||
| } | ||||
|  | ||||
| sub i_duplex_admin { | ||||
|     my $c2900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $interfaces    = $c2900->interfaces($partial); | ||||
|     my $c2900_p_index = $c2900->c2900_p_index() || {}; | ||||
|     my $c2900_p_admin = $c2900->c2900_p_duplex_admin(); | ||||
|  | ||||
|     my %reverse_2900 = reverse %$c2900_p_index; | ||||
|  | ||||
|     my %i_duplex_admin; | ||||
|     foreach my $if ( keys %$interfaces ) { | ||||
|         my $port_2900 = $reverse_2900{$if}; | ||||
|         next unless defined $port_2900; | ||||
|         my $duplex = $c2900_p_admin->{$port_2900}; | ||||
|         next unless defined $duplex; | ||||
|  | ||||
|         $duplex = 'half' if $duplex =~ /half/i; | ||||
|         $duplex = 'full' if $duplex =~ /full/i; | ||||
|         $duplex = 'auto' if $duplex =~ /auto/i; | ||||
|         $i_duplex_admin{$if} = $duplex; | ||||
|     } | ||||
|     return \%i_duplex_admin; | ||||
| } | ||||
|  | ||||
| sub i_speed_admin { | ||||
|     my $c2900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my %i_speed_admin; | ||||
|     my $p_port        = $c2900->p_port() || {}; | ||||
|     my $interfaces    = $c2900->interfaces($partial); | ||||
|     my $c2900_p_index = $c2900->c2900_p_index() || {}; | ||||
|  | ||||
|     my %reverse_2900 = reverse %$c2900_p_index; | ||||
|     my $c2900_p_speed | ||||
|         = $c2900->c2900_p_speed_admin( $reverse_2900{$partial} ); | ||||
|  | ||||
|     my %speeds = ( | ||||
|         'autoDetect' => 'auto', | ||||
|         's10000000'  => '10 Mbps', | ||||
|         's100000000' => '100 Mbps', | ||||
|     ); | ||||
|  | ||||
|     %i_speed_admin | ||||
|         = map { $c2900_p_index->{$_} => $speeds{ $c2900_p_speed->{$_} } } | ||||
|         keys %$c2900_p_index; | ||||
|  | ||||
|     return \%i_speed_admin; | ||||
| } | ||||
|  | ||||
| sub set_i_speed_admin { | ||||
|     my $c2900 = shift; | ||||
|     my ( $speed, $iid ) = @_; | ||||
|  | ||||
|     # map speeds to those the switch will understand | ||||
|     my %speeds = qw/auto 1 10 10000000 100 100000000/; | ||||
|  | ||||
|     my $c2900_p_index = $c2900->c2900_p_index() || {}; | ||||
|     my %reverse_2900 = reverse %$c2900_p_index; | ||||
|  | ||||
|     $speed = lc($speed); | ||||
|  | ||||
|     return unless defined $speeds{$speed}; | ||||
|  | ||||
|     # account for weirdness of c2900 mib | ||||
|     $iid = $reverse_2900{$iid}; | ||||
|  | ||||
|     return $c2900->set_c2900_p_speed_admin( $speeds{$speed}, $iid ); | ||||
| } | ||||
|  | ||||
| sub set_i_duplex_admin { | ||||
|     my $c2900 = shift; | ||||
|     my ( $duplex, $iid ) = @_; | ||||
|  | ||||
|     # map a textual duplex to an integer one the switch understands | ||||
|     my %duplexes = qw/full 1 half 2 auto 3/; | ||||
|  | ||||
|     my $c2900_p_index = $c2900->c2900_p_index() || {}; | ||||
|     my %reverse_2900 = reverse %$c2900_p_index; | ||||
|  | ||||
|     $duplex = lc($duplex); | ||||
|  | ||||
|     return unless defined $duplexes{$duplex}; | ||||
|  | ||||
|     # account for weirdness of c2900 mib | ||||
|     $iid = $reverse_2900{$iid}; | ||||
|  | ||||
|     return $c2900->set_c2900_p_duplex_admin( $duplexes{$duplex}, $iid ); | ||||
| } | ||||
|  | ||||
| # Use i_descritption for port key, cuz i_name can be manually entered. | ||||
| sub interfaces { | ||||
|     my $c2900   = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $interfaces = $c2900->i_index($partial)       || {}; | ||||
|     my $i_descr    = $c2900->i_description($partial) || {}; | ||||
|  | ||||
|     my %if; | ||||
|     foreach my $iid ( keys %$interfaces ) { | ||||
|         my $port = $i_descr->{$iid}; | ||||
|         next unless defined $port; | ||||
|  | ||||
|         $port =~ s/\./\//g if ( $port =~ /\d+\.\d+$/ ); | ||||
|         $port =~ s/[^\d\/,()\w]+//gi; | ||||
|  | ||||
|         $if{$iid} = $port; | ||||
|     } | ||||
|  | ||||
|     return \%if; | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::C2900 - SNMP Interface to Cisco Catalyst 2900 Switches | ||||
| running IOS | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Baker | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $c2900 = new SNMP::Info( | ||||
|                         AutoSpecify => 1, | ||||
|                         Debug       => 1, | ||||
|                         # These arguments are passed directly to SNMP::Session | ||||
|                         DestHost    => 'myswitch', | ||||
|                         Community   => 'public', | ||||
|                         Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class = $c2900->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from a  | ||||
| C2900 device through SNMP.  | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
|  my $c2900 = new SNMP::Info::Layer2::C2900(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2::Cisco | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<CISCO-C2900-MIB> | ||||
|  | ||||
| Part of the v2 MIBs from Cisco. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Inherited MIBs | ||||
|  | ||||
| See L<SNMP::Info::Layer2::Cisco/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $c2900->vendor() | ||||
|  | ||||
| Returns 'cisco' :) | ||||
|  | ||||
| =item $c2900->cisco_comm_indexing() | ||||
|  | ||||
| Returns 1.  Use vlan indexing. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2::Cisco | ||||
|  | ||||
| See L<SNMP::Info::Layer2::Cisco/"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 $c2900->interfaces() | ||||
|  | ||||
| Returns reference to the map between IID and physical Port. | ||||
|  | ||||
| On the 2900 devices i_name isn't reliable, so we override to just the | ||||
| description. | ||||
|  | ||||
| Next all dots are changed for forward slashes so that the physical port name  | ||||
| is the same as the broad-casted CDP port name.  | ||||
|     (Ethernet0.1 -> Ethernet0/1) | ||||
|  | ||||
| Also, any weird characters are removed, as I saw a few pop up. | ||||
|  | ||||
| =item $c2900->i_duplex() | ||||
|  | ||||
| Returns reference to map of IIDs to current link duplex | ||||
|  | ||||
| Crosses $c2900->c2900_p_index() with $c2900->c2900_p_duplex() | ||||
|  | ||||
| =item $c2900->i_duplex_admin() | ||||
|  | ||||
| Returns reference to hash of IIDs to admin duplex setting | ||||
|  | ||||
| Crosses $c2900->c2900_p_index() with $c2900->c2900_p_duplex_admin() | ||||
|  | ||||
| =item $c2900->i_speed_admin() | ||||
|  | ||||
| Returns reference to hash of IIDs to admin speed setting. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 F<C2900-MIB> Port Entry Table  | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $c2900->c2900_p_index() | ||||
|  | ||||
| Maps the Switch Port Table to the IID | ||||
|  | ||||
| (C<c2900PortIfIndex>) | ||||
|  | ||||
| =item $c2900->c2900_p_duplex() | ||||
|  | ||||
| Gives Port Duplex Info | ||||
|  | ||||
| (C<c2900PortDuplexStatus>) | ||||
|  | ||||
| =item $c2900->c2900_p_duplex_admin() | ||||
|  | ||||
| Gives admin setting for Duplex Info | ||||
|  | ||||
| (C<c2900PortDuplexState>) | ||||
|  | ||||
| =item $c2900->c2900_p_speed_admin() | ||||
|  | ||||
| Gives Admin speed of port  | ||||
|  | ||||
| (C<c2900PortAdminSpeed>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2::Cisco | ||||
|  | ||||
| See L<SNMP::Info::Layer2::Cisco/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head1 SET METHODS | ||||
|  | ||||
| These are methods that provide SNMP set functionality for overridden methods | ||||
| or provide a simpler interface to complex set operations.  See | ||||
| L<SNMP::Info/"SETTING DATA VIA SNMP"> for general information on set | ||||
| operations.  | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $c2900->set_i_speed_admin(speed, ifIndex) | ||||
|  | ||||
| Sets port speed, must be supplied with speed and port C<ifIndex> | ||||
|  | ||||
| Speed choices are 'auto', '10', '100' | ||||
|  | ||||
| Crosses $c2900->c2900_p_index() with $c2900->c2900_p_speed_admin() to utilize | ||||
| port C<ifIndex>. | ||||
|  | ||||
|     Example: | ||||
|     my %if_map = reverse %{$c2900->interfaces()}; | ||||
|     $c2900->set_i_speed_admin('auto', $if_map{'FastEthernet0/1'})  | ||||
|         or die "Couldn't change port speed. ",$c2900->error(1); | ||||
|  | ||||
| =item $c2900->set_i_duplex_admin(duplex, ifIndex) | ||||
|  | ||||
| Sets port duplex, must be supplied with duplex and port C<ifIndex> | ||||
|  | ||||
| Speed choices are 'auto', 'half', 'full' | ||||
|  | ||||
| Crosses $c2900->c2900_p_index() with $c2900->c2900_p_duplex_admin() to utilize | ||||
| port C<ifIndex>. | ||||
|  | ||||
|     Example: | ||||
|     my %if_map = reverse %{$c2900->interfaces()}; | ||||
|     $c2900->set_i_duplex_admin('auto', $if_map{'FastEthernet0/1'})  | ||||
|         or die "Couldn't change port duplex. ",$c2900->error(1); | ||||
|  | ||||
| =back | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										312
									
								
								lib/SNMP/Info/Layer2/Catalyst.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								lib/SNMP/Info/Layer2/Catalyst.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,312 @@ | ||||
| # SNMP::Info::Layer2::Catalyst | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2002,2003 Regents of the University of California | ||||
| # Copyright (c) 2008 Max Baker changes from version 0.8 and beyond | ||||
| # 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::Catalyst; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::CiscoStack; | ||||
| use SNMP::Info::Layer2::Cisco; | ||||
|  | ||||
| @SNMP::Info::Layer2::Catalyst::ISA | ||||
|     = qw/SNMP::Info::CiscoStack SNMP::Info::Layer2::Cisco Exporter/; | ||||
| @SNMP::Info::Layer2::Catalyst::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::Cisco::MIBS, | ||||
|     %SNMP::Info::CiscoStack::MIBS, | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::Cisco::GLOBALS, | ||||
|     %SNMP::Info::CiscoStack::GLOBALS, | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::Cisco::FUNCS, | ||||
|     %SNMP::Info::CiscoStack::FUNCS, | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::Layer2::Cisco::MUNGE, | ||||
|     %SNMP::Info::CiscoStack::MUNGE, | ||||
| ); | ||||
|  | ||||
| # Overidden Methods | ||||
|  | ||||
| # i_physical sets a hash entry as true if the iid is a physical port | ||||
| sub i_physical { | ||||
|     my $cat = shift; | ||||
|  | ||||
|     my $p_port = $cat->p_port(); | ||||
|  | ||||
|     my %i_physical; | ||||
|     foreach my $port ( keys %$p_port ) { | ||||
|         my $iid = $p_port->{$port}; | ||||
|         $i_physical{$iid} = 1; | ||||
|     } | ||||
|     return \%i_physical; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'cisco'; | ||||
| } | ||||
|  | ||||
| sub os { | ||||
|     return 'catalyst'; | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|     my $cat    = shift; | ||||
|     my $os_ver = $cat->SUPER::os_ver(); | ||||
|     return $os_ver if defined $os_ver; | ||||
|  | ||||
|     my $m_swver = $cat->m_swver(); | ||||
|     return unless defined $m_swver; | ||||
|  | ||||
|     # assume .1 entry is the chassis and the sw version we want. | ||||
|     return $m_swver->{1} if defined $m_swver->{1}; | ||||
|     return; | ||||
| } | ||||
|  | ||||
| # Workaround for incomplete bp_index | ||||
| sub bp_index { | ||||
|     my $cat     = shift; | ||||
|     my $p_index = $cat->p_port(); | ||||
|     my $b_index = $cat->p_oidx(); | ||||
|  | ||||
|     my %bp_index; | ||||
|     foreach my $iid ( keys %$p_index ) { | ||||
|         my $ifidx = $p_index->{$iid}; | ||||
|         next unless defined $ifidx; | ||||
|         my $bpidx = $b_index->{$iid} || 0; | ||||
|  | ||||
|         $bp_index{$bpidx} = $ifidx; | ||||
|     } | ||||
|     return \%bp_index; | ||||
| } | ||||
|  | ||||
| sub cisco_comm_indexing { | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| sub interfaces { | ||||
|     my $cat     = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $i_index   = $cat->i_index($partial); | ||||
|     my $portnames = $cat->p_port() || {}; | ||||
|     my %portmap   = reverse %$portnames; | ||||
|  | ||||
|     my %interfaces = (); | ||||
|     foreach my $iid ( keys %$i_index ) { | ||||
|         next unless defined $iid; | ||||
|         my $if   = $i_index->{$iid}; | ||||
|         $if =~ s/\./\// if $if; | ||||
|         my $port = $portmap{$iid}; | ||||
|         $port =~ s/\./\// if $port; | ||||
|         $interfaces{$iid} = $port || $if; | ||||
|     } | ||||
|     return \%interfaces; | ||||
| } | ||||
|  | ||||
| sub i_name { | ||||
|     my $cat     = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $p_port = $cat->p_port() || {}; | ||||
|     my $p_name = $cat->p_name() || {}; | ||||
|  | ||||
|     my %i_name; | ||||
|     foreach my $port ( keys %$p_name ) { | ||||
|         my $iid = $p_port->{$port}; | ||||
|         next unless defined $iid; | ||||
|         next if ( defined $partial and $iid !~ /^$partial$/ ); | ||||
|         $i_name{$iid} = $p_name->{$port}; | ||||
|     } | ||||
|     return \%i_name; | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Catalyst - SNMP Interface to Cisco Catalyst devices | ||||
| running Catalyst OS. | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Baker | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $cat = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $cat->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| SNMP::Info subclass to provide information for Cisco Catalyst series switches | ||||
| running CatOS. | ||||
|  | ||||
| This class includes the Catalyst 2920, 4000, 5000, 6000 (hybrid mode) | ||||
| families. | ||||
|  | ||||
| This subclass is not for all devices that have the name Catalyst.  Note that | ||||
| some Catalyst switches run IOS, like the 2900 and 3550 families.  Cisco | ||||
| Catalyst 1900 switches use their own MIB and have a separate subclass.  Use | ||||
| the method above to have SNMP::Info determine the appropriate subclass before | ||||
| using this class directly. | ||||
|  | ||||
| See SNMP::Info::device_type() for specifics. | ||||
|  | ||||
| Note:  Some older Catalyst switches will only talk SNMP version 1.  Some | ||||
| newer ones will not return all their data if connected via 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 $cat = new SNMP::Info::Layer2::Catalyst(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2::Cisco | ||||
|  | ||||
| =item SNMP::Info::CiscoStack | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item Inherited Classes' MIBs | ||||
|  | ||||
| See L<SNMP::Info::Layer2::Cisco/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoStack/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| =back | ||||
|  | ||||
| These MIBs are found in the standard v2 MIBs from Cisco. | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $cat->os() | ||||
|  | ||||
| Returns 'catalyst' | ||||
|  | ||||
| =item $cat->os_ver() | ||||
|  | ||||
| Tries to use the value from SNMP::Info::CiscoStats->os_ver() and if it fails  | ||||
| it grabs $cat->m_swver()->{1} and uses that. | ||||
|  | ||||
| =item $cat->vendor() | ||||
|  | ||||
| Returns 'cisco' | ||||
|  | ||||
| =item $cat->cisco_comm_indexing() | ||||
|  | ||||
| Returns 1.  Use vlan indexing. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::Layer2::Cisco | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2::Cisco/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::CiscoStack | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoStack/"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 $cat->interfaces() | ||||
|  | ||||
| Returns the map between SNMP Interface Identifier (iid) and physical port | ||||
| name.  | ||||
|  | ||||
| =item $cat->i_name() | ||||
|  | ||||
| Returns reference to hash of iid to human set name.  | ||||
|  | ||||
| C<portName> | ||||
|  | ||||
| =item $cat->i_physical() | ||||
|  | ||||
| Returns a map to IID for ports that are physical ports, not vlans, etc. | ||||
|  | ||||
| =item $cat->bp_index() | ||||
|  | ||||
| Returns reference to hash of bridge port table entries map back to interface | ||||
| identifier (iid) | ||||
|  | ||||
| Crosses (C<portCrossIndex>) to (C<portIfIndex>) since some devices seem to | ||||
| have problems with F<BRIDGE-MIB> | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2::Cisco | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2::Cisco/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoStack | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoStack/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										530
									
								
								lib/SNMP/Info/Layer2/Centillion.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										530
									
								
								lib/SNMP/Info/Layer2/Centillion.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,530 @@ | ||||
| # SNMP::Info::Layer2::Centillion | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008 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::Layer2::Centillion; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info; | ||||
| use SNMP::Info::Bridge; | ||||
| use SNMP::Info::NortelStack; | ||||
| use SNMP::Info::SONMP; | ||||
|  | ||||
| @SNMP::Info::Layer2::Centillion::ISA | ||||
|     = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::NortelStack SNMP::Info::SONMP Exporter/; | ||||
| @SNMP::Info::Layer2::Centillion::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::MIBS, | ||||
|     %SNMP::Info::Bridge::MIBS, | ||||
|     %SNMP::Info::NortelStack::MIBS, | ||||
|     %SNMP::Info::SONMP::MIBS, | ||||
|     'CENTILLION-DOT3-EXTENSIONS-MIB' => 'cnDot3ExtnTable', | ||||
|     'S5-COMMON-STATS-MIB'            => 's5CmStat', | ||||
|     'CENTILLION-VLAN-MIB'            => 'cnVlanENETMgt', | ||||
|     'CENTILLION-CONFIG-MIB'          => 'sysTFTPStart', | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::GLOBALS, | ||||
|     %SNMP::Info::Bridge::GLOBALS, | ||||
|     %SNMP::Info::NortelStack::GLOBALS, | ||||
|     %SNMP::Info::SONMP::GLOBALS, | ||||
|     'tftp_action' => 'sysTFTPStart', | ||||
|     'tftp_host'   => 'sysTFTPIpAddress', | ||||
|     'tftp_file'   => 'sysTFTPFileName', | ||||
|     'tftp_type'   => 'sysTFTPFileType', | ||||
|     'tftp_result' => 'sysTFTPResult', | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::FUNCS, | ||||
|     %SNMP::Info::Bridge::FUNCS, | ||||
|     %SNMP::Info::NortelStack::FUNCS, | ||||
|     %SNMP::Info::SONMP::FUNCS, | ||||
|  | ||||
|     # CENTILLION-DOT3-EXTENSIONS-MIB::cnDot3ExtnTable | ||||
|     'centillion_p_index'        => 'cnDot3ExtnIfIndex', | ||||
|     'centillion_p_duplex'       => 'cnDot3ExtnIfOperConnectionType', | ||||
|     'centillion_p_duplex_admin' => 'cnDot3ExtnIfAdminConnectionType', | ||||
|  | ||||
|     # S5-COMMON-STATS-MIB::s5CmSNodeTable | ||||
|     'fw_mac'  => 's5CmSNodeMacAddr', | ||||
|     'fw_port' => 's5CmSNodeIfIndx', | ||||
|  | ||||
|     # CENTILLION-VLAN-MIB::cnVlanPortMemberTable | ||||
|     'centillion_i_vlan_index' => 'cnVlanPortMemberIfIndex', | ||||
|     'centillion_i_vlan'       => 'cnVlanPortMemberVID', | ||||
|     'centillion_i_vlan_type'  => 'cnVlanPortMemberIngressType', | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|  | ||||
|     # Inherit all the built in munging | ||||
|     %SNMP::Info::MUNGE, | ||||
|     %SNMP::Info::Bridge::MUNGE, | ||||
|     %SNMP::Info::NortelStack::MUNGE, | ||||
|     %SNMP::Info::SONMP::MUNGE, | ||||
| ); | ||||
|  | ||||
| sub os { | ||||
|     return 'centillion'; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'nortel'; | ||||
| } | ||||
|  | ||||
| sub i_ignore { | ||||
|     my $centillion = shift; | ||||
|     my $descr      = $centillion->i_description(); | ||||
|  | ||||
|     my %i_ignore; | ||||
|     foreach my $if ( keys %$descr ) { | ||||
|         my $type = $descr->{$if}; | ||||
|  | ||||
|         # Skip virtual interfaces | ||||
|         $i_ignore{$if}++ if $type =~ /(VE|VID|vc|lp)/i; | ||||
|     } | ||||
|     return \%i_ignore; | ||||
| } | ||||
|  | ||||
| sub interfaces { | ||||
|     my $centillion = shift; | ||||
|     my $i_index    = $centillion->i_index(); | ||||
|     my $i_descr    = $centillion->i_description(); | ||||
|  | ||||
|     my %if; | ||||
|     foreach my $iid ( keys %$i_index ) { | ||||
|         my $index = $i_index->{$iid}; | ||||
|         next unless defined $index; | ||||
|         my $descr = $i_descr->{$iid}; | ||||
|  | ||||
|         # Skip ATM and virtual interfaces | ||||
|         next if $descr =~ /(VE|VID|vc|lp)/i; | ||||
|  | ||||
|         # Index numbers are deterministic slot * 256 + port | ||||
|         my $port     = $index % 256; | ||||
|         my $slot     = int( $index / 256 ); | ||||
|         my $slotport = "$slot.$port"; | ||||
|  | ||||
|         $slotport = "$descr" if $descr =~ /(mcp)/i; | ||||
|  | ||||
|         $if{$index} = $slotport; | ||||
|     } | ||||
|  | ||||
|     return \%if; | ||||
| } | ||||
|  | ||||
| sub i_duplex { | ||||
|     my $centillion = shift; | ||||
|  | ||||
|     my $port_index  = $centillion->centillion_p_index(); | ||||
|     my $port_duplex = $centillion->centillion_p_duplex(); | ||||
|  | ||||
|     my %i_duplex; | ||||
|     foreach my $iid ( keys %$port_index ) { | ||||
|         my $index = $port_index->{$iid}; | ||||
|         next unless defined $index; | ||||
|         my $duplex = $port_duplex->{$iid}; | ||||
|         next unless defined $duplex; | ||||
|  | ||||
|         $duplex = 'half' if $duplex =~ /half/i; | ||||
|         $duplex = 'full' if $duplex =~ /full/i; | ||||
|         $i_duplex{$index} = $duplex; | ||||
|     } | ||||
|     return \%i_duplex; | ||||
| } | ||||
|  | ||||
| sub i_duplex_admin { | ||||
|     my $centillion = shift; | ||||
|  | ||||
|     my $port_index = $centillion->centillion_p_index(); | ||||
|     my $port_admin = $centillion->centillion_p_duplex_admin(); | ||||
|  | ||||
|     my %i_duplex_admin; | ||||
|     foreach my $iid ( keys %$port_index ) { | ||||
|         my $index = $port_index->{$iid}; | ||||
|         next unless defined $index; | ||||
|         my $duplex = $port_admin->{$iid}; | ||||
|         next unless defined $duplex; | ||||
|  | ||||
|         $duplex = 'half' if $duplex =~ /half/i; | ||||
|         $duplex = 'full' if $duplex =~ /full/i; | ||||
|         $duplex = 'auto' if $duplex =~ /auto/i; | ||||
|         $i_duplex_admin{$index} = $duplex; | ||||
|     } | ||||
|     return \%i_duplex_admin; | ||||
| } | ||||
|  | ||||
| sub i_vlan { | ||||
|     my $centillion = shift; | ||||
|  | ||||
|     my $cn_vlan_index = $centillion->centillion_i_vlan_index(); | ||||
|     my $cn_vlan       = $centillion->centillion_i_vlan(); | ||||
|  | ||||
|     my %i_vlan; | ||||
|     foreach my $iid ( keys %$cn_vlan_index ) { | ||||
|         my $index = $cn_vlan_index->{$iid}; | ||||
|         next unless defined $index; | ||||
|         my $vlan = $cn_vlan->{$iid}; | ||||
|         next unless defined $vlan; | ||||
|  | ||||
|         $i_vlan{$index} = $vlan; | ||||
|     } | ||||
|     return \%i_vlan; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $centillion = shift; | ||||
|     my $id         = $centillion->id(); | ||||
|     return unless defined $id; | ||||
|     my $model = &SNMP::translateObj($id); | ||||
|     return $id unless defined $model; | ||||
|     $model =~ s/^sreg-//i; | ||||
|  | ||||
|     return '5000BH' if ( $model =~ /5000BH/ ); | ||||
|     return '5005BH' if ( $model =~ /5005BH/ ); | ||||
|     return 'C100'   if ( $model =~ /Centillion100/ ); | ||||
|     return 'C50N'   if ( $model =~ /Centillion50N/ ); | ||||
|     return 'C50T'   if ( $model =~ /Centillion50T/ ); | ||||
|     return $model; | ||||
| } | ||||
|  | ||||
| sub bp_index { | ||||
|     my $centillion = shift; | ||||
|     my $index      = $centillion->fw_port(); | ||||
|  | ||||
|     my %bp_index; | ||||
|     foreach my $iid ( keys %$index ) { | ||||
|         my $b_index = $index->{$iid}; | ||||
|         next unless defined $b_index; | ||||
|  | ||||
|         #Index value is the same as ifIndex | ||||
|         $bp_index{$b_index} = $b_index; | ||||
|     } | ||||
|  | ||||
|     return \%bp_index; | ||||
| } | ||||
|  | ||||
| sub index_factor { | ||||
|     return 256; | ||||
| } | ||||
|  | ||||
| sub slot_offset { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| sub fw_mac { | ||||
|     my $centillion = shift; | ||||
|     my $partial   = shift; | ||||
|  | ||||
|     return $centillion->SUPER::fw_mac($partial); | ||||
| } | ||||
|  | ||||
| sub fw_port { | ||||
|     my $centillion = shift; | ||||
|     my $partial   = shift; | ||||
|  | ||||
|     return $centillion->SUPER::fw_port($partial); | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Centillion - SNMP Interface to Nortel Centillion based | ||||
| ATM Switches | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Eric Miller | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $centillion = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $centillion->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from a  | ||||
| Centillion device through SNMP.  | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
|  my $centillion = new SNMP::Info::Layer2::centillion(...); | ||||
|   | ||||
| Note:  This class supports version 4.X and 5.X which are VLAN based rather | ||||
| than bridge group based. | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info | ||||
|  | ||||
| =item SNMP::Info::Bridge | ||||
|  | ||||
| =item SNMP::Info::NortelStack | ||||
|  | ||||
| =item SNMP::Info::SONMP | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<CENTILLION-DOT3-EXTENSIONS-MIB> | ||||
|  | ||||
| =item F<S5-COMMON-STATS-MIB> | ||||
|  | ||||
| =item F<CENTILLION-VLAN-MIB> | ||||
|  | ||||
| =item F<CENTILLION-CONFIG-MIB> | ||||
|  | ||||
| =item Inherited Classes' MIBs | ||||
|  | ||||
| See L<SNMP::Info/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::Bridge/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::NortelStack/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::SONMP/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $centillion->vendor() | ||||
|  | ||||
| Returns 'Nortel' | ||||
|  | ||||
| =item $centillion->model() | ||||
|  | ||||
| Cross references $centillion->id() to the F<SYNOPTICS-MIB> and returns | ||||
| the results. | ||||
|  | ||||
| Removes C<sreg-> from the model name | ||||
|  | ||||
| =item $centillion->os() | ||||
|  | ||||
| Returns 'Centillion' | ||||
|  | ||||
| =item $centillion->tftp_action() | ||||
|  | ||||
| (C<sysTFTPStart>) | ||||
|  | ||||
| =item $centillion->tftp_host() | ||||
|  | ||||
| (C<sysTFTPIpAddress>) | ||||
|  | ||||
| =item $centillion->tftp_file() | ||||
|  | ||||
| (C<sysTFTPFileName>) | ||||
|  | ||||
| =item $centillion->tftp_type() | ||||
|  | ||||
| (C<sysTFTPFileType>) | ||||
|  | ||||
| =item $centillion->tftp_result() | ||||
|  | ||||
| (C<sysTFTPResult>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item  $centillion->index_factor() | ||||
|  | ||||
| Required by SNMP::Info::SONMP.  Number representing the number of ports | ||||
| reserved per slot within the device MIB.  Returns 256. | ||||
|  | ||||
| =item $centillion->slot_offset() | ||||
|  | ||||
| Required by SNMP::Info::SONMP.  Offset if slot numbering does not | ||||
| start at 0.  Returns 0. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info | ||||
|  | ||||
| See documentation in L<SNMP::Info/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Bridge | ||||
|  | ||||
| See documentation in L<SNMP::Info::Bridge/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::NortelStack | ||||
|  | ||||
| See documentation in L<SNMP::Info::NortelStack/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::SONMP | ||||
|  | ||||
| See documentation in L<SNMP::Info::SONMP/"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 $centillion->interfaces() | ||||
|  | ||||
|     Returns reference to the map between IID and physical Port. | ||||
|  | ||||
|     Slot and port numbers on the Passport switches are determined by the | ||||
|     formula: | ||||
|       port = index % 256 | ||||
|       slot = int(index / 256) | ||||
|   | ||||
|     The physical port name is returned as slot.port. | ||||
|  | ||||
| =item $centillion->i_duplex() | ||||
|  | ||||
| Returns reference to map of IIDs to current link duplex | ||||
|  | ||||
| =item $centillion->i_duplex_admin() | ||||
|  | ||||
| Returns reference to hash of IIDs to admin duplex setting | ||||
|  | ||||
| =item $centillion->i_ignore() | ||||
|  | ||||
| Returns reference to hash of IIDs to ignore. | ||||
|  | ||||
| =item $centillion->fw_mac() | ||||
|  | ||||
| (C<s5CmSNodeMacAddr>) | ||||
|  | ||||
| =item $centillion->fw_port() | ||||
|  | ||||
| (C<s5CmSNodeIfIndx>) | ||||
|  | ||||
| =item $centillion->bp_index() | ||||
|  | ||||
| Returns a mapping between C<ifIndex> and the Bridge Table. | ||||
|  | ||||
| =item $centillion->i_vlan() | ||||
|  | ||||
| Returns a mapping between C<ifIndex> and the VLAN. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Centillion 802.3 Extension Table (C<cnDot3ExtnTable>) | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $centillion->centillion_p_index() | ||||
|  | ||||
| Returns reference to hash.  Maps table IIDs to Interface IIDs  | ||||
|  | ||||
| (C<cnDot3ExtnIfIndex>) | ||||
|  | ||||
| =item $centillion->centillion_p_duplex() | ||||
|  | ||||
| Returns reference to hash.  Maps port operational duplexes to IIDs  | ||||
|  | ||||
| (C<cnDot3ExtnIfOperConnectionType>) | ||||
|  | ||||
| =item $centillion->rc_centillion_p_duplex_admin() | ||||
|  | ||||
| Returns reference to hash.  Maps port admin duplexes to IIDs | ||||
|  | ||||
| (C<cnDot3ExtnIfAdminConnectionType>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Centillion VLAN Table (C<cnVlanPortMemberTable>) | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $centillion->centillion_i_vlan_index() | ||||
|  | ||||
| Returns reference to hash.  Key: Table entry, Value: Index  | ||||
|  | ||||
| (C<cnVlanPortMemberIfIndex>) | ||||
|  | ||||
| =item $centillion->centillion_i_vlan() | ||||
|  | ||||
| Returns reference to hash.  Key: Table entry, Value: VLAN ID  | ||||
|  | ||||
| (C<cnVlanPortMemberVID>) | ||||
|  | ||||
| =item $centillion->centillion_i_vlan_type() | ||||
|  | ||||
| Returns reference to hash.  Key: Table entry, Value: VLAN Type  | ||||
|  | ||||
| (C<cnVlanPortMemberIngressType>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info | ||||
|  | ||||
| See documentation in L<SNMP::Info/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Bridge | ||||
|  | ||||
| See documentation in L<SNMP::Info::Bridge/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::NortelStack | ||||
|  | ||||
| See documentation in L<SNMP::Info::NortelStack/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::SONMP | ||||
|  | ||||
| See documentation in L<SNMP::Info::SONMP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										278
									
								
								lib/SNMP/Info/Layer2/Cisco.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								lib/SNMP/Info/Layer2/Cisco.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,278 @@ | ||||
| # SNMP::Info::Layer2::Cisco | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008 Max Baker | ||||
| # 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::Cisco; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::CiscoVTP; | ||||
| use SNMP::Info::CDP; | ||||
| use SNMP::Info::CiscoStats; | ||||
| use SNMP::Info::CiscoRTT; | ||||
| use SNMP::Info::CiscoConfig; | ||||
| use SNMP::Info::CiscoPortSecurity; | ||||
| use SNMP::Info::CiscoStpExtensions; | ||||
| use SNMP::Info::CiscoAgg; | ||||
| use SNMP::Info::Layer2; | ||||
|  | ||||
| @SNMP::Info::Layer2::Cisco::ISA = qw/SNMP::Info::CiscoVTP SNMP::Info::CDP | ||||
|     SNMP::Info::CiscoStats SNMP::Info::CiscoRTT | ||||
|     SNMP::Info::CiscoConfig SNMP::Info::CiscoPortSecurity | ||||
|     SNMP::Info::CiscoStpExtensions SNMP::Info::CiscoAgg | ||||
|     SNMP::Info::Layer2 | ||||
|     Exporter/; | ||||
| @SNMP::Info::Layer2::Cisco::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     %SNMP::Info::CiscoAgg::MIBS, | ||||
|     %SNMP::Info::CiscoStpExtensions::MIBS, | ||||
|     %SNMP::Info::CiscoPortSecurity::MIBS, | ||||
|     %SNMP::Info::CiscoConfig::MIBS, | ||||
|     %SNMP::Info::CiscoRTT::MIBS, | ||||
|     %SNMP::Info::CiscoStats::MIBS, | ||||
|     %SNMP::Info::CDP::MIBS, | ||||
|     %SNMP::Info::CiscoVTP::MIBS, | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::GLOBALS, | ||||
|     %SNMP::Info::CiscoAgg::GLOBALS, | ||||
|     %SNMP::Info::CiscoStpExtensions::GLOBALS, | ||||
|     %SNMP::Info::CiscoPortSecurity::GLOBALS, | ||||
|     %SNMP::Info::CiscoConfig::GLOBALS, | ||||
|     %SNMP::Info::CiscoRTT::GLOBALS, | ||||
|     %SNMP::Info::CiscoStats::GLOBALS, | ||||
|     %SNMP::Info::CDP::GLOBALS, | ||||
|     %SNMP::Info::CiscoVTP::GLOBALS, | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     %SNMP::Info::CiscoAgg::FUNCS, | ||||
|     %SNMP::Info::CiscoStpExtensions::FUNCS, | ||||
|     %SNMP::Info::CiscoPortSecurity::FUNCS, | ||||
|     %SNMP::Info::CiscoConfig::FUNCS, | ||||
|     %SNMP::Info::CiscoRTT::FUNCS, | ||||
|     %SNMP::Info::CiscoStats::FUNCS, | ||||
|     %SNMP::Info::CDP::FUNCS, | ||||
|     %SNMP::Info::CiscoVTP::FUNCS, | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::Layer2::MUNGE, | ||||
|     %SNMP::Info::CiscoAgg::MUNGE, | ||||
|     %SNMP::Info::CiscoStpExtensions::MUNGE, | ||||
|     %SNMP::Info::CiscoPortSecurity::MUNGE, | ||||
|     %SNMP::Info::CiscoConfig::MUNGE, | ||||
|     %SNMP::Info::CiscoRTT::MUNGE, | ||||
|     %SNMP::Info::CiscoStats::MUNGE, | ||||
|     %SNMP::Info::CDP::MUNGE, | ||||
|     %SNMP::Info::CiscoVTP::MUNGE, | ||||
| ); | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Cisco - SNMP Interface to L2 Cisco devices that are | ||||
| not covered in other classes and the base L2 Cisco class for other device | ||||
| specific L2 Cisco classes. | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Baker | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $cisco = new SNMP::Info( | ||||
|                         AutoSpecify => 1, | ||||
|                         Debug       => 1, | ||||
|                         # These arguments are passed directly to SNMP::Session | ||||
|                         DestHost    => 'myswitch', | ||||
|                         Community   => 'public', | ||||
|                         Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $cisco->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Subclass for Generic Layer 2 Cisco devices and the base L2 Cisco class for | ||||
| other device specific L2 Cisco classes. | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::CiscoVTP | ||||
|  | ||||
| =item SNMP::Info::CDP | ||||
|  | ||||
| =item SNMP::Info::CiscoStats | ||||
|  | ||||
| =item SNMP::Info::CiscoRTT | ||||
|  | ||||
| =item SNMP::Info::CiscoConfig | ||||
|  | ||||
| =item SNMP::Info::CiscoPortSecurity | ||||
|  | ||||
| =item SNMP::Info::CiscoStpExtensions | ||||
|  | ||||
| =item SNMP::Info::CiscoAgg | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item Inherited Classes' MIBs | ||||
|  | ||||
| See L<SNMP::Info::CiscoVTP/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CDP/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoStats/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoRTT/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoConfig/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoPortSecurity/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoStpExtensions/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::CiscoAgg/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $cisco->vendor() | ||||
|  | ||||
|     Returns 'cisco' | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::CiscoVTP | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoVTP/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CDP | ||||
|  | ||||
| See documentation in L<SNMP::Info::CDP/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoStats | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoStats/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoRTT | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoRTT/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoConfig | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoConfig/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoPortSecurity | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoPortSecurity/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoStpExtensions | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoStpExtensions/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::CiscoAgg | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoAgg/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head1 TABLE METHODS | ||||
|  | ||||
| These are methods that return tables of information in the form of a reference | ||||
| to a hash. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoVTP | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoVTP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CDP | ||||
|  | ||||
| See documentation in L<SNMP::Info::CDP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoStats | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoStats/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoRTT | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoRTT/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoConfig | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoConfig/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoPortSecurity | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoPortSecurity/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoStpExtensions | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoStpExtensions/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::CiscoAgg | ||||
|  | ||||
| See documentation in L<SNMP::Info::CiscoAgg/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										274
									
								
								lib/SNMP/Info/Layer2/CiscoSB.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								lib/SNMP/Info/Layer2/CiscoSB.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,274 @@ | ||||
| # SNMP::Info::Layer2::CiscoSB | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2013 Nic Bernstein | ||||
| # | ||||
| # Copyright (c) 2008-2009 Max Baker changes from version 0.8 and beyond. | ||||
| # | ||||
| # Copyright (c) 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::CiscoSB; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2; | ||||
| use SNMP::Info::Entity; | ||||
| use SNMP::Info::EtherLike; | ||||
| use SNMP::Info::CiscoStats; | ||||
| use SNMP::Info::CiscoConfig; | ||||
| use SNMP::Info::CDP; | ||||
|  | ||||
| @SNMP::Info::Layer2::CiscoSB::ISA | ||||
|     = qw/SNMP::Info::Layer2 SNMP::Info::Entity SNMP::Info::EtherLike | ||||
|     SNMP::Info::CiscoStats SNMP::Info::CiscoConfig SNMP::Info::CDP Exporter/; | ||||
| @SNMP::Info::Layer2::CiscoSB::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::GLOBALS, | ||||
|     %SNMP::Info::Entity::GLOBALS, | ||||
|     %SNMP::Info::EtherLike::GLOBALS, | ||||
|     %SNMP::Info::CiscoStats::GLOBALS, | ||||
|     %SNMP::Info::CiscoConfig::GLOBALS, | ||||
|     %SNMP::Info::CDP::GLOBALS, | ||||
|     'descr'  => 'sysDescr' | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     %SNMP::Info::Entity::FUNCS, | ||||
|     %SNMP::Info::EtherLike::FUNCS, | ||||
|     %SNMP::Info::CiscoStats::FUNCS, | ||||
|     %SNMP::Info::CiscoConfig::FUNCS, | ||||
|     %SNMP::Info::CDP::FUNCS, | ||||
| ); | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     %SNMP::Info::Entity::MIBS, | ||||
|     %SNMP::Info::EtherLike::MIBS, | ||||
|     %SNMP::Info::CiscoStats::MIBS, | ||||
|     %SNMP::Info::CiscoConfig::MIBS, | ||||
|     %SNMP::Info::CDP::MIBS, | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::Layer2::MUNGE, | ||||
|     %SNMP::Info::Entity::MUNGE, | ||||
|     %SNMP::Info::EtherLike::MUNGE, | ||||
|     %SNMP::Info::CiscoStats::MUNGE, | ||||
|     %SNMP::Info::CiscoConfig::MUNGE, | ||||
|     %SNMP::Info::CDP::MUNGE, | ||||
| ); | ||||
|  | ||||
|  | ||||
| sub vendor { | ||||
|     return 'cisco'; | ||||
| } | ||||
|  | ||||
| sub os { | ||||
|     return 'ros'; | ||||
| } | ||||
|  | ||||
| # Walk the entPhysicalSerialNum table and return the first serial found | ||||
| sub serial { | ||||
|     my $ciscosb  = shift; | ||||
|     my $e_serial = $ciscosb->e_serial(); | ||||
|  | ||||
|     # Find entity table entry for this unit | ||||
|     foreach my $e ( sort keys %$e_serial ) { | ||||
|         if (defined $e_serial->{$e} and $e_serial->{$e} !~ /^\s*$/) { | ||||
|             return $e_serial->{$e}; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|     my $ciscosb = shift; | ||||
|     my $e_swver  = $ciscosb->e_swver(); | ||||
|  | ||||
|     foreach my $e ( sort keys %$e_swver ) { | ||||
|         if (defined $e_swver->{$e} and $e_swver->{$e} !~ /^\s*$/) { | ||||
|             return $e_swver->{$e}; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| # Grab e_model from Entity and tag on e_hwver | ||||
| sub model { | ||||
|     my $ciscosb = shift; | ||||
|     my $e_model = $ciscosb->e_model(); | ||||
|     my $e_hwver = $ciscosb->e_hwver(); | ||||
|  | ||||
|     foreach my $e ( sort keys %$e_model ) { | ||||
|         if (defined $e_model->{$e} and $e_model->{$e} !~ /^\s*$/) { | ||||
|             my $model = "$e_model->{$e} $e_hwver->{$e}"; | ||||
|             return $model; | ||||
|         } | ||||
|     } | ||||
|     return $ciscosb->description(); | ||||
| } | ||||
|  | ||||
| # ifDescr is the same for all interfaces in a class, but the ifName is | ||||
| # unique, so let's use that for port name. | ||||
| sub interfaces { | ||||
|     my $ciscosb = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $interfaces = $ciscosb->i_name($partial); | ||||
|  | ||||
|     return $interfaces; | ||||
| } | ||||
|  | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::CiscoSB - SNMP Interface to Cisco Small Business series | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Nic Bernstein (shamelessly stolen from Max Baker's Aironet code) | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you. | ||||
|  my $ciscosb = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         ) | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $ciscosb->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides interface to SNMP Data available on Cisco Small Business (nee LinkSys) | ||||
| managed switches. [i.e. those matching enterprises(1).cisco(9).otherEnterprises(6).ciscosb(1)] | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =item SNMP::Info::Entity | ||||
|  | ||||
| =item SNMP::Info::EtherLike | ||||
|  | ||||
| =item SNMP::Info::CiscoStats | ||||
|  | ||||
| =item SNMP::Info::CiscoConfig | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item Inherited Classes | ||||
|  | ||||
| MIBs required by the inherited classes listed above. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $ciscosb->vendor() | ||||
|  | ||||
| Returns 'cisco' | ||||
|  | ||||
| =item $ciscosb->os() | ||||
|  | ||||
| Returns 'ros' | ||||
|  | ||||
| =item $ciscosb->os_ver() | ||||
|  | ||||
| Returns software version (C<entPhysicalSoftwareRev>) | ||||
|  | ||||
| =item $ciscosb->serial() | ||||
|  | ||||
| Returns serial number of unit (C<entPhysicalSerialNum>) | ||||
|  | ||||
| =item $ciscosb->model() | ||||
|  | ||||
| Returns model and hardware revision of unit | ||||
| (C<entPhysicalModelName+entPhysicalHardwareRev>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Entity | ||||
|  | ||||
| See documentation in L<SNMP::Info::Entity/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::EtherLike | ||||
|  | ||||
| See documentation in L<SNMP::Info::EtherLike/"GLOBALS"> for details. | ||||
|  | ||||
| =head1 TABLE METHODS | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $ciscosb->interfaces() | ||||
|  | ||||
| Uses the i_name() field. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Entity | ||||
|  | ||||
| See documentation in L<SNMP::Info::Entity/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::EtherLike | ||||
|  | ||||
| See documentation in L<SNMP::Info::EtherLike/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										905
									
								
								lib/SNMP/Info/Layer2/HP.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										905
									
								
								lib/SNMP/Info/Layer2/HP.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,905 @@ | ||||
| # SNMP::Info::Layer2::HP - SNMP Interface to HP ProCurve Switches | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008-2009 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::Layer2::HP; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer3; | ||||
| use SNMP::Info::MAU; | ||||
| use SNMP::Info::CDP; | ||||
| use SNMP::Info::Aggregate 'agg_ports_ifstack'; | ||||
|  | ||||
| @SNMP::Info::Layer2::HP::ISA = qw/ | ||||
|     SNMP::Info::Aggregate | ||||
|     SNMP::Info::Layer3  | ||||
|     SNMP::Info::MAU  | ||||
|     SNMP::Info::CDP  | ||||
|     Exporter | ||||
| /; | ||||
| @SNMP::Info::Layer2::HP::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MODEL_MAP %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer3::MIBS, | ||||
|     %SNMP::Info::MAU::MIBS, | ||||
|     %SNMP::Info::CDP::MIBS, | ||||
|     %SNMP::Info::Aggregate::MIBS, | ||||
|     'RFC1271-MIB'    => 'logDescription', | ||||
|     'HP-ICF-OID'     => 'hpSwitch4000', | ||||
|     'STATISTICS-MIB' => 'hpSwitchCpuStat', | ||||
|     'NETSWITCH-MIB'  => 'hpMsgBufFree', | ||||
|     'CONFIG-MIB'     => 'hpSwitchConfig', | ||||
|     'HP-ICF-CHASSIS' => 'hpicfSensorObjectId', | ||||
|     'HP-ICF-BRIDGE'  => 'hpicfBridgeRstpForceVersion', | ||||
|     'HP-ICF-POE-MIB' => 'hpicfPoePethPsePortCurrent', | ||||
|     'SEMI-MIB'       => 'hpHttpMgSerialNumber', | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer3::GLOBALS, | ||||
|     %SNMP::Info::MAU::GLOBALS, | ||||
|     %SNMP::Info::CDP::GLOBALS, | ||||
|     %SNMP::Info::Aggregate::GLOBALS, | ||||
|     'serial1'      => 'entPhysicalSerialNum.1', | ||||
|     'serial2'      => 'hpHttpMgSerialNumber.0', | ||||
|     'hp_cpu'       => 'hpSwitchCpuStat.0', | ||||
|     'hp_mem_total' => 'hpGlobalMemTotalBytes.1', | ||||
|     'mem_free'     => 'hpGlobalMemFreeBytes.1', | ||||
|     'mem_used'     => 'hpGlobalMemAllocBytes.1', | ||||
|     'os_version'   => 'hpSwitchOsVersion.0', | ||||
|     'os_version2'  => 'hpHttpMgVersion.0', | ||||
|     'os_bin'       => 'hpSwitchRomVersion.0', | ||||
|     'mac'          => 'hpSwitchBaseMACAddress.0', | ||||
|     'rstp_ver'     => 'hpicfBridgeRstpForceVersion', | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer3::FUNCS, | ||||
|     %SNMP::Info::MAU::FUNCS, | ||||
|     %SNMP::Info::CDP::FUNCS, | ||||
|     %SNMP::Info::Aggregate::FUNCS, | ||||
|     'i_type2'   => 'ifType', | ||||
|  | ||||
|     # RFC1271 | ||||
|     'l_descr' => 'logDescription', | ||||
|  | ||||
|     # CONFIG-MIB::hpSwitchPortTable | ||||
|     'hp_duplex'       => 'hpSwitchPortEtherMode', | ||||
|     'hp_duplex_admin' => 'hpSwitchPortFastEtherMode', | ||||
|     'vendor_i_type'   => 'hpSwitchPortType', | ||||
|  | ||||
|     # HP-ICF-CHASSIS | ||||
|     'hp_s_oid'    => 'hpicfSensorObjectId', | ||||
|     'hp_s_name'   => 'hpicfSensorDescr', | ||||
|     'hp_s_status' => 'hpicfSensorStatus', | ||||
|      | ||||
|     # HP-ICF-POE-MIB | ||||
|     'peth_port_power'   => 'hpicfPoePethPsePortPower', | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     # Inherit all the built in munging | ||||
|     %SNMP::Info::Layer3::MUNGE, | ||||
|     %SNMP::Info::MAU::MUNGE, | ||||
|     %SNMP::Info::CDP::MUNGE, | ||||
|     %SNMP::Info::Aggregate::MUNGE, | ||||
|     'c_id'   => \&munge_hp_c_id, | ||||
| ); | ||||
|  | ||||
|  | ||||
| # Model map, reverse sorted by common model name (sort -k2 -r) | ||||
| # Potential sources for model information: http://www.hp.com/rnd/software/switches.htm or HP-ICF-OID MIB  | ||||
| %MODEL_MAP = ( | ||||
|     'J8131A' => 'WAP-420-WW', | ||||
|     'J8130A' => 'WAP-420-NA', | ||||
|     'J9833A' => 'PS1810-8G', | ||||
|     'J9834A' => 'PS1810-24G', | ||||
|     'J8133A' => 'AP520WL', | ||||
|     'J8680A' => '9408sl', | ||||
|     'J9091A' => '8212zl', | ||||
|     'J9475A' => '8206zl', | ||||
|     'J9265A' => '6600ml-24XG', | ||||
|     'J9264A' => '6600ml-24G-4XG', | ||||
|     'J9263A' => '6600ml-24G', | ||||
|     'J9452A' => '6600-48G-4XG', | ||||
|     'J9451A' => '6600-48G', | ||||
|     'J8474A' => '6410cl-6XG', | ||||
|     'J8433A' => '6400cl-6XG', | ||||
|     'J8992A' => '6200yl-24G', | ||||
|     'J4902A' => '6108', | ||||
|     'J8698A' => '5412zl', | ||||
|     'J9851A' => '5412R-zl2', | ||||
|     'J8719A' => '5408yl', | ||||
|     'J8697A' => '5406zl', | ||||
|     'J9850A' => '5406R-zl2', | ||||
|     'J8718A' => '5404yl', | ||||
|     'J4819A' => '5308XL', | ||||
|     'J4850A' => '5304XL', | ||||
|     'J8773A' => '4208vl', | ||||
|     'J8770A' => '4204vl', | ||||
|     'J8772A' => '4202vl-72', | ||||
|     'J9032A' => '4202vl-68G', | ||||
|     'J9031A' => '4202vl-68', | ||||
|     'J8771A' => '4202vl-48G', | ||||
|     'J4865A' => '4108GL', | ||||
|     'J4887A' => '4104GL', | ||||
|     'J9588A' => '3800-48G-PoE+-4XG', | ||||
|     'J9574A' => '3800-48G-PoE+-4SFP+', | ||||
|     'J9586A' => '3800-48G-4XG', | ||||
|     'J9576A' => '3800-48G-4SFP+', | ||||
|     'J9584A' => '3800-24SFP-2SFP+', | ||||
|     'J9587A' => '3800-24G-PoE+-2XG', | ||||
|     'J9573A' => '3800-24G-PoE+-2SFP+', | ||||
|     'J9585A' => '3800-24G-2XG', | ||||
|     'J9575A' => '3800-24G-2SFP+', | ||||
|     'J8693A' => '3500yl-48G-PWR', | ||||
|     'J8692A' => '3500yl-24G-PWR', | ||||
|     'J9473A' => '3500-48-PoE', | ||||
|     'J9472A' => '3500-48', | ||||
|     'J9471A' => '3500-24-PoE', | ||||
|     'J9470A' => '3500-24', | ||||
|     'J4906A' => '3400cl-48G', | ||||
|     'J4905A' => '3400cl-24G', | ||||
|     'J4815A' => '3324XL', | ||||
|     'J4851A' => '3124', | ||||
|     'J9729A' => '2920-48G-PoE+', | ||||
|     'J9729A' => '2920-48G-PoE+', | ||||
|     'J9728A' => '2920-48G', | ||||
|     'J9728A' => '2920-48G', | ||||
|     'J9727A' => '2920-24G-PoE+', | ||||
|     'J9727A' => '2920-24G-PoE+', | ||||
|     'J9726A' => '2920-24G', | ||||
|     'J9726A' => '2920-24G', | ||||
|     'J9562A' => '2915-8G-PoE', | ||||
|     'J9148A' => '2910al-48G-PoE+', | ||||
|     'J9147A' => '2910al-48G', | ||||
|     'J9146A' => '2910al-24G-PoE+', | ||||
|     'J9145A' => '2910al-24G', | ||||
|     'J9050A' => '2900-48G', | ||||
|     'J9049A' => '2900-24G', | ||||
|     'J4904A' => '2848', | ||||
|     'J4903A' => '2824', | ||||
|     'J9022A' => '2810-48G', | ||||
|     'J9021A' => '2810-24G', | ||||
|     'J8165A' => '2650-PWR', | ||||
|     'J4899B' => '2650-CR', | ||||
|     'J4899C' => '2650C', | ||||
|     'J4899A' => '2650', | ||||
|     'J8164A' => '2626-PWR', | ||||
|     'J4900B' => '2626-CR', | ||||
|     'J4900C' => '2626C', | ||||
|     'J4900A' => '2626', | ||||
|     'J9627A' => '2620-48-PoE+', | ||||
|     'J9626A' => '2620-48', | ||||
|     'J9624A' => '2620-24-PPoE+', | ||||
|     'J9625A' => '2620-24-PoE+', | ||||
|     'J9623A' => '2620-24', | ||||
|     'J9565A' => '2615-8-PoE', | ||||
|     'J9089A' => '2610-48-PWR', | ||||
|     'J9088A' => '2610-48', | ||||
|     'J9087A' => '2610-24-PWR', | ||||
|     'J9086A' => '2610-24/12PWR', | ||||
|     'J9085A' => '2610-24', | ||||
|     'J8762A' => '2600-8-PWR', | ||||
|     'J9780A' => '2530-8-PoE+', | ||||
|     'J9777A' => '2530-8G', | ||||
|     'J9783A' => '2530-8', | ||||
|     'J9778A' => '2530-48-PoE+', | ||||
|     'J9853A' => '2530-48G-PoE+-2SFP+', | ||||
|     'J9772A' => '2530-48G-PoE+', | ||||
|     'J9855A' => '2530-48G-2SFP+', | ||||
|     'J9775A' => '2530-48G', | ||||
|     'J9781A' => '2530-48', | ||||
|     'J9779A' => '2530-24-PoE+', | ||||
|     'J9854A' => '2530-24G-PoE+-2SFP+', | ||||
|     'J9773A' => '2530-24G-PoE+', | ||||
|     'J9856A' => '2530-24G-2SFP+', | ||||
|     'J9776A' => '2530-24G', | ||||
|     'J9782A' => '2530-24', | ||||
|     'J4813A' => '2524', | ||||
|     'J9298A' => '2520G-8-PoE', | ||||
|     'J9299A' => '2520G-24-PoE', | ||||
|     'J9137A' => '2520-8-PoE', | ||||
|     'J9138A' => '2520-24-PoE', | ||||
|     'J4812A' => '2512', | ||||
|     'J9280A' => '2510G-48', | ||||
|     'J9279A' => '2510G-24', | ||||
|     'J9020A' => '2510-48A', | ||||
|     'J9019B' => '2510-24B', | ||||
|     'J9019A' => '2510-24A', | ||||
|     'J4818A' => '2324', | ||||
|     'J4817A' => '2312', | ||||
|     'J9449A' => '1810G-8', | ||||
|     'J9450A' => '1810G-24', | ||||
|     'J9802A' => '1810-8G', | ||||
|     'J9803A' => '1810-24G', | ||||
|     'J9029A' => '1800-8G', | ||||
|     'J9028A' => '1800-24G', | ||||
| ); | ||||
|  | ||||
| # Method Overrides | ||||
|  | ||||
| sub stp_ver { | ||||
|     my $hp = shift; | ||||
|     return $hp->rstp_ver() || $hp->SUPER::stp_ver(); | ||||
| } | ||||
|  | ||||
| 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() || $hp->os_version2(); | ||||
|     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; | ||||
| } | ||||
|  | ||||
| # Regular managed ProCurve switches have the serial num in entity mib,  | ||||
| # the web-managed models in the semi mib (hphttpmanageable). | ||||
| sub serial { | ||||
|     my $hp = shift; | ||||
|  | ||||
|     my $serial = $hp->serial1() || $hp->serial2() || undef;; | ||||
|  | ||||
|     return $serial; | ||||
| } | ||||
|  | ||||
| # Lookup model number, and translate the part number to the common number | ||||
| sub model { | ||||
|     my $hp = shift; | ||||
|     my $id = $hp->id(); | ||||
|     return unless defined $id; | ||||
|     my $model = &SNMP::translateObj($id); | ||||
|     return $id unless defined $model; | ||||
|  | ||||
|     $model =~ s/^hpswitch//i; | ||||
|  | ||||
|     return defined $MODEL_MAP{$model} ? $MODEL_MAP{$model} : $model; | ||||
| } | ||||
|  | ||||
| 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_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 i_duplex { | ||||
|     my $hp = shift; | ||||
|  | ||||
|     return $hp->mau_i_duplex(); | ||||
| } | ||||
|  | ||||
| sub i_duplex_admin { | ||||
|     my $hp      = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     # Try HP MIB first | ||||
|     my $hp_duplex = $hp->hp_duplex_admin($partial); | ||||
|     if ( defined $hp_duplex and scalar( keys %$hp_duplex ) ) { | ||||
|  | ||||
|         my %i_duplex; | ||||
|         foreach my $if ( keys %$hp_duplex ) { | ||||
|             my $duplex = $hp_duplex->{$if}; | ||||
|             next unless defined $duplex; | ||||
|  | ||||
|             $duplex = 'half' if $duplex =~ /half/i; | ||||
|             $duplex = 'full' if $duplex =~ /full/i; | ||||
|             $duplex = 'auto' if $duplex =~ /auto/i; | ||||
|             $i_duplex{$if} = $duplex; | ||||
|         } | ||||
|         return \%i_duplex; | ||||
|     } | ||||
|     else { | ||||
|         return $hp->mau_i_duplex_admin(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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 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; | ||||
|     return &_sensor( $hp, 'fan' ); | ||||
| } | ||||
|  | ||||
| sub ps1_status { | ||||
|     my $hp = shift; | ||||
|     return &_sensor( $hp, 'power', '^power supply 1' ) | ||||
|         || &_sensor( $hp, 'power', '^power supply sensor' ); | ||||
| } | ||||
|  | ||||
| sub ps2_status { | ||||
|     my $hp = shift; | ||||
|     return &_sensor( $hp, 'power', '^power supply 2' ) | ||||
|         || &_sensor( $hp, 'power', '^redundant' ); | ||||
| } | ||||
|  | ||||
| sub _sensor { | ||||
|     my $hp          = shift; | ||||
|     my $search_type = shift || 'fan'; | ||||
|     my $search_name = shift || ''; | ||||
|     my $hp_s_oid    = $hp->hp_s_oid(); | ||||
|     my $result; | ||||
|     foreach my $sensor ( keys %$hp_s_oid ) { | ||||
|         my $sensortype = &SNMP::translateObj( $hp_s_oid->{$sensor} ); | ||||
|         if ( $sensortype =~ /$search_type/i ) { | ||||
|             my $sensorname   = $hp->hp_s_name()->{$sensor}; | ||||
|             my $sensorstatus = $hp->hp_s_status()->{$sensor}; | ||||
|             if ( $sensorname =~ /$search_name/i ) { | ||||
|                 $result = $sensorstatus; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return $result; | ||||
| } | ||||
|  | ||||
| sub munge_hp_c_id { | ||||
|     my ($v) = @_; | ||||
|     if ( length(unpack('H*', $v)) == 12 ){ | ||||
| 	return join(':',map { sprintf "%02x", $_ } unpack('C*', $v)); | ||||
|     }if ( length(unpack('H*', $v)) == 10 ){ | ||||
| 	# IP address (first octet is sign, I guess) | ||||
| 	my @octets = (map { sprintf "%02x",$_ } unpack('C*', $v))[1..4]; | ||||
| 	return join '.', map { hex($_) } @octets; | ||||
|     }else{ | ||||
| 	return $v; | ||||
|     } | ||||
| } | ||||
|  | ||||
| # POWER-ETHERNET-MIB doesn't define a mapping of its | ||||
| # "module"/"port" index to ifIndex.  Different vendors | ||||
| # do this in different ways. | ||||
| # HP switches use the ifIndex as port index, so we can | ||||
| # ignore the module information and map the index directly | ||||
| # onto an ifIndex. | ||||
| sub peth_port_ifindex { | ||||
|     my $peth    = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $peth_port_status = $peth->peth_port_status($partial); | ||||
|     my $peth_port_ifindex; | ||||
|  | ||||
|     foreach my $i ( keys %$peth_port_status ) { | ||||
|         my ( $module, $port ) = split( /\./, $i ); | ||||
|         $peth_port_ifindex->{$i} = $port; | ||||
|     } | ||||
|     return $peth_port_ifindex; | ||||
| } | ||||
|  | ||||
| sub set_i_vlan { | ||||
|     my $hp = shift; | ||||
|     my $rv; | ||||
|  | ||||
|     my $qb_i_vlan = $hp->qb_i_vlan_t(); | ||||
|     if (defined $qb_i_vlan and scalar(keys %$qb_i_vlan)){ | ||||
|         my $vlan = shift; | ||||
|         my $iid = shift; | ||||
|  | ||||
|         my $qb_v_egress = $hp->qb_v_egress(); | ||||
|         if (defined $qb_v_egress and scalar($qb_v_egress->{$vlan})) { | ||||
|             # store current untagged VLAN to remove it from the port list later | ||||
|             my $old_untagged = $qb_i_vlan->{$iid}; | ||||
|  | ||||
|             # set new untagged / native VLAN | ||||
|             $rv = $hp->set_qb_i_vlan($vlan, $iid); | ||||
|  | ||||
|             # If change is successful, the old native VLAN will now be a tagged VLAN on the port. This is generally not what we want. | ||||
|             # We'll have to remove this VLAN from the "egress list" on the port. | ||||
|             if (defined $rv and $old_untagged != $vlan) { | ||||
|                 if (defined $old_untagged and defined $qb_v_egress and scalar($qb_v_egress->{$vlan})){ | ||||
|  | ||||
|                     # First, get the egress list of the old native VLAN (arrayref structure) | ||||
|                     my $egressports = $qb_v_egress->{$old_untagged}; | ||||
|  | ||||
|                     # Since arrays are zero-based, we have to change the element at Index - 1 | ||||
|                     $egressports->[$iid-1] = "0"; | ||||
|  | ||||
|                     # After changing, pack the array into a binary structure (expected by set_qb_v_egress) and set the new value on the device. | ||||
|                     my $new_egresslist = pack("B*", join('', @$egressports)); | ||||
|  | ||||
|                     $rv = $hp->set_qb_v_egress($new_egresslist, $old_untagged); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             $hp->error_throw(sprintf("Requested VLAN %s doesn't seem to exist on device...", $vlan)); | ||||
|         } | ||||
|     } | ||||
|     return $rv; | ||||
| } | ||||
|  | ||||
| sub set_i_vlan_tagged { | ||||
|     my $hp = shift; | ||||
|     my $rv; | ||||
|  | ||||
|     my $qb_i_vlan = $hp->qb_i_vlan_t(); | ||||
|     if (defined $qb_i_vlan and scalar(keys %$qb_i_vlan)){ | ||||
|         my $vlan = shift; | ||||
|         my $iid = shift; | ||||
|  | ||||
|         my $qb_v_egress = $hp->qb_v_egress(); | ||||
|         if (defined $qb_v_egress and scalar($qb_v_egress->{$vlan})) { | ||||
|  | ||||
|             # First, get the egress list of the VLAN we want to add to the port. | ||||
|             my $egressports = $qb_v_egress->{$vlan}; | ||||
|  | ||||
|             # Since arrays are zero-based, we have to change the element at Index - 1 | ||||
|             $egressports->[$iid-1] = "1"; | ||||
|  | ||||
|             # After changing, pack the array into a binary structure (expected by set_qb_v_egress) and set the new value on the device. | ||||
|             my $new_egresslist = pack("B*", join('', @$egressports)); | ||||
|             $rv = $hp->set_qb_v_egress($new_egresslist, $vlan); | ||||
|             return $rv; | ||||
|         } else { | ||||
|             $hp->error_throw(sprintf("Requested VLAN %s doesn't seem to exist on device...", $vlan)); | ||||
|         } | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub agg_ports { return agg_ports_ifstack(@_) } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::HP - SNMP Interface to HP Procurve Switches | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Baker | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $hp = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           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::MAU | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<RFC1271-MIB> | ||||
|  | ||||
| Included in V2 mibs from Cisco | ||||
|  | ||||
| =item F<HP-ICF-OID> | ||||
|  | ||||
| (this MIB new with SNMP::Info 0.8) | ||||
|  | ||||
| =item F<STATISTICS-MIB> | ||||
|  | ||||
| =item F<NETSWITCH-MIB> | ||||
|  | ||||
| =item F<CONFIG-MIB> | ||||
|  | ||||
| =item F<HP-ICF-BRIDGE> | ||||
|  | ||||
| =item F<HP-ICF-POE-MIB> | ||||
|  | ||||
| =back | ||||
|  | ||||
| The last four MIBs listed are from HP and can be found at | ||||
| L<http://www.hp.com/rnd/software> or | ||||
| L<http://www.hp.com/rnd/software/MIBs.htm> | ||||
|  | ||||
| =head1 Change Log | ||||
|  | ||||
| Version 0.4 - Removed F<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 = ( | ||||
|     'J8131A' => 'WAP-420-WW', | ||||
|     'J8130A' => 'WAP-420-NA', | ||||
|     'J8133A' => 'AP520WL', | ||||
|     'J8680A' => '9408sl', | ||||
|     'J9091A' => '8212zl', | ||||
|     'J9475A' => '8206zl', | ||||
|     'J9265A' => '6600ml-24XG', | ||||
|     'J9264A' => '6600ml-24G-4XG', | ||||
|     'J9263A' => '6600ml-24G', | ||||
|     'J9452A' => '6600-48G-4XG', | ||||
|     'J9451A' => '6600-48G', | ||||
|     'J8474A' => '6410cl-6XG', | ||||
|     'J8433A' => '6400cl-6XG', | ||||
|     'J8992A' => '6200yl-24G', | ||||
|     'J4902A' => '6108', | ||||
|     'J8698A' => '5412zl', | ||||
|     'J8719A' => '5408yl', | ||||
|     'J8697A' => '5406zl', | ||||
|     'J8718A' => '5404yl', | ||||
|     'J4819A' => '5308XL', | ||||
|     'J4850A' => '5304XL', | ||||
|     'J8773A' => '4208vl', | ||||
|     'J8770A' => '4204vl', | ||||
|     'J8772A' => '4202vl-72', | ||||
|     'J9032A' => '4202vl-68G', | ||||
|     'J9031A' => '4202vl-68', | ||||
|     'J8771A' => '4202vl-48G', | ||||
|     'J4865A' => '4108GL', | ||||
|     'J4887A' => '4104GL', | ||||
|     'J9588A' => '3800-48G-PoE+-4XG', | ||||
|     'J9574A' => '3800-48G-PoE+-4SFP+', | ||||
|     'J9586A' => '3800-48G-4XG', | ||||
|     'J9576A' => '3800-48G-4SFP+', | ||||
|     'J9584A' => '3800-24SFP-2SFP+', | ||||
|     'J9587A' => '3800-24G-PoE+-2XG', | ||||
|     'J9573A' => '3800-24G-PoE+-2SFP+', | ||||
|     'J9585A' => '3800-24G-2XG', | ||||
|     'J9575A' => '3800-24G-2SFP+', | ||||
|     'J8693A' => '3500yl-48G-PWR', | ||||
|     'J8692A' => '3500yl-24G-PWR', | ||||
|     'J9473A' => '3500-48-PoE', | ||||
|     'J9472A' => '3500-48', | ||||
|     'J9471A' => '3500-24-PoE', | ||||
|     'J9470A' => '3500-24', | ||||
|     'J4906A' => '3400cl-48G', | ||||
|     'J4905A' => '3400cl-24G', | ||||
|     'J4815A' => '3324XL', | ||||
|     'J4851A' => '3124', | ||||
|     'J9562A' => '2915-8G-PoE', | ||||
|     'J9148A' => '2910al-48G-PoE+', | ||||
|     'J9147A' => '2910al-48G', | ||||
|     'J9146A' => '2910al-24G-PoE+', | ||||
|     'J9145A' => '2910al-24G', | ||||
|     'J9050A' => '2900-48G', | ||||
|     'J9049A' => '2900-24G', | ||||
|     'J4904A' => '2848', | ||||
|     'J4903A' => '2824', | ||||
|     'J9022A' => '2810-48G', | ||||
|     'J9021A' => '2810-24G', | ||||
|     'J8165A' => '2650-PWR', | ||||
|     'J4899B' => '2650-CR', | ||||
|     'J4899C' => '2650C', | ||||
|     'J4899A' => '2650', | ||||
|     'J8164A' => '2626-PWR', | ||||
|     'J4900B' => '2626-CR', | ||||
|     'J4900C' => '2626C', | ||||
|     'J4900A' => '2626', | ||||
|     'J9627A' => '2620-48-PoE+', | ||||
|     'J9626A' => '2620-48', | ||||
|     'J9624A' => '2620-24-PPoE+', | ||||
|     'J9625A' => '2620-24-PoE+', | ||||
|     'J9623A' => '2620-24', | ||||
|     'J9565A' => '2615-8-PoE', | ||||
|     'J9089A' => '2610-48-PWR', | ||||
|     'J9088A' => '2610-48', | ||||
|     'J9087A' => '2610-24-PWR', | ||||
|     'J9086A' => '2610-24/12PWR', | ||||
|     'J9085A' => '2610-24', | ||||
|     'J8762A' => '2600-8-PWR', | ||||
|     'J4813A' => '2524', | ||||
|     'J9298A' => '2520G-8-PoE', | ||||
|     'J9299A' => '2520G-24-PoE', | ||||
|     'J9137A' => '2520-8-PoE', | ||||
|     'J9138A' => '2520-24-PoE', | ||||
|     'J4812A' => '2512', | ||||
|     'J9280A' => '2510G-48', | ||||
|     'J9279A' => '2510G-24', | ||||
|     'J9020A' => '2510-48A', | ||||
|     'J9019B' => '2510-24B', | ||||
|     'J9019A' => '2510-24A', | ||||
|     'J4818A' => '2324', | ||||
|     'J4817A' => '2312', | ||||
|     'J9449A' => '1810G-8', | ||||
|     'J9450A' => '1810G-24', | ||||
|     'J9029A' => '1800-8G', | ||||
|     'J9028A' => '1800-24G', | ||||
|  ); | ||||
|  | ||||
| =item $hp->os() | ||||
|  | ||||
| Returns hp | ||||
|  | ||||
| =item $hp->os_bin() | ||||
|  | ||||
| C<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() | ||||
|  | ||||
| C<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 | ||||
|  | ||||
| =item $hp->fan() | ||||
|  | ||||
| Returns fan status | ||||
|  | ||||
| =item $hp->ps1_status() | ||||
|  | ||||
| Power supply 1 status | ||||
|  | ||||
| =item $hp->ps2_status() | ||||
|  | ||||
| Power supply 2 status | ||||
|  | ||||
| =item $hp->peth_port_power() | ||||
|  | ||||
| Power supplied by PoE ports, in milliwatts | ||||
| (C<hpicfPoePethPsePortPower>) | ||||
|  | ||||
| =item $hp->stp_ver() | ||||
|  | ||||
| Returns what version of STP the device is running. | ||||
| (C<hpicfBridgeRstpForceVersion> with fallback to inherited stp_ver()) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::MAU | ||||
|  | ||||
| See documentation in L<SNMP::Info::MAU/"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 4 | ||||
|  | ||||
| =item $hp->interfaces()  | ||||
|  | ||||
| Uses $hp->i_description() | ||||
|  | ||||
| =item $hp->i_duplex() | ||||
|  | ||||
| Returns reference to map of IIDs to current link duplex. | ||||
|  | ||||
| =item $hp->i_duplex_admin() | ||||
|  | ||||
| Returns reference to hash of IIDs to admin duplex setting. | ||||
|  | ||||
| =item $hp->vendor_i_type() | ||||
|  | ||||
| Returns reference to hash of IIDs to HP specific port type | ||||
| (C<hpSwitchPortType>). | ||||
|  | ||||
| =item $hp->i_name() | ||||
|  | ||||
| Crosses i_name() with $hp->e_name() using $hp->e_port() and i_alias() | ||||
|  | ||||
| =item $hp->peth_port_ifindex() | ||||
|  | ||||
| Returns reference to hash of power Ethernet port table entries map back to | ||||
| interface index (c<ifIndex>) | ||||
|  | ||||
| =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. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::MAU | ||||
|  | ||||
| See documentation in L<SNMP::Info::MAU/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head1 MUNGES | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item munge_hp_c_id() | ||||
|  | ||||
| Munge for c_id which handles CDP and LLDP. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 SET METHODS | ||||
|  | ||||
| These are methods that provide SNMP set functionality for overridden methods | ||||
| or provide a simpler interface to complex set operations.  See | ||||
| L<SNMP::Info/"SETTING DATA VIA SNMP"> for general information on set | ||||
| operations.  | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item set_i_vlan() | ||||
|  | ||||
| =item set_i_vlan_tagged() | ||||
|  | ||||
| =back | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										744
									
								
								lib/SNMP/Info/Layer2/HP4000.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										744
									
								
								lib/SNMP/Info/Layer2/HP4000.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,744 @@ | ||||
| # SNMP::Info::Layer2::HP4000 - SNMP Interface to older HP ProCurve Switches (1600, 2400, 2424M, 4000 and 8000) | ||||
| # | ||||
| # 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::Layer2::HP4000; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer3; | ||||
| use SNMP::Info::MAU; | ||||
| use SNMP::Info::CDP; | ||||
|  | ||||
| @SNMP::Info::Layer2::HP4000::ISA | ||||
|     = qw/SNMP::Info::Layer3 SNMP::Info::MAU | ||||
|     SNMP::Info::CDP Exporter/; | ||||
| @SNMP::Info::Layer2::HP4000::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MODEL_MAP %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer3::MIBS, | ||||
|     %SNMP::Info::MAU::MIBS, | ||||
|     %SNMP::Info::LLDP::MIBS, | ||||
|     %SNMP::Info::CDP::MIBS, | ||||
|     'RFC1271-MIB'    => 'logDescription', | ||||
|     'HP-ICF-OID'     => 'hpSwitch4000', | ||||
|     'HP-VLAN'        => 'hpVlanMemberIndex', | ||||
|     'STATISTICS-MIB' => 'hpSwitchCpuStat', | ||||
|     'NETSWITCH-MIB'  => 'hpMsgBufFree', | ||||
|     'CONFIG-MIB'     => 'hpSwitchConfig', | ||||
|     'SEMI-MIB'       => 'hpHttpMgSerialNumber', | ||||
|     'HP-ICF-CHASSIS' => 'hpicfSensorObjectId', | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer3::GLOBALS, | ||||
|     %SNMP::Info::MAU::GLOBALS, | ||||
|     %SNMP::Info::CDP::GLOBALS, | ||||
|     'serial1'      => 'hpHttpMgSerialNumber.0', | ||||
|     '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', | ||||
|     'hp_vlans'     => 'hpVlanNumber', | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer3::FUNCS, | ||||
|     %SNMP::Info::MAU::FUNCS, | ||||
|     %SNMP::Info::CDP::FUNCS, | ||||
|     'bp_index2' => 'dot1dBasePortIfIndex', | ||||
|     'i_type2'   => 'ifType', | ||||
|  | ||||
|     # RFC1271 | ||||
|     'l_descr' => 'logDescription', | ||||
|  | ||||
|     # HP-VLAN-MIB | ||||
|     'hp_v_index'    => 'hpVlanDot1QID', | ||||
|     'hp_v_name'     => 'hpVlanIdentName', | ||||
|     'hp_v_state'    => 'hpVlanIdentState', | ||||
|     'hp_v_type'     => 'hpVlanIdentType', | ||||
|     'hp_v_status'   => 'hpVlanIdentStatus', | ||||
|     'hp_v_mac'      => 'hpVlanAddrPhysAddress', | ||||
|     'hp_v_if_index' => 'hpVlanMemberIndex', | ||||
|     'hp_v_if_tag'   => 'hpVlanMemberTagged2', | ||||
|  | ||||
|     # CONFIG-MIB::hpSwitchPortTable | ||||
|     'hp_duplex'       => 'hpSwitchPortEtherMode', | ||||
|     'hp_duplex_admin' => 'hpSwitchPortFastEtherMode', | ||||
|     'vendor_i_type'   => 'hpSwitchPortType', | ||||
|  | ||||
|     # HP-ICF-CHASSIS | ||||
|     'hp_s_oid'    => 'hpicfSensorObjectId', | ||||
|     'hp_s_name'   => 'hpicfSensorDescr', | ||||
|     'hp_s_status' => 'hpicfSensorStatus', | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|  | ||||
|     # Inherit all the built in munging | ||||
|     %SNMP::Info::Layer3::MUNGE, | ||||
|     %SNMP::Info::MAU::MUNGE, | ||||
|     %SNMP::Info::CDP::MUNGE | ||||
| ); | ||||
|  | ||||
| %MODEL_MAP = ( | ||||
|     'J4093A' => '2424M', | ||||
|     'J4110A' => '8000M', | ||||
|     'J4120A' => '1600M', | ||||
|     'J4121A' => '4000M', | ||||
|     'J4122A' => '2400M', | ||||
|     'J4122B' => '2424M', | ||||
| ); | ||||
|  | ||||
| # 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; | ||||
| } | ||||
|  | ||||
| # Lookup model number, and translate the part number to the common number | ||||
| sub model { | ||||
|     my $hp = shift; | ||||
|     my $id = $hp->id(); | ||||
|     return unless defined $id; | ||||
|     my $model = &SNMP::translateObj($id); | ||||
|     return $id unless defined $model; | ||||
|  | ||||
|     $model =~ s/^hpswitch//i; | ||||
|  | ||||
|     return defined $MODEL_MAP{$model} ? $MODEL_MAP{$model} : $model; | ||||
| } | ||||
|  | ||||
| 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_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 i_duplex { | ||||
|     my $hp = shift; | ||||
|  | ||||
|     return $hp->mau_i_duplex(); | ||||
| } | ||||
|  | ||||
| sub i_duplex_admin { | ||||
|     my $hp      = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     # Try HP MIB first | ||||
|     my $hp_duplex = $hp->hp_duplex_admin($partial); | ||||
|     if ( defined $hp_duplex and scalar( keys %$hp_duplex ) ) { | ||||
|  | ||||
|         my %i_duplex; | ||||
|         foreach my $if ( keys %$hp_duplex ) { | ||||
|             my $duplex = $hp_duplex->{$if}; | ||||
|             next unless defined $duplex; | ||||
|  | ||||
|             $duplex = 'half' if $duplex =~ /half/i; | ||||
|             $duplex = 'full' if $duplex =~ /full/i; | ||||
|             $duplex = 'auto' if $duplex =~ /auto/i; | ||||
|             $i_duplex{$if} = $duplex; | ||||
|         } | ||||
|         return \%i_duplex; | ||||
|     } | ||||
|     else { | ||||
|         return $hp->mau_i_duplex_admin(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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 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; | ||||
|     return &_sensor( $hp, 'fan' ); | ||||
| } | ||||
|  | ||||
| sub ps1_status { | ||||
|     my $hp = shift; | ||||
|     return &_sensor( $hp, 'power', '^power supply 1' ) | ||||
|         || &_sensor( $hp, 'power', '^power supply sensor' ); | ||||
| } | ||||
|  | ||||
| sub ps2_status { | ||||
|     my $hp = shift; | ||||
|     return &_sensor( $hp, 'power', '^power supply 2' ) | ||||
|         || &_sensor( $hp, 'power', '^redundant' ); | ||||
| } | ||||
|  | ||||
| sub _sensor { | ||||
|     my $hp          = shift; | ||||
|     my $search_type = shift || 'fan'; | ||||
|     my $search_name = shift || ''; | ||||
|     my $hp_s_oid    = $hp->hp_s_oid(); | ||||
|     my $result; | ||||
|     foreach my $sensor ( keys %$hp_s_oid ) { | ||||
|         my $sensortype = &SNMP::translateObj( $hp_s_oid->{$sensor} ); | ||||
|         if ( $sensortype =~ /$search_type/i ) { | ||||
|             my $sensorname   = $hp->hp_s_name()->{$sensor}; | ||||
|             my $sensorstatus = $hp->hp_s_status()->{$sensor}; | ||||
|             if ( $sensorname =~ /$search_name/i ) { | ||||
|                 $result = $sensorstatus; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return $result; | ||||
| } | ||||
|  | ||||
| # Bridge MIB does not map Bridge Port to ifIndex correctly on older models, but Bridge Port equals ifIndex in these devices | ||||
| sub bp_index { | ||||
|     my $hp      = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $if_index = $hp->i_index($partial); | ||||
|     my %mod_bp_index; | ||||
|     foreach my $iid ( keys %$if_index ) { | ||||
|         $mod_bp_index{$iid} = $iid; | ||||
|     } | ||||
|     return \%mod_bp_index; | ||||
| } | ||||
|  | ||||
| # VLAN methods. Devices in this class use the proprietary HP-VLAN-MIB. | ||||
|  | ||||
| sub v_index { | ||||
|     my $hp      = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $hp->hp_v_index($partial); | ||||
| } | ||||
|  | ||||
| sub v_name { | ||||
|     my $hp      = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     return $hp->hp_v_name($partial); | ||||
| } | ||||
|  | ||||
| sub i_vlan { | ||||
|     my $hp = shift; | ||||
|  | ||||
|     # the hpvlanmembertagged2 table has an entry in the form of | ||||
|     #   vlan.interface = /untagged/no/tagged/auto | ||||
|     my $i_vlan      = {}; | ||||
|     my $hp_v_index  = $hp->hp_v_index(); | ||||
|     my $hp_v_if_tag = $hp->hp_v_if_tag(); | ||||
|     foreach my $row ( keys %$hp_v_if_tag ) { | ||||
|         my ( $index, $if ) = split( /\./, $row ); | ||||
|  | ||||
|         my $tag  = $hp_v_if_tag->{$row}; | ||||
|         my $vlan = $hp_v_index->{$index}; | ||||
|  | ||||
|         next unless ( defined $tag and $tag =~ /untagged/ ); | ||||
|  | ||||
|         $i_vlan->{$if} = $vlan if defined $vlan; | ||||
|     } | ||||
|  | ||||
|     return $i_vlan; | ||||
| } | ||||
|  | ||||
| sub i_vlan_membership { | ||||
|     my $hp = shift; | ||||
|  | ||||
|     my $i_vlan_membership = {}; | ||||
|     my $hp_v_index        = $hp->hp_v_index(); | ||||
|     my $hp_v_if_tag       = $hp->hp_v_if_tag(); | ||||
|     foreach my $row ( keys %$hp_v_if_tag ) { | ||||
|         my ( $index, $if ) = split( /\./, $row ); | ||||
|  | ||||
|         my $tag  = $hp_v_if_tag->{$row}; | ||||
|         my $vlan = $hp_v_index->{$index}; | ||||
|  | ||||
|         next unless ( defined $tag ); | ||||
|         next if ( $tag eq 'no' ); | ||||
|  | ||||
|         push( @{ $i_vlan_membership->{$if} }, $vlan ); | ||||
|     } | ||||
|  | ||||
|     return $i_vlan_membership; | ||||
| } | ||||
|  | ||||
| sub i_vlan_membership_untagged { | ||||
|     my $hp  = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $vlans = $hp->i_vlan($partial); | ||||
|     my $i_vlan_membership = {}; | ||||
|     foreach my $port (keys %$vlans) { | ||||
|         my $vlan = $vlans->{$port}; | ||||
|         push( @{ $i_vlan_membership->{$port} }, $vlan ); | ||||
|     } | ||||
|      | ||||
|     return $i_vlan_membership; | ||||
| } | ||||
|  | ||||
| sub set_i_vlan { | ||||
|     my $hp = shift; | ||||
|     my $rv; | ||||
|  | ||||
|     my $hp_v_index  = $hp->hp_v_index(); | ||||
|     my $hp_v_if_tag = $hp->hp_v_if_tag(); | ||||
|     if (defined $hp_v_index and scalar(keys %$hp_v_index)){ | ||||
|         my $vlan = shift; | ||||
|         my $iid = shift; | ||||
|         my $old_untagged; | ||||
|         # Hash to lookup VLAN index of the VID (dot1q tag) | ||||
|         my %vl_trans = reverse %$hp_v_index; | ||||
|  | ||||
|         # Translate the VLAN identifier (tag) value to the index used by the HP-VLAN MIB | ||||
|         my $vlan_index = $vl_trans{$vlan}; | ||||
|         if (defined $vlan_index) { | ||||
|  | ||||
|             # First, loop through table to determine current untagged vlan for the port we're about to change | ||||
|             foreach my $row (keys %$hp_v_if_tag){ | ||||
|                 my ($index,$if) = split(/\./,$row); | ||||
|                 if ($if == $iid and $hp_v_if_tag->{$row} =~ /untagged/) { | ||||
|                     # Store the row information of the current untagged VLAN and temporarily set it to tagged | ||||
|                     $old_untagged = $row; | ||||
|                     $rv = $hp->set_hp_v_if_tag(1, $row); | ||||
|                     last; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             # Then set our port untagged in the desired VLAN | ||||
|             my $rv = $hp->set_hp_v_if_tag(2, "$vlan_index.$iid"); | ||||
|             if (defined $rv) { | ||||
|                 # If vlan change is successful, remove VLAN that used to be untagged from the port | ||||
|                 if (defined $old_untagged) { | ||||
|                     $rv = $hp->set_hp_v_if_tag(3, $old_untagged); | ||||
|                     $hp->error_throw("Error removing previous untagged vlan from port, should never happen...\n") unless defined $rv; | ||||
|                 } | ||||
|             } else { | ||||
|                 # If vlan change was not succesful, try to revert to the old situation. | ||||
|                 if (defined $old_untagged) { | ||||
|                     $rv = $hp->set_hp_v_if_tag(2, $old_untagged) if defined $old_untagged; | ||||
|                     if (defined $rv) { | ||||
|                         $hp->error_throw("VLAN change failed, restored port to previous configuration.\n"); | ||||
|                     } else { | ||||
|                         $hp->error_throw("VLAN change failed, unable to restore old configuration. Check device.\n"); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             $hp->error_throw("Requested VLAN (VLAN ID: $vlan) not available on device.\n"); | ||||
|         } | ||||
|     } else { | ||||
|         $hp->error_throw("Error retrieving VLAN information from device.\n"); | ||||
|     } | ||||
|     return $rv; | ||||
| } | ||||
|  | ||||
| sub set_i_vlan_tagged { | ||||
|     my $hp = shift; | ||||
|     my $vlan = shift; | ||||
|     my $iid = shift; | ||||
|     my $rv; | ||||
|  | ||||
|     my $hp_v_index  = $hp->hp_v_index(); | ||||
|     if (defined $hp_v_index and scalar(keys %$hp_v_index)){ | ||||
|         # Hash to lookup VLAN index of the VID (dot1q tag) | ||||
|         my %vl_trans = reverse %$hp_v_index; | ||||
|  | ||||
|         # Translate the VLAN identifier (tag) value to the index used by the HP-VLAN MIB | ||||
|         my $vlan_index = $vl_trans{$vlan}; | ||||
|         if (defined $vlan_index) { | ||||
|             # Set our port tagged in the desired VLAN | ||||
|             $rv = $hp->set_hp_v_if_tag(1, "$vlan_index.$iid"); | ||||
|         } else { | ||||
|             $hp->error_throw("Requested VLAN (VLAN ID: $vlan) not available on device.\n"); | ||||
|         } | ||||
|     } | ||||
|     return $rv; | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::HP4000 - SNMP Interface to older HP ProCurve Switches (1600, 2400, 2424M, 4000 and 8000) | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Baker | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $hp = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           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::HP4000(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
|  | ||||
| =item SNMP::Info::MAU | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<RFC1271-MIB> | ||||
|  | ||||
| Included in V2 mibs from Cisco | ||||
|  | ||||
| =item F<HP-ICF-OID> | ||||
|  | ||||
| =item F<HP-VLAN> | ||||
|  | ||||
| (this MIB new with SNMP::Info 0.8) | ||||
|  | ||||
| =item F<STATISTICS-MIB> | ||||
|  | ||||
| =item F<NETSWITCH-MIB> | ||||
|  | ||||
| =item F<CONFIG-MIB> | ||||
|  | ||||
| =back | ||||
|  | ||||
| The last five MIBs listed are from HP and can be found at | ||||
| L<http://www.hp.com/rnd/software> or | ||||
| L<http://www.hp.com/rnd/software/MIBs.htm> | ||||
|  | ||||
| =head1 Change Log | ||||
|  | ||||
| Version 0.4 - Removed F<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 = (  | ||||
|                 'J4093A' => '2424M', | ||||
|                 'J4110A' => '8000M', | ||||
|                 'J4120A' => '1600M', | ||||
|                 'J4121A' => '4000M', | ||||
|                 'J4122A' => '2400M', | ||||
|                 'J4122B' => '2424M', | ||||
|                 ); | ||||
|  | ||||
| =item $hp->os() | ||||
|  | ||||
| Returns hp | ||||
|  | ||||
| =item $hp->os_bin() | ||||
|  | ||||
| C<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() | ||||
|  | ||||
| C<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 | ||||
|  | ||||
| =item $hp->fan() | ||||
|  | ||||
| Returns fan status | ||||
|  | ||||
| =item $hp->ps1_status() | ||||
|  | ||||
| Power supply 1 status | ||||
|  | ||||
| =item $hp->ps2_status() | ||||
|  | ||||
| Power supply 2 status | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::MAU | ||||
|  | ||||
| See documentation in L<SNMP::Info::MAU/"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 $hp->interfaces()  | ||||
|  | ||||
| Uses $hp->i_description() | ||||
|  | ||||
| =item $hp->i_duplex() | ||||
|  | ||||
| Returns reference to map of IIDs to current link duplex. | ||||
|  | ||||
| =item $hp->i_duplex_admin() | ||||
|  | ||||
| Returns reference to hash of IIDs to admin duplex setting. | ||||
|  | ||||
| =item $hp->vendor_i_type() | ||||
|  | ||||
| Returns reference to hash of IIDs to HP specific port type | ||||
| (C<hpSwitchPortType>). | ||||
|  | ||||
| =item $hp->i_name() | ||||
|  | ||||
| Crosses i_name() with $hp->e_name() using $hp->e_port() and i_alias() | ||||
|  | ||||
| =item $hp->i_vlan() | ||||
|  | ||||
| Returns a mapping between C<ifIndex> and the PVID (default VLAN) or untagged | ||||
| port when using F<HP-VLAN>. | ||||
|  | ||||
| =item $hp->i_vlan_membership() | ||||
|  | ||||
| Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN | ||||
| IDs.  These are the VLANs which are members of the egress list for the port. | ||||
| It is the union of tagged, untagged, and auto ports. | ||||
|  | ||||
|   Example: | ||||
|   my $interfaces = $hp->interfaces(); | ||||
|   my $vlans      = $hp->i_vlan_membership(); | ||||
|    | ||||
|   foreach my $iid (sort keys %$interfaces) { | ||||
|     my $port = $interfaces->{$iid}; | ||||
|     my $vlan = join(',', sort(@{$vlans->{$iid}})); | ||||
|     print "Port: $port VLAN: $vlan\n"; | ||||
|   } | ||||
|  | ||||
| =item $hp->i_vlan_membership_untagged() | ||||
|  | ||||
| Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN | ||||
| IDs.  These are the VLANs which are members of the untagged egress list for | ||||
| the port. | ||||
|  | ||||
| =item $hp->v_index() | ||||
|  | ||||
| Returns VLAN IDs | ||||
|  | ||||
| =item $hp->v_name() | ||||
|  | ||||
| Returns VLAN names | ||||
|  | ||||
| =item $hp->bp_index() | ||||
|  | ||||
| Returns reference to hash of bridge port table entries map back to interface | ||||
| identifier (iid) | ||||
|  | ||||
| Returns (C<ifIndex>) for both key and value for 1600, 2424, 4000, and 8000 | ||||
| models since they seem to have problems with F<BRIDGE-MIB> | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::MAU | ||||
|  | ||||
| See documentation in L<SNMP::Info::MAU/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head1 SET METHODS | ||||
|  | ||||
| These are methods that provide SNMP set functionality for overridden methods | ||||
| or provide a simpler interface to complex set operations.  See | ||||
| L<SNMP::Info/"SETTING DATA VIA SNMP"> for general information on set | ||||
| operations.  | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item set_i_vlan() | ||||
|  | ||||
| =item set_i_vlan_tagged() | ||||
|  | ||||
| =back | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										214
									
								
								lib/SNMP/Info/Layer2/HPVC.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								lib/SNMP/Info/Layer2/HPVC.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,214 @@ | ||||
| # SNMP::Info::Layer2::HPVC - SNMP Interface to HP VirtualConnect Switches | ||||
| # | ||||
| # Copyright (c) 2011 Jeroen van Ingen | ||||
| # | ||||
| # 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::HPVC; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2; | ||||
| use SNMP::Info::LLDP; | ||||
|  | ||||
| @SNMP::Info::Layer2::HPVC::ISA | ||||
|     = qw/SNMP::Info::Layer2 SNMP::Info::LLDP Exporter/; | ||||
| @SNMP::Info::Layer2::HPVC::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     %SNMP::Info::LLDP::MIBS, | ||||
|     'HPVC-MIB'       => 'vcDomainName', | ||||
|     'CPQSINFO-MIB'   => 'cpqSiSysSerialNum', | ||||
|     'HPVCMODULE-MIB' => 'vcModuleDomainName', | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::GLOBALS, | ||||
|     %SNMP::Info::LLDP::GLOBALS, | ||||
|     'serial1'      => 'cpqSiSysSerialNum.0', | ||||
|     'os_ver'       => 'cpqHoSWRunningVersion.1', | ||||
|     'os_bin'       => 'cpqHoFwVerVersion.1', | ||||
|     'productname'  => 'cpqSiProductName.0', | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     %SNMP::Info::LLDP::FUNCS, | ||||
|      | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     # Inherit all the built in munging | ||||
|     %SNMP::Info::Layer2::MUNGE, | ||||
|     %SNMP::Info::LLDP::MUNGE, | ||||
| ); | ||||
|  | ||||
|  | ||||
| # Method Overrides | ||||
|  | ||||
| sub os { | ||||
|     return 'hpvc'; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'hp'; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $hp = shift; | ||||
|     return $hp->productname(); | ||||
| } | ||||
|  | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::HPVC - SNMP Interface to HP Virtual Connect Switches | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Jeroen van Ingen | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $hp = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           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 Virtual Connect Switch via SNMP.  | ||||
|  | ||||
| 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::HPVC(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<HPVC-MIB> | ||||
|  | ||||
| =item F<CPQSINFO-MIB> | ||||
|  | ||||
| =item F<HPVCMODULE-MIB> | ||||
|  | ||||
| =back | ||||
|  | ||||
| All required MIBs can be found in the netdisco-mibs package. | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $hp->os() | ||||
|  | ||||
| Returns C<'hpvc'> | ||||
|  | ||||
| =item $hp->os_bin() | ||||
|  | ||||
| C<cpqHoFwVerVersion.1> | ||||
|  | ||||
| =item $hp->os_ver() | ||||
|  | ||||
| C<cpqHoSWRunningVersion.1> | ||||
|  | ||||
| =item $hp->serial() | ||||
|  | ||||
| C<cpqSiSysSerialNum.0> | ||||
|  | ||||
| =item $hp->vendor() | ||||
|  | ||||
| hp | ||||
|  | ||||
| =item $hp->model() | ||||
|  | ||||
| C<cpqSiProductName.0> | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"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 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head1 MUNGES | ||||
|  | ||||
| =over | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 SET METHODS | ||||
|  | ||||
| These are methods that provide SNMP set functionality for overridden methods | ||||
| or provide a simpler interface to complex set operations.  See | ||||
| L<SNMP::Info/"SETTING DATA VIA SNMP"> for general information on set | ||||
| operations.  | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										180
									
								
								lib/SNMP/Info/Layer2/Kentrox.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								lib/SNMP/Info/Layer2/Kentrox.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,180 @@ | ||||
| package SNMP::Info::Layer2::Kentrox; | ||||
|  | ||||
| # Copyright (c) 2011 Netdisco Project | ||||
| # 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. | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2; | ||||
|  | ||||
| @SNMP::Info::Layer2::Kentrox::ISA       = qw/SNMP::Info::Layer2 Exporter/; | ||||
| @SNMP::Info::Layer2::Kentrox::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::GLOBALS, | ||||
|         #from DATASMART-MIB | ||||
|         # MIB isn't yet in netdisco-mibs (not clear permission) | ||||
|         # ... when it is, this can change to dsScWyv | ||||
|         'ds_sysinfo' => '.1.3.6.1.4.1.181.2.2.12.15.0', | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( %SNMP::Info::Layer2::MUNGE, ); | ||||
|  | ||||
| sub os { | ||||
|     return 'Kentrox'; | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|     my $dsver = shift; | ||||
|     my $descr = $dsver->description(); | ||||
|     if ( $descr =~ /^\S+\s\S+\s\S+\s(\S+)/){ | ||||
|         return $1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| sub serial { | ||||
|     my $dsserial = shift; | ||||
|     my $serial = $dsserial->ds_sysinfo(); | ||||
|     if ( $serial =~ /SERIAL\s(\S+)/){ | ||||
|         my $str = substr($1,8,10); | ||||
|         return $str; | ||||
|     } | ||||
|  | ||||
| } | ||||
| sub vendor { | ||||
|     return 'Kentrox'; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $dsmodel = shift; | ||||
|     my $descr = $dsmodel->description(); | ||||
|     if ( $descr =~ /^(\S+\s\S+)/){ | ||||
|         return $1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Kentrox - SNMP Interface to L2 Kentrox DataSMART DSU/CSU | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| phishphreek@gmail.com | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you. | ||||
|  my $router = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myrouter', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 1 | ||||
|                         ) | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $router->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Subclass for Kentrox DataSMART DSU/CSU | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item Inherited Classes' MIBs | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $router->vendor() | ||||
|  | ||||
| =item $router->os() | ||||
|  | ||||
| =item $router->os_ver() | ||||
|  | ||||
| =item $router->model() | ||||
|  | ||||
| =item $router->serial() | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"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 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
|  | ||||
							
								
								
									
										248
									
								
								lib/SNMP/Info/Layer2/N2270.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								lib/SNMP/Info/Layer2/N2270.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,248 @@ | ||||
| # SNMP::Info::Layer2::N2270 | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008 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::Layer2::N2270; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info; | ||||
| use SNMP::Info::Bridge; | ||||
| use SNMP::Info::SONMP; | ||||
| use SNMP::Info::Airespace; | ||||
|  | ||||
| @SNMP::Info::Layer2::N2270::ISA | ||||
|     = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::SONMP SNMP::Info::Airespace Exporter/; | ||||
| @SNMP::Info::Layer2::N2270::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::MIBS,        %SNMP::Info::Bridge::MIBS, | ||||
|     %SNMP::Info::SONMP::MIBS, %SNMP::Info::Airespace::MIBS, | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::GLOBALS,        %SNMP::Info::Bridge::GLOBALS, | ||||
|     %SNMP::Info::SONMP::GLOBALS, %SNMP::Info::Airespace::GLOBALS, | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::FUNCS,        %SNMP::Info::Bridge::FUNCS, | ||||
|     %SNMP::Info::SONMP::FUNCS, %SNMP::Info::Airespace::FUNCS, | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::MUNGE,        %SNMP::Info::Bridge::MUNGE, | ||||
|     %SNMP::Info::SONMP::MUNGE, %SNMP::Info::Airespace::MUNGE, | ||||
| ); | ||||
|  | ||||
| sub os { | ||||
|     return 'nortel'; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'nortel'; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $n2270 = shift; | ||||
|     my $id    = $n2270->id(); | ||||
|     return unless defined $id; | ||||
|     my $model = &SNMP::translateObj($id); | ||||
|     return $id unless defined $model; | ||||
|     $model =~ s/^sreg-WLANSecuritySwitch//i; | ||||
|  | ||||
|     return $model; | ||||
| } | ||||
|  | ||||
| sub index_factor { | ||||
|     return 256; | ||||
| } | ||||
|  | ||||
| sub slot_offset { | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::N2270 - SNMP Interface to Nortel 2270 Series Wireless | ||||
| Switch | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Eric Miller | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|     #Let SNMP::Info determine the correct subclass for you. | ||||
|  | ||||
|     my $n2270 = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|     my $class = $n2270->class(); | ||||
|     print " Using device sub class : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from a  | ||||
| Nortel 2270 Series Wireless Switch through SNMP. | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
| my $n2270 = new SNMP::Info::Layer2::N2270(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info | ||||
|  | ||||
| =item SNMP::Info::Bridge | ||||
|  | ||||
| =item SNMP::Info::SONMP | ||||
|  | ||||
| =item SNMP::Info::Airespace | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item Inherited Classes' MIBs | ||||
|  | ||||
| See L<SNMP::Info/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::Bridge/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::SONMP/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::Airespace/"Required MIBs"> for its own MIB requirements. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $n2270->vendor() | ||||
|  | ||||
| Returns 'nortel' | ||||
|  | ||||
| =item $n2270->os() | ||||
|  | ||||
| Returns 'nortel' | ||||
|  | ||||
| =item $n2270->model() | ||||
|  | ||||
| Cross references $bayhub->id() to the F<SYNOPTICS-ROOT-MIB> and returns | ||||
| the results. | ||||
|  | ||||
| Removes C<sreg-WLANSecuritySwitch> from the model name | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item  $bayhub->index_factor() | ||||
|  | ||||
| Required by SNMP::Info::SONMP.  Number representing the number of ports | ||||
| reserved per slot within the device MIB.  Returns 256. | ||||
|  | ||||
| =item $bayhub->slot_offset() | ||||
|  | ||||
| Required by SNMP::Info::SONMP.  Offset if slot numbering does not | ||||
| start at 0.  Returns 0. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info | ||||
|  | ||||
| See documentation in L<SNMP::Info/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Bridge | ||||
|  | ||||
| See documentation in L<SNMP::Info::Bridge/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::SONMP | ||||
|  | ||||
| See documentation in L<SNMP::Info::SONMP/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::Airespace | ||||
|  | ||||
| See documentation in L<SNMP::Info::Airespace/"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 None | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info | ||||
|  | ||||
| See documentation in L<SNMP::Info/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Bridge | ||||
|  | ||||
| See documentation in L<SNMP::Info::Bridge/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::SONMP | ||||
|  | ||||
| See documentation in L<SNMP::Info::SONMP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Airespace | ||||
|  | ||||
| See documentation in L<SNMP::Info::Airespace/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										586
									
								
								lib/SNMP/Info/Layer2/NAP222x.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										586
									
								
								lib/SNMP/Info/Layer2/NAP222x.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,586 @@ | ||||
| # SNMP::Info::Layer2::NAP222x | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008 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::Layer2::NAP222x; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::SONMP; | ||||
| use SNMP::Info::IEEE802dot11; | ||||
| use SNMP::Info::Layer2; | ||||
|  | ||||
| @SNMP::Info::Layer2::NAP222x::ISA | ||||
|     = qw/SNMP::Info::SONMP SNMP::Info::IEEE802dot11 SNMP::Info::Layer2 Exporter/; | ||||
| @SNMP::Info::Layer2::NAP222x::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, %SNMP::Info::IEEE802dot11::MIBS, | ||||
|     %SNMP::Info::SONMP::MIBS, 'NORTEL-WLAN-AP-MIB' => 'ntWlanSwHardwareVer', | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::GLOBALS, | ||||
|     %SNMP::Info::IEEE802dot11::GLOBALS, | ||||
|     %SNMP::Info::SONMP::GLOBALS, | ||||
|     'nt_hw_ver'     => 'ntWlanSwHardwareVer', | ||||
|     'nt_fw_ver'     => 'ntWlanSwBootRomVer', | ||||
|     'nt_sw_ver'     => 'ntWlanSwOpCodeVer', | ||||
|     'nt_cc'         => 'ntWlanSwCountryCode', | ||||
|     'tftp_action'   => 'ntWlanTransferStart', | ||||
|     'tftp_host'     => 'ntWlanFileServer', | ||||
|     'tftp_file'     => 'ntWlanDestFile', | ||||
|     'tftp_type'     => 'ntWlanFileType', | ||||
|     'tftp_result'   => 'ntWlanFileTransferStatus', | ||||
|     'tftp_xtype'    => 'ntWlanTransferType', | ||||
|     'tftp_src_file' => 'ntWlanSrcFile', | ||||
|     'ftp_user'      => 'ntWlanUserName', | ||||
|     'ftp_pass'      => 'ntWlanPassword', | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     %SNMP::Info::IEEE802dot11::FUNCS, | ||||
|     %SNMP::Info::SONMP::FUNCS, | ||||
|  | ||||
|     # From ntWlanPortTable | ||||
|     'nt_prt_name'  => 'ntWlanPortName', | ||||
|     'nt_dpx_admin' => 'ntWlanPortCapabilities', | ||||
|     'nt_auto'      => 'ntWlanPortAutonegotiation', | ||||
|     'nt_dpx'       => 'ntWlanPortSpeedDpxStatus', | ||||
|  | ||||
|     # From ntWlanDot11PhyOperationTable | ||||
|     'nt_i_broadcast' => 'ntWlanDot11ClosedSystem', | ||||
|  | ||||
|     # From ntWlanApVlanTable | ||||
|     'nt_i_vlan' => 'ntWlanApVlanDefaultVid', | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( | ||||
|     %SNMP::Info::Layer2::MUNGE, %SNMP::Info::IEEE802dot11::MUNGE, | ||||
|     %SNMP::Info::SONMP::MUNGE, | ||||
| ); | ||||
|  | ||||
| sub os { | ||||
|     return 'nortel'; | ||||
| } | ||||
|  | ||||
| sub os_bin { | ||||
|     my $nap222x = shift; | ||||
|     my $bin     = $nap222x->nt_fw_ver(); | ||||
|     return unless defined $bin; | ||||
|  | ||||
|     if ( $bin =~ m/(\d+\.\d+\.\d+)/ ) { | ||||
|         return $1; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $nap222x = shift; | ||||
|     my $descr   = $nap222x->description(); | ||||
|     return unless defined $descr; | ||||
|  | ||||
|     return 'AP-2220' if ( $descr =~ /2220/ ); | ||||
|     return 'AP-2221' if ( $descr =~ /2221/ ); | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub mac { | ||||
|     my $nap222x = shift; | ||||
|     my $i_mac   = $nap222x->i_mac(); | ||||
|  | ||||
|     # Return Interface MAC | ||||
|     foreach my $entry ( keys %$i_mac ) { | ||||
|         my $sn = $i_mac->{$entry}; | ||||
|         next unless $sn; | ||||
|         return $sn; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub serial { | ||||
|     my $nap222x = shift; | ||||
|     my $i_mac   = $nap222x->i_mac(); | ||||
|  | ||||
|     # Return Interface MAC | ||||
|     foreach my $entry ( keys %$i_mac ) { | ||||
|         my $sn = $i_mac->{$entry}; | ||||
|         next unless $sn; | ||||
|         return $sn; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub interfaces { | ||||
|     my $nap222x = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $interfaces  = $nap222x->i_index($partial)       || {}; | ||||
|     my $description = $nap222x->i_description($partial) || {}; | ||||
|  | ||||
|     my %interfaces = (); | ||||
|     foreach my $iid ( keys %$interfaces ) { | ||||
|         my $desc = $description->{$iid}; | ||||
|         next unless defined $desc; | ||||
|         next if $desc =~ /lo/i; | ||||
|  | ||||
|         $interfaces{$iid} = $desc; | ||||
|     } | ||||
|     return \%interfaces; | ||||
| } | ||||
|  | ||||
| sub i_duplex { | ||||
|     my $nap222x = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $mode       = $nap222x->nt_dpx($partial)      || {}; | ||||
|     my $port_name  = $nap222x->nt_prt_name($partial) || {}; | ||||
|     my $interfaces = $nap222x->interfaces($partial)  || {}; | ||||
|  | ||||
|     my %i_duplex; | ||||
|     foreach my $if ( keys %$interfaces ) { | ||||
|         my $port = $interfaces->{$if}; | ||||
|         next unless $port =~ /dp/i; | ||||
|         foreach my $idx ( keys %$mode ) { | ||||
|             my $name = $port_name->{$idx} || 'unknown'; | ||||
|             next unless $name eq $port; | ||||
|             my $duplex = $mode->{$idx}; | ||||
|  | ||||
|             $duplex = 'other' unless defined $duplex; | ||||
|             $duplex = 'half' if $duplex =~ /half/i; | ||||
|             $duplex = 'full' if $duplex =~ /full/i; | ||||
|  | ||||
|             $i_duplex{$if} = $duplex; | ||||
|         } | ||||
|     } | ||||
|     return \%i_duplex; | ||||
| } | ||||
|  | ||||
| sub i_duplex_admin { | ||||
|     my $nap222x = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $dpx_admin  = $nap222x->nt_dpx_admin($partial) || {}; | ||||
|     my $nt_auto    = $nap222x->nt_auto($partial)      || {}; | ||||
|     my $interfaces = $nap222x->interfaces($partial)   || {}; | ||||
|     my $port_name  = $nap222x->nt_prt_name($partial)  || {}; | ||||
|  | ||||
|     my %i_duplex_admin; | ||||
|     foreach my $if ( keys %$interfaces ) { | ||||
|         my $port = $interfaces->{$if}; | ||||
|         next unless $port =~ /dp/i; | ||||
|         foreach my $idx ( keys %$dpx_admin ) { | ||||
|             my $name = $port_name->{$idx} || 'unknown'; | ||||
|             next unless $name eq $port; | ||||
|             my $duplex = $dpx_admin->{$idx}; | ||||
|             my $auto   = $nt_auto->{$idx}; | ||||
|  | ||||
|             $duplex = 'other' unless defined $duplex; | ||||
|             $duplex = 'half' | ||||
|                 if ( $duplex =~ /half/i and $auto =~ /disabled/i ); | ||||
|             $duplex = 'full' | ||||
|                 if ( $duplex =~ /full/i and $auto =~ /disabled/i ); | ||||
|             $duplex = 'auto' if $auto =~ /enabled/i; | ||||
|  | ||||
|             $i_duplex_admin{$if} = $duplex; | ||||
|         } | ||||
|     } | ||||
|     return \%i_duplex_admin; | ||||
| } | ||||
|  | ||||
| sub i_name { | ||||
|     my $nap222x = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $interfaces = $nap222x->interfaces($partial) || {}; | ||||
|  | ||||
|     my %i_name; | ||||
|     foreach my $if ( keys %$interfaces ) { | ||||
|         my $desc = $interfaces->{$if}; | ||||
|         next unless defined $desc; | ||||
|  | ||||
|         my $name = 'unknown'; | ||||
|         $name = 'Ethernet Interface'   if $desc =~ /dp/i; | ||||
|         $name = 'Wireless Interface B' if $desc =~ /ndc/i; | ||||
|         $name = 'Wireless Interface A' if $desc =~ /ar/i; | ||||
|  | ||||
|         $i_name{$if} = $name; | ||||
|     } | ||||
|     return \%i_name; | ||||
| } | ||||
|  | ||||
| # dot1dBasePortTable does not exist and dot1dTpFdbPort does not map to ifIndex | ||||
| sub bp_index { | ||||
|     my $nap222x = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $interfaces = $nap222x->interfaces($partial) || {}; | ||||
|  | ||||
|     my %bp_index; | ||||
|     foreach my $iid ( keys %$interfaces ) { | ||||
|         my $desc = $interfaces->{$iid}; | ||||
|         next unless defined $desc; | ||||
|         next unless $desc =~ /(ndc|ar)/i; | ||||
|  | ||||
|         my $port = 1; | ||||
|         $port = 2 if $desc =~ /ndc/i; | ||||
|  | ||||
|         $bp_index{$port} = $iid; | ||||
|     } | ||||
|     return \%bp_index; | ||||
| } | ||||
|  | ||||
| # Indicies don't match anywhere in these devices! Need to override to match | ||||
| # IfIndex. | ||||
| sub i_ssidlist { | ||||
|     my $nap222x = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     # modify partial to match index | ||||
|     if ( defined $partial ) { | ||||
|         $partial = $partial - 2; | ||||
|     } | ||||
|     my $ssids = $nap222x->orig_i_ssidlist($partial) || {}; | ||||
|  | ||||
|     my %i_ssidlist; | ||||
|     foreach my $iid ( keys %$ssids ) { | ||||
|         my $port = $iid + 2; | ||||
|         my $ssid = $ssids->{$iid}; | ||||
|         next unless defined $ssid; | ||||
|  | ||||
|         $i_ssidlist{$port} = $ssid; | ||||
|     } | ||||
|     return \%i_ssidlist; | ||||
| } | ||||
|  | ||||
| sub i_ssidbcast { | ||||
|     my $nap222x = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     # modify partial to match index | ||||
|     if ( defined $partial ) { | ||||
|         $partial = $partial - 2; | ||||
|     } | ||||
|     my $bcast = $nap222x->nt_i_broadcast($partial) || {}; | ||||
|  | ||||
|     my %i_ssidbcast; | ||||
|     foreach my $iid ( keys %$bcast ) { | ||||
|         my $port = $iid + 2; | ||||
|         my $bc   = $bcast->{$iid}; | ||||
|         next unless defined $bc; | ||||
|  | ||||
|         $i_ssidbcast{$port} = $bc; | ||||
|     } | ||||
|     return \%i_ssidbcast; | ||||
| } | ||||
|  | ||||
| sub i_80211channel { | ||||
|     my $nap222x = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     # modify partial to match index | ||||
|     if ( defined $partial ) { | ||||
|         $partial = $partial - 2; | ||||
|     } | ||||
|     my $phy_type = $nap222x->dot11_phy_type($partial) || {}; | ||||
|     my $cur_freq = $nap222x->dot11_cur_freq()         || {}; | ||||
|     my $cur_ch   = $nap222x->dot11_cur_ch()           || {}; | ||||
|  | ||||
|     my %i_80211channel; | ||||
|     foreach my $iid ( keys %$phy_type ) { | ||||
|         my $port = $iid + 2; | ||||
|         my $type = $phy_type->{$iid}; | ||||
|         next unless defined $type; | ||||
|         if ( $type =~ /dsss/ ) { | ||||
|             my $ch = $cur_ch->{1}; | ||||
|             next unless defined $ch; | ||||
|             $i_80211channel{$port} = $ch; | ||||
|         } | ||||
|         elsif ( $type =~ /ofdm/ ) { | ||||
|             my $ch = $cur_freq->{0}; | ||||
|             next unless defined $ch; | ||||
|             $i_80211channel{$port} = $ch; | ||||
|         } | ||||
|         else { | ||||
|             next; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return \%i_80211channel; | ||||
| } | ||||
|  | ||||
| sub i_vlan { | ||||
|     my $nap222x = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     # modify partial to match index | ||||
|     if ( defined $partial ) { | ||||
|         $partial = $partial - 2; | ||||
|     } | ||||
|     my $vlans = $nap222x->nt_i_vlan($partial) || {}; | ||||
|  | ||||
|     my %i_vlan; | ||||
|     foreach my $iid ( keys %$vlans ) { | ||||
|         my $port = $iid + 2; | ||||
|         my $vlan = $vlans->{$iid}; | ||||
|         next unless defined $vlan; | ||||
|  | ||||
|         $i_vlan{$port} = $vlan; | ||||
|     } | ||||
|     return \%i_vlan; | ||||
| } | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::NAP222x - SNMP Interface to Nortel 2220 Series Access | ||||
| Points | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Eric Miller | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $nap222x = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class = $nap222x->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from a Nortel | ||||
| 2220 series wireless Access Points through SNMP.  | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
|  my $nap222x = new SNMP::Info::Layer2::NAP222x(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::SONMP | ||||
|  | ||||
| =item SNMP::Info::IEEE802dot11 | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<NORTEL-WLAN-AP-MIB> | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Inherited MIBs | ||||
|  | ||||
| See L<SNMP::Info::SONMP/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::IEEE802dot11/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $nap222x->model() | ||||
|  | ||||
| Returns the model extracted from C<sysDescr>. | ||||
|  | ||||
| =item $nap222x->os() | ||||
|  | ||||
| Returns 'nortel' | ||||
|  | ||||
| =item $nap222x->os_bin() | ||||
|  | ||||
| Returns the firmware version extracted from C<ntWlanSwBootRomVer>. | ||||
|  | ||||
| =item $nap222x->mac() | ||||
|  | ||||
| Returns the MAC address of the first Ethernet Interface. | ||||
|  | ||||
| =item $nap222x->serial() | ||||
|  | ||||
| Returns the MAC address of the first Ethernet Interface. | ||||
|  | ||||
| =item $nap222x->nt_hw_ver() | ||||
|  | ||||
| Returns the hardware version. | ||||
|  | ||||
| (C<ntWlanSwHardwareVer>) | ||||
|  | ||||
| =item $nap222x->nt_cc() | ||||
|  | ||||
| Returns the country code of the AP. | ||||
|  | ||||
| (C<ntWlanSwHardwareVer>) | ||||
|  | ||||
| =item $nap222x->tftp_action() | ||||
|  | ||||
| (C<ntWlanTransferStart>) | ||||
|  | ||||
| =item $nap222x->tftp_host() | ||||
|  | ||||
| (C<ntWlanFileServer>) | ||||
|  | ||||
| =item $nap222x->tftp_file() | ||||
|  | ||||
| (C<ntWlanDestFile>) | ||||
|  | ||||
| =item $nap222x->tftp_type() | ||||
|  | ||||
| (C<ntWlanFileType>) | ||||
|  | ||||
| =item $nap222x->tftp_result() | ||||
|  | ||||
| (C<ntWlanFileTransferStatus>) | ||||
|  | ||||
| =item $nap222x->tftp_xtype() | ||||
|  | ||||
| (C<ntWlanTransferType>) | ||||
|  | ||||
| =item $nap222x->tftp_src_file() | ||||
|  | ||||
| (C<ntWlanSrcFile>) | ||||
|  | ||||
| =item $nap222x->ftp_user() | ||||
|  | ||||
| (C<ntWlanUserName>) | ||||
|  | ||||
| =item $nap222x->ftp_pass() | ||||
|  | ||||
| (C<ntWlanPassword>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::SONMP | ||||
|  | ||||
| See L<SNMP::Info::SONMP/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::IEEE802dot11 | ||||
|  | ||||
| See L<SNMP::Info::IEEE802dot11/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"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 $nap222x->interfaces() | ||||
|  | ||||
| Returns reference to map of IIDs to physical ports.  | ||||
|  | ||||
| =item $nap222x->i_duplex() | ||||
|  | ||||
| Returns reference to hash.  Maps port operational duplexes to IIDs. | ||||
|  | ||||
| (C<ntWlanPortSpeedDpxStatus>) | ||||
|  | ||||
| =item $nap222x->i_duplex_admin() | ||||
|  | ||||
| Returns reference to hash.  Maps port admin duplexes to IIDs. | ||||
|  | ||||
| (C<ntWlanPortCapabilities>) | ||||
|  | ||||
| =item $nap222x->i_name() | ||||
|  | ||||
| Returns a human name based upon port description. | ||||
|  | ||||
| =item $nap222x->bp_index() | ||||
|  | ||||
| Returns a mapping between C<ifIndex> and the Bridge Table.  This does not | ||||
| exist in the MIB and bridge port index is not the same as C<ifIndex> so it is | ||||
| created.  | ||||
|  | ||||
| =item $nap222x->i_ssidlist() | ||||
|  | ||||
| Returns reference to hash.  SSID's recognized by the radio interface. | ||||
|  | ||||
| =item $nap222x->i_ssidbcast() | ||||
|  | ||||
| Returns reference to hash.  Indicates whether the SSID is broadcast. | ||||
|  | ||||
| =item $nap222x->i_80211channel() | ||||
|  | ||||
| Returns reference to hash.  Current operating frequency channel of the radio | ||||
| interface. | ||||
|  | ||||
| =item $nap222x->i_vlan() | ||||
|  | ||||
| The default Vlan ID of the radio interfaces. | ||||
|  | ||||
| (C<ntWlanApVlanDefaultVid>) | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::SONMP | ||||
|  | ||||
| See L<SNMP::Info::SONMP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::IEEE802dot11 | ||||
|  | ||||
| See L<SNMP::Info::IEEE802dot11/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										1299
									
								
								lib/SNMP/Info/Layer2/NWSS2300.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1299
									
								
								lib/SNMP/Info/Layer2/NWSS2300.pm
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										286
									
								
								lib/SNMP/Info/Layer2/Netgear.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								lib/SNMP/Info/Layer2/Netgear.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,286 @@ | ||||
| # SNMP::Info::Layer2::Netgear | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008 Bill Fenner | ||||
| # 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::Netgear; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2; | ||||
| use SNMP::Info::LLDP; | ||||
|  | ||||
| @SNMP::Info::Layer2::Netgear::ISA       = qw/SNMP::Info::LLDP SNMP::Info::Layer2 Exporter/; | ||||
| @SNMP::Info::Layer2::Netgear::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| # This will be filled in with the device's index into the EntPhysicalEntry | ||||
| # table by the serial() function. | ||||
| our $index = undef; | ||||
|  | ||||
| %MIBS = ( %SNMP::Info::Layer2::MIBS, %SNMP::Info::LLDP::MIBS, ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::LLDP::GLOBALS, | ||||
|     ng_fsosver   => '.1.3.6.1.4.1.4526.11.11.1.0', | ||||
|     ng_gsmserial => '.1.3.6.1.4.1.4526.10.1.1.1.4.0', | ||||
|     ng_gsmosver  => '.1.3.6.1.4.1.4526.10.1.1.1.13.0', | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( %SNMP::Info::Layer2::FUNCS, %SNMP::Info::LLDP::FUNCS, ); | ||||
|  | ||||
| %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::LLDP::MUNGE, ); | ||||
|  | ||||
| sub vendor { | ||||
|     return 'netgear'; | ||||
| } | ||||
|  | ||||
| sub os { | ||||
|     return 'netgear'; | ||||
| } | ||||
|  | ||||
| # We will attempt to use Entity-MIB if present.  In that case, we will | ||||
| # also set the shared variable $index, which is used by other functions | ||||
| # to index within Entity-MIB tables. This assumes, of course, that there | ||||
| # is only one serial number (entPhysicalSerialNum) present in the table. | ||||
| sub serial { | ||||
|     my $netgear = shift; | ||||
|     my $serial = undef; | ||||
|      | ||||
|     my $e_serial = $netgear->e_serial(); | ||||
|     if (defined($e_serial)) { # This unit sports the Entity-MIB | ||||
|         # Find entity table entry for this unit | ||||
|         foreach my $e ( keys %$e_serial ) { | ||||
|             if (defined ($e_serial->{$e}) and $e_serial->{$e} !~ /^\s*$/) { | ||||
|                 $index = $e; | ||||
|                 last; | ||||
|             } | ||||
|         } | ||||
|         return $e_serial->{$index} if defined $index; | ||||
|     } | ||||
|  | ||||
|     # Without Enitity-MIB, we've got to work our way through a bunch of | ||||
|     # different locales... | ||||
|     return $netgear->ng_gsmserial() if defined $netgear->model and $netgear->model =~ m/GSM\d/i;; | ||||
|     return 'none'; | ||||
| } | ||||
|  | ||||
| # If device supports Entity-MIB, index into that to divine model and | ||||
| # hardware version, otherwise default to sysDescr. | ||||
| sub model { | ||||
|     my $netgear = shift; | ||||
|     if (defined($index)) { | ||||
|         my $model   = $netgear->e_descr(); | ||||
|         my $e_hwver = $netgear->e_hwver(); | ||||
|  | ||||
|         $model = "$model->{$index} $e_hwver->{$index}"; | ||||
|         return $model; | ||||
|     } | ||||
|     return $netgear->description(); | ||||
| } | ||||
|  | ||||
| # ifDescr is the same for all interfaces in a class, but the ifName is | ||||
| # unique, so let's use that for port name.  If all else fails,  | ||||
| # concatentate ifDesc and ifIndex. | ||||
| sub interfaces { | ||||
|     my $netgear = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $interfaces = $netgear->i_index($partial)       || {}; | ||||
|     my $i_descr    = $netgear->i_description($partial) || {}; | ||||
|     my $i_name     = $netgear->i_name($partial); | ||||
|     my $i_isset    = (); | ||||
|     # Replace the description with the ifName field, if set | ||||
|     foreach my $iid ( keys %$i_name ) { | ||||
|         my $name = $i_name->{$iid}; | ||||
|         next unless defined $name; | ||||
|         if (defined $name and $name !~ /^\s*$/) { | ||||
|             $interfaces->{$iid} = $name; | ||||
|             $i_isset->{$iid} = 1; | ||||
|         } | ||||
|     } | ||||
|     # Replace the Index with the ifDescr field, appended with index | ||||
|     # number, to deal with devices with non-unique ifDescr. | ||||
|     foreach my $iid ( keys %$i_descr ) { | ||||
|         my $port = $i_descr->{$iid} . '-' . $iid; | ||||
|         next unless defined $port; | ||||
|         next if (defined $i_isset->{$iid} and $i_isset->{$iid} == 1); | ||||
|         $interfaces->{$iid} = $port; | ||||
|     } | ||||
|  | ||||
|     return $interfaces; | ||||
| } | ||||
|  | ||||
| # these seem to work for GSM models but not GS | ||||
| # https://sourceforge.net/tracker/?func=detail&aid=3085413&group_id=70362&atid=527529 | ||||
| sub os_ver { | ||||
|     my $netgear = shift; | ||||
|     my $serial  = $netgear->serial(); # Make sure that index gets primed | ||||
|     if (defined($index)) { | ||||
|         my $os_ver  = $netgear->e_swver(); | ||||
|         return $os_ver->{$index} if defined $os_ver; | ||||
|     } | ||||
|     return $netgear->ng_gsmosver() if defined  $netgear->model and $netgear->model =~ m/GSM\d/i; | ||||
|     return $netgear->ng_fsosver() if defined  $netgear->model and $netgear->model =~ m/FS\d/i; | ||||
| } | ||||
|  | ||||
| 1; | ||||
|  | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Netgear - SNMP Interface to Netgear switches | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
|  Bill Fenner and Zoltan Erszenyi,  | ||||
|  Hacked in LLDP support from Baystack.pm by  | ||||
|  Nic Bernstein <nic@onlight.com> | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $netgear = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $netgear->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from a  | ||||
| Netgear device through SNMP. See inherited classes' documentation for  | ||||
| inherited methods. | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
| =item SNMP::Info::Entity | ||||
| =item SNMP::Info::LLDP | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item Inherited Classes' MIBs | ||||
|  | ||||
| MIBs listed in L<SNMP::Info::Layer2/"Required MIBs"> and its inherited | ||||
| classes. | ||||
|  | ||||
| See L<SNMP::Info::Entity/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::LLDP/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $netgear->vendor() | ||||
|  | ||||
| Returns 'netgear' | ||||
|  | ||||
| =item $netgear->os() | ||||
|  | ||||
| Returns 'netgear'  | ||||
|  | ||||
| =item $netgear->model() | ||||
|  | ||||
| Returns concatenation of $e_model and $e_hwver if Entity MIB present,  | ||||
| otherwise returns description() | ||||
|  | ||||
| =item $netgear->os_ver() | ||||
|  | ||||
| Returns OS Version. | ||||
|  | ||||
| =item $netgear->serial() | ||||
|  | ||||
| Returns Serial Number if available (older FS switches have no accessible | ||||
| serial number). | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals imported from SNMP::Info::Entity | ||||
|  | ||||
| See documentation in L<SNMP::Info::Entity/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Globals 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 $netgear->interfaces() | ||||
|  | ||||
| Uses the i_name() field. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Entity | ||||
|  | ||||
| See documentation in L<SNMP::Info::Entity/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::LLDP | ||||
|  | ||||
| See documentation in L<SNMP::Info::LLDP/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										312
									
								
								lib/SNMP/Info/Layer2/Orinoco.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								lib/SNMP/Info/Layer2/Orinoco.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,312 @@ | ||||
| # SNMP::Info::Layer2::Orinoco | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008 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::Layer2::Orinoco; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::IEEE802dot11; | ||||
| use SNMP::Info::Layer2; | ||||
|  | ||||
| @SNMP::Info::Layer2::Orinoco::ISA | ||||
|     = qw/SNMP::Info::IEEE802dot11 SNMP::Info::Layer2 Exporter/; | ||||
| @SNMP::Info::Layer2::Orinoco::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     %SNMP::Info::IEEE802dot11::MIBS, | ||||
|  | ||||
|     #'ORiNOCO-MIB' => 'orinoco', | ||||
| ); | ||||
|  | ||||
| %GLOBALS | ||||
|     = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::IEEE802dot11::GLOBALS, ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     %SNMP::Info::IEEE802dot11::FUNCS, | ||||
|  | ||||
|     # ORiNOCO-MIB:oriWirelessIfPropertiesTable | ||||
|     #'ori_ssid'       => 'oriWirelessIfNetworkName', | ||||
|     #'ori_channel'    => 'oriWirelessIfChannel', | ||||
|     #'ori_closed_sys' => 'oriWirelessIfClosedSystem', | ||||
|     # ORiNOCO-MIB:oriSystemInvMgmtComponentTable | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::IEEE802dot11::MUNGE, ); | ||||
|  | ||||
| sub os { | ||||
|     return 'orinoco'; | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|     my $orinoco = shift; | ||||
|  | ||||
|     my $descr = $orinoco->description(); | ||||
|     return unless defined $descr; | ||||
|  | ||||
|     if ( $descr =~ m/V(\d+\.\d+)/ ) { | ||||
|         return $1; | ||||
|     } | ||||
|     if ( $descr =~ m/v(\d+\.\d+\.\d+)/ ) { | ||||
|         return $1; | ||||
|     } | ||||
|  | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub os_bin { | ||||
|     my $orinoco = shift; | ||||
|  | ||||
|     my $descr = $orinoco->description(); | ||||
|     return unless defined $descr; | ||||
|  | ||||
|     if ( $descr =~ m/V(\d+\.\d+)$/ ) { | ||||
|         return $1; | ||||
|     } | ||||
|     if ( $descr =~ m/v(\d+\.\d+\.\d+)$/ ) { | ||||
|         return $1; | ||||
|     } | ||||
|  | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'proxim'; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $orinoco = shift; | ||||
|  | ||||
|     my $descr = $orinoco->description(); | ||||
|     return unless defined $descr; | ||||
|  | ||||
|     return $1             if ( $descr =~ /(AP-\d+)/ ); | ||||
|     return 'WavePOINT-II' if ( $descr =~ /WavePOINT-II/ ); | ||||
|     return 'Outdoor Router' if ( $descr =~ /Wireless Router/ ); | ||||
|  | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub serial { | ||||
|     my $orinoco = shift; | ||||
|  | ||||
|     my $descr = $orinoco->description(); | ||||
|     return unless defined $descr; | ||||
|  | ||||
|     $descr = $1 if $descr =~ /SN-(\S+)/; | ||||
|     return $descr; | ||||
| } | ||||
|  | ||||
| sub i_ignore { | ||||
|     my $orinoco = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $descr = $orinoco->i_description($partial) || {}; | ||||
|  | ||||
|     my %i_ignore; | ||||
|     foreach my $if ( keys %$descr ) { | ||||
|         my $type = $descr->{$if}; | ||||
|  | ||||
|         # Skip virtual interfaces | ||||
|         $i_ignore{$if}++ if $type =~ /(lo|empty|PCMCIA)/i; | ||||
|     } | ||||
|     return \%i_ignore; | ||||
| } | ||||
|  | ||||
| sub interfaces { | ||||
|     my $orinoco = shift; | ||||
|     my $partial = shift; | ||||
|  | ||||
|     my $interfaces   = $orinoco->i_index($partial)       || {}; | ||||
|     my $descriptions = $orinoco->i_description($partial) || {}; | ||||
|  | ||||
|     my %interfaces = (); | ||||
|     foreach my $iid ( keys %$interfaces ) { | ||||
|         my $desc = $descriptions->{$iid}; | ||||
|         next unless defined $desc; | ||||
|         next if $desc =~ /(lo|empty|PCMCIA)/i; | ||||
|  | ||||
|         $desc = 'AMD' if $desc =~ /AMD/; | ||||
|  | ||||
|         $interfaces{$iid} = $desc; | ||||
|     } | ||||
|     return \%interfaces; | ||||
| } | ||||
|  | ||||
| #sub i_ssidbcast { | ||||
| #    my $orinoco = shift; | ||||
| #    my $partial = shift; | ||||
| # | ||||
| #    my $bcast = $orinoco->ori_closed_sys($partial) || {}; | ||||
| # | ||||
| #    my %i_ssidbcast; | ||||
| #    foreach my $iid (keys %$bcast){ | ||||
| #        my $bc   = $bcast->{$iid}; | ||||
| #        next unless defined $bc; | ||||
| # | ||||
| #        $i_ssidbcast{$iid} = $bc; | ||||
| #    } | ||||
| #    return \%i_ssidbcast; | ||||
| #} | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Orinoco - SNMP Interface to Orinoco Series Access Points | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Eric Miller | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $orinoco = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class = $orinoco->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from | ||||
| Orinoco Access Point through SNMP.  Orinoco devices have been manufactured | ||||
| by Proxim, Agere, and Lucent. | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
|  my $orinoco = new SNMP::Info::Layer2::Orinoco(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =item SNMP::Info::IEEE802dot11 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| None. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Inherited MIBs | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::IEEE802dot11/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $orinoco->vendor() | ||||
|  | ||||
| Returns 'proxim' | ||||
|  | ||||
| =item $orinoco->model() | ||||
|  | ||||
| Returns the model extracted from C<sysDescr>. | ||||
|  | ||||
| =item $orinoco->os() | ||||
|  | ||||
| Returns 'Orinoco' | ||||
|  | ||||
| =item $orinoco->os_ver() | ||||
|  | ||||
| Returns the software version extracted from C<sysDescr>. | ||||
|  | ||||
| =item $orinoco->os_bin() | ||||
|  | ||||
| Returns the firmware version extracted from C<sysDescr>. | ||||
|  | ||||
| =item $orinoco->serial() | ||||
|  | ||||
| Returns the serial number extracted from C<sysDescr>. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::IEEE802dot11 | ||||
|  | ||||
| See L<SNMP::Info::IEEE802dot11/"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 $orinoco->interfaces() | ||||
|  | ||||
| Returns reference to map of IIDs to physical ports.  | ||||
|  | ||||
| =item $orinoco->i_ignore() | ||||
|  | ||||
| Returns reference to hash of IIDs to ignore. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::IEEE802dot11 | ||||
|  | ||||
| See L<SNMP::Info::IEEE802dot11/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										1303
									
								
								lib/SNMP/Info/Layer2/Trapeze.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1303
									
								
								lib/SNMP/Info/Layer2/Trapeze.pm
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										177
									
								
								lib/SNMP/Info/Layer2/Ubiquiti.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								lib/SNMP/Info/Layer2/Ubiquiti.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | ||||
| # SNMP::Info::Layer2::Ubiquiti | ||||
| # $Id$ | ||||
| # | ||||
|  | ||||
| package SNMP::Info::Layer2::Ubiquiti; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::IEEE802dot11; | ||||
| use SNMP::Info::Layer2; | ||||
|  | ||||
| @SNMP::Info::Layer2::Ubiquiti::ISA | ||||
|     = qw/SNMP::Info::IEEE802dot11 SNMP::Info::Layer2 Exporter/; | ||||
| @SNMP::Info::Layer2::Ubiquiti::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     %SNMP::Info::IEEE802dot11::MIBS, | ||||
|  | ||||
| ); | ||||
|  | ||||
| %GLOBALS | ||||
|     = ( %SNMP::Info::Layer2::GLOBALS, %SNMP::Info::IEEE802dot11::GLOBALS, ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     %SNMP::Info::IEEE802dot11::FUNCS, | ||||
|  | ||||
| ); | ||||
|  | ||||
| %MUNGE = ( %SNMP::Info::Layer2::MUNGE, %SNMP::Info::IEEE802dot11::MUNGE, ); | ||||
|  | ||||
| sub os { | ||||
|     return 'Ubiquiti'; | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|     my $dot11 = shift; | ||||
|  | ||||
|     my $versions = $dot11->dot11_prod_ver(); | ||||
|  | ||||
|     foreach my $iid ( keys %$versions ) { | ||||
|         my $ver = $versions->{$iid}; | ||||
|         next unless defined $ver; | ||||
| 	return $ver; | ||||
|         if ( $ver =~ /([\d\.]+)/ ) { | ||||
|             return $1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'Ubiquiti Networks, Inc.'; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $dot11 = shift; | ||||
|  | ||||
|     my $names = $dot11->dot11_prod_name(); | ||||
|  | ||||
|     foreach my $iid ( keys %$names ) { | ||||
|         my $prod = $names->{$iid}; | ||||
|         next unless defined $prod; | ||||
|         return $prod; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
|  | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Ubiquiti - SNMP Interface to Ubiquiti Access Points | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Max Kosmach | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $ubnt = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class = $ubnt->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from | ||||
| Ubiquiti Access Point through SNMP. | ||||
|  | ||||
| For speed or debugging purposes you can call the subclass directly, but not | ||||
| after determining a more specific class using the method above.  | ||||
|  | ||||
|  my $ubnt = new SNMP::Info::Layer2::Ubiquiti(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =item SNMP::Info::IEEE802dot11 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| None. | ||||
|  | ||||
| =head2 Inherited MIBs | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| See L<SNMP::Info::IEEE802dot11/"Required MIBs"> for its MIB requirements. | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $ubnt->vendor() | ||||
|  | ||||
| Returns 'Ubiquiti Networks, Inc.' | ||||
|  | ||||
| =item $ubnt->model() | ||||
|  | ||||
| Returns the model extracted from C<dot11manufacturerProductName>. | ||||
|  | ||||
| =item $ubnt->os() | ||||
|  | ||||
| Returns 'Ubiquiti' | ||||
|  | ||||
| =item $ubnt->os_ver() | ||||
|  | ||||
| Returns the software version extracted from C<dot11manufacturerProductVersion>. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::IEEE802dot11 | ||||
|  | ||||
| See L<SNMP::Info::IEEE802dot11/"GLOBALS"> for details. | ||||
|  | ||||
| =head1 TABLE METHODS | ||||
|  | ||||
| These are methods that return tables of information in the form of a reference | ||||
| to a hash. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::IEEE802dot11 | ||||
|  | ||||
| See L<SNMP::Info::IEEE802dot11/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										225
									
								
								lib/SNMP/Info/Layer2/ZyXEL_DSLAM.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								lib/SNMP/Info/Layer2/ZyXEL_DSLAM.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,225 @@ | ||||
| # SNMP::Info::Layer2::ZyXEL_DSLAM | ||||
| # $Id$ | ||||
| # | ||||
| # Copyright (c) 2008 Max Baker | ||||
| # 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::ZyXEL_DSLAM; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2; | ||||
|  | ||||
| @SNMP::Info::Layer2::ZyXEL_DSLAM::ISA       = qw/SNMP::Info::Layer2 Exporter/; | ||||
| @SNMP::Info::Layer2::ZyXEL_DSLAM::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.35'; | ||||
|  | ||||
| # Set for No CDP | ||||
| %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|     'ip_adresses'   => 'ipAdEntAddr', | ||||
|     'i_name'        => 'ifDescr', | ||||
|     'i_description' => 'adslLineConfProfile', | ||||
| ); | ||||
|  | ||||
| %MIBS | ||||
|     = ( %SNMP::Info::Layer2::MIBS, 'ADSL-LINE-MIB' => 'adslLineConfProfile' ); | ||||
|  | ||||
| %MUNGE = ( %SNMP::Info::Layer2::MUNGE ); | ||||
|  | ||||
| sub layers { | ||||
|     my $zyxel  = shift; | ||||
|     my $layers = $zyxel->layers(); | ||||
|     return $layers if defined $layers; | ||||
|  | ||||
|     # If these don't claim to have any layers, so we'll give them 1+2 | ||||
|     return '00000011'; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'zyxel'; | ||||
| } | ||||
|  | ||||
| sub os { | ||||
|     return 'zyxel'; | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|     my $zyxel = shift; | ||||
|     my $descr = $zyxel->description(); | ||||
|  | ||||
|     if ( $descr =~ m/version (\S+) / ) { | ||||
|         return $1; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $zyxel = shift; | ||||
|  | ||||
|     my $desc = $zyxel->description(); | ||||
|  | ||||
|     if ( $desc =~ /8-port ADSL Module\(Annex A\)/ ) { | ||||
|         return "AAM1008-61"; | ||||
|     } | ||||
|     elsif ( $desc =~ /8-port ADSL Module\(Annex B\)/ ) { | ||||
|         return "AAM1008-63"; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub ip { | ||||
|     my $zyxel   = shift; | ||||
|     my $ip_hash = $zyxel->ip_addresses(); | ||||
|     my $found_ip; | ||||
|  | ||||
|     foreach my $ip ( keys %{$ip_hash} ) { | ||||
|         $found_ip = $ip | ||||
|             if ( defined $ip | ||||
|             and $ip =~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ ); | ||||
|     } | ||||
|     return $found_ip; | ||||
| } | ||||
| 1; | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::ZyXEL_DSLAM - SNMP Interface to ZyXEL DSLAM | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Dmitry Sergienko (C<dmitry@trifle.net>) | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $zyxel = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myhub', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 1 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class      = $l2->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from a  | ||||
| ZyXEL device through SNMP. See inherited classes' documentation for  | ||||
| inherited methods. | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<ADSL-LINE-MIB> | ||||
|  | ||||
| =item Inherited Classes | ||||
|  | ||||
| MIBs listed in L<SNMP::Info::Layer2/"Required MIBs"> and their inherited | ||||
| classes. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head1 GLOBALS | ||||
|  | ||||
| These are methods that return scalar value from SNMP | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $zyxel->vendor() | ||||
|  | ||||
| Returns 'ZyXEL' :) | ||||
|  | ||||
| =item $zyxel->os() | ||||
|  | ||||
| Returns 'ZyXEL'  | ||||
|  | ||||
| =item $zyxel->os_ver() | ||||
|  | ||||
| Culls Version from description() | ||||
|  | ||||
| =item $zyxel->ip() | ||||
|  | ||||
| Returns IP Address of DSLAM. | ||||
|  | ||||
| (C<ipAdEntAddr>) | ||||
|  | ||||
| =item $zyxel->model() | ||||
|  | ||||
| Tries to cull out model out of the description field. | ||||
|  | ||||
| =item $zyxel->layers() | ||||
|  | ||||
| Returns 00000011. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Global Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"GLOBALS"> for details. | ||||
|  | ||||
| =head1 TABLE METHODS | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $zyxel->i_name() | ||||
|  | ||||
| Returns reference to map of IIDs to port name (C<ifDescr>). | ||||
|  | ||||
| =item $zyxel->i_description() | ||||
|  | ||||
| Returns reference to map of IIDs to human-set port description (profile name). | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
		Reference in New Issue
	
	Block a user