561 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			561 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| # SNMP::Info::IPv6
 | |
| #
 | |
| # Copyright (c) 2010 Jeroen van Ingen and Carlos Vicente
 | |
| # 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::IPv6;
 | |
| 
 | |
| use strict;
 | |
| use warnings;
 | |
| use Exporter;
 | |
| use SNMP::Info;
 | |
| 
 | |
| @SNMP::Info::IPv6::ISA       = qw/SNMP::Info Exporter/;
 | |
| @SNMP::Info::IPv6::EXPORT_OK = qw//;
 | |
| 
 | |
| our ($VERSION, %MIBS, %FUNCS, %GLOBALS, %MUNGE, $METHOD);
 | |
| 
 | |
| use constant {
 | |
|     IPMIB   => 1,
 | |
|     CISCO   => 2,
 | |
|     IPV6MIB => 3,
 | |
| };
 | |
| 
 | |
| $VERSION = '3.72';
 | |
| 
 | |
| 
 | |
| 
 | |
| %MIBS = (
 | |
|     'IP-MIB'            => 'ipv6InterfaceTableLastChange',
 | |
|     'IPV6-MIB'          => 'ipv6IfTableLastChange',
 | |
|     'CISCO-IETF-IP-MIB' => 'cInetNetToMediaNetAddress',
 | |
| );
 | |
| 
 | |
| %GLOBALS = ();
 | |
| 
 | |
| %FUNCS = (
 | |
|     'ip_n2p_phys_addr'  => 'ipNetToPhysicalPhysAddress',    # IP-MIB
 | |
|     'c_inet_phys_addr'  => 'cInetNetToMediaPhysAddress',    # CISCO-IETF-IP-MIB
 | |
|     'i6_n2p_phys_addr'  => 'ipv6NetToMediaPhysAddress',     # IPV6-MIB
 | |
| 
 | |
|     'ip_n2p_phys_type'  => 'ipNetToPhysicalType',           # IP-MIB
 | |
|     'c_inet_phys_type'  => 'cInetNetToMediaType',           # CISCO-IETF-IP-MIB
 | |
|     'i6_n2p_phys_type'  => 'ipv6NetToMediaType',            # IPV6-MIB
 | |
| 
 | |
|     'ip_n2p_phys_state' => 'ipNetToPhysicalState',          # IP-MIB
 | |
|     'c_inet_phys_state' => 'cInetNetToMediaState',          # CISCO-IETF-IP-MIB
 | |
|     'i6_n2p_phys_state' => 'ipv6IfNetToMediaState',         # IPV6-MIB
 | |
| 
 | |
|     'ip_pfx_origin'     => 'ipAddressPrefixOrigin',         # IP-MIB
 | |
|     'c_pfx_origin'      => 'cIpAddressPfxOrigin',           # CISCO-IETF-IP-MIB
 | |
| 
 | |
|     'ip_addr6_pfx'      => 'ipAddressPrefix',               # IP-MIB
 | |
|     'c_addr6_pfx'       => 'cIpAddressPrefix',              # CISCO-IETF-IP-MIB
 | |
| 
 | |
|     # Commented out are not-accessible according to MIB
 | |
|     #'ip_addr6_pfxlen'   => 'ipAddressPrefixLength',        # IP-MIB
 | |
|     #'c_addr6_pfxlen'    => 'cIpAddressPfxLength',          # CISCO-IETF-IP-MIB
 | |
|     'i6_addr_pfxlen'    => 'ipv6AddrPfxLength',             # IPV6-MIB
 | |
| 
 | |
|     'ip_addr6_index'    => 'ipAddressIfIndex',              # IP-MIB
 | |
|     'c_addr6_index'     => 'cIpAddressIfIndex',             # CISCO-IETF-IP-MIB
 | |
| 
 | |
|     'ip_addr6_type'     => 'ipAddressType',                 # IP-MIB
 | |
|     'c_addr6_type'      => 'cIpAddressType',                # CISCO-IETF-IP-MIB
 | |
| );
 | |
| 
 | |
| %MUNGE = (
 | |
|     'ip_n2p_phys_addr'  => \&SNMP::Info::munge_mac,
 | |
|     'c_inet_phys_addr'  => \&munge_physaddr,
 | |
|     'i6_n2p_phys_addr'  => \&SNMP::Info::munge_mac,
 | |
| );
 | |
| 
 | |
| 
 | |
| sub ipv6_n2p_mac {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $phys_addr = &_test_methods( $info, {
 | |
|         ip_n2p_phys_addr => IPMIB,
 | |
|         c_inet_phys_addr => CISCO,
 | |
|         i6_n2p_phys_addr => IPV6MIB,
 | |
|     });
 | |
|     return unless defined $phys_addr;
 | |
|     foreach my $row (keys %$phys_addr) {
 | |
|         if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) {
 | |
|             my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4;
 | |
|             if ($info::METHOD == IPV6MIB) {
 | |
|                 # IPV6-MIB doesn't include the addrtype in the index;
 | |
|                 # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes)
 | |
|                 $v6addr = join('.', $addrtype, $addrsize, $v6addr);
 | |
|                 $addrtype = 2;
 | |
|             }
 | |
|             if (($addrtype == 2) && (defined $phys_addr->{$row})) { # IPv6
 | |
|                 $return->{$row} = substr($phys_addr->{$row}, 0, 17);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_n2p_addr {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $net_addr = &_test_methods( $info, {
 | |
|         ip_n2p_phys_addr => IPMIB,
 | |
|         c_inet_phys_addr => CISCO,
 | |
|         i6_n2p_phys_addr => IPV6MIB,
 | |
|     });
 | |
|     return unless defined $net_addr;
 | |
|     foreach my $row (keys %$net_addr) {
 | |
|         if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) {
 | |
|             my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4;
 | |
|             if ($info::METHOD == IPV6MIB) {
 | |
|                 # IPV6-MIB doesn't include the addrtype in the index;
 | |
|                 # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes)
 | |
|                 $v6addr = join('.', $addrtype, $addrsize, $v6addr);
 | |
|                 $addrtype = 2;
 | |
|             }
 | |
|             if ($addrtype == 2) { # IPv6
 | |
|                 my $v6_packed = pack("C*", split(/\./, $v6addr));
 | |
|                 if (length($v6_packed) == 15) {
 | |
|                     # Workaround for some some IP-MIB implementations, eg on Cisco Nexus: no explicit addrsize,
 | |
|                     # so what we've collected in that variable is actually the first byte of the address.
 | |
|                     $v6_packed = pack('C', $addrsize) . $v6_packed;
 | |
|                 }
 | |
|                 if (length($v6_packed) == 17) {
 | |
|                     # Workaround for IPV6-MIB on Windows 2012: if the address is one byte too long, the SNMP agent probably has an incorrect
 | |
|                     # implementation where a length field precedes the actual IPv6 address.
 | |
|                     # In that case, the first character should be chr(16), ie 0x10; strip it if that's the case.
 | |
|                     $v6_packed =~ s/^\x10//;
 | |
|                 }
 | |
|                 if (length($v6_packed) == 16) {
 | |
|                     $v6addr = join(':', map { sprintf("%04x", $_) } unpack("n*", $v6_packed) );
 | |
|                     $return->{$row} = $v6addr;
 | |
|                 } else {
 | |
|                     printf("Invalid size for IPv6 address: expected 16 bytes, got %d (%s = %s)\n", length($v6_packed), $row, $net_addr->{$row});
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_n2p_if {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $phys_addr = &_test_methods( $info, {
 | |
|         ip_n2p_phys_addr => IPMIB,
 | |
|         c_inet_phys_addr => CISCO,
 | |
|         i6_n2p_phys_addr => IPV6MIB,
 | |
|     });
 | |
|     return unless defined $phys_addr;
 | |
|     foreach my $row (keys %$phys_addr) {
 | |
|         if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) {
 | |
|             my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4;
 | |
|             if ($info::METHOD == IPV6MIB) {
 | |
|                 # IPV6-MIB doesn't include the addrtype in the index;
 | |
|                 # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes)
 | |
|                 $v6addr = join('.', $addrtype, $addrsize, $v6addr);
 | |
|                 $addrtype = 2;
 | |
|             }
 | |
|             if ($addrtype == 2) { # IPv6
 | |
|                 $return->{$row} = $ifindex;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_n2p_type {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $phys_type = &_test_methods( $info, {
 | |
|         ip_n2p_phys_type => IPMIB,
 | |
|         c_inet_phys_type => CISCO,
 | |
|         i6_n2p_phys_type => IPV6MIB,
 | |
|     });
 | |
|     return unless defined $phys_type;
 | |
|     foreach my $row (keys %$phys_type) {
 | |
|         if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) {
 | |
|             my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4;
 | |
|             if ($info::METHOD == IPV6MIB) {
 | |
|                 # IPV6-MIB doesn't include the addrtype in the index;
 | |
|                 # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes)
 | |
|                 $v6addr = join('.', $addrtype, $addrsize, $v6addr);
 | |
|                 $addrtype = 2;
 | |
|             }
 | |
|             if ($addrtype == 2) { # IPv6
 | |
|                 $return->{$row} = $phys_type->{$row};
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_n2p_state {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $phys_state = &_test_methods( $info, {
 | |
|         ip_n2p_phys_state => IPMIB,
 | |
|         c_inet_phys_state => CISCO,
 | |
|         i6_n2p_phys_state => IPV6MIB,
 | |
|     });
 | |
|     return unless defined $phys_state;
 | |
|     foreach my $row (keys %$phys_state) {
 | |
|         if ($row =~ /^(\d+)\.(\d+)\.(\d+)\.([\d\.]+)$/) {
 | |
|             my $ifindex = $1; my $addrtype = $2; my $addrsize = $3; my $v6addr = $4;
 | |
|             if ($info::METHOD == IPV6MIB) {
 | |
|                 # IPV6-MIB doesn't include the addrtype in the index;
 | |
|                 # also, address syntax is IPv6Address (fixed 16 bytes) and not InetAddress (length field followed by address bytes)
 | |
|                 $v6addr = join('.', $addrtype, $addrsize, $v6addr);
 | |
|                 $addrtype = 2;
 | |
|             }
 | |
|             if ($addrtype == 2) { # IPv6
 | |
|                 $return->{$row} = $phys_state->{$row};
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_index {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $ipv6_index = &_test_methods( $info, {
 | |
| 	ip_addr6_index  => IPMIB,
 | |
| 	c_addr6_index   => CISCO,
 | |
| 				    });
 | |
|     return unless defined $ipv6_index;
 | |
|     foreach my $row (keys %$ipv6_index){
 | |
|         if ($row =~ /^(\d+)\.([\d\.]+)$/) {
 | |
|             my $addrtype = $1; my $v6addr = $2;
 | |
|             if ($addrtype == 2) { # IPv6
 | |
| 		$return->{$row} = $ipv6_index->{$row};
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_type {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $ipv6_type = &_test_methods( $info, {
 | |
| 	ip_addr6_type  => IPMIB,
 | |
| 	c_addr6_type   => CISCO,
 | |
| 				    });
 | |
|     return unless defined $ipv6_type;
 | |
|     foreach my $row (keys %$ipv6_type){
 | |
|         if ($row =~ /^(\d+)\.([\d\.]+)$/) {
 | |
|             my $addrtype = $1; my $v6addr = $2;
 | |
|             if ($addrtype == 2) { # IPv6
 | |
| 		$return->{$row} = $ipv6_type->{$row};
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_pfx_origin {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $ipv6_pfx_origin = &_test_methods( $info, {
 | |
| 	ip_pfx_origin  => IPMIB,
 | |
| 	c_pfx_origin   => CISCO,
 | |
| 				    });
 | |
|     return unless defined $ipv6_pfx_origin;
 | |
|     foreach my $row (keys %$ipv6_pfx_origin){
 | |
|         if ($row =~ /^(\d+)\.(\d+)\.([\d\.]+)\.(\d+)$/) {
 | |
|             my $ifindex = $1; my $type = $2; my $pfx = $3; my $len = $4;
 | |
|             if ($type == 2) { # IPv6
 | |
| 		$return->{$row} = $ipv6_pfx_origin->{$row};
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_addr_prefix {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $ipv6_addr_prefix = &_test_methods( $info, {
 | |
| 	ip_addr6_pfx  => IPMIB,
 | |
| 	c_addr6_pfx   => CISCO,
 | |
| 				    });
 | |
|     return unless defined $ipv6_addr_prefix;
 | |
|     foreach my $row (keys %$ipv6_addr_prefix){
 | |
|         if ($row =~ /^(\d+)\.[\d\.]+$/) {
 | |
|             my $type = $1;
 | |
| 	    if (($type == 2) or ($type == 4)) { # IPv6
 | |
| 		# Remove interface specific part from vrf interfaces
 | |
| 		if ($row =~ /^((\d+\.){17}\d+)/) { $row = $1 }
 | |
| 		# Remove the OID part from the value
 | |
| 		my $val = $ipv6_addr_prefix->{$row};
 | |
| 		if ( $val =~ /^.+?((?:\d+\.){19}\d+)$/ ){
 | |
| 		    $val = $1;
 | |
| 		    $return->{$row} = $val;
 | |
| 		}
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_addr_prefixlength {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $ipv6_addr_prefix = &_test_methods( $info, {
 | |
|         ip_addr6_pfx  => IPMIB,
 | |
|         c_addr6_pfx   => CISCO,
 | |
|     });
 | |
|     return unless defined $ipv6_addr_prefix;
 | |
|     foreach my $row (keys %$ipv6_addr_prefix) {
 | |
|         if ($row =~ /^(\d+)\.[\d\.]+$/) {
 | |
|             my $type = $1;
 | |
|             if (($type == 2) or ($type == 4)) { # IPv6
 | |
|                 # Remove interface specific part from vrf interfaces
 | |
|                 if ($row =~ /^((\d+\.){17}\d+)/) { $row = $1 }
 | |
|                 # Remove the OID part from the value
 | |
|                 my $val = $ipv6_addr_prefix->{$row};
 | |
|                 if ( $val =~ /^.+?((?:\d+\.){19}(\d+))$/ ) {
 | |
|                     $val = $2;
 | |
|                     $return->{$row} = $val;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     printf("%s: data comes from %s.\n", &_my_sub_name, $info->_method_used() ) if $info->debug();
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub ipv6_addr {
 | |
|     my $info = shift;
 | |
|     my $return;
 | |
|     my $indexes = $info->ipv6_index();
 | |
|     foreach my $row (keys %$indexes) {
 | |
|         my @parts = split(/\./, $row);
 | |
|         my $is_valid = 0;
 | |
|         if (scalar @parts == 18) {
 | |
|             my $addrtype = shift @parts;
 | |
|             $is_valid = 1;
 | |
|         } elsif (scalar @parts == 17) {
 | |
|             $is_valid = 1;
 | |
|         }
 | |
|         my $addrsize = shift @parts; # First element now is addrsize, should be 16
 | |
|         if ($is_valid && $addrsize == 16) {
 | |
|             $return->{$row} = join(':', unpack('(H4)*', pack('C*', @parts)));
 | |
|         } else {
 | |
|             warn sprintf("%s: unable to decode table index to IPv6 address. Raw data is [%s].\n", &_my_sub_name, $row);
 | |
|         }
 | |
|     }
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub _method_used {
 | |
|     my $info = shift;
 | |
|     my $return = 'none of the MIBs';
 | |
|     # FIXME ugh! a global. makes order of calls important for debug.
 | |
|     if (defined $info::METHOD) {
 | |
|         if ($info::METHOD eq IPMIB) {
 | |
|             $return = 'IP-MIB';
 | |
|         } elsif ($info::METHOD eq IPV6MIB) {
 | |
|             $return = 'IPV6-MIB';
 | |
|         } elsif ($info::METHOD eq CISCO) {
 | |
|             $return = 'CISCO-IETF-IP-MIB';
 | |
|         }
 | |
|     }
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub _test_methods {
 | |
|     my $info = shift;
 | |
|     my $test = shift;
 | |
|     my $return = {};
 | |
|     foreach my $method (sort {$test->{$a} <=> $test->{$b}} keys %$test) {
 | |
|         $return = $info->$method || {};
 | |
|         if (scalar keys %$return) {
 | |
|             # FIXME ugh! a global. makes order of calls important for debug.
 | |
|             $info::METHOD = $test->{$method};
 | |
|             last;
 | |
|         }
 | |
|     }
 | |
|     return $return;
 | |
| }
 | |
| 
 | |
| sub _my_sub_name {
 | |
|     my @callinfo = caller(1);
 | |
|     return $callinfo[3];
 | |
| }
 | |
| 
 | |
| sub munge_physaddr {
 | |
|     my $addr = shift;
 | |
|     return unless defined $addr;
 | |
|     return unless length $addr;
 | |
|     $addr = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $addr ) );
 | |
|     return $addr;
 | |
| }
 | |
| 
 | |
| 1;
 | |
| 
 | |
| __END__
 | |
| 
 | |
| =head1 NAME
 | |
| 
 | |
| SNMP::Info::IPv6 - SNMP Interface for obtaining IPv6 addresses and IPv6
 | |
| address mappings
 | |
| 
 | |
| =head1 AUTHOR
 | |
| 
 | |
| Jeroen van Ingen and Carlos Vicente
 | |
| 
 | |
| =head1 SYNOPSIS
 | |
| 
 | |
|  # Let SNMP::Info determine the correct subclass for you.
 | |
|  my $info = new SNMP::Info(
 | |
|                           AutoSpecify => 1,
 | |
|                           Debug       => 1,
 | |
|                           DestHost    => 'myswitch',
 | |
|                           Community   => 'public',
 | |
|                           Version     => 2
 | |
|                         )
 | |
|     or die "Can't connect to DestHost.\n";
 | |
| 
 | |
|  my $class      = $info->class();
 | |
|  print "SNMP::Info determined this device to fall under subclass : $class\n";
 | |
| 
 | |
| =head1 DESCRIPTION
 | |
| 
 | |
| The SNMP::Info::IPv6 class implements functions to for mapping IPv6 addresses
 | |
| to MAC addresses, interfaces and more. It will use data from the F<IP-MIB>,
 | |
| F<IPV6-MIB>, or the F<CISCO-IETF-IP-MIB>, whichever is supported by the
 | |
| device.
 | |
| 
 | |
| This class is inherited by Info::Layer3 to provide IPv6 node tracking across
 | |
| device classes.
 | |
| 
 | |
| For debugging purposes you can call this class directly as you would
 | |
| SNMP::Info
 | |
| 
 | |
|  my $info = new SNMP::Info::IPv6 (...);
 | |
| 
 | |
| =head2 Inherited Classes
 | |
| 
 | |
| none.
 | |
| 
 | |
| =head2 Required MIBs
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item F<IP-MIB>
 | |
| 
 | |
| =item F<IPV6-MIB>
 | |
| 
 | |
| =item F<CISCO-IETF-IP-MIB>
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 GLOBALS
 | |
| 
 | |
| none.
 | |
| 
 | |
| =head1 TABLE METHODS
 | |
| 
 | |
| These are methods that return tables of information in the form of a reference
 | |
| to a hash.
 | |
| 
 | |
| =head2  Internet Address Table
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $info->ipv6_n2p_addr()
 | |
| 
 | |
| =item $info->ipv6_n2p_if()
 | |
| 
 | |
| =item $info->ipv6_n2p_mac()
 | |
| 
 | |
| =item $info->ipv6_n2p_state()
 | |
| 
 | |
| =item $info->ipv6_n2p_type()
 | |
| 
 | |
| =item $info->ipv6_index()
 | |
| 
 | |
| Maps an IPv6 address to an interface C<ifIndex>
 | |
| 
 | |
| =item $info->ipv6_type()
 | |
| 
 | |
| Maps an IPv6 address to its type (unicast, anycast, etc.)
 | |
| 
 | |
| =item $info->ipv6_pfx_origin()
 | |
| 
 | |
| Maps an IPv6 prefix with its origin (manual, well-known, dhcp, etc.)
 | |
| 
 | |
| =item $info->ipv6_addr_prefix()
 | |
| 
 | |
| Maps IPv6 addresses with their prefixes
 | |
| 
 | |
| =item $info->ipv6_addr_prefixlength()
 | |
| 
 | |
| Maps IPv6 addresses with their prefix length
 | |
| 
 | |
| =item $info->ipv6_addr()
 | |
| 
 | |
| Maps a table instance to an IPv6 address
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2  Internet Address Translation Table
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $info->c_inet_phys_address()
 | |
| 
 | |
| Maps an address of type C<cInetNetToMediaNetAddressType> on interface C<ifIndex> to a physical address.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 MUNGES
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item munge_physaddr()
 | |
| 
 | |
| Takes an octet stream (HEX-STRING) and returns a colon separated ASCII hex
 | |
| string.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =cut
 |