#202 Support for Aerohive access points
This commit is contained in:
		
							
								
								
									
										4
									
								
								Changes
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Changes
									
									
									
									
									
								
							| @@ -1,5 +1,9 @@ | ||||
| Version 3.58 | ||||
|  | ||||
|   [NEW FEATURES] | ||||
|  | ||||
|   * #202 Support for Aerohive access points | ||||
|  | ||||
|   [ENHANCEMENTS] | ||||
|  | ||||
|   * Add fan and power supply status to L3::Huawei | ||||
|   | ||||
							
								
								
									
										3
									
								
								MANIFEST
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								MANIFEST
									
									
									
									
									
								
							| @@ -1,3 +1,4 @@ | ||||
| .perltidyrc | ||||
| Build.PL | ||||
| Changes | ||||
| contrib/DEVELOP | ||||
| @@ -41,6 +42,7 @@ lib/SNMP/Info/Layer1/S3000.pm | ||||
| lib/SNMP/Info/Layer2.pm | ||||
| lib/SNMP/Info/Layer2/3Com.pm | ||||
| lib/SNMP/Info/Layer2/Adtran.pm | ||||
| lib/SNMP/Info/Layer2/Aerohive.pm | ||||
| lib/SNMP/Info/Layer2/Airespace.pm | ||||
| lib/SNMP/Info/Layer2/Aironet.pm | ||||
| lib/SNMP/Info/Layer2/Allied.pm | ||||
| @@ -181,6 +183,7 @@ xt/lib/Test/SNMP/Info/Layer1/Cyclades.pm | ||||
| xt/lib/Test/SNMP/Info/Layer1/S3000.pm | ||||
| xt/lib/Test/SNMP/Info/Layer2.pm | ||||
| xt/lib/Test/SNMP/Info/Layer2/3Com.pm | ||||
| xt/lib/Test/SNMP/Info/Layer2/Aerohive.pm | ||||
| xt/lib/Test/SNMP/Info/Layer2/Airespace.pm | ||||
| xt/lib/Test/SNMP/Info/Layer2/Aironet.pm | ||||
| xt/lib/Test/SNMP/Info/Layer2/Allied.pm | ||||
|   | ||||
| @@ -507,6 +507,12 @@ Subclass for Adtran devices. | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2::Adtran> for details. | ||||
|  | ||||
| =item SNMP::Info::Layer2::Aerohive | ||||
|  | ||||
| Subclass for Aerohive Access Points. | ||||
|  | ||||
| See documentation in L<SNMP::Info::Layer2::Aerohive> for details. | ||||
|  | ||||
| =item SNMP::Info::Layer2::Airespace | ||||
|  | ||||
| Subclass for Cisco (Airespace) wireless controllers. | ||||
| @@ -1629,6 +1635,7 @@ sub device_type { | ||||
|         35098 => 'SNMP::Info::Layer3::Pica8', | ||||
|         41112 => 'SNMP::Info::Layer2::Ubiquiti', | ||||
|         4413 => 'SNMP::Info::Layer2::Ubiquiti', | ||||
|         26928 => 'SNMP::Info::Layer2::Aerohive', | ||||
|         30803 => 'SNMP::Info::Layer3::VyOS', | ||||
|         40310 => 'SNMP::Info::Layer3::Cumulus', | ||||
|     ); | ||||
| @@ -1663,6 +1670,7 @@ sub device_type { | ||||
|         17163 => 'SNMP::Info::Layer3::Steelhead', | ||||
|         20540 => 'SNMP::Info::Layer2::Sixnet', | ||||
|         26543 => 'SNMP::Info::Layer3::IBMGbTor', | ||||
|         26928 => 'SNMP::Info::Layer2::Aerohive', | ||||
|     ); | ||||
|  | ||||
|     my %l1sysoidmap = ( | ||||
|   | ||||
							
								
								
									
										472
									
								
								lib/SNMP/Info/Layer2/Aerohive.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										472
									
								
								lib/SNMP/Info/Layer2/Aerohive.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,472 @@ | ||||
| # SNMP::Info::Layer2::Aerohive | ||||
| # | ||||
| # Copyright (c) 2018 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::Aerohive; | ||||
|  | ||||
| use strict; | ||||
| use Exporter; | ||||
| use SNMP::Info::Layer2; | ||||
|  | ||||
| @SNMP::Info::Layer2::Aerohive::ISA       = qw/SNMP::Info::Layer2 Exporter/; | ||||
| @SNMP::Info::Layer2::Aerohive::EXPORT_OK = qw//; | ||||
|  | ||||
| use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/; | ||||
|  | ||||
| $VERSION = '3.57'; | ||||
|  | ||||
| %MIBS = ( | ||||
|     %SNMP::Info::Layer2::MIBS, | ||||
|     'AH-SYSTEM-MIB'    => 'ahSystemSerial', | ||||
|     'AH-INTERFACE-MIB' => 'ahSSIDName', | ||||
| ); | ||||
|  | ||||
| %GLOBALS = ( | ||||
|     %SNMP::Info::Layer2::GLOBALS, | ||||
|  | ||||
|     # AH-SYSTEM-MIB | ||||
|     'serial' => 'ahSystemSerial', | ||||
|     'os_bin' => 'ahFirmwareVersion', | ||||
| ); | ||||
|  | ||||
| %FUNCS = ( | ||||
|     %SNMP::Info::Layer2::FUNCS, | ||||
|  | ||||
|     # AH-INTERFACE-MIB::ahRadioAttributeTable | ||||
|     'i_80211channel'      => 'ahRadioChannel', | ||||
|     'dot11_cur_tx_pwr_mw' => 'ahRadioTxPower', | ||||
|  | ||||
|     # AH-INTERFACE-MIB::ahXIfTable | ||||
|     'ah_i_ssidlist' => 'ahSSIDName', | ||||
|  | ||||
|     # AH-INTERFACE-MIB::ahAssociationTable | ||||
|     'cd11_txrate'      => 'ahClientLastTxRate', | ||||
|     'cd11_uptime'      => 'ahClientLinkUptime', | ||||
|     'cd11_sigstrength' => 'ahClientRSSI', | ||||
|     'cd11_rxpkt'       => 'ahClientRxDataFrames', | ||||
|     'cd11_txpkt'       => 'ahClientTxDataFrames', | ||||
|     'cd11_rxbyte'      => 'ahClientRxDataOctets', | ||||
|     'cd11_txbyte'      => 'ahClientTxDataOctets', | ||||
|     'cd11_ssid'        => 'ahClientSSID', | ||||
|     'ah_c_vlan'        => 'ahClientVLAN', | ||||
|     'ah_c_ip'          => 'ahClientIP', | ||||
| ); | ||||
|  | ||||
| %MUNGE | ||||
|     = ( %SNMP::Info::Layer2::MUNGE, 'at_paddr' => \&SNMP::Info::munge_mac, ); | ||||
|  | ||||
| sub layers { | ||||
|     return '00000111'; | ||||
| } | ||||
|  | ||||
| sub vendor { | ||||
|     return 'aerohive'; | ||||
| } | ||||
|  | ||||
| sub os { | ||||
|     return 'hiveos'; | ||||
| } | ||||
|  | ||||
| sub os_ver { | ||||
|     my $aerohive = shift; | ||||
|     my $descr    = $aerohive->description(); | ||||
|  | ||||
|     if ( $descr =~ m/\bHiveOS\s(\d\.\w+)\b/ix ) { | ||||
|         return $1; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub model { | ||||
|     my $aerohive = shift; | ||||
|     my $descr    = $aerohive->description(); | ||||
|  | ||||
|     if ( $descr =~ m/\bHive(AP\d+)\b/ix ) { | ||||
|         return $1; | ||||
|     } | ||||
|     return; | ||||
| } | ||||
|  | ||||
| sub i_ssidlist { | ||||
|     my $aerohive = shift; | ||||
|     my $partial  = shift; | ||||
|  | ||||
|     my $ssids = $aerohive->ah_i_ssidlist($partial) || {}; | ||||
|  | ||||
|     my %i_ssidlist; | ||||
|     foreach my $iid ( keys %$ssids ) { | ||||
|         my $ssid = $ssids->{$iid}; | ||||
|         next if $ssid =~ /N\/A/i; | ||||
|  | ||||
|         $i_ssidlist{$iid} = $ssid; | ||||
|     } | ||||
|     return \%i_ssidlist; | ||||
| } | ||||
|  | ||||
| sub i_ssidmac { | ||||
|     my $aerohive = shift; | ||||
|     my $partial  = shift; | ||||
|  | ||||
|     my $ssids = $aerohive->i_ssidlist($partial) || {}; | ||||
|     my $macs  = $aerohive->i_mac($partial)      || {}; | ||||
|  | ||||
|     my %i_ssidmac; | ||||
|     foreach my $iid ( keys %$ssids ) { | ||||
|         my $mac = $macs->{$iid}; | ||||
|         next unless $mac; | ||||
|  | ||||
|         $i_ssidmac{$iid} = $mac; | ||||
|     } | ||||
|     return \%i_ssidmac; | ||||
| } | ||||
|  | ||||
| # Break up the ahAssociationEntry INDEX into ifIndex and MAC Address. | ||||
| sub _ah_association_index { | ||||
|     my $idx     = shift; | ||||
|     my @values  = split( /\./, $idx ); | ||||
|     my $ifindex = shift(@values); | ||||
|     my $length  = shift(@values); | ||||
|     return ( $ifindex, join( ':', map { sprintf "%02x", $_ } @values ) ); | ||||
| } | ||||
|  | ||||
| sub cd11_port { | ||||
|     my $aerohive = shift; | ||||
|  | ||||
|     my $cd11_txrate = $aerohive->cd11_txrate(); | ||||
|     my $interfaces  = $aerohive->interfaces(); | ||||
|  | ||||
|     my %ret; | ||||
|     foreach ( keys %$cd11_txrate ) { | ||||
|         my ( $ifindex, $mac ) = _ah_association_index($_); | ||||
|         $ret{$_} = $interfaces->{$ifindex}; | ||||
|     } | ||||
|     return \%ret; | ||||
| } | ||||
|  | ||||
| sub cd11_mac { | ||||
|     my $aerohive = shift; | ||||
|  | ||||
|     my $cd11_txrate = $aerohive->cd11_txrate(); | ||||
|  | ||||
|     my %ret; | ||||
|     foreach ( keys %$cd11_txrate ) { | ||||
|         my ( $ifindex, $mac ) = _ah_association_index($_); | ||||
|         $ret{$_} = $mac; | ||||
|     } | ||||
|     return \%ret; | ||||
| } | ||||
|  | ||||
| # Does not support the standard Bridge MIB | ||||
| sub bp_index { | ||||
|     my $aerohive = shift; | ||||
|     my $partial  = shift; | ||||
|  | ||||
|     my $i_index = $aerohive->i_index($partial) || {}; | ||||
|  | ||||
|     my %bp_index; | ||||
|     foreach my $iid ( keys %$i_index ) { | ||||
|         my $index = $i_index->{$iid}; | ||||
|         next unless defined $index; | ||||
|  | ||||
|         $bp_index{$index} = $iid; | ||||
|     } | ||||
|  | ||||
|     return \%bp_index; | ||||
| } | ||||
|  | ||||
| sub qb_fw_port { | ||||
|     my $aerohive = shift; | ||||
|     my $partial  = shift; | ||||
|  | ||||
|     my $txrate = $aerohive->cd11_txrate($partial) || {}; | ||||
|  | ||||
|     my $qb_fw_port = {}; | ||||
|     foreach my $idx ( keys %$txrate ) { | ||||
|         my ( $fdb_id, $mac ) = _ah_association_index($idx); | ||||
|         $qb_fw_port->{$idx} = $fdb_id; | ||||
|     } | ||||
|     return $qb_fw_port; | ||||
| } | ||||
|  | ||||
| sub qb_fw_mac { | ||||
|     my $aerohive = shift; | ||||
|     my $partial  = shift; | ||||
|  | ||||
|     my $txrate = $aerohive->cd11_txrate($partial) || {}; | ||||
|  | ||||
|     my $qb_fw_mac = {}; | ||||
|     foreach my $idx ( keys %$txrate ) { | ||||
|         my ( $fdb_id, $mac ) = _ah_association_index($idx); | ||||
|         $qb_fw_mac->{$idx} = $mac; | ||||
|     } | ||||
|     return $qb_fw_mac; | ||||
| } | ||||
|  | ||||
| sub qb_fw_vlan { | ||||
|     my $aerohive = shift; | ||||
|     my $partial  = shift; | ||||
|  | ||||
|     my $vlans = $aerohive->ah_c_vlan($partial) || {}; | ||||
|  | ||||
|     my $qb_fw_vlan = {}; | ||||
|     foreach my $idx ( keys %$vlans ) { | ||||
|         my $vlan = $vlans->{$idx}; | ||||
|         next unless defined $vlan; | ||||
|         $qb_fw_vlan->{$idx} = $vlan; | ||||
|     } | ||||
|     return $qb_fw_vlan; | ||||
| } | ||||
|  | ||||
| # arpnip: | ||||
| # | ||||
| # This is the AP snooping on the MAC->IP mappings. | ||||
| # Pretending this is arpnip data allows us to get MAC->IP | ||||
| # mappings even for stations that only communicate locally. | ||||
|  | ||||
| sub at_paddr { | ||||
|     my $aerohive = shift; | ||||
|  | ||||
|     my $txrate = $aerohive->cd11_txrate() || {}; | ||||
|  | ||||
|     my $at_paddr = {}; | ||||
|     foreach my $idx ( keys %$txrate ) { | ||||
|         my ( $fdb_id, $mac ) = _ah_association_index($idx); | ||||
|         $at_paddr->{$idx} = $mac; | ||||
|     } | ||||
|     return $at_paddr; | ||||
| } | ||||
|  | ||||
| sub at_netaddr { | ||||
|     my $aerohive = shift; | ||||
|  | ||||
|     my $ips = $aerohive->ah_c_ip() || {}; | ||||
|  | ||||
|     my $ret = {}; | ||||
|     foreach my $idx ( keys %$ips ) { | ||||
|         next if ( $ips->{$idx} eq '0.0.0.0' ); | ||||
|         $ret->{$idx} = $ips->{$idx}; | ||||
|     } | ||||
|     return $ret; | ||||
| } | ||||
|  | ||||
| 1; | ||||
|  | ||||
| __END__ | ||||
|  | ||||
| =head1 NAME | ||||
|  | ||||
| SNMP::Info::Layer2::Aerohive - SNMP Interface to Aerohive Access Points | ||||
|  | ||||
| =head1 AUTHOR | ||||
|  | ||||
| Eric Miller | ||||
|  | ||||
| =head1 SYNOPSIS | ||||
|  | ||||
|  # Let SNMP::Info determine the correct subclass for you.  | ||||
|  my $aerohive = new SNMP::Info( | ||||
|                           AutoSpecify => 1, | ||||
|                           Debug       => 1, | ||||
|                           DestHost    => 'myswitch', | ||||
|                           Community   => 'public', | ||||
|                           Version     => 2 | ||||
|                         )  | ||||
|     or die "Can't connect to DestHost.\n"; | ||||
|  | ||||
|  my $class = $aerohive->class(); | ||||
|  print "SNMP::Info determined this device to fall under subclass : $class\n"; | ||||
|  | ||||
| =head1 DESCRIPTION | ||||
|  | ||||
| Provides abstraction to the configuration information obtainable from an | ||||
| Aerohive wireless 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 $aerohive = new SNMP::Info::Layer2::Aerohive(...); | ||||
|  | ||||
| =head2 Inherited Classes | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item SNMP::Info::Layer2 | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Required MIBs | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item F<AH-SYSTEM-MIB> | ||||
|  | ||||
| =item F<AH-INTERFACE-MIB> | ||||
|  | ||||
| =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 | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $aerohive->vendor() | ||||
|  | ||||
| Returns 'aerohive'. | ||||
|  | ||||
| =item $aerohive->os() | ||||
|  | ||||
| Returns 'hive_os'. | ||||
|  | ||||
| =item $aerohive->os_ver() | ||||
|  | ||||
| Returns the OS versionl extracted from C<sysDescr>. | ||||
|  | ||||
| =item $aerohive->os_bin() | ||||
|  | ||||
| Returns the firmware version extracted from C<ahFirmwareVersion>. | ||||
|  | ||||
| =item $aerohive->model() | ||||
|  | ||||
| Returns the model extracted from C<sysDescr>. | ||||
|  | ||||
| =item $aerohive->serial() | ||||
|  | ||||
| Returns the serial number extracted from C<ahSystemSerial>. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $aerohive->layers() | ||||
|  | ||||
| Returns 00000111. Layer 2 and Layer 3 functionality through proprietary MIBs. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =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. | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $aerohive->i_ssidlist() | ||||
|  | ||||
| Returns reference to hash.  SSID's recognized by the radio interface. | ||||
|  | ||||
| =item $aerohive->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 $aerohive->i_80211channel() | ||||
|  | ||||
| Returns reference to hash.  Current operating frequency channel of the radio | ||||
| interface. | ||||
|  | ||||
| C<ahRadioChannel> | ||||
|  | ||||
| =item $aerohive->dot11_cur_tx_pwr_mw() | ||||
|  | ||||
| Returns reference to hash.  Current transmit power, in milliwatts, of the | ||||
| radio interface. | ||||
|  | ||||
| C<ahRadioTxPower> | ||||
|  | ||||
| =item $aironet->cd11_port() | ||||
|  | ||||
| Returns radio interfaces. | ||||
|  | ||||
| =item $aironet->cd11_mac() | ||||
|  | ||||
| Returns client radio interface MAC addresses. | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Overrides | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $aerohive->bp_index() | ||||
|  | ||||
| Simulates bridge MIB by returning reference to a hash mapping i_index() to | ||||
| the interface iid. | ||||
|  | ||||
| =item $aerohive->qb_fw_port() | ||||
|  | ||||
| Returns reference to hash of forwarding table entries port interface | ||||
| identifier (iid) | ||||
|  | ||||
| =item $aerohive->qb_fw_mac() | ||||
|  | ||||
| Returns reference to hash of forwarding table MAC Addresses | ||||
|  | ||||
| C<ahClientMac> | ||||
|  | ||||
| =item $aerohive->qb_fw_vlan() | ||||
|  | ||||
| Returns reference to hash of forwarding table entries VLAN ID | ||||
|  | ||||
| C<ahClientVLAN> | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Arp Cache Table Augmentation | ||||
|  | ||||
| The AP has knowledge of MAC->IP mappings for wireless clients. | ||||
| Augmenting the arp cache data with these MAC->IP mappings enables visibility | ||||
| for stations that only communicate locally. | ||||
|  | ||||
| =over | ||||
|  | ||||
| =item $aerohive->at_paddr() | ||||
|  | ||||
| C<ahClientMac> | ||||
|  | ||||
| =item $aerohive->at_netaddr() | ||||
|  | ||||
| C<ahClientIP> | ||||
|  | ||||
| =back | ||||
|  | ||||
| =head2 Table Methods imported from SNMP::Info::Layer2 | ||||
|  | ||||
| See L<SNMP::Info::Layer2/"TABLE METHODS"> for details. | ||||
|  | ||||
| =cut | ||||
							
								
								
									
										300
									
								
								xt/lib/Test/SNMP/Info/Layer2/Aerohive.pm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								xt/lib/Test/SNMP/Info/Layer2/Aerohive.pm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,300 @@ | ||||
| # Test::SNMP::Info::Layer2::Aerohive | ||||
| # | ||||
| # Copyright (c) 2018 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 Test::SNMP::Info::Layer2::Aerohive; | ||||
|  | ||||
| use Test::Class::Most parent => 'My::Test::Class'; | ||||
|  | ||||
| use SNMP::Info::Layer1::Allied; | ||||
|  | ||||
| sub setup : Tests(setup) { | ||||
|   my $test = shift; | ||||
|   $test->SUPER::setup; | ||||
|  | ||||
|   # Start with a common cache that will serve most tests | ||||
|   my $cache_data = { | ||||
|  | ||||
|     # Example walk had no sysServices returned | ||||
|     #'_layers'      => 1, | ||||
|     '_description' => 'HiveAP121, HiveOS 6.2r1 release build1924', | ||||
|  | ||||
|     # AH-SMI-MIB::ahProduct | ||||
|     '_id'            => '.1.3.6.1.4.1.26928.1', | ||||
|     '_i_index'       => 1, | ||||
|     '_i_description' => 1, | ||||
|     '_i_mac'         => 1, | ||||
|     '_ah_i_ssidlist' => 1, | ||||
|     '_cd11_txrate'   => 1, | ||||
|     '_ah_c_vlan'     => 1, | ||||
|     '_ah_c_ip'       => 1, | ||||
|     'store'          => { | ||||
|       'i_index' => {3 => 3, 10 => 10, 12 => 12, 15 => 15}, | ||||
|       'i_description' => | ||||
|         {3 => 'eth0', 10 => 'wifi0.1', 12 => 'wifi0.2', 15 => 'wifi1.1'}, | ||||
|       'i_mac' => { | ||||
|         3  => pack("H*", '4018B13A4C40'), | ||||
|         10 => pack("H*", '4018B13A4C54'), | ||||
|         12 => pack("H*", '4018B13A4C55'), | ||||
|         15 => pack("H*", '4018B13A4C68') | ||||
|       }, | ||||
|       'ah_i_ssidlist' => | ||||
|         {3 => 'N/A', 10 => 'MyGuest', 12 => 'MyPrivate', 15 => 'MyGuest'}, | ||||
|       'cd11_txrate' => { | ||||
|         '10.6.128.150.177.92.153.130' => 6000, | ||||
|         '15.6.40.106.186.61.150.231'  => 58500, | ||||
|         '15.6.96.190.181.42.99.151'   => 72200 | ||||
|       }, | ||||
|       'ah_c_vlan' => { | ||||
|         '10.6.128.150.177.92.153.130' => 50, | ||||
|         '15.6.40.106.186.61.150.231'  => 1, | ||||
|         '15.6.96.190.181.42.99.151'   => 1 | ||||
|       }, | ||||
|       'ah_c_ip' => { | ||||
|         '10.6.128.150.177.92.153.130' => '1.2.3.4', | ||||
|         '15.6.40.106.186.61.150.231'  => '0.0.0.0', | ||||
|         '15.6.96.190.181.42.99.151'   => '4.3.2.1' | ||||
|       }, | ||||
|     } | ||||
|   }; | ||||
|   $test->{info}->cache($cache_data); | ||||
| } | ||||
|  | ||||
| sub layers : Tests(2) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'layers'); | ||||
|   is($test->{info}->layers(), '00000111', q(Vendor returns '00000011')); | ||||
| } | ||||
|  | ||||
| sub vendor : Tests(2) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'vendor'); | ||||
|   is($test->{info}->vendor(), 'aerohive', q(Vendor returns 'aerohive')); | ||||
| } | ||||
|  | ||||
| sub os : Tests(2) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'os'); | ||||
|   is($test->{info}->os(), 'hiveos', q(OS returns 'hiveos')); | ||||
| } | ||||
|  | ||||
| sub os_ver : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'os_ver'); | ||||
|   is($test->{info}->os_ver(), '6.2r1', q(OS version is expected value)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   is($test->{info}->os_ver(), undef, q(No description returns undef os_ver)); | ||||
| } | ||||
|  | ||||
| sub model : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'model'); | ||||
|   is($test->{info}->model(), 'AP121', q(Model is expected value)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   is($test->{info}->model(), undef, q(No description returns undef model)); | ||||
| } | ||||
|  | ||||
| sub i_ssidlist : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'i_ssidlist'); | ||||
|  | ||||
|   my $expected = {10 => 'MyGuest', 12 => 'MyPrivate', 15 => 'MyGuest'}; | ||||
|  | ||||
|   cmp_deeply($test->{info}->i_ssidlist(), | ||||
|     $expected, q(Interface SSIDs have expected values)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->i_ssidlist(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| sub i_ssidmac : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'i_ssidmac'); | ||||
|  | ||||
|   my $expected = { | ||||
|     10 => '40:18:b1:3a:4c:54', | ||||
|     12 => '40:18:b1:3a:4c:55', | ||||
|     15 => '40:18:b1:3a:4c:68' | ||||
|   }; | ||||
|  | ||||
|   cmp_deeply($test->{info}->i_ssidmac(), | ||||
|     $expected, q(Wireless MACs have expected values)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->i_ssidmac(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| sub cd11_port : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'cd11_port'); | ||||
|  | ||||
|   my $expected = { | ||||
|     '10.6.128.150.177.92.153.130' => 'wifi0.1', | ||||
|     '15.6.40.106.186.61.150.231'  => 'wifi1.1', | ||||
|     '15.6.96.190.181.42.99.151'   => 'wifi1.1' | ||||
|   }; | ||||
|  | ||||
|   cmp_deeply($test->{info}->cd11_port(), | ||||
|     $expected, q(Wireless clients map to wireless interfaces)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->cd11_port(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| sub cd11_mac : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'cd11_mac'); | ||||
|  | ||||
|   my $expected = { | ||||
|     '10.6.128.150.177.92.153.130' => '80:96:b1:5c:99:82', | ||||
|     '15.6.40.106.186.61.150.231'  => '28:6a:ba:3d:96:e7', | ||||
|     '15.6.96.190.181.42.99.151'   => '60:be:b5:2a:63:97' | ||||
|   }; | ||||
|  | ||||
|   cmp_deeply($test->{info}->cd11_mac(), | ||||
|     $expected, q(Wireless clients MACs have expected values)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->cd11_mac(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| sub bp_index : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'bp_index'); | ||||
|  | ||||
|   my $expected = {3 => 3, 10 => 10, 12 => 12, 15 => 15}; | ||||
|  | ||||
|   cmp_deeply($test->{info}->bp_index(), | ||||
|     $expected, q(Bridge interface mapping has expected values)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->bp_index(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| sub qb_fw_port : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'qb_fw_port'); | ||||
|  | ||||
|   my $expected = { | ||||
|     '10.6.128.150.177.92.153.130' => '10', | ||||
|     '15.6.40.106.186.61.150.231'  => '15', | ||||
|     '15.6.96.190.181.42.99.151'   => '15' | ||||
|   }; | ||||
|  | ||||
|   cmp_deeply($test->{info}->qb_fw_port(), | ||||
|     $expected, q(MAC interface mapping has expected values)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->qb_fw_port(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| sub qb_fw_mac : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'qb_fw_mac'); | ||||
|  | ||||
|   my $expected = { | ||||
|     '10.6.128.150.177.92.153.130' => '80:96:b1:5c:99:82', | ||||
|     '15.6.40.106.186.61.150.231'  => '28:6a:ba:3d:96:e7', | ||||
|     '15.6.96.190.181.42.99.151'   => '60:be:b5:2a:63:97' | ||||
|   }; | ||||
|  | ||||
|   cmp_deeply($test->{info}->qb_fw_mac(), | ||||
|     $expected, q(MAC forwarding entries has expected values)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->qb_fw_mac(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| sub qb_fw_vlan : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'qb_fw_vlan'); | ||||
|  | ||||
|   my $expected = { | ||||
|     '10.6.128.150.177.92.153.130' => 50, | ||||
|     '15.6.40.106.186.61.150.231'  => 1, | ||||
|     '15.6.96.190.181.42.99.151'   => 1 | ||||
|   }; | ||||
|  | ||||
|   cmp_deeply($test->{info}->qb_fw_vlan(), | ||||
|     $expected, q(MAC forwarding entries has expected values)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->qb_fw_vlan(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| sub at_paddr : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'at_paddr'); | ||||
|  | ||||
|   my $expected = { | ||||
|     '10.6.128.150.177.92.153.130' => '80:96:b1:5c:99:82', | ||||
|     '15.6.40.106.186.61.150.231'  => '28:6a:ba:3d:96:e7', | ||||
|     '15.6.96.190.181.42.99.151'   => '60:be:b5:2a:63:97' | ||||
|   }; | ||||
|  | ||||
|   cmp_deeply($test->{info}->at_paddr(), | ||||
|     $expected, q(ARP MAC entries have expected values)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->at_paddr(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| sub at_netaddr : Tests(3) { | ||||
|   my $test = shift; | ||||
|  | ||||
|   can_ok($test->{info}, 'at_netaddr'); | ||||
|  | ||||
|   my $expected = { | ||||
|     '10.6.128.150.177.92.153.130' => '1.2.3.4', | ||||
|     '15.6.96.190.181.42.99.151'   => '4.3.2.1' | ||||
|   }; | ||||
|  | ||||
|   cmp_deeply($test->{info}->at_netaddr(), | ||||
|     $expected, q(ARP IP entries have expected values)); | ||||
|  | ||||
|   $test->{info}->clear_cache(); | ||||
|   cmp_deeply($test->{info}->at_netaddr(), {}, q(No data returns empty hash)); | ||||
| } | ||||
|  | ||||
| 1; | ||||
		Reference in New Issue
	
	Block a user