1465 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			1465 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| # SNMP::Info::Layer3::Passport
 | |
| #
 | |
| # Copyright (c) 2016 Eric Miller
 | |
| # All rights reserved.
 | |
| #
 | |
| # Redistribution and use in source and binary forms, with or without
 | |
| # modification, are permitted provided that the following conditions are met:
 | |
| #
 | |
| #     * Redistributions of source code must retain the above copyright notice,
 | |
| #       this list of conditions and the following disclaimer.
 | |
| #     * Redistributions in binary form must reproduce the above copyright
 | |
| #       notice, this list of conditions and the following disclaimer in the
 | |
| #       documentation and/or other materials provided with the distribution.
 | |
| #     * Neither the name of the University of California, Santa Cruz nor the
 | |
| #       names of its contributors may be used to endorse or promote products
 | |
| #       derived from this software without specific prior written permission.
 | |
| #
 | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | |
| # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 | |
| # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | |
| # POSSIBILITY OF SUCH DAMAGE.
 | |
| 
 | |
| package SNMP::Info::Layer3::Passport;
 | |
| 
 | |
| use warnings;
 | |
| use strict;
 | |
| use Exporter;
 | |
| use SNMP::Info::SONMP;
 | |
| use SNMP::Info::RapidCity;
 | |
| use SNMP::Info::Layer3;
 | |
| 
 | |
| @SNMP::Info::Layer3::Passport::ISA
 | |
|     = qw/SNMP::Info::SONMP SNMP::Info::RapidCity
 | |
|     SNMP::Info::Layer3 Exporter/;
 | |
| @SNMP::Info::Layer3::Passport::EXPORT_OK = qw//;
 | |
| 
 | |
| our ($VERSION, %GLOBALS, %FUNCS, %MIBS, %MUNGE);
 | |
| 
 | |
| $VERSION = '3.86';
 | |
| 
 | |
| %MIBS = (
 | |
|     %SNMP::Info::Layer3::MIBS, %SNMP::Info::RapidCity::MIBS,
 | |
|     %SNMP::Info::SONMP::MIBS,
 | |
| );
 | |
| 
 | |
| %GLOBALS = (
 | |
|     %SNMP::Info::Layer3::GLOBALS, %SNMP::Info::RapidCity::GLOBALS,
 | |
|     %SNMP::Info::SONMP::GLOBALS,
 | |
| );
 | |
| 
 | |
| %FUNCS = (
 | |
|     %SNMP::Info::Layer3::FUNCS, %SNMP::Info::RapidCity::FUNCS,
 | |
|     %SNMP::Info::SONMP::FUNCS,
 | |
| );
 | |
| 
 | |
| %MUNGE = (
 | |
|     %SNMP::Info::Layer3::MUNGE, %SNMP::Info::RapidCity::MUNGE,
 | |
|     %SNMP::Info::SONMP::MUNGE,
 | |
| );
 | |
| 
 | |
| sub model {
 | |
|     my $passport = shift;
 | |
|     my $id       = $passport->id();
 | |
| 
 | |
|     unless ( defined $id ) {
 | |
|         print
 | |
|             " SNMP::Info::Layer3::Passport::model() - Device does not support sysObjectID\n"
 | |
|             if $passport->debug();
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     my $model = &SNMP::translateObj($id);
 | |
| 
 | |
|     return $id unless defined $model;
 | |
| 
 | |
|     $model =~ s/^rc(A)?//i;
 | |
|     return $model;
 | |
| }
 | |
| 
 | |
| sub vendor {
 | |
|     return 'avaya';
 | |
| }
 | |
| 
 | |
| sub os {
 | |
|     return 'passport';
 | |
| }
 | |
| 
 | |
| sub os_ver {
 | |
|     my $passport = shift;
 | |
|     my $descr    = $passport->description();
 | |
|     return unless defined $descr;
 | |
| 
 | |
|     #ERS / Passport
 | |
|     if ( $descr =~ m/(\d+\.\d+\.\d+\.\d+)/ ) {
 | |
|         return $1;
 | |
|     }
 | |
| 
 | |
|     #Accelar
 | |
|     if ( $descr =~ m/(\d+\.\d+\.\d+)/ ) {
 | |
|         return $1;
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| sub i_index {
 | |
|     my $passport = shift;
 | |
|     my $partial  = shift;
 | |
| 
 | |
|     my $i_index = $passport->orig_i_index($partial);
 | |
|     my $model   = $passport->model();
 | |
| 
 | |
|     my %if_index;
 | |
|     foreach my $iid ( keys %$i_index ) {
 | |
|         my $index = $i_index->{$iid};
 | |
|         next unless defined $index;
 | |
| 
 | |
|         $if_index{$iid} = $index;
 | |
|     }
 | |
| 
 | |
|     # Get VLAN Virtual Router Interfaces
 | |
|     if (!defined $partial
 | |
|         || (defined $model
 | |
|             && (  ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ )
 | |
|                 || ( $partial > 256 && $model =~ /^1[012][05]0/ ) )
 | |
|         )
 | |
|         )
 | |
|     {
 | |
| 
 | |
|         my $vlan_index = $passport->rc_vlan_if() || {};
 | |
| 
 | |
|         foreach my $vid ( keys %$vlan_index ) {
 | |
|             my $v_index = $vlan_index->{$vid};
 | |
|             next unless defined $v_index;
 | |
|             next if $v_index == 0;
 | |
|             next if ( defined $partial and $v_index !~ /^$partial$/ );
 | |
| 
 | |
|             $if_index{$v_index} = $v_index;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ( defined $model and $model =~ /^8[86]/ ) {
 | |
| 
 | |
|         my $cpu_index = $passport->rc_cpu_ifindex($partial) || {};
 | |
|         my $virt_ip = $passport->rc_virt_ip();
 | |
| 
 | |
|         # Get CPU Ethernet Interfaces
 | |
|         foreach my $cid ( keys %$cpu_index ) {
 | |
|             my $c_index = $cpu_index->{$cid};
 | |
|             next unless defined $c_index;
 | |
|             next if $c_index == 0;
 | |
| 
 | |
|             $if_index{$c_index} = $c_index;
 | |
|         }
 | |
| 
 | |
|         # Check for Virtual Mgmt Interface
 | |
|         unless ( $virt_ip eq '0.0.0.0' ) {
 | |
| 
 | |
|             # Make up an index number, 1 is not reserved AFAIK
 | |
|             $if_index{1} = 1;
 | |
|         }
 | |
|     }
 | |
|     return \%if_index;
 | |
| }
 | |
| 
 | |
| sub interfaces {
 | |
|     my $passport = shift;
 | |
|     my $partial  = shift;
 | |
| 
 | |
|     my $i_index      = $passport->i_index($partial);
 | |
|     my $i_descr      = $passport->orig_i_description($partial) || {};
 | |
|     my $model        = $passport->model();
 | |
|     my $index_factor = $passport->index_factor();
 | |
|     my $port_offset  = $passport->port_offset();
 | |
|     my $slot_offset  = $passport->slot_offset();
 | |
|     my $vlan_index   = {};
 | |
|     my %reverse_vlan;
 | |
|     my $vlan_id = {};
 | |
| 
 | |
|     if (!defined $partial
 | |
|         || (defined $model
 | |
|             && (  ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ )
 | |
|                 || ( $partial > 256 && $model =~ /^1[012][05]0/ ) )
 | |
|         )
 | |
|         )
 | |
|     {
 | |
|         $vlan_index   = $passport->rc_vlan_if() || {};
 | |
|         %reverse_vlan = reverse %$vlan_index;
 | |
|         $vlan_id      = $passport->rc_vlan_id();
 | |
|     }
 | |
| 
 | |
|     my %if;
 | |
|     foreach my $iid ( keys %$i_index ) {
 | |
|         my $index = $i_index->{$iid};
 | |
|         next unless defined $index;
 | |
| 
 | |
|         if ( ( $index == 1 ) and ( $model =~ /^8[86]/ ) ) {
 | |
|             $if{$index} = 'Cpu.Virtual';
 | |
|         }
 | |
| 
 | |
|         elsif ( ( $iid == 64 ) and ( $model =~ /^VSP[478]/ ) ) {
 | |
|             $if{$index} = 'Mgmt.1';
 | |
|         }
 | |
| 
 | |
|         elsif ( ( $index == 192 ) and ( $model =~ /^8[86]03/ ) ) {
 | |
|             $if{$index} = 'Cpu.3';
 | |
|         }
 | |
| 
 | |
|         elsif ( ( $index == 320 ) and ( $model =~ /^8[86][10][06]/ ) ) {
 | |
|             $if{$index} = 'Cpu.5';
 | |
|         }
 | |
| 
 | |
|         elsif ( ( $index == 384 ) and ( $model =~ /^8[86][10][06]/ ) ) {
 | |
|             $if{$index} = 'Cpu.6';
 | |
|         }
 | |
| 
 | |
|         elsif (( $index > 2000 and $model =~ /^8[8631]|16|VSP/ )
 | |
|             or ( $index > 256 and $model =~ /^1[012][05]0/ ) )
 | |
|         {
 | |
| 
 | |
|             my $v_index = $reverse_vlan{$iid};
 | |
|             my $v_id    = $vlan_id->{$v_index};
 | |
|             next unless defined $v_id;
 | |
|             my $v_port = 'Vlan' . "$v_id";
 | |
|             $if{$index} = $v_port;
 | |
|         }
 | |
| 
 | |
|         else {
 | |
|             if ($model =~ /VSP/ and $i_descr->{$iid} and $i_descr->{$iid} =~ m<Port\s+(\d+(?:/\d+)*)>) {
 | |
|                 my $ps = $1;
 | |
|                 $ps =~ s|/|.|g;
 | |
|                 $if{$iid} = $ps;
 | |
|             }
 | |
|             else {
 | |
|                 my $port = ( $index % $index_factor ) + $port_offset;
 | |
|                 my $slot = int( $index / $index_factor ) + $slot_offset;
 | |
| 
 | |
|                 my $slotport = "$slot.$port";
 | |
|                 $if{$iid} = $slotport;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|     }
 | |
| 
 | |
|     return \%if;
 | |
| }
 | |
| 
 | |
| sub i_mac {
 | |
|     my $passport = shift;
 | |
|     my $partial  = shift;
 | |
| 
 | |
|     my $i_mac = $passport->orig_i_mac($partial) || {};
 | |
|     my $model = $passport->model();
 | |
| 
 | |
|     my %if_mac;
 | |
|     foreach my $iid ( keys %$i_mac ) {
 | |
|         my $mac = $i_mac->{$iid};
 | |
|         next unless defined $mac;
 | |
| 
 | |
|         $if_mac{$iid} = $mac;
 | |
|     }
 | |
| 
 | |
|     # Get VLAN Virtual Router Interfaces
 | |
|     if (!defined $partial
 | |
|         || (defined $model
 | |
|             && (  ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ )
 | |
|                 || ( $partial > 256 && $model =~ /^1[012][05]0/ ) )
 | |
|         )
 | |
|         )
 | |
|     {
 | |
| 
 | |
|         my $vlan_index = $passport->rc_vlan_if()  || {};
 | |
|         my $vlan_mac   = $passport->rc_vlan_mac() || {};
 | |
| 
 | |
|         foreach my $iid ( keys %$vlan_mac ) {
 | |
|             my $v_mac = $vlan_mac->{$iid};
 | |
|             next unless defined $v_mac;
 | |
|             my $v_id = $vlan_index->{$iid};
 | |
|             next unless defined $v_id;
 | |
|             next if ( defined $partial and $v_id !~ /^$partial$/ );
 | |
| 
 | |
|             $if_mac{$v_id} = $v_mac;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ( defined $model and $model =~ /^8[86]/ ) {
 | |
| 
 | |
|         my $cpu_mac = $passport->rc_cpu_mac($partial) || {};
 | |
|         my $virt_ip = $passport->rc_virt_ip()         || '0.0.0.0';
 | |
| 
 | |
|         # Get CPU Ethernet Interfaces
 | |
|         foreach my $iid ( keys %$cpu_mac ) {
 | |
|             my $mac = $cpu_mac->{$iid};
 | |
|             next unless defined $mac;
 | |
| 
 | |
|             $if_mac{$iid} = $mac;
 | |
|         }
 | |
| 
 | |
|         # Check for Virtual Mgmt Interface
 | |
|         unless ( ( $virt_ip eq '0.0.0.0' )
 | |
|             or ( defined $partial and $partial ne "1" ) )
 | |
|         {
 | |
|             my $chassis_base_mac = $passport->rc_base_mac();
 | |
|             if ( defined $chassis_base_mac ) {
 | |
|                 my @virt_mac = split /:/, $chassis_base_mac;
 | |
|                 $virt_mac[0] = hex( $virt_mac[0] );
 | |
|                 $virt_mac[1] = hex( $virt_mac[1] );
 | |
|                 $virt_mac[2] = hex( $virt_mac[2] );
 | |
|                 $virt_mac[3] = hex( $virt_mac[3] );
 | |
|                 $virt_mac[4] = hex( $virt_mac[4] ) + 0x03;
 | |
|                 $virt_mac[5] = hex( $virt_mac[5] ) + 0xF8;
 | |
| 
 | |
|                 my $mac = join( ':', map { sprintf "%02x", $_ } @virt_mac );
 | |
| 
 | |
|                 $if_mac{1} = $mac;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return \%if_mac;
 | |
| }
 | |
| 
 | |
| sub i_description {
 | |
|     my $passport = shift;
 | |
|     my $partial  = shift;
 | |
| 
 | |
|     my $i_descr = $passport->orig_i_description($partial) || {};
 | |
|     my $model = $passport->model();
 | |
| 
 | |
|     my %descr;
 | |
|     foreach my $iid ( keys %$i_descr ) {
 | |
|         my $if_descr = $i_descr->{$iid};
 | |
|         next unless defined $if_descr;
 | |
| 
 | |
|         $descr{$iid} = $if_descr;
 | |
|     }
 | |
| 
 | |
|     # Get VLAN Virtual Router Interfaces
 | |
|     if (!defined $partial
 | |
|         || (defined $model
 | |
|             && (  ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ )
 | |
|                 || ( $partial > 256 && $model =~ /^1[012][05]0/ ) )
 | |
|         )
 | |
|         )
 | |
|     {
 | |
| 
 | |
|         my $v_descr    = $passport->v_name();
 | |
|         my $vlan_index = $passport->rc_vlan_if();
 | |
| 
 | |
|         foreach my $vid ( keys %$v_descr ) {
 | |
|             my $vl_descr = $v_descr->{$vid};
 | |
|             next unless defined $vl_descr;
 | |
|             my $v_id = $vlan_index->{$vid};
 | |
|             next unless defined $v_id;
 | |
|             next if ( defined $partial and $v_id !~ /^$partial$/ );
 | |
| 
 | |
|             $descr{$v_id} = $vl_descr;
 | |
|         }
 | |
|     }
 | |
|     return \%descr;
 | |
| }
 | |
| 
 | |
| sub i_name {
 | |
|     my $passport = shift;
 | |
|     my $partial  = shift;
 | |
| 
 | |
|     my $model      = $passport->model();
 | |
|     my $i_index    = $passport->i_index($partial) || {};
 | |
|     my $rc_alias   = $passport->rc_alias($partial) || {};
 | |
|     my $i_alias    = $passport->i_alias($partial) || {};
 | |
|     my $i_name2    = $passport->orig_i_name($partial) || {};
 | |
|     my $v_name     = {};
 | |
|     my $vlan_index = {};
 | |
|     my %reverse_vlan;
 | |
| 
 | |
|     if (!defined $partial
 | |
|         || (defined $model
 | |
|             && (  ( $partial > 2000 && $model =~ /^8[8631]|16|VSP/ )
 | |
|                 || ( $partial > 256 && $model =~ /^1[012][05]0/ ) )
 | |
|         )
 | |
|         )
 | |
|     {
 | |
|         $v_name     = $passport->v_name()     || {};
 | |
|         $vlan_index = $passport->rc_vlan_if() || {};
 | |
|         %reverse_vlan = reverse %$vlan_index;
 | |
|     }
 | |
| 
 | |
|     my %i_name;
 | |
|     foreach my $iid ( keys %$i_index ) {
 | |
| 
 | |
|         if ( ( $iid == 1 ) and ( $model =~ /^8[86]/ ) ) {
 | |
|             $i_name{$iid} = 'CPU Virtual Management IP';
 | |
|         }
 | |
| 
 | |
|         elsif ( ( $iid == 64 ) and ( $model =~ /^VSP[478]/ ) ) {
 | |
|             $i_name{$iid} = 'Mgmt Port';
 | |
|         }
 | |
| 
 | |
|         elsif ( ( $iid == 192 ) and ( $model =~ /^8[86]03/ ) ) {
 | |
|             $i_name{$iid} = 'CPU 3 Ethernet Port';
 | |
|         }
 | |
| 
 | |
|         elsif ( ( $iid == 320 ) and ( $model =~ /^8[86][10][06]/ ) ) {
 | |
|             $i_name{$iid} = 'CPU 5 Ethernet Port';
 | |
|         }
 | |
| 
 | |
|         elsif ( ( $iid == 384 ) and ( $model =~ /^8[86][10][06]/ ) ) {
 | |
|             $i_name{$iid} = 'CPU 6 Ethernet Port';
 | |
|         }
 | |
| 
 | |
|         elsif (
 | |
|             ( $iid > 2000 and defined $model and $model =~ /^8[8631]|16|VSP/ )
 | |
|             or (    $iid > 256
 | |
|                 and defined $model
 | |
|                 and $model =~ /^1[012][05]0/ )
 | |
|             )
 | |
|         {
 | |
|             my $vlan_idx = $reverse_vlan{$iid};
 | |
|             my $vlan_name  = $v_name->{$vlan_idx};
 | |
|             next unless defined $vlan_name;
 | |
| 
 | |
|             $i_name{$iid} = $vlan_name;
 | |
|         }
 | |
| 
 | |
|         else {
 | |
|             my $name      = $i_name2->{$iid};
 | |
|             my $pp_alias  = $rc_alias->{$iid};
 | |
|             my $std_alias = $i_alias->{$iid};
 | |
|             my $alias
 | |
|                 = ( defined $pp_alias and $pp_alias !~ /^\s*$/ )
 | |
|                 ? $pp_alias
 | |
|                 : $std_alias;
 | |
|             $i_name{$iid}
 | |
|                 = ( defined $alias and $alias !~ /^\s*$/ )
 | |
|                 ? $alias
 | |
|                 : $name;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return \%i_name;
 | |
| }
 | |
| 
 | |
| sub ip_index {
 | |
|     my $passport = shift;
 | |
|     my $partial  = shift;
 | |
| 
 | |
|     my $model = $passport->model();
 | |
|     my $ip_index = $passport->SUPER::ip_index($partial) || {};
 | |
| 
 | |
|     my %ip_index;
 | |
|     foreach my $ip ( keys %$ip_index ) {
 | |
|         my $iid = $ip_index->{$ip};
 | |
|         next unless defined $iid;
 | |
|         # Skip VSP default CPU addresses
 | |
|         next if ($ip =~ /^192\.168\.1\.1/);
 | |
|         # Skip default CPU addresses
 | |
|         next if ($ip =~ /^192\.168\.168\.16[89]/);
 | |
| 
 | |
|         $ip_index{$ip} = $iid;
 | |
|     }
 | |
| 
 | |
|     # Only 8600 has CPU and Virtual Management IP
 | |
|     if ( defined $model and $model =~ /^8[86]/ ) {
 | |
| 
 | |
|         my $cpu_ip = $passport->rc_cpu_ip($partial) || {};
 | |
|         my $virt_ip = $passport->rc_virt_ip($partial);
 | |
| 
 | |
|         # Get CPU Ethernet IP
 | |
|         foreach my $cid ( keys %$cpu_ip ) {
 | |
|             my $c_ip = $cpu_ip->{$cid};
 | |
|             next unless defined $c_ip;
 | |
|             # Skip default CPU addresses
 | |
|             next if ($c_ip =~ /192\.168\.168\.16[89]/);
 | |
| 
 | |
|             $ip_index{$c_ip} = $cid;
 | |
|         }
 | |
| 
 | |
|         # Get Virtual Mgmt IP
 | |
|         $ip_index{$virt_ip} = 1 if ( defined $virt_ip );
 | |
|     }
 | |
| 
 | |
|     return \%ip_index;
 | |
| }
 | |
| 
 | |
| sub ip_netmask {
 | |
|     my $passport = shift;
 | |
|     my $partial  = shift;
 | |
| 
 | |
|     my $model = $passport->model();
 | |
|     my $ip_mask = $passport->SUPER::ip_netmask($partial) || {};
 | |
| 
 | |
|     my %ip_index;
 | |
|     foreach my $iid ( keys %$ip_mask ) {
 | |
|         # Skip VSP default CPU addresses
 | |
|         next if ($iid =~ /^192\.168\.1\./);
 | |
|         # Skip default CPU addresses
 | |
|         next if ($iid =~ /^192\.168\.168\.16[89]/);
 | |
|         my $mask = $ip_mask->{$iid};
 | |
|         next unless defined $mask;
 | |
| 
 | |
|         $ip_index{$iid} = $mask;
 | |
|     }
 | |
| 
 | |
|     # Only 8600 has CPU and Virtual Management IP
 | |
|     if ( defined $model and $model =~ /^8[86]/ ) {
 | |
| 
 | |
|         my $cpu_ip    = $passport->rc_cpu_ip($partial)    || {};
 | |
|         my $cpu_mask  = $passport->rc_cpu_mask($partial)  || {};
 | |
|         my $virt_ip   = $passport->rc_virt_ip($partial);
 | |
|         my $virt_mask = $passport->rc_virt_mask($partial) || {};
 | |
| 
 | |
|         # Get CPU Ethernet IP
 | |
|         foreach my $iid ( keys %$cpu_mask ) {
 | |
|             my $c_ip = $cpu_ip->{$iid};
 | |
|             next unless defined $c_ip;
 | |
|             # Skip default CPU addresses
 | |
|             next if ($c_ip =~ /192\.168\.168\.16[89]/);
 | |
|             my $c_mask = $cpu_mask->{$iid};
 | |
|             next unless defined $c_mask;
 | |
| 
 | |
|             $ip_index{$c_ip} = $c_mask;
 | |
|         }
 | |
| 
 | |
|         # Get Virtual Mgmt IP
 | |
|         $ip_index{$virt_ip} = $virt_mask
 | |
|             if ( defined $virt_mask and defined $virt_ip );
 | |
|     }
 | |
| 
 | |
|     return \%ip_index;
 | |
| }
 | |
| 
 | |
| sub root_ip {
 | |
|     my $passport        = shift;
 | |
|     my $model           = $passport->model();
 | |
|     my $rc_ip_addr      = $passport->rc_ip_addr();
 | |
|     my $rc_ip_type      = $passport->rc_ip_type();
 | |
|     my $virt_ip         = $passport->rc_virt_ip();
 | |
|     my $router_ip       = $passport->router_ip();
 | |
|     my $sonmp_topo_port = $passport->sonmp_topo_port();
 | |
|     my $sonmp_topo_ip   = $passport->sonmp_topo_ip();
 | |
| 
 | |
|     # Only 8600 and 1600 have CLIP or Management Virtual IP
 | |
|     if ( defined $model and $model =~ /^8[86]|16|VSP/ ) {
 | |
| 
 | |
|         # Return CLIP (CircuitLess IP)
 | |
|         foreach my $iid ( keys %$rc_ip_type ) {
 | |
|             my $ip_type = $rc_ip_type->{$iid};
 | |
|             next
 | |
|                 unless ( ( defined $ip_type )
 | |
|                 and ( $ip_type =~ /circuitLess/i ) );
 | |
|             my $ip = $rc_ip_addr->{$iid};
 | |
|             next unless defined $ip;
 | |
| 
 | |
|             return $ip if $passport->snmp_connect_ip($ip);
 | |
|         }
 | |
| 
 | |
|         # Return Management Virtual IP address
 | |
|         if ( ( defined $virt_ip ) and ( $virt_ip ne '0.0.0.0' ) ) {
 | |
|             return $virt_ip if $passport->snmp_connect_ip($virt_ip);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # Return OSPF Router ID
 | |
|     if ( ( defined $router_ip ) and ( $router_ip ne '0.0.0.0' ) ) {
 | |
|         foreach my $iid ( keys %$rc_ip_addr ) {
 | |
|             my $ip = $rc_ip_addr->{$iid};
 | |
|             next unless $router_ip eq $ip;
 | |
|             return $router_ip if $passport->snmp_connect_ip($router_ip);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # Otherwise Return SONMP Advertised IP Address
 | |
|     foreach my $entry ( keys %$sonmp_topo_port ) {
 | |
|         my $port = $sonmp_topo_port->{$entry};
 | |
|         next unless $port == 0;
 | |
|         my $ip = $sonmp_topo_ip->{$entry};
 | |
|         return $ip
 | |
|             if (( defined $ip )
 | |
|             and ( $ip ne '0.0.0.0' )
 | |
|             and ( $passport->snmp_connect_ip($ip) ) );
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| # Required for SNMP::Info::SONMP
 | |
| sub index_factor {
 | |
|     my $passport     = shift;
 | |
|     my $model        = $passport->model();
 | |
|     my $index_factor = 64;
 | |
| 
 | |
|     # Older Accelar models use base 16 instead of 64
 | |
|     $index_factor = 16
 | |
|         if ( defined $model and $model =~ /^1[012][05]0/ );
 | |
| 
 | |
|     return $index_factor;
 | |
| }
 | |
| 
 | |
| sub slot_offset {
 | |
|     my $passport     = shift;
 | |
|     my $model        = $passport->model();
 | |
|     # Newer VSP 4K and 8K start at an index of 192 ~ slot 3 but really slot 1
 | |
|     return -2
 | |
|         if ( defined $model and $model =~ /^VSP[478]/ );
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| sub port_offset {
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| # Bridge MIB does not map Bridge Port to ifIndex correctly
 | |
| sub bp_index {
 | |
|     my $passport = shift;
 | |
|     my $partial  = shift;
 | |
| 
 | |
|     my $if_index = $passport->i_index($partial) || {};
 | |
| 
 | |
|     my %bp_index;
 | |
|     foreach my $iid ( keys %$if_index ) {
 | |
|         $bp_index{$iid} = $iid;
 | |
|     }
 | |
| 
 | |
|     # If we have MLT's map them to the designated port
 | |
|     my $trunks = $passport->rc_mlt_index;
 | |
|     my $dps    = $passport->rc_mlt_dp || {};
 | |
| 
 | |
|     if ( ref {} eq ref $trunks and scalar keys %$trunks ) {
 | |
|         foreach my $m ( keys %$trunks ) {
 | |
|             my $m_idx = $trunks->{$m};
 | |
|             next unless $m_idx;
 | |
|             my $i_idx = $dps->{$m} ? $dps->{$m} : $m_idx;
 | |
|             $bp_index{$m_idx} = $i_idx;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return \%bp_index;
 | |
| }
 | |
| 
 | |
| # We have devices which support BRIDGE-MIB, Q-BRIDGE-MIB, and RAPID-CITY
 | |
| # exclusively.  Use standards-based first and fall back to RAPID-CITY.
 | |
| sub fw_mac {
 | |
|     my $passport  = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     my $qb = $passport->SUPER::fw_mac($partial);
 | |
|     return $qb if (ref {} eq ref $qb and scalar keys %$qb);
 | |
| 
 | |
|     my $qb_fw_port = $passport->rcBridgeTpFdbPort($partial);
 | |
|     my $qb_fw_mac  = {};
 | |
|     foreach my $idx ( keys %$qb_fw_port ) {
 | |
|         my ( $fdb_id, $mac ) = _rc_fdbtable_index($idx);
 | |
|         $qb_fw_mac->{$idx} = $mac;
 | |
|     }
 | |
|     return $qb_fw_mac;
 | |
| }
 | |
| 
 | |
| sub fw_port {
 | |
|     my $passport  = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     my $qb = $passport->SUPER::fw_port($partial);
 | |
|     return $qb if (ref {} eq ref $qb and scalar keys %$qb);
 | |
| 
 | |
|     return $passport->rcBridgeTpFdbPort($partial);
 | |
| }
 | |
| 
 | |
| sub fw_status {
 | |
|     my $passport  = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     my $qb = $passport->SUPER::fw_status($partial);
 | |
|     return $qb if (ref {} eq ref $qb and scalar keys %$qb);
 | |
| 
 | |
|     return $passport->rcBridgeTpFdbStatus($partial);
 | |
| }
 | |
| 
 | |
| sub qb_fw_vlan {
 | |
|     my $passport  = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     my $qb = $passport->SUPER::qb_fw_vlan($partial);
 | |
|     return $qb if (ref {} eq ref $qb and scalar keys %$qb);
 | |
| 
 | |
|     my $qb_fw_port = $passport->rcBridgeTpFdbPort($partial);
 | |
|     my $qb_fw_vlan = {};
 | |
|     foreach my $idx ( keys %$qb_fw_port ) {
 | |
|         my ( $fdb_id, $mac ) = _rc_fdbtable_index($idx);
 | |
|         $qb_fw_vlan->{$idx} = $fdb_id;
 | |
|     }
 | |
|     return $qb_fw_vlan;
 | |
| }
 | |
| 
 | |
| # break up the rcBridgeTpFdbEntry INDEX into FDB ID and MAC Address.
 | |
| sub _rc_fdbtable_index {
 | |
|     my $idx    = shift;
 | |
|     my @values = split( /\./, $idx );
 | |
|     my $fdb_id = shift(@values);
 | |
|     return ( $fdb_id, join( ':', map { sprintf "%02x", $_ } @values ) );
 | |
| }
 | |
| 
 | |
| 
 | |
| # Pseudo ENTITY-MIB methods
 | |
| 
 | |
| sub e_index {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $model = $passport->model();
 | |
|     my $rc_ps_t = $passport->rc_ps_type() || {};
 | |
| 
 | |
|     # We're going to hack an index: Slot/Mda/Position
 | |
|     # We're going to put chassis and power supplies in a slot
 | |
|     # which doesn't exist
 | |
|     my %rc_e_index;
 | |
| 
 | |
|     # Make up a chassis index
 | |
|     $rc_e_index{1} = 1;
 | |
| 
 | |
|     # Power supplies are common, handle them first
 | |
|     foreach my $idx ( keys %$rc_ps_t ) {
 | |
|         next unless $idx;
 | |
| 
 | |
|         # We should never have 90 slots, they will also
 | |
|         # sort numerically at the bottom
 | |
|         my $index = $idx + 90 . "0000";
 | |
|         $rc_e_index{$index} = $index;
 | |
|     }
 | |
| 
 | |
|     # Older Accelars use RAPID-CITY::rcCardTable
 | |
|     if ( defined $model and $model =~ /^1[012][05]0/ ) {
 | |
|         my $rc_c_t = $passport->rc_c_type() || {};
 | |
|         foreach my $idx ( keys %$rc_c_t ) {
 | |
|             next unless $idx;
 | |
| 
 | |
|             my $index = "$idx" . "0000";
 | |
|             $rc_e_index{$index} = $index;
 | |
|             $index++;
 | |
|             $rc_e_index{$index} = $index;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # All newer models use RAPID-CITY::rc2kCardTable
 | |
|     else {
 | |
|         my $rc2_c_t = $passport->rc2k_c_ftype()  || {};
 | |
|         my $rc2_m_t = $passport->rc2k_mda_type() || {};
 | |
| 
 | |
|         foreach my $idx ( keys %$rc2_c_t ) {
 | |
|             next unless $idx;
 | |
| 
 | |
|             my $index = "$idx" . "0000";
 | |
|             for ( 0 .. 2 ) {
 | |
|                 $rc_e_index{$index} = $index;
 | |
|                 $index++;
 | |
|             }
 | |
|         }
 | |
|         foreach my $idx ( keys %$rc2_m_t ) {
 | |
|             next unless $idx;
 | |
|             next if $idx == 0;
 | |
| 
 | |
|             my ( $slot, $mda ) = split /\./, $idx;
 | |
|             $mda = sprintf( "%02d", $mda );
 | |
| 
 | |
|             my $index = "$idx" . "$mda" . "00";
 | |
|             $rc_e_index{$index} = $index;
 | |
|             $index++;
 | |
|             $rc_e_index{$index} = $index;
 | |
|         }
 | |
|     }
 | |
|     return \%rc_e_index;
 | |
| }
 | |
| 
 | |
| sub e_class {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $rc_e_idx = $passport->e_index() || {};
 | |
| 
 | |
|     my %rc_e_class;
 | |
|     foreach my $iid ( keys %$rc_e_idx ) {
 | |
|         if ( $iid == 1 ) {
 | |
|             $rc_e_class{$iid} = 'chassis';
 | |
|         }
 | |
|         elsif ( $iid =~ /^9(\d)/ and length $iid > 5 ) {
 | |
|             $rc_e_class{$iid} = 'powerSupply';
 | |
|         }
 | |
|         elsif ( $iid =~ /0000$/ ) {
 | |
|             $rc_e_class{$iid} = 'container';
 | |
|         }
 | |
|         else {
 | |
|             $rc_e_class{$iid} = 'module';
 | |
|         }
 | |
|     }
 | |
|     return \%rc_e_class;
 | |
| }
 | |
| 
 | |
| sub e_descr {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $model = $passport->model();
 | |
|     my $rc_ps = $passport->rc_ps_detail() || {};
 | |
|     my $rc_ch = $passport->chassis() || '';
 | |
|     $rc_ch =~ s/a//;
 | |
| 
 | |
|     my %rc_e_descr;
 | |
| 
 | |
|     # Chassis
 | |
|     $rc_e_descr{1} = $rc_ch;
 | |
| 
 | |
|     # Power supplies are common, handle them first
 | |
|     foreach my $idx ( keys %$rc_ps ) {
 | |
|         next unless $idx;
 | |
|         my $ps = $rc_ps->{$idx};
 | |
|         next unless $ps;
 | |
|         my $index = $idx + 90 . "0000";
 | |
|         $rc_e_descr{$index} = $ps;
 | |
|     }
 | |
| 
 | |
|     # Older Accelars use RAPID-CITY::rcCardTable
 | |
|     if ( defined $model and $model =~ /^1[012][05]0/ ) {
 | |
|         my $rc_c_t = $passport->rc_c_type() || {};
 | |
|         foreach my $idx ( keys %$rc_c_t ) {
 | |
|             next unless $idx;
 | |
|             my $type = $rc_c_t->{$idx};
 | |
|             next unless $type;
 | |
|             my $index = "$idx" . "0000";
 | |
|             $rc_e_descr{$index} = "Slot " . "$idx";
 | |
|             $index++;
 | |
|             $rc_e_descr{$index} = $type;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # All newer models use RAPID-CITY::rc2kCardTable
 | |
|     else {
 | |
|         my $rc2_cf = $passport->rc2k_c_fdesc()  || {};
 | |
|         my $rc2_cb = $passport->rc2k_c_bdesc()  || {};
 | |
|         my $rc2_m  = $passport->rc2k_mda_desc() || {};
 | |
| 
 | |
|         foreach my $idx ( keys %$rc2_cf ) {
 | |
|             next unless $idx;
 | |
|             my $cf = $rc2_cf->{$idx};
 | |
|             next unless $idx;
 | |
|             my $cb = $rc2_cb->{$idx};
 | |
| 
 | |
|             my $index = "$idx" . "0000";
 | |
|             $rc_e_descr{$index} = "Slot " . "$idx";
 | |
|             $index++;
 | |
|             $rc_e_descr{$index} = $cf;
 | |
|             $index++;
 | |
|             $rc_e_descr{$index} = $cb;
 | |
|         }
 | |
|         foreach my $idx ( keys %$rc2_m ) {
 | |
|             next unless $idx;
 | |
|             my $cm = $rc2_m->{$idx};
 | |
|             next unless $cm;
 | |
|             my ( $slot, $mda ) = split /\./, $idx;
 | |
|             $mda = sprintf( "%02d", $mda );
 | |
| 
 | |
|             my $index = "$idx" . "$mda" . "00";
 | |
|             $rc_e_descr{$index} = $cm;
 | |
|         }
 | |
|     }
 | |
|     return \%rc_e_descr;
 | |
| }
 | |
| 
 | |
| sub e_type {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $model = $passport->model();
 | |
|     my $rc_ps = $passport->rc_ps_type() || {};
 | |
|     my $rc_ch = $passport->chassis();
 | |
| 
 | |
|     my %rc_e_type;
 | |
| 
 | |
|     # Chassis
 | |
|     $rc_e_type{1} = $rc_ch;
 | |
| 
 | |
|     # Power supplies are common, handle them first
 | |
|     foreach my $idx ( keys %$rc_ps ) {
 | |
|         next unless $idx;
 | |
|         my $ps = $rc_ps->{$idx};
 | |
|         next unless $ps;
 | |
|         my $index = $idx + 90 . "0000";
 | |
|         $rc_e_type{$index} = $ps;
 | |
|     }
 | |
| 
 | |
|     # Older Accelars use RAPID-CITY::rcCardTable
 | |
|     if ( defined $model and $model =~ /^1[012][05]0/ ) {
 | |
|         my $rc_c_t = $passport->rc_c_type() || {};
 | |
|         foreach my $idx ( keys %$rc_c_t ) {
 | |
|             next unless $idx;
 | |
|             my $type = $rc_c_t->{$idx};
 | |
|             next unless $type;
 | |
|             my $index = "$idx" . "0000";
 | |
|             $rc_e_type{$index} = "zeroDotZero";
 | |
|             $index++;
 | |
|             $rc_e_type{$index} = $type;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # All newer models use RAPID-CITY::rc2kCardTable
 | |
|     else {
 | |
|         my $rc2_cf = $passport->rc2k_c_ftype()  || {};
 | |
|         my $rc2_cb = $passport->rc2k_c_btype()  || {};
 | |
|         my $rc2_m  = $passport->rc2k_mda_type() || {};
 | |
| 
 | |
|         foreach my $idx ( keys %$rc2_cf ) {
 | |
|             next unless $idx;
 | |
|             my $cf = $rc2_cf->{$idx};
 | |
|             next unless $idx;
 | |
|             my $cb = $rc2_cb->{$idx};
 | |
| 
 | |
|             my $index = "$idx" . "0000";
 | |
|             $rc_e_type{$index} = "zeroDotZero";
 | |
|             $index++;
 | |
|             $rc_e_type{$index} = $cf;
 | |
|             $index++;
 | |
|             $rc_e_type{$index} = $cb;
 | |
|         }
 | |
|         foreach my $idx ( keys %$rc2_m ) {
 | |
|             next unless $idx;
 | |
|             my $cm = $rc2_m->{$idx};
 | |
|             next unless $cm;
 | |
|             my ( $slot, $mda ) = split /\./, $idx;
 | |
|             $mda = sprintf( "%02d", $mda );
 | |
| 
 | |
|             my $index = "$idx" . "$mda" . "00";
 | |
|             $rc_e_type{$index} = $cm;
 | |
|         }
 | |
|     }
 | |
|     return \%rc_e_type;
 | |
| }
 | |
| 
 | |
| sub e_name {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $model = $passport->model();
 | |
|     my $rc_e_idx = $passport->e_index() || {};
 | |
| 
 | |
|     my %rc_e_name;
 | |
|     foreach my $iid ( keys %$rc_e_idx ) {
 | |
| 
 | |
|         if ( $iid == 1 ) {
 | |
|             $rc_e_name{$iid} = 'Chassis';
 | |
|             next;
 | |
|         }
 | |
| 
 | |
|         my $mod = int( substr( $iid, -4, 2 ) );
 | |
|         my $slot = substr( $iid, -6, 2 );
 | |
| 
 | |
|         if ( $iid =~ /^9(\d)/ and length $iid > 5 ) {
 | |
|             $rc_e_name{$iid} = "Power Supply $1";
 | |
|         }
 | |
|         elsif ( $iid =~ /(00){2}$/ ) {
 | |
|             $rc_e_name{$iid} = "Slot $slot";
 | |
|         }
 | |
|         elsif ( $iid =~ /(00){1}$/ ) {
 | |
|             $rc_e_name{$iid} = "Card $slot, MDA $mod";
 | |
|         }
 | |
|         elsif ( defined $model
 | |
|             and $model =~ /^1[012][05]0/
 | |
|             and $iid   =~ /1$/ )
 | |
|         {
 | |
|             $rc_e_name{$iid} = "Card $slot";
 | |
|         }
 | |
|         elsif ( $iid =~ /1$/ ) {
 | |
|             $rc_e_name{$iid} = "Card $slot (front)";
 | |
|         }
 | |
|         elsif ( $iid =~ /2$/ ) {
 | |
|             $rc_e_name{$iid} = "Card $slot (back)";
 | |
|         }
 | |
|     }
 | |
|     return \%rc_e_name;
 | |
| }
 | |
| 
 | |
| sub e_hwver {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $model = $passport->model();
 | |
|     my $rc_ps = $passport->rc_ps_rev() || {};
 | |
| 
 | |
|     my %rc_e_hwver;
 | |
| 
 | |
|     # Chassis
 | |
|     $rc_e_hwver{1} = $passport->rc_ch_rev();
 | |
| 
 | |
|     # Power supplies are common, handle them first
 | |
|     foreach my $idx ( keys %$rc_ps ) {
 | |
|         next unless $idx;
 | |
|         my $ps = $rc_ps->{$idx};
 | |
|         next unless $ps;
 | |
|         my $index = $idx + 90 . "0000";
 | |
|         $rc_e_hwver{$index} = $ps;
 | |
|     }
 | |
| 
 | |
|     # Older Accelars use RAPID-CITY::rcCardTable
 | |
|     if ( defined $model and $model =~ /^1[012][05]0/ ) {
 | |
|         my $rc_c_t = $passport->rc_c_rev() || {};
 | |
|         foreach my $idx ( keys %$rc_c_t ) {
 | |
|             next unless $idx;
 | |
|             my $type = $rc_c_t->{$idx};
 | |
|             next unless $type;
 | |
|             my $index = "$idx" . "0001";
 | |
|             $rc_e_hwver{$index} = $type;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # All newer models use RAPID-CITY::rc2kCardTable
 | |
|     else {
 | |
|         my $rc2_cf = $passport->rc2k_c_frev()  || {};
 | |
|         my $rc2_cb = $passport->rc2k_c_brev()  || {};
 | |
|         my $rc2_m  = $passport->rc2k_mda_rev() || {};
 | |
| 
 | |
|         foreach my $idx ( keys %$rc2_cf ) {
 | |
|             next unless $idx;
 | |
|             my $cf = $rc2_cf->{$idx};
 | |
|             next unless $idx;
 | |
|             my $cb = $rc2_cb->{$idx};
 | |
| 
 | |
|             my $index = "$idx" . "0001";
 | |
|             $rc_e_hwver{$index} = $cf;
 | |
|             $index++;
 | |
|             $rc_e_hwver{$index} = $cb;
 | |
|         }
 | |
|         foreach my $idx ( keys %$rc2_m ) {
 | |
|             next unless $idx;
 | |
|             my $cm = $rc2_m->{$idx};
 | |
|             next unless $cm;
 | |
|             my ( $slot, $mda ) = split /\./, $idx;
 | |
|             $mda = sprintf( "%02d", $mda );
 | |
| 
 | |
|             my $index = "$idx" . "$mda" . "00";
 | |
|             $rc_e_hwver{$index} = $cm;
 | |
|         }
 | |
|     }
 | |
|     return \%rc_e_hwver;
 | |
| }
 | |
| 
 | |
| sub e_vendor {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $rc_e_idx = $passport->e_index() || {};
 | |
| 
 | |
|     my %rc_e_vendor;
 | |
|     foreach my $iid ( keys %$rc_e_idx ) {
 | |
|         $rc_e_vendor{$iid} = 'avaya';
 | |
|     }
 | |
|     return \%rc_e_vendor;
 | |
| }
 | |
| 
 | |
| sub e_serial {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $model = $passport->model();
 | |
|     my $rc_ps = $passport->rc_ps_serial() || {};
 | |
| 
 | |
|     my %rc_e_serial;
 | |
| 
 | |
|     # Chassis
 | |
|     $rc_e_serial{1} = $passport->rc_serial();
 | |
| 
 | |
|     # Power supplies are common, handle them first
 | |
|     foreach my $idx ( keys %$rc_ps ) {
 | |
|         next unless $idx;
 | |
|         my $ps = $rc_ps->{$idx};
 | |
|         next unless $ps;
 | |
|         my $index = $idx + 90 . "0000";
 | |
|         $rc_e_serial{$index} = $ps;
 | |
|     }
 | |
| 
 | |
|     # Older Accelars use RAPID-CITY::rcCardTable
 | |
|     if ( defined $model and $model =~ /^1[012][05]0/ ) {
 | |
|         my $rc_c_t = $passport->rc_c_serial() || {};
 | |
|         foreach my $idx ( keys %$rc_c_t ) {
 | |
|             next unless $idx;
 | |
|             my $type = $rc_c_t->{$idx};
 | |
|             next unless $type;
 | |
|             my $index = "$idx" . "0001";
 | |
|             $rc_e_serial{$index} = $type;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # All newer models use RAPID-CITY::rc2kCardTable
 | |
|     else {
 | |
|         my $rc2_cf = $passport->rc2k_c_fserial()  || {};
 | |
|         my $rc2_cb = $passport->rc2k_c_bserial()  || {};
 | |
|         my $rc2_m  = $passport->rc2k_mda_serial() || {};
 | |
| 
 | |
|         foreach my $idx ( keys %$rc2_cf ) {
 | |
|             next unless $idx;
 | |
|             my $cf = $rc2_cf->{$idx};
 | |
|             next unless $idx;
 | |
|             my $cb = $rc2_cb->{$idx};
 | |
| 
 | |
|             my $index = "$idx" . "0001";
 | |
|             $rc_e_serial{$index} = $cf;
 | |
|             $index++;
 | |
|             $rc_e_serial{$index} = $cb;
 | |
|         }
 | |
|         foreach my $idx ( keys %$rc2_m ) {
 | |
|             next unless $idx;
 | |
|             my $cm = $rc2_m->{$idx};
 | |
|             next unless $cm;
 | |
|             my ( $slot, $mda ) = split /\./, $idx;
 | |
|             $mda = sprintf( "%02d", $mda );
 | |
| 
 | |
|             my $index = "$idx" . "$mda" . "00";
 | |
|             $rc_e_serial{$index} = $cm;
 | |
|         }
 | |
|     }
 | |
|     return \%rc_e_serial;
 | |
| }
 | |
| 
 | |
| sub e_pos {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $rc_e_idx = $passport->e_index() || {};
 | |
| 
 | |
|     my %rc_e_pos;
 | |
|     foreach my $iid ( keys %$rc_e_idx ) {
 | |
|         next unless $iid;
 | |
|         if ( $iid == 1 ) {
 | |
|             $rc_e_pos{$iid} = -1;
 | |
|             next;
 | |
|         }
 | |
|         my $sub = int( substr( $iid, -2, 2 ) );
 | |
|         my $mod = int( substr( $iid, -4, 2 ) );
 | |
|         my $slot = substr( $iid, -6, 2 );
 | |
|         if ( $iid =~ /(00){2}$/ ) {
 | |
|             $rc_e_pos{$iid} = $slot;
 | |
|         }
 | |
|         elsif ( $iid =~ /(00){1}$/ ) {
 | |
|             $rc_e_pos{$iid} = $mod * 100;
 | |
|         }
 | |
|         else {
 | |
|             $rc_e_pos{$iid} = $sub;
 | |
|         }
 | |
|     }
 | |
|     return \%rc_e_pos;
 | |
| }
 | |
| 
 | |
| sub e_parent {
 | |
|     my $passport = shift;
 | |
| 
 | |
|     my $rc_e_idx = $passport->e_index() || {};
 | |
| 
 | |
|     my %rc_e_parent;
 | |
|     foreach my $iid ( keys %$rc_e_idx ) {
 | |
|         next unless $iid;
 | |
|         if ( $iid == 1 ) {
 | |
|             $rc_e_parent{$iid} = 0;
 | |
|             next;
 | |
|         }
 | |
|         my $slot = substr( $iid, -6, 2 );
 | |
|         if ( $iid =~ /(00){1,2}$/ ) {
 | |
|             $rc_e_parent{$iid} = 1;
 | |
|         }
 | |
|         else {
 | |
|             $rc_e_parent{$iid} = "$slot" . "0000";
 | |
|         }
 | |
|     }
 | |
|     return \%rc_e_parent;
 | |
| }
 | |
| 
 | |
| 1;
 | |
| __END__
 | |
| 
 | |
| =head1 NAME
 | |
| 
 | |
| SNMP::Info::Layer3::Passport - SNMP Interface to modular Avaya
 | |
| Ethernet Routing Switch 8000 Series and VSP 9000 Series switches.
 | |
| 
 | |
| =head1 AUTHOR
 | |
| 
 | |
| Eric Miller
 | |
| 
 | |
| =head1 SYNOPSIS
 | |
| 
 | |
|  # Let SNMP::Info determine the correct subclass for you.
 | |
|  my $passport = new SNMP::Info(
 | |
|                           AutoSpecify => 1,
 | |
|                           Debug       => 1,
 | |
|                           DestHost    => 'myswitch',
 | |
|                           Community   => 'public',
 | |
|                           Version     => 2
 | |
|                         )
 | |
|     or die "Can't connect to DestHost.\n";
 | |
| 
 | |
|  my $class = $passport->class();
 | |
|  print "SNMP::Info determined this device to fall under subclass : $class\n";
 | |
| 
 | |
| =head1 DESCRIPTION
 | |
| 
 | |
| Abstraction subclass for modular Avaya Ethernet Routing Switch 8000 Series
 | |
| (formerly Nortel/Bay Passport/Accelar) and VSP 9000 Series switches.
 | |
| 
 | |
| These devices have some of the same characteristics as the stackable Avaya
 | |
| Ethernet Switches (Baystack).  For example, extended interface information is
 | |
| gleaned from F<RAPID-CITY>.
 | |
| 
 | |
| For speed or debugging purposes you can call the subclass directly, but not
 | |
| after determining a more specific class using the method above.
 | |
| 
 | |
|  my $passport = new SNMP::Info::Layer3::Passport(...);
 | |
| 
 | |
| =head2 Inherited Classes
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item SNMP::Info::SONMP
 | |
| 
 | |
| =item SNMP::Info::RapidCity
 | |
| 
 | |
| =item SNMP::Info::Layer3
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Required MIBs
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item Inherited Classes' MIBs
 | |
| 
 | |
| See L<SNMP::Info::SONMP/"Required MIBs"> for its own MIB requirements.
 | |
| 
 | |
| See L<SNMP::Info::RapidCity/"Required MIBs"> for its own MIB requirements.
 | |
| 
 | |
| See L<SNMP::Info::Layer3/"Required MIBs"> for its own MIB requirements.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 GLOBALS
 | |
| 
 | |
| These are methods that return scalar value from SNMP
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $passport->model()
 | |
| 
 | |
| Returns model type.  Checks $passport->id() against the
 | |
| F<RAPID-CITY-MIB> and then parses out C<rcA>.
 | |
| 
 | |
| =item $passport->vendor()
 | |
| 
 | |
| Returns 'avaya'
 | |
| 
 | |
| =item $passport->os()
 | |
| 
 | |
| Returns 'passport'
 | |
| 
 | |
| =item $passport->os_ver()
 | |
| 
 | |
| Returns the software version extracted from C<sysDescr>
 | |
| 
 | |
| =item $passport->serial()
 | |
| 
 | |
| Returns (C<rcChasSerialNumber>)
 | |
| 
 | |
| =item $passport->root_ip()
 | |
| 
 | |
| Returns the primary IP used to communicate with the device.  Returns the first
 | |
| found:  CLIP (CircuitLess IP), Management Virtual IP (C<rcSysVirtualIpAddr>),
 | |
| OSPF Router ID (C<ospfRouterId>), SONMP Advertised IP Address.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Overrides
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $passport->index_factor()
 | |
| 
 | |
| Required by SNMP::Info::SONMP.  Returns 64 for 8600, 16 for Accelar.
 | |
| 
 | |
| =item $passport->port_offset()
 | |
| 
 | |
| Required by SNMP::Info::SONMP.  Returns 1.
 | |
| 
 | |
| =item $passport->slot_offset()
 | |
| 
 | |
| Required by SNMP::Info::SONMP.  Returns 0.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =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::RapidCity
 | |
| 
 | |
| See documentation in L<SNMP::Info::RapidCity/"GLOBALS"> for details.
 | |
| 
 | |
| =head2 Globals imported from SNMP::Info::Layer3
 | |
| 
 | |
| See documentation in 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 $passport->i_index()
 | |
| 
 | |
| Returns SNMP IID to Interface index.  Extends (C<ifIndex>) by adding the index
 | |
| of the CPU virtual management IP (if present), each CPU Ethernet port, and
 | |
| each VLAN to ensure the virtual router ports are captured.
 | |
| 
 | |
| =item $passport->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 = (C<ifIndex % index_factor>) + port_offset,
 | |
| slot = int(C<ifIndex / index_factor>).
 | |
| 
 | |
| The physical port name is returned as slot.port.  CPU Ethernet ports are
 | |
| prefixed with CPU and VLAN interfaces are returned as the VLAN ID prefixed
 | |
| with Vlan.
 | |
| 
 | |
| =item $passport->i_mac()
 | |
| 
 | |
| MAC address of the interface.  Note this is just the MAC of the port, not
 | |
| anything connected to it.
 | |
| 
 | |
| =item $passport->i_description()
 | |
| 
 | |
| Description of the interface. Usually a little longer single word name that is both
 | |
| human and machine friendly.  Not always.
 | |
| 
 | |
| =item $passport->i_name()
 | |
| 
 | |
| Crosses rc_alias() (C<rcPortName>) with ifAlias() and returns the human set
 | |
| port name if exists.
 | |
| 
 | |
| =item $passport->ip_index()
 | |
| 
 | |
| Maps the IP Table to the IID.  Extends (C<ipAdEntIfIndex>) by adding the index of
 | |
| the CPU virtual management IP (if present) and each CPU Ethernet port.
 | |
| 
 | |
| =item $passport->ip_netmask()
 | |
| 
 | |
| Extends (C<ipAdEntNetMask>) by adding the mask of the CPU virtual management
 | |
| IP (if present) and each CPU Ethernet port.
 | |
| 
 | |
| =item $passport->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 since some devices seem to have
 | |
| problems with F<BRIDGE-MIB>
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Forwarding Table
 | |
| 
 | |
| These methods utilize, in order; F<Q-BRIDGE-MIB>, F<BRIDGE-MIB>, and
 | |
| F<RAPID-CITY> to obtain the forwarding table information.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $passport->fw_mac()
 | |
| 
 | |
| Returns reference to hash of forwarding table MAC Addresses
 | |
| 
 | |
| (C<dot1qTpFdbAddress>), (C<dot1dTpFdbAddress>), (C<rcBridgeTpFdbAddress>)
 | |
| 
 | |
| =item $passport->fw_port()
 | |
| 
 | |
| Returns reference to hash of forwarding table entries port interface
 | |
| identifier (iid)
 | |
| 
 | |
| (C<dot1qTpFdbPort>), (C<dot1dTpFdbPort>), (C<rcBridgeTpFdbPort>)
 | |
| 
 | |
| =item $passport->fw_status()
 | |
| 
 | |
| Returns reference to hash of forwarding table entries status
 | |
| 
 | |
| (C<dot1qTpFdbStatus>), (C<dot1dTpFdbStatus>), (C<rcBridgeTpFdbStatus>)
 | |
| 
 | |
| =item $passport->qb_fw_vlan()
 | |
| 
 | |
| Returns reference to hash of forwarding table entries VLAN ID
 | |
| 
 | |
| (C<dot1qFdbId>), (C<rcBridgeTpFdbVlanId>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Pseudo F<ENTITY-MIB> information
 | |
| 
 | |
| These devices do not support F<ENTITY-MIB>.  These methods emulate Physical
 | |
| Table methods using the F<RAPID-CITY MIB>.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $passport->e_index()
 | |
| 
 | |
| Returns reference to hash.  Key and Value: Integer. The index is created by
 | |
| combining the slot, module, and position into a five or six digit integer.
 | |
| Slot can be either one or two digits while the module and position are each
 | |
| two digits padded with leading zero if required.
 | |
| 
 | |
| =item $passport->e_class()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: General hardware type.  This
 | |
| class only returns container, module, and power supply types.
 | |
| 
 | |
| =item $passport->e_descr()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Human friendly name.
 | |
| 
 | |
| =item $passport->e_name()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Human friendly name.
 | |
| 
 | |
| =item $passport->e_hwver()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Hardware version.
 | |
| 
 | |
| =item $passport->e_vendor()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: avaya.
 | |
| 
 | |
| =item $passport->e_serial()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Serial number.
 | |
| 
 | |
| =item $passport->e_pos()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: The relative position among all
 | |
| entities sharing the same parent.
 | |
| 
 | |
| =item $passport->e_type()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: Type of component/sub-component.
 | |
| 
 | |
| =item $passport->e_parent()
 | |
| 
 | |
| Returns reference to hash.  Key: IID, Value: The value of e_index() for the
 | |
| entity which 'contains' this entity.  A value of zero indicates	this entity
 | |
| is not contained in any other entity.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =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::RapidCity
 | |
| 
 | |
| See documentation in L<SNMP::Info::RapidCity/"TABLE METHODS"> for details.
 | |
| 
 | |
| =head2 Table Methods imported from SNMP::Info::Layer3
 | |
| 
 | |
| See documentation in L<SNMP::Info::Layer3/"TABLE METHODS"> for details.
 | |
| 
 | |
| =cut
 |