package Router::Statistics::Cisco;

use strict vars;
use Router::Statistics::OID;
use Net::SNMP qw (:snmp :asn1);

# this is the core module to Poll Cisco Routers and CPE equipment connected to them.
# the code is relatively simple however there are some Cisco IOS bug work arounds in
# place.

our $VERSION = '6.001';

# Andrew S. Kennedy 23 November 2006.

# Module now semi supports blocking and non blocking mode.
# It has been discovered that non-blocking is significantly longer to
# execute. Not entirely sure why, however to speed things up
# some functions now have _Blocking mirrors so they can be called
# instead.

# Added support to retrieve the STM information very simple implementation
# to poll the STM mib provided on Cisco equipment.

# Bug in Cisco IOS ( ooo shock ) for STM CSCsg21480
# if you poll the STM mib when STM is not active, you can crash the router involved.

# Added Network Link Map Generator
# Added CPE snmp read key cycler ( not finished ).

sub new {

        my $self = {};
	bless $self;

	my ( $class , $attr ) =@_;

	while (my($field, $val) = splice(@{$attr}, 0, 2)) 
		{ $self->{_GLOBAL}{$field}=$val; }

	$self->{_GLOBAL}{'STATUS'}="OK";

        return $self;
}

sub get_globals
{ my $self=shift; return $self->{_GLOBAL}; }

sub get_global
{ my $self=shift; my $attribute=shift; return $self->{_GLOBAL}{$attribute}; }

sub get_status
{ 
my $self = shift;
return $self->get_global('STATUS'); 
}

sub CPE_Remove
{
my $self = shift;
my $ip_address = shift;

if ( !$self->{_GLOBAL}{'CPE'}{$ip_address} )
        { $self->{_GLOBAL}{STATUS}="CPE IP Address Not Added"; return 0; }
$self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'}->close();
delete ($self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'});
delete ($self->{_GLOBAL}{'CPE'}{$ip_address});
return 1;
}


sub CPE_Ready
{
my $self = shift;
my $ip_address = shift;
my $oids = shift;

if ( !$self->{_GLOBAL}{'CPE'}{$ip_address} )
	{ 
	print "Not added '$ip_address' failed ready'\n";
	$self->{_GLOBAL}{STATUS}="CPE IP Address Not Added"; return 0; }

my ( $session, $error ) =
		Net::SNMP->session(
			-hostname  =>  $ip_address,
			-community =>  $self->{_GLOBAL}{'CPE'}{$ip_address}{'key'},
			-port 	   =>  161,
			-timeout   =>  $self->{_GLOBAL}{'CPE'}{$ip_address}{'timeout'},
			-version   =>  "snmpv2c",
			-nonblocking => 1,
			-retries   =>  0,
			-translate =>   [-timeticks => 0x0,-octetstring     => 0x0]
				);

if ( $error )
	{
	$self->{_GLOBAL}{'STATUS'}=$error;
	undef $session;
	return 0;
	}
$self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'}=$session;
$self->{_GLOBAL}{'CPE'}{$ip_address}{'OID'}=$oids;
return 1;
}

sub Router_Ready
{
my $self = shift;

my $ip_address = shift;

if ( !$self->{_GLOBAL}{'Router'}{$ip_address} )
        { $self->{_GLOBAL}{STATUS}="UBR IP Address Not Added"; return 0; }
	
my ($session, $error) = 
		Net::SNMP->session(
      			-hostname  =>  $ip_address,
      			-community =>  $self->{_GLOBAL}{'Router'}{$ip_address}{'key'},
       			-port      =>  161,
 	       		-timeout   =>  $self->{_GLOBAL}{'Router'}{$ip_address}{'timeout'},
 	       		-version   =>  "snmpv2c",
			-translate =>  [-timeticks => 0x0,-octetstring     => 0x0],
			-nonblocking => 1,
       			-retries   =>  2 );
if ( $error )
	{
	$self->{_GLOBAL}{'STATUS'}=$error;
	undef $session;
	return 0;
	}
$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}=$session;
return 1;
}

sub Router_Ready_Blocking
{
my $self = shift;

my $ip_address = shift;

if ( !$self->{_GLOBAL}{'Router'}{$ip_address} )
        { $self->{_GLOBAL}{STATUS}="UBR IP Address Not Added"; return 0; }

my ($session, $error) =
		Net::SNMP->session(
			-hostname  =>  $ip_address,
			-community =>  $self->{_GLOBAL}{'Router'}{$ip_address}{'key'},
			-port      =>  161,
			-timeout   =>  $self->{_GLOBAL}{'Router'}{$ip_address}{'timeout'},
			-version   =>  "snmpv2c",
			-translate =>  [-timeticks => 0x0,-octetstring     => 0x0],
			-nonblocking => 0,
			-retries   =>  2 );
if ( $error )
	{
	$self->{_GLOBAL}{'STATUS'}=$error;
	undef $session;
	return 0;
	}
$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}=$session;
return 1;
}


sub CPE_Return_All
{
my $self = shift;
return $self->{_GLOBAL}{'CPE'};
}

sub UBR_Return_All
{
my $self = shift;
return $self->{_GLOBAL}{'Router'};
}

sub CPE_Add
{
my $self = shift;
my $ip_address = shift;
my $snmp_key = shift;
my $router = shift;
my $cpe_id = shift;
my $timeout = shift;
if ( !$ip_address || !$snmp_key )
	{ $self->{_GLOBAL}{STATUS}="No IP Address or SNMP Key Specified."; return 0; }

if ( !$timeout )
	{ $timeout=2; }

$self->{_GLOBAL}{'CPE'}{$ip_address}{'key'}=$snmp_key;
$self->{_GLOBAL}{'CPE'}{$ip_address}{'router'}=$router;
$self->{_GLOBAL}{'CPE'}{$ip_address}{'timeout'}=$timeout;
$self->{_GLOBAL}{'CPE'}{$ip_address}{'id'} = $cpe_id;
return 1;
}

sub Router_Add
{
my $self = shift;
my $ip_address = shift;
my $snmp_key = shift;
my $timeout = shift;
if ( !$ip_address || !$snmp_key )
        { $self->{_GLOBAL}{STATUS}="No IP Address or SNMP Key Specified."; return 0; }

if ( !$timeout ) { $timeout=1; }
$self->{_GLOBAL}{'Router'}{$ip_address}{'key'}=$snmp_key;
$self->{_GLOBAL}{'Router'}{$ip_address}{'timeout'}=$timeout;
return 1;
}

sub UBR_Remove
{
my $self = shift;
my $ip_address = shift;
if ( !$ip_address )
	{ $self->{_GLOBAL}{STATUS}="No IP Address Specified."; return 0; }
delete ( $self->{_GLOBAL}{'Router'}{$ip_address} );
return 1;
}

sub CPE_Remove
{
my $self = shift;
my $ip_address = shift;
if ( !$ip_address )
	{ $self->{_GLOBAL}{STATUS}="No IP Address Specified."; return 0; }
delete ( $self->{_GLOBAL}{'CPE'}{$ip_address} );
return 1;
}

sub CPE_export_import_fields
{
my $self = shift;
my $fields = shift;
$self->{_GLOBAL}{'EXPORT'}{'CPE'}=$fields;
return 1;
}

sub CPE_export_fields
{
my $self = shift;
return $self->{_GLOBAL}{'EXPORT'}{'CPE'};
}

sub CPE_export_schema
{
my $self = shift;
my $handle = shift;
my $format = shift;
my $fields = $self->CPE_return_export_fields();

if ( $format=~/xml-dtd/i )
        {
	# we generate a DTD and XML schema, then the user can break them up as needed
	my $output;
	print $handle "<!ELEMENT cpe (";
	foreach my $field ( @{$fields} ) { $output.="$field,"; } chop($output);
	print $handle $output;
	print $handle ")>\n";
        print $handle "<cpe>\n";
        foreach my $field ( @{$fields} ) { print $handle "<!ELEMENT> $field (#PCDATA)>\n"; }
        }

if ( $format!~/xml-dtd/i )
	{ $self->{_GLOBAL}{STATUS}="Only xml-dtd supported at this time.";return 0;}

return 1;
}

sub CPE_export_data_start
{
my $self = shift;
$self->{_GLOBAL}{'EXPORT'}{'START'}=1;
return 1;
}

sub CPE_export_data_end
{
my $self;
$self->{_GLOBAL}{'EXPORT'}{'START'}=0;
return 1;
}

sub CPE_export_data
{
my $self = shift;
my $ip_address = shift;
my $cpe_data = shift;
my $format = shift;
my $handle = shift;

if ( !${$cpe_data}{$ip_address} )
	{ $self->{_GLOBAL}{STATUS}="No CPE Data Found."; return 0; }

if ( !$format )
	{ $self->{_GLOBAL}{STATUS}="Format Not Specified."; return 0; }

if ( !$handle )
	{ $self->{_GLOBAL}{STATUS}="Output Handle Not Specified."; return 0; }

my $fields = $self->CPE_export_fields();

if ( !$fields )
        { $self->{_GLOBAL}{STATUS}="Output Fields Not Specified."; return 0; }

if ( $self->{_GLOBAL}{'EXPORT'}{'START'}==1 && $format=~/xml/i )
	{
	print $handle "<?xml version=\"1.0\"?>\n";
	$self->{_GLOBAL}{'EXPORT'}{'START'}=0;
	}

if ( $self->{_GLOBAL}{'EXPORT'}{'START'}==1 && $format=~/csv/i )
	{
	my $output="";
	foreach my $field ( @{$fields} ){ $output.="\"".$field."\","; }; chop($output);
	print $handle $output."\n";
	$self->{_GLOBAL}{'EXPORT'}{'START'}=0;
	}

if ( $format=~/xml/i )
	{
	print $handle "<cpe>\n";
	foreach my $field ( @{$fields} )
		{ print $handle "<$field>".${$cpe_data}{$ip_address}{$field}."</$field>\n"; 
		}
	print $handle "</cpe>\n";
	}

if ( $format=~/csv/i )
	{
	my $output;
	foreach my $field ( @{$fields} )
		{ $output.="\"".${$cpe_data}{$ip_address}{$field}."\","; }
	chop($output);
	$output.="\n";
	print $handle $output;
	}

if ( $format!~/xml/i && $format!~/csv/i )
	{ $self->{_GLOBAL}{STATUS}="Format Specified is not supported, only 'xml or csv'."; return 0; }

return 1;
}

sub CPE_gather_all_data_walk
{
my $self = shift;
my $data = shift;

# Entry into the function is a point to a hash to store the data
# the result is a hash with the following

my $cpes=$self->CPE_Return_All();

if ( scalar ( keys %{$cpes}==0 ) )
        { $self->{_GLOBAL}{'STATUS'}="No CPEs setup"; return 0; }

my $snmp_variables = Router::Statistics::OID->CPE_populate_oid();

foreach my $cpe ( keys %{$cpes} )
	{
		my ($interface_information)=${$cpes}{$cpe}{'SESSION'}->
        	        get_table(
        	                -callback       => [ \&validate_one_cpe, $data, $cpe, $snmp_variables ],
        	                -baseoid => ${$cpes}{$cpe}{'OID'} );
	}

snmp_dispatcher();

if ( scalar ( keys %{$data} ) == 0 )
        { $self->{_GLOBAL}{'STATUS'}="No CPE Data Found.\n"; return 0; }

return 1;
}

sub CPE_gather_all_data
{
my $self = shift;
my $data = shift;

# Entry into the function is a point to a hash to store the data
# the result is a hash with the following

my $cpes=$self->CPE_Return_All();

if ( scalar ( keys %{$cpes}==0 ) )
        { $self->{_GLOBAL}{'STATUS'}="No CPEs setup"; return 0; }

my $snmp_variables = Router::Statistics::OID->CPE_populate_oid();

foreach my $cpe ( keys %{$cpes} )
	{
		my ($interface_information)=${$cpes}{$cpe}{'SESSION'}->
        	        get_request(
        	                -callback       => [ \&get_cpe_information, $cpe, $data, $snmp_variables ],
        	                -varbindlist =>
        	                  ${$cpes}{$cpe}{'OID'} );
	}

snmp_dispatcher();

foreach my $cpe ( keys %{$data} )
	{
	foreach my $attribute ( keys %{${$data}{$cpe}} )
		{
		if ( $attribute=~/ifPhysAddress/)
			{
			${$data}{$cpe}{$attribute}=_convert_mac_address( ${$data}{$cpe}{$attribute} );
			}
		}
	}

if ( scalar ( keys %{$data} ) == 0 )
        { $self->{_GLOBAL}{'STATUS'}="No CPE Data Found.\n"; return 0; }

return 1;
}

sub Router_get_networks
{
my $self = shift;
my $data = shift;
my $interface_data = shift;
my $router_data = shift;

my $output;

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->Router_Link_Map_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
        next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
        my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
                get_table(
                -callback       => [ \&validate_six_net, $data, $ip_address, $snmp_variables ],
               -baseoid => ${$snmp_variables}{'PRIVATE_atEnt'} );
        }
snmp_dispatcher();

my $snmp_variables = Router::Statistics::OID->Router_Link_Map_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
        next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
        my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
                get_table(
                -callback       => [ \&validate_four_net, $data, $ip_address, $snmp_variables ],
               -baseoid => ${$snmp_variables}{'PRIVATE_ipEnt'} );
        }
snmp_dispatcher();

foreach my $ip_address ( keys %{$data} )
	{
	foreach my $interfaces ( keys %{${$data}{$ip_address}} )
		{
		foreach my $ips ( keys %{${$data}{$ip_address}{$interfaces}{'address'}} )
			{
			${$data}{$ip_address}{$interfaces}{'address'}{$ips}{'atPhysAddress'}=
				_convert_mac_address(${$data}{$ip_address}{$interfaces}{'atPhysAddress'});
			}
		}
	}

foreach my $ip_address ( keys %{$data} )
	{
	foreach my $interfaces ( keys %{${$data}{$ip_address}} )
		{
		foreach my $ips ( keys %{${$data}{$ip_address}{$interfaces}{'address'}} )
			{
			my $real_address = $self->_IpQuadToInt( $ips );
			my $real_netmask = $self->_IpQuadToInt( ${$data}{$ip_address}{$interfaces}{'address'}{$ips}{'ipAdEntNetMask'} );
			my $network_address = $real_address&$real_netmask ;
			${$data}{$ip_address}{$interfaces}{'ipAdEntNetWork'} = $self->_IpIntToQuad( $network_address );
			${$data}{$ip_address}{$interfaces}{'ipAdEntNetMask'} = ${$data}{$ip_address}{$interfaces}{'address'}{$ips}{'ipAdEntNetMask'};
			}
		}
	}

my %interface_remapper;
my %interface_map;
my %remote_map;
my %network_map;
my %router_owners;

foreach my $router ( keys %{$data} )
        {
        foreach my $interface ( keys %{${$data}{$router}} )
                {
                foreach my $ip_address ( keys %{${$data}{$router}{$interface}{'address'}} )
                        {
                        next unless ${$data}{$router}{$interface}{'address'}{$ip_address}{'ipAdEntNetMask'};
                        $router_owners{$ip_address}=$router;
                        my $network_layer = $self->_IpQuadToInt( $ip_address )
                                        &
                                        $self->_IpQuadToInt(
                                                ${$data}{$router}{$interface}{'address'}{$ip_address}{'ipAdEntNetMask'}
                                                        );
                        $network_map { $network_layer } {$ip_address}=$router;
                        if ( ${$data}{$router}{$interface}{'address'}{$ip_address}{'ipAdEntIfIndex'} )
                                {
                                $interface_map{${$data}{$router}{$interface}{'ipAdEntNetWork'}}{$router}=1;
                                }
                                else
                                {
                                $remote_map{$router}{${$interface_data}{$router}{$interface}{'ifDescr'} } { $ip_address } =1;
                                }
                        }
                }
        }

$output.="router_ip,router_name,link_ifDescr,local_ip,remote_ip,remote_router_ip,remote_router_name,netmask,link_ifAdminStatus,link_ifOperStatus,link_ifAlias\n";

foreach my $router ( keys %{$data} )
        {
        foreach my $interface ( keys %{${$data}{$router}} )
                {
                my ($local,$remote,$remote_router,@remote_link, $netmask, $network, @network_link );
                foreach my $ip_address ( keys %{${$data}{$router}{$interface}{'address'}} )
                        {
                        next unless ${$data}{$router}{$interface}{'address'}{$ip_address}{'ipAdEntNetMask'};
                        $netmask= ${$data}{$router}{$interface}{'address'}{$ip_address}{'ipAdEntNetMask'};
                        $local=$ip_address;
                        @remote_link=keys %{ $remote_map{$router}{ ${$interface_data}{$router}{$interface}{'ifDescr'} }};
                        if ( scalar(@remote_link) >1 ) {
                                $remote=""; } else { $remote=$remote_link[0]; }
                        if ( !$remote )
                                {
                                $remote=$ip_address if $interface_remapper{$ip_address}{$router}{'type'}=~/remote/i;
                                }
                        @remote_link=keys %{$interface_map{${$data}{$router}{$interface}{'ipAdEntNetWork'}}};
                        $remote_router="";
                        foreach my $not_local ( @remote_link )
                                { $remote_router = $not_local if $self->_IpQuadToInt($not_local)!=$self->_IpQuadToInt($ip_address); }
                        if ( $self->_IpQuadToInt($remote_router)==$self->_IpQuadToInt($router) )
                                { $remote_router=""; }
                        }

                if ( !$remote )
                        {
                        $network= $self->_IpQuadToInt($local)&$self->_IpQuadToInt($netmask);
                        @network_link = keys %{ $network_map{ $network } };
                        if ( scalar(@network_link)>1 )
                                {
                                foreach my $not_local ( @network_link )
                                        {
                                        $remote = $not_local if  $self->_IpQuadToInt($not_local)!=$self->_IpQuadToInt($local);
                                        }
                                }
                        }

                 $output .="$router,${$router_data}{$router}{'hostName'},${$interface_data}{$router}{$interface}{'ifDescr'},$local,$remote,$router_owners{$remote},${$router_data}{$router_owners{$remote}}{'hostName'},$netmask,${$interface_data}{$router}{$interface}{'ifAdminStatus'},${$interface_data}{$router}{$interface}{'ifOperStatus'},${$interface_data}{$router}{$interface}{'ifAlias'}\n";
                }
        }

return $output;
}

sub UBR_get_stm
{
my $self = shift;
my $data = shift;

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->STM_populate_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
			-callback       => [ \&validate_two_plain, $data, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'PRIVATE_stm_base'} );
	}
snmp_dispatcher();
foreach my $ip_address ( keys %{$current_ubrs} )
	{
	foreach my $instance ( keys %{${$data}{$ip_address}} )
		{
		${$data}{$ip_address}{$instance}{'ccqmEnfRuleViolateMacAddr'}=
			_convert_mac_address( ${$data}{$ip_address}{$instance}{'ccqmEnfRuleViolateMacAddr'} );
		${$data}{$ip_address}{$instance}{'ccqmEnfRuleViolateLastDetectTime'}=
			_convert_time_mask( ${$data}{$ip_address}{$instance}{'ccqmEnfRuleViolateLastDetectTime'} );
		${$data}{$ip_address}{$instance}{'ccqmEnfRuleViolatePenaltyExpTime'}=
			_convert_time_mask( ${$data}{$ip_address}{$instance}{'ccqmEnfRuleViolatePenaltyExpTime'} );
		}
	}
return 1;
}


sub Router_get_interfaces
{
my $self = shift;
my $data = shift;

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->Router_interface_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
		-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
		-baseoid => ${$snmp_variables}{'PRIVATE_interface_base'} );
	}
snmp_dispatcher();

foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
		-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
		-baseoid => ${$snmp_variables}{'ifAlias'} );
	}
snmp_dispatcher();

foreach my $ip_address ( keys %{$data} )
	{
	foreach my $interfaces ( keys %{${$data}{$ip_address}} )
		{
		${$data}{$ip_address}{$interfaces}{'ifPhysAddress'}=
			_convert_mac_address(${$data}{$ip_address}{$interfaces}{'ifPhysAddress'}); 
		${$data}{$ip_address}{$interfaces}{'ifAdminStatus'}=
			('0_Unknown','1_Up','2_Down','3_Testing')[${$data}{$ip_address}{$interfaces}{'ifAdminStatus'}];
		${$data}{$ip_address}{$interfaces}{'ifOperStatus'}=
			('0_Unknown','1_Up','2_Down','3_Testing','4_Unknown','5_Dormant','6_NotPresent','7_LowerLayerDown')
				[${$data}{$ip_address}{$interfaces}{'ifOperStatus'}];
		}
	}
return 1;
}

sub Router_get_interfaces_Blocking
{
my $self = shift;
my $data = shift;

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->Router_interface_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ( $foo, $bar );
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
		-baseoid => ${$snmp_variables}{'PRIVATE_interface_base'} );
	while(($foo, $bar) = each(%{$profile_information}))
		{
		next unless($foo =~ /^${$snmp_variables}{'PRIVATE_interface_base'}.(\d+)/);
		if ( $foo=~/^${$snmp_variables}{'ifDescr'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifDescr'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifType'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifType'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifMtu'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifMtu'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifSpeed'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifSpeed'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifPhysAddress'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifPhysAddress'}=_convert_mac_address($bar); }
		if ( $foo=~/^${$snmp_variables}{'ifAdminStatus'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifAdminStatus'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifOperStatus'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifOperStatus'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifLastChange'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifLastChange'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifInOctets'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifInOctets'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifInUcastPkts'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifInUcastPkts'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifInNUcastPkts'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifInNUcastPkts'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifInDiscards'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifInDiscards'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifInErrors'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifInErrors'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifInUnknownProtos'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifInUnknownProtos'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifOutOctets'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifOutOctets'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifOutUcastPkts'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifOutUcastPkts'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifOutNUcastPkts'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifOutNUcastPkts'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifOutDiscards'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifOutDiscards'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'ifOutErrors'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'ifOutErrors'}=$bar; }
		}
	}

return 1;
}

sub Get_7500_inventory
{
my $self = shift;
my $data = shift;
my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }
my $snmp_variables = Router::Statistics::OID->Router_inventory_oid();

my %temp;

foreach my $ip_address ( keys %{$current_ubrs} )
        {
        next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
        my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
                get_table(
                        -callback       => [ \&validate_one, \%temp, $ip_address, $snmp_variables ],
                        -baseoid => ${$snmp_variables}{'PRIVATE_inventory'} );
        }
snmp_dispatcher();

foreach my $ip_address ( keys %temp )
        {
        foreach my $relative (  keys %{$temp{$ip_address}} )
                {
		if ( $temp{$ip_address}{$relative}{'entPhysicalName'}=~/^Line Card (\d+)/ )
			{ $temp{$ip_address}{'rev'}{ $1 }{'main'}=$relative; }
		if ( $temp{$ip_address}{$relative}{'entPhysicalName'}=~/^RSP at Slot (\d+)/ )
			{ $temp{$ip_address}{'rev'}{ $1 }{'main'}=$relative; }
		if ( $temp{$ip_address}{$relative}{'entPhysicalName'}=~/^Card Slot (\d+), Bay (\d+)/ )
			{ $temp{$ip_address}{'rev'}{ $1 }{'child'}{$2}=$relative; }
		if ( $temp{$ip_address}{$relative}{'entPhysicalName'}=~/^PA at Slot (\d+), Bay (\d+)/ )
			{ ${$data}{$ip_address}{'slot'}{$1}{'child'}{$2}{'name'}="Empty"; }
                }
        foreach my $a ( keys %{$temp{$ip_address}{'rev'}} )
                {
		foreach my $child ( keys %{$temp{$ip_address}{'rev'}{$a}{'child'}} )
			{
	                foreach my $attribute ( keys %{$snmp_variables} )
        	                {
        	                next if $attribute=~/PRIVATE/;
        	                ${$data}{$ip_address}{'slot'}{$a}{'child'}{$child}{$attribute}=
                	                $temp{$ip_address}{ $temp{$ip_address}{'rev'}{$a}{'child'}{$child} } {$attribute};
				}
                        }

                foreach my $attribute ( keys %{$snmp_variables} )
                        {
                        next if $attribute=~/PRIVATE/;
                        ${$data}{$ip_address}{'slot'}{$a}{'main'}{$attribute}=
                                $temp{$ip_address}{ $temp{$ip_address}{'rev'}{$a}{'main'} }{$attribute};
                        }
		#${$data}{$ip_address}{'slot'}{$a}{'main'}{'entPhysicalDescr'}=$temp{$ip_address}{ $temp{$ip_address}{'rev'}{$a}{'main'} }{'entPhysicalDescr'};
                }
        $temp{$ip_address}{'1'}{'entPhysicalDescr'}=~/^(\d+)/;
        ${$data}{$ip_address}{'total_slots'}=substr($1,2,2);
        }
undef %temp;
return 1;
}

sub Export_7500_Slot_Inventory
{
my $self = shift;
my $data = shift;
my $router_list = shift;
my $handle = shift;
my $format = shift;

if ( scalar ( keys %{$data} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="No Router Data Available."; return 0; }

if ( scalar ( keys %{$router_list} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="Router List Required."; return 0; }

if ( !$handle )
	{ $self->{_GLOBAL}{'STATUS'}="File Handle Required."; return 0; }

if ( $format!~/csv/i )
	{ $self->{_GLOBAL}{'STATUS'}="Only CSV Format Supported."; return 0; }

if ( $format=~/csv/i )
	{ print $handle "ip_address,hostname,slot,bay,description,serialnumber,partcode\n"; }

foreach my $ip_address ( keys %{$data} )
        {
	if ( $format=~/csv/i )
		{
		for(my $slot=0;$slot<${$data}{$ip_address}{'total_slots'};$slot++)
			{
			if ( !${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalDescr'} )
				{ ${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalDescr'}="Empty"; }
			print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",\"$slot\",";
			print $handle "\"Main\",\"".${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalDescr'}."\",";
			print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalSerialNum'}."\",";
			print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalModelName'}."\"\n";
			for (my $bay=0;$bay< keys ( %{${$data}{$ip_address}{'slot'}{$slot}{'child'}} ); $bay++ )
				{
				if ( !${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalDescr'} )
					{ ${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalDescr'}="Empty"; }
				next unless ${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalSerialNum'} ||
					${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalDescr'}=~/^Empty/;
				print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",\"$slot\",";
				print $handle "\"$bay\",\"".${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalDescr'}."\",";
				print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalSerialNum'}."\",";
				print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalModelName'}."\"\n";
				}
			}
		}
	}

return 1;
}

sub Export_7500_Port_Inventory
{
my $self = shift;
my $data = shift;
my $router_list = shift;
my $handle = shift;
my $format = shift;

if ( scalar ( keys %{$data} ) == 0 )
        { $self->{_GLOBAL}{'STATUS'}="No Router Data Available."; return 0; }

if ( scalar ( keys %{$router_list} ) == 0 )
        { $self->{_GLOBAL}{'STATUS'}="Router List Required."; return 0; }

if ( !$handle )
        { $self->{_GLOBAL}{'STATUS'}="File Handle Required."; return 0; }

if ( $format!~/csv/i )
        { $self->{_GLOBAL}{'STATUS'}="Only CSV Format Supported."; return 0; }

if ( $format=~/csv/i )
        { print $handle "ip_address,hostname,slot,port,bay,interface_name,operstatus,adminstatus\n"; }

foreach my $ip_address ( keys %{$data} )
	{
	if ( $format=~/csv/i )
		{
		foreach my $interface ( keys %{${$data}{$ip_address}} )
			{
			my ($slot,$port,$bay);
			if ( ${$data}{$ip_address}{$interface}{'ifDescr'}=~/(\d+)$/ )
				{ $slot="$1"; $port="Main Controller"; $bay="None";  }
			if ( ${$data}{$ip_address}{$interface}{'ifDescr'}=~/(\d+)\/(\d+)\/(\d+)/ )
				{ $slot=$1; $port=$2; $bay=$3; }
			print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",";
			print $handle "\"$slot\",\"$port\",\"$bay\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifDescr'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifOperStatus'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifAdminStatus'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifAlias'}\"";
			print $handle "\n";
			}
		}
	}
return 1;
}

sub Get_GSR_inventory
{
my $self = shift;
my $data = shift;
my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }
my $snmp_variables = Router::Statistics::OID->Router_inventory_oid();

my %temp;

foreach my $ip_address ( keys %{$current_ubrs} )
	{
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
			-callback       => [ \&validate_one, \%temp, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'PRIVATE_inventory'} );
	}
snmp_dispatcher();
foreach my $ip_address ( keys %temp )
	{
	foreach my $relative (  keys %{$temp{$ip_address}} )
		{
		next unless $temp{$ip_address}{$relative}{'entPhysicalName'}=~/^slot (\d+)/;
		$temp{$ip_address}{'rev'}{ $1 }=$relative;
		}
	foreach my $a ( keys %{$temp{$ip_address}{'rev'}} ) 
		{
		foreach my $attribute ( keys %{$snmp_variables} )
			{
			next if $attribute=~/PRIVATE/;
			${$data}{$ip_address}{'slot'}{$a}{$attribute}=
				$temp{$ip_address}{  $temp{$ip_address}{'rev'}{$a} }{$attribute};
			}
		}
	$temp{$ip_address}{'1'}{'entPhysicalDescr'}=~/^(\d+)\//;
	${$data}{$ip_address}{'total_slots'}=substr($1,3,2);
	}
undef %temp;
return 1;
}

sub Export_GSR_Slot_Inventory
{
my $self = shift;
my $data = shift;
my $router_list = shift;
my $handle = shift;
my $format = shift;

if ( scalar ( keys %{$data} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="No Router Data Available."; return 0; }

if ( scalar ( keys %{$router_list} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="Router List Required."; return 0; }

if ( !$handle )
	{ $self->{_GLOBAL}{'STATUS'}="File Handle Required."; return 0; }

if ( $format!~/csv/i )
	{ $self->{_GLOBAL}{'STATUS'}="Only CSV Format Supported."; return 0; }

if ( $format=~/csv/i )
	{ print $handle "ip_address,hostname,slot,description,serialnumber,partcode\n"; }

foreach my $ip_address ( keys %{$data} )
	{
	if ( $format=~/csv/i )
		{
		for(my $slot=0;$slot<${$data}{$ip_address}{'total_slots'};$slot++)
			{
			if ( !${$data}{$ip_address}{'slot'}{$slot}{'entPhysicalDescr'} )
				{ ${$data}{$ip_address}{'slot'}{$slot}{'entPhysicalDescr'}="Empty"; }
			print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",\"$slot\",";
			print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'entPhysicalDescr'}."\",";
			print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'entPhysicalSerialNum'}."\",";
			print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'entPhysicalModelName'}."\"\n";
			}
		}
	}
return 1;
}

sub Export_GSR_Port_Inventory
{
my $self = shift;
my $data = shift;
my $router_list = shift;
my $handle = shift;
my $format = shift;

if ( scalar ( keys %{$data} ) == 0 )
        { $self->{_GLOBAL}{'STATUS'}="No Router Data Available."; return 0; }

if ( scalar ( keys %{$router_list} ) == 0 )
        { $self->{_GLOBAL}{'STATUS'}="Router List Required."; return 0; }

if ( !$handle )
        { $self->{_GLOBAL}{'STATUS'}="File Handle Required."; return 0; }

if ( $format!~/csv/i )
        { $self->{_GLOBAL}{'STATUS'}="Only CSV Format Supported."; return 0; }

if ( $format=~/csv/i )
        { print $handle "ip_address,hostname,slot,port,interface_name,operstatus,adminstatus\n"; }

foreach my $ip_address ( keys %{$data} )
	{
	if ( $format=~/csv/i )
		{
		foreach my $interface ( keys %{${$data}{$ip_address}} )
			{
			my ($slot,$port);
			if ( ${$data}{$ip_address}{$interface}{'ifDescr'}=~/(\d+)$/ )
				{ $slot="$1"; $port="Main Controller"; }
			if ( ${$data}{$ip_address}{$interface}{'ifDescr'}=~/(\d+)\/(\d+)/ )
				{ $slot=$1; $port=$2; }
			print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",";
			print $handle "\"$slot\",\"$port\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifDescr'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifOperStatus'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifAdminStatus'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifAlias'}\"";
			print $handle "\n";
			}
		}
	}
return 1;
}

sub Export_7600_Slot_Inventory
{
my $self = shift;
my $data = shift;
my $router_list = shift;
my $handle = shift;
my $format = shift;

if ( scalar ( keys %{$data} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="No Router Data Available."; return 0; }

if ( scalar ( keys %{$router_list} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="Router List Required."; return 0; }

if ( !$handle )
	{ $self->{_GLOBAL}{'STATUS'}="File Handle Required."; return 0; }

if ( $format!~/csv/i )
	{ $self->{_GLOBAL}{'STATUS'}="Only CSV Format Supported."; return 0; }

if ( $format=~/csv/i )
	{ print $handle "ip_address,hostname,slot,port,description,serialnumber,partcode\n"; }

foreach my $ip_address ( keys %{$data} )
        {
	if ( $format=~/csv/i )
		{
		for(my $slot=0;$slot<${$data}{$ip_address}{'total_slots'};$slot++)
			{
			if ( !${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalDescr'} )
				{ ${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalDescr'}="Empty"; }
			print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",\"$slot\",";
			print $handle "\"Main\",\"".${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalDescr'}."\",";
			print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalSerialNum'}."\",";
			print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'main'}{'entPhysicalModelName'}."\"\n";
			for (my $bay=1;$bay< keys ( %{${$data}{$ip_address}{'slot'}{$slot}{'child'}} )+1; $bay++ )
				{
				if ( !${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalDescr'} )
					{ ${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalDescr'}="Empty"; }
				print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",\"$slot\",";
				print $handle "\"$bay\",\"".${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalDescr'}."\",";
				print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalSerialNum'}."\",";
				print $handle "\"".${$data}{$ip_address}{'slot'}{$slot}{'child'}{$bay}{'entPhysicalModelName'}."\"\n";
				}
			}
		}
	}
return 1;
}

sub Export_7600_Port_Inventory
{
my $self = shift;
my $data = shift;
my $router_list = shift;
my $handle = shift;
my $format = shift;

if ( scalar ( keys %{$data} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="No Router Data Available."; return 0; }

if ( scalar ( keys %{$router_list} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="Router List Required."; return 0; }

if ( !$handle )
	{ $self->{_GLOBAL}{'STATUS'}="File Handle Required."; return 0; }

if ( $format!~/csv/i )
	{ $self->{_GLOBAL}{'STATUS'}="Only CSV Format Supported."; return 0; }

if ( $format=~/csv/i )
	{ print $handle "ip_address,hostname,slot,port,description,operstatus,adminstatus\n"; }

foreach my $ip_address ( keys %{$data} )
        {
	if ( $format=~/csv/i )
		{
		foreach my $interface ( keys %{${$data}{$ip_address}} )
			{
			my ($slot,$port);
			if ( ${$data}{$ip_address}{$interface}{'ifDescr'}=~/(\d+)$/ )
				{ $slot="$1"; $port="Main Controller"; }
			if ( ${$data}{$ip_address}{$interface}{'ifDescr'}=~/(\d+)\/(\d+)/ )
				{ $slot=$1; $port=$2; }
			print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",";
			print $handle "\"$slot\",\"$port\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifDescr'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifOperStatus'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifAdminStatus'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifAlias'}\"";
			print $handle "\n";
			}
		}
	}

return 1;
}



sub Get_UBR_Inventory
{
my $self = shift;
my $data = shift;
my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }
my $snmp_variables = Router::Statistics::OID->Router_inventory_oid();
my %temp;
foreach my $ip_address ( keys %{$current_ubrs} )
	{
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
			-callback       => [ \&validate_one, \%temp, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'PRIVATE_inventory'} );
	}
snmp_dispatcher();
foreach my $ip_address ( keys %temp )
	{
	foreach my $relative (  keys %{$temp{$ip_address}} )
		{
		next unless $temp{$ip_address}{$relative}{'entPhysicalDescr'}=~/mc/i ||
			$temp{$ip_address}{$relative}{'entPhysicalDescr'}=~/ether/i;
		$temp{$ip_address}{'rev'}{ $temp{$ip_address}{$relative}{'entPhysicalParentRelPos'} }=
			$relative;
		}
	foreach my $a ( keys %{$temp{$ip_address}{'rev'}} ) 
		{
		foreach my $attribute ( keys %{$snmp_variables} )
			{
			next if $attribute=~/PRIVATE/;
			${$data}{$ip_address}{$a}{$attribute}=
				$temp{$ip_address}{  $temp{$ip_address}{'rev'}{$a} }{$attribute};
			}
		}
	${$data}{$ip_address}{'total_slots'}=6;
	}
undef %temp;
return 1;
}

sub Export_UBR_Slot_Inventory
{
my $self = shift;
my $data = shift;
my $router_list = shift;
my $handle = shift;
my $format = shift;

if ( scalar ( keys %{$data} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="No Router Data Available."; return 0; }

if ( scalar ( keys %{$router_list} ) == 0 )
	{ $self->{_GLOBAL}{'STATUS'}="Router List Required."; return 0; }

if ( !$handle )
	{ $self->{_GLOBAL}{'STATUS'}="File Handle Required."; return 0; }

if ( $format!~/csv/i )
	{ $self->{_GLOBAL}{'STATUS'}="Only CSV Format Supported."; return 0; }

if ( $format=~/csv/i )
	{ print $handle "ip_address,hostname,slot,description,serialnum,partcode\n"; }

foreach my $ip_address ( keys %{$data} )
        {
	if ( $format=~/csv/i )
		{
        	for(my $slot=0;$slot<${$data}{$ip_address}{'total_slots'}+1;$slot++)
                	{
                	if ( !${$data}{$ip_address}{$slot}{'entPhysicalDescr'} )
                	        { ${$data}{$ip_address}{$slot}{'entPhysicalDescr'}="Empty"; }
                	print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",\"$slot\",";
                	print $handle "\"${$data}{$ip_address}{$slot}{'entPhysicalDescr'}\",";
                	print $handle "\"${$data}{$ip_address}{$slot}{'entPhysicalSerialNum'}\",";
			print $handle "\"${$data}{$ip_address}{$slot}{'entPhysicalModelName'}\"";	
			print $handle "\n";
                	}
        	}
	}
return 1;
}

sub Export_UBR_Port_Inventory
{
my $self = shift;
my $data = shift;
my $router_list = shift;
my $handle = shift;
my $format = shift;

if ( scalar ( keys %{$data} ) == 0 )
        { $self->{_GLOBAL}{'STATUS'}="No Router Data Available."; return 0; }

if ( scalar ( keys %{$router_list} ) == 0 )
        { $self->{_GLOBAL}{'STATUS'}="Router List Required."; return 0; }

if ( !$handle )
        { $self->{_GLOBAL}{'STATUS'}="File Handle Required."; return 0; }

if ( $format!~/csv/i )
        { $self->{_GLOBAL}{'STATUS'}="Only CSV Format Supported."; return 0; }

if ( $format=~/csv/i )
        { print $handle "ip_address,hostname,slot,port,interface_name,operstatus,adminstatus\n"; }

foreach my $ip_address ( keys %{$data} )
	{
	if ( $format=~/csv/i )
		{
		foreach my $interface ( keys %{${$data}{$ip_address}} )
			{
			my ($slot,$port);
			if ( ${$data}{$ip_address}{$interface}{'ifDescr'}=~/(\d+)$/ )
				{ $slot="$1"; $port="Main Controller"; }
			if ( ${$data}{$ip_address}{$interface}{'ifDescr'}=~/(\d+)\/(\d+)/ )
				{ $slot=$1; $port=$2; }
			print $handle "\"$ip_address\",\"${$router_list}{$ip_address}{'hostName'}\",";
			print $handle "\"$slot\",\"$port\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifDescr'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifOperStatus'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifAdminStatus'}\",";
			print $handle "\"${$data}{$ip_address}{$interface}{'ifAlias'}\"";
			print $handle "\n";
			}
		}
	}
return 1;
}

sub Get_7600_inventory
{
my $self = shift;
my $data = shift;
my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }
my $snmp_variables = Router::Statistics::OID->Router_inventory_oid();

my %temp;

foreach my $ip_address ( keys %{$current_ubrs} )
	{
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
			-callback       => [ \&validate_one, \%temp, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'PRIVATE_inventory'} );
	}
snmp_dispatcher();


foreach my $ip_address ( keys %temp )
        {
        foreach my $relative (  keys %{$temp{$ip_address}} )
                {
		if ( $temp{$ip_address}{$relative}{'entPhysicalName'}=~/^(\d+)$/ )
			{ $temp{$ip_address}{'rev'}{ $1 }{'main'}=$relative; }
                if ( $temp{$ip_address}{$relative}{'entPhysicalName'}=~/(\d+)\/(\d+)$/ )
                        { $temp{$ip_address}{'rev'}{ $1 }{'child'}{$2}=$relative; }
                }
        foreach my $a ( keys %{$temp{$ip_address}{'rev'}} )
                {
                foreach my $child ( keys %{$temp{$ip_address}{'rev'}{$a}{'child'}} )
                        {
                        foreach my $attribute ( keys %{$snmp_variables} )
                                {
                                next if $attribute=~/PRIVATE/;
                                ${$data}{$ip_address}{'slot'}{$a}{'child'}{$child}{$attribute}=
                                        $temp{$ip_address}{ $temp{$ip_address}{'rev'}{$a}{'child'}{$child} } {$attribute};
                                }
                        }
		foreach my $attribute ( keys %{$snmp_variables} )
			{
			next if $attribute=~/PRIVATE/;
			${$data}{$ip_address}{'slot'}{$a}{'main'}{$attribute}=
				$temp{$ip_address}{ $temp{$ip_address}{'rev'}{$a}{'main'} }{$attribute};
			}
                }
	$temp{$ip_address}{'1'}{'entPhysicalDescr'}=~/Cisco (\d+) (\d+)-slot/;
	${$data}{$ip_address}{'total_slots'}=$2;
        }
undef %temp;
return 1;
}


sub UBR_get_DOCSIS_upstream_interfaces
{
my $self = shift;
my $data = shift;
# ie
#
# $result = $Object -> get_DOCSIS_upstream_interaces ( \%upstream_interfaces );
#
# $result contains 1 or 0 for 1 = success, 0 = failure.

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
			-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'PRIVATE_cable_channel_information'} );
	}
snmp_dispatcher();

return 1;
}


sub UBR_get_DOCSIS_interface_information
{
my $self = shift;
my $data = shift;

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
			-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'PRIVATE_cable_signal_base'} );
	}
snmp_dispatcher();

return 1;
}

sub UBR_get_DOCSIS_downstream_interfaces
{
my $self = shift;
my $data = shift;


my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
			-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'PRIVATE_downstream_interface'} );
	}

snmp_dispatcher();

foreach my $ip_address ( keys %{$current_ubrs} )
        {
        foreach my $interface ( keys %{${$data}{$ip_address}} )
                {
		${$data}{$ip_address}{$interface}{'docsIfDownChannelModulation'}=
			( '0_Unknown', '1_other', '2_qam64', '3_qam256' )
			[${$data}{$ip_address}{$interface}{'docsIfDownChannelModulation'}];
                }
        }


return 1;
}

sub UBR_get_active_upstream_profiles
{
my $self = shift;
my $data = shift;

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
	{
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table(
			-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
			-baseoid =>	${$snmp_variables}{'PRIVATE_docsIfCmtsModulationEntry'} );
	}

snmp_dispatcher();

foreach my $ip_address ( keys %{$current_ubrs} )
	{
	foreach my $profile ( keys %{${$data}{$ip_address}} )
		{
		foreach my $attribute ( keys %{${$data}{$ip_address}{$profile}} )
			{
        	        if ( $attribute=~/docsIfCmtsModType/ )
        	                { ${$data}{$ip_address}{$profile}{'docsIfCmtsModType'}=
        	                        (
					'Unknown',
					'other',
					'qpsk',
					'qam16',
					'qam8',
					'qam32',
					'qam64',
					'qam128'
					)
					[${$data}{$ip_address}{$profile}{'docsIfCmtsModType'}]; 
				}
			}
		}
	}
return 1;
}

sub UBR_get_CPE_information_Blocking
{

my $self = shift;
my $data = shift;
my $data_selector = shift;

# Entry into the function is a point to a hash to store the data
# the result is a hash with the following

my ($foo, $bar );
my (%rev_data_pack);
my (%other_addresses);

# This is where we get some information from the UBR about the CPEs connected
# This function should be modified so only the information needed is collected
# as you may not need it all, and on a busy UBR can take a while to return.

# Cisco Bug 1

# When snmp ifIndexPersist is configured, changing out MC16Cs, with MC28Us (
# or more than likely any other card ) causes some information to be 
# inaccessable using a standard get_table, so you have to fudge your way
# around the MIB tree

my ($check_loop);

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();


foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ( $foo , $bar );
	for ($check_loop=0;$check_loop<100;$check_loop++)
		{
		my $sider=${$snmp_variables}{'docsIfCmtsServiceCmStatusIndex'}.".".$check_loop;
		my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
        	        get_table( 
			-baseoid => $sider );
		while(($foo, $bar) = each(%{$status_information}))
			{
			if ( $foo=~/^${$snmp_variables}{'docsIfCmtsServiceCmStatusIndex'}.(\d+).(\d+)/ )
				{
				my $cmindexcode="$1:$2";
				$rev_data_pack{$ip_address}{$cmindexcode}=$bar;
				delete ${$status_information}{$foo};
				}
			}
		}
	}


if ( $data_selector=~/CPEIP/i || $data_selector=~/ALL/i )
        {
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
			get_table(
			-baseoid => ${$snmp_variables}{'docsIfCmtsCmStatusIpAddress'} );
		while(($foo, $bar) = each(%{$status_information}))
			{
			if ( $foo=~/^${$snmp_variables}{'docsIfCmtsCmStatusIpAddress'}.(\d+)/ )
				{ ${$data}{$ip_address}{$1}{'docsIfCmtsCmStatusIpAddress'}=$bar; }
			delete ${$status_information}{$foo};
			}
		
		}
        }

if ( $data_selector=~/USERIP/i || $data_selector=~/ALL/i )
        {
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
			get_table(
			-baseoid => ${$snmp_variables}{'cdxCmCpeIpAddress'} );
		while(($foo, $bar) = each(%{$status_information}))
			{
			if ( $foo=~/^${$snmp_variables}{'cdxCmCpeIpAddress'}.(\d+).(\d+).(\d+).(\d+).(\d+).(\d+)/ )
				{
				my $cmindexcode="$1:$2:$3:$4:$5:$6";
				$other_addresses{$cmindexcode}=$bar;
				}
			delete ${$status_information}{$foo};
			}
		}
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
			get_table(
			-baseoid => ${$snmp_variables}{'cdxCmCpeCmStatusIndex'} );
		while(($foo, $bar) = each(%{$status_information}))
			{
			if ( $foo=~/^${$snmp_variables}{'cdxCmCpeCmStatusIndex'}.(\d+).(\d+).(\d+).(\d+).(\d+).(\d+)/ )
				{
				my $cmindexcode="$1:$2:$3:$4:$5:$6";
				${$data}{$ip_address}{$bar}{'cdxCmCpeCmStatusIndex'}=$cmindexcode;
				}
			delete ${$status_information}{$foo};
			}
		}
	}


if ( $data_selector=~/IFINDEX/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
			my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table( -baseoid => ${$snmp_variables}{'docsIfCmtsCmStatusUpChannelIfIndex'} );
			while(($foo, $bar) = each(%{$status_information}))
				{
				if ( $foo=~/^${$snmp_variables}{'docsIfCmtsCmStatusUpChannelIfIndex'}.(\d+)/ )
					{
					${$data}{$ip_address}{$1}{'docsIfCmtsCmStatusUpChannelIfIndex'}=$bar;
					}
				delete ${$status_information}{$foo};
			}
		}
	}

if ( $data_selector=~/QOSPROFILE/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<50;$check_loop++)
			{
			my $sider=${$snmp_variables}{'docsIfCmtsServiceQosProfile'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table(
				-baseoid => $sider );
			while(($foo, $bar) = each(%{$status_information}))
				{
				if ( $foo=~/^${$snmp_variables}{'docsIfCmtsServiceQosProfile'}.(\d+).(\d+)/ )
					{
					my $cmindexcode="$1:$2";
					$cmindexcode=$rev_data_pack{$ip_address}{$cmindexcode};
					${$data}{$ip_address}{$cmindexcode}{'docsIfCmtsServiceQosProfile'}=$bar;
					}
				delete ${$status_information}{$foo};
				}
			}
		}
	}

if ( $data_selector=~/INOCTETS/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<100;$check_loop++)
			{
			my $sider=${$snmp_variables}{'docsIfCmtsServiceInOctets'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table(
				-baseoid => $sider );
			while(($foo, $bar) = each(%{$status_information}))
				{
				if ( $foo=~/^${$snmp_variables}{'docsIfCmtsServiceInOctets'}.(\d+).(\d+)/ )
					{
					my $cmindexcode="$1:$2";
					$cmindexcode=$rev_data_pack{$ip_address}{$cmindexcode};
					${$data}{$ip_address}{$cmindexcode}{'docsIfCmtsServiceInOctets'}=$bar;
					}
				delete ${$status_information}{$foo};
				}
			}
		}
	}

if ( $data_selector=~/INPACKETS/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<100;$check_loop++)
			{
			my $sider=${$snmp_variables}{'docsIfCmtsServiceInPackets'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table(
				-baseoid => $sider );
			while(($foo, $bar) = each(%{$status_information}))
				{
				if ( $foo=~/^${$snmp_variables}{'docsIfCmtsServiceInPackets'}.(\d+).(\d+)/ )
					{
					my $cmindexcode="$1:$2";
					$cmindexcode=$rev_data_pack{$ip_address}{$cmindexcode};
					${$data}{$ip_address}{$cmindexcode}{'docsIfCmtsServiceInPackets'}=$bar;
					}
				delete ${$status_information}{$foo};
				}
			}
		}
        }


if ( $data_selector=~/OUTOCTETS/i || $data_selector=~/ALL/i )
        {
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<100;$check_loop++)
			{
			my $sider=${$snmp_variables}{'cdxIfCmtsServiceOutOctets'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table(
				-baseoid => $sider );
			while(($foo, $bar) = each(%{$status_information}))
				{
				if ( $foo=~/^${$snmp_variables}{'cdxIfCmtsServiceOutOctets'}.(\d+).(\d+)/ )
					{
					my $cmindexcode="$1:$2";
					$cmindexcode=$rev_data_pack{$ip_address}{$cmindexcode};
					${$data}{$ip_address}{$cmindexcode}{'cdxIfCmtsServiceOutOctets'}=$bar;
					}
				delete ${$status_information}{$foo};
				}
			}
		}
	}

if ( $data_selector=~/OUTPACKETS/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<100;$check_loop++)
			{
			my $sider=${$snmp_variables}{'cdxIfCmtsServiceOutPackets'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table(
				-baseoid => $sider );
			while(($foo, $bar) = each(%{$status_information}))
				{
				if ( $foo=~/^${$snmp_variables}{'cdxIfCmtsServiceOutPackets'}.(\d+).(\d+)/ )
					{
					my $cmindexcode="$1:$2";
					$cmindexcode=$rev_data_pack{$ip_address}{$cmindexcode};
					${$data}{$ip_address}{$cmindexcode}{'cdxIfCmtsServiceOutPackets'}=$bar;
					}
				delete ${$status_information}{$foo};
				}
			}
		}
	}

if ( $data_selector=~/CPEMAC/i || $data_selector=~/ALL/i )
        {
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
			get_table(
			-baseoid => ${$snmp_variables}{'docsIfCmtsCmStatusMacAddress'} );
		while(($foo, $bar) = each(%{$status_information}))
			{
			if ( $foo=~/^${$snmp_variables}{'docsIfCmtsCmStatusMacAddress'}.(\d+)/ )
				{
				${$data}{$ip_address}{$1}{'docsIfCmtsCmStatusMacAddress'}=_convert_mac_address($bar);
				}
			delete ${$status_information}{$foo};
			}
		}
	}

if ( $data_selector=~/STATUS/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
			get_table(
			-baseoid => ${$snmp_variables}{'docsIfCmtsCmStatusValue'} );
		while(($foo, $bar) = each(%{$status_information}))
			{
			if ( $foo=~/^${$snmp_variables}{'docsIfCmtsCmStatusValue'}.(\d+)/ )
				{
				${$data}{$ip_address}{$1}{'docsIfCmtsCmStatusValue'}=
						(
						'0_Unknown',
						'1_other',
						'2_ranging',
						'3_rangingAborted',
						'4_rangingComplete',
						'5_ipComplete',
						'6_registrationComplete',
						'7_accessDenied',
						'8_operational (older IOS)',
						'9_registeredBPIInitializing')
						[$bar];
				}
			delete ${$status_information}{$foo};
			}
		}
	}
return 1;
}


sub UBR_get_CPE_information
{

my $self = shift;
my $data = shift;
my $data_selector = shift;

# Entry into the function is a point to a hash to store the data
# the result is a hash with the following

my ($foo, $bar );
my (%rev_data_pack);
my (%other_addresses);

# This is where we get some information from the UBR about the CPEs connected
# This function should be modified so only the information needed is collected
# as you may not need it all, and on a busy UBR can take a while to return.

# Cisco Bug 1

# When snmp ifIndexPersist is configured, changing out MC16Cs, with MC28Us (
# or more than likely any other card ) causes some information to be 
# inaccessable using a standard get_table, so you have to fudge your way
# around the MIB tree

my ($check_loop);

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();


foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	for ($check_loop=0;$check_loop<100;$check_loop++)
		{
		my $sider=${$snmp_variables}{'docsIfCmtsServiceCmStatusIndex'}.".".$check_loop;
		my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
        	        get_table( 
			-callback       => [ \&validate_two_rev, \%rev_data_pack, $ip_address, $snmp_variables ],
			-baseoid => $sider );
		}
	}
snmp_dispatcher();

if ( $data_selector=~/CPEIP/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
			get_table( 
			-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'docsIfCmtsCmStatusIpAddress'} );
		}
	snmp_dispatcher();
	}

if ( $data_selector=~/USERIP/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
        	    get_table( 
			-callback       => [ \&validate_two, \%other_addresses, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'cdxCmCpeIpAddress'} );
		}
	snmp_dispatcher();
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
	            get_table( 
			-callback       => [ \&validate_two, $data, $ip_address,$snmp_variables ],
			-baseoid => ${$snmp_variables}{'cdxCmCpeCmStatusIndex'} );
		}
	snmp_dispatcher();
	foreach my $cpe ( keys %{$data} ) { chop ( ${$data}{$cpe}->{'cdxCmCpeIpAddress'} ); }
	}

if ( $data_selector=~/IFINDEX/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
        	    get_table( 
			-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'docsIfCmtsCmStatusUpChannelIfIndex'} );
		}
	snmp_dispatcher();
	}

if ( $data_selector=~/QOSPROFILE/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<50;$check_loop++)
			{
			my $sider=${$snmp_variables}{'docsIfCmtsServiceQosProfile'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table( 
					-callback       => [ \&validate_two_special, $data, $ip_address, $snmp_variables, \%rev_data_pack ],
					-baseoid => $sider );
			}
		}
	snmp_dispatcher();
	}

if ( $data_selector=~/INOCTETS/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<100;$check_loop++)
			{
			my $sider=${$snmp_variables}{'docsIfCmtsServiceInOctets'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table( 
					-callback       => [ \&validate_two_special, $data, $ip_address, $snmp_variables, \%rev_data_pack ],
					-baseoid => $sider );
			}
		}
	snmp_dispatcher();
	}

if ( $data_selector=~/INPACKETS/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<100;$check_loop++)
			{
			my $sider=${$snmp_variables}{'docsIfCmtsServiceInPackets'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table( 
					-callback       => [ \&validate_two_special, $data, $ip_address, $snmp_variables, \%rev_data_pack ],
					-baseoid => $sider );
			}
		}
	snmp_dispatcher();
	}

if ( $data_selector=~/OUTOCTETS/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<100;$check_loop++)
			{
			my $sider=${$snmp_variables}{'cdxIfCmtsServiceOutOctets'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table( 
					-callback       => [ \&validate_two_special, $data, $ip_address, $snmp_variables, \%rev_data_pack ],
					-baseoid => $sider );
			}
		}
	snmp_dispatcher();
	}

if ( $data_selector=~/OUTPACKETS/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		for ($check_loop=0;$check_loop<100;$check_loop++)
			{
			my $sider=${$snmp_variables}{'cdxIfCmtsServiceOutPackets'}.".".$check_loop;
			my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
				get_table( 
					-callback       => [ \&validate_two_special, $data, $ip_address, $snmp_variables, \%rev_data_pack ],
					-baseoid => $sider );
			}
		}
	snmp_dispatcher();
	}

if ( $data_selector=~/CPEMAC/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
			get_table( 
				-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
				-baseoid => ${$snmp_variables}{'docsIfCmtsCmStatusMacAddress'} );
		}
	snmp_dispatcher();
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		foreach my $cpe ( keys %{${$data}{$ip_address}} )
			{
			${$data}{$ip_address}{$cpe}{'docsIfCmtsCmStatusMacAddress'}=
				_convert_mac_address( ${$data}{$ip_address}{$cpe}{'docsIfCmtsCmStatusMacAddress'} );
			}
		}
	}

if ( $data_selector=~/STATUS/i || $data_selector=~/ALL/i )
	{
	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
		my ($status_information) = $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table( 
			-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'docsIfCmtsCmStatusValue'} );
		}
	snmp_dispatcher();

	foreach my $ip_address ( keys %{$current_ubrs} )
		{
		foreach my $cpe ( keys %{${$data}{$ip_address}} )
			{
			${$data}{$ip_address}{$cpe}{'docsIfCmtsCmStatusValue'}=
				(
			'0_Unknown',
			'1_other',
			'2_ranging',
			'3_rangingAborted',
			'4_rangingComplete',
			'5_ipComplete',
			'6_registrationComplete',
			'7_accessDenied',
			'8_operational (older IOS)',
			'9_registeredBPIInitializing')
			[${$data}{$ip_address}{$cpe}{'docsIfCmtsCmStatusValue'}];
			}
		}
	}

undef %other_addresses;
undef %rev_data_pack;

if ( scalar ( keys %{$data} ) == 0 )
        { $self->{_GLOBAL}{'STATUS'}="No UBR CPE Information Data Found.\n"; return 0; }

return 1;
}

sub UBR_modify_cpe_DOCSIS_profile
{
my $self = shift;
my $ip_address = shift;
my $profiles = shift;
my $profile_change = shift;
my $cpe_information = shift;
my $mac_to_change = shift;

if (!$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'})
        { $self->{_GLOBAL}{'STATUS'}="UBR Not Ready"; return 0; }

if ( !$profiles )
	{ $self->{_GLOBAL}{'STATUS'}="No Profiles Found"; return 0; }

if ( !$cpe_information )
	{ $self->{_GLOBAL}{'STATUS'}="No CPE Device Information Found"; return 0; }

if ( !$mac_to_change )
	{ $self->{_GLOBAL}{'STATUS'}="No MAC Address Specified"; return 0; }

if ( !$profile_change )
	{ $self->{_GLOBAL}{'STATUS'}="No Profile Specified"; return 0; }

if ( scalar ( split(/\//,$profile_change )) !=2 )
	{ $self->{_GLOBAL}{'STATUS'}="Profile Incorrect format ( upstream/downstream )"; return 0; }

my ($lock_profile)=0;
foreach my $profile ( %{${$profiles}{$ip_address}} )
	{
	my $merge = ${$profiles}{$ip_address}{$profile}{'docsIfQosProfMaxUpBandwidth'}."/".${$profiles}{$ip_address}{$profile}{'docsIfQosProfMaxDownBandwidth'};
	if ( $merge=~/^$profile_change$/ )
		{ $lock_profile=1; $profile_change=$profile; }
	}

if ( !$lock_profile )
	{ $self->{_GLOBAL}{'STATUS'}="Profile Specified Is Not Currently Configured"; return 0; }

($lock_profile)=0;
foreach my $mac_find ( keys %{${$cpe_information}{$ip_address}} )
	{
	if ( ${$cpe_information}{$ip_address}{$mac_find}{'docsIfCmtsCmStatusMacAddress'}=~/^$mac_to_change$/i )
		{
		$lock_profile=1;
		$mac_to_change=$mac_find;
		}
	}
if ( !$lock_profile )
	{ $self->{_GLOBAL}{'STATUS'}="MAC Specified Is Not Currently Online"; return 0; }

my @snmp_array;
my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();

push @snmp_array, ( ${$snmp_variables}{'cdxCmtsCmCurrQoSPro'}.".$mac_to_change" , INTEGER, $profile_change );
my ($reset)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
                        set_request( 
				-callback       => [ \&validate_one, {} , {} ],
				-varbindlist => [@snmp_array] );
snmp_dispatcher();

undef $snmp_variables;
undef @snmp_array;
undef $mac_to_change;
undef $profile_change;
undef $reset;

if ( $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->error )
        { $self->{_GLOBAL}{'STATUS'}=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->error; return 0; }

return 1;
}

sub UBR_reset_cpe_device
{
my $self = shift;
my $ip_address = shift;
my $mac_address = shift;

if (!$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'})
	{
	$self->{_GLOBAL}{'STATUS'}="UBR Not Ready"; return 0;
	}

my @mac_split=split(/\./,$mac_address);
my $index;
if ( scalar(@mac_split)==6 )
	{ foreach my $octet (@mac_split) { $index.=oct("0x$octet")."."; } chop($index); }

if ( scalar(@mac_split)==3 )
	{ foreach my $octet (@mac_split)
		{ my $first=substr($octet,0,2); my $second=substr($octet,2,2); 
		$index.=oct("0x$first")."."; $index.=oct("0x$second")."."; 	
		} chop($index);
	}
undef @mac_split;

if ( !$index )
	{ undef $index; $self->{_GLOBAL}{'STATUS'}="Incorrect MAC address format"; return 0; }

my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();
my @snmp_array;
push @snmp_array, ( ${$snmp_variables}{'cdxCmCpeResetNow'}.".$index" , INTEGER, 1 );
my ($reset)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
			set_request( 
				-callback       => [ \&validate_one, {} , {} ],
				-varbindlist => [@snmp_array] );
snmp_dispatcher();
undef @snmp_array;
undef $index;

if ( $self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->error )
	{ $self->{_GLOBAL}{'STATUS'}=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->error; return 0; }
return 1;
}



sub UBR_get_active_cpe_profiles
{
my $self = shift;
my $data = shift;

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table( 
			-callback       => [ \&validate_one, $data, $ip_address, $snmp_variables ],
			-baseoid => ${$snmp_variables}{'PRIVATE_docs_profile_main'} );
	}
snmp_dispatcher();
return 1;
}

sub UBR_get_active_cpe_profiles_Blocking
{
my $self = shift;
my $data = shift;

my $current_ubrs=$self->UBR_Return_All();
if ( scalar( keys %{$current_ubrs})==0 ) { return 0; }

my $snmp_variables = Router::Statistics::OID->DOCSIS_populate_oid();
foreach my $ip_address ( keys %{$current_ubrs} )
        {
	my ( $foo, $bar );
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my ($profile_information)=$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_table( 
			-baseoid => ${$snmp_variables}{'PRIVATE_docs_profile_main'} );
	while(($foo, $bar) = each(%{$profile_information})) 
		{
		next unless($foo =~ /^${$snmp_variables}{'PRIVATE_docs_profile_main'}.(\d+).(\d+)/);
		if ( $foo=~/^${$snmp_variables}{'docsIfQosProfPriority'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'docsIfQosProfPriority'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'docsIfQosProfMaxDownBandwidth'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'docsIfQosProfMaxDownBandwidth'}=$bar; }
		if ( $foo=~/^${$snmp_variables}{'docsIfQosProfMaxUpBandwidth'}.(\d+)/ )
			{ ${$data}{$ip_address}{$1}{'docsIfQosProfMaxUpBandwidth'}=$bar; }

		}
	}
return 1;
}

sub get_CPE_info
{
my $self = shift;
my $ip_address = shift;

my $snmp_variables = Router::Statistics::OID->CPE_populate_oid();

if (!$self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'})
	{ return 1; }

my $get_info = $self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'}
		->get_request
			(
			-varbindlist => [ ${$snmp_variables}{'sysDescr'} ] );
undef $snmp_variables;
return 1;
}

sub Router_Test_Connection
{
my $self = shift;
my $data = shift;

my $current_ubrs=$self->UBR_Return_All();

my $snmp_variables = Router::Statistics::OID->Host_populate_oid();

foreach my $ip_address ( keys %{$current_ubrs} )
	{
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my $result = 
	$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_request( 
			-callback 	=> [ \&validate_callback, $ip_address, $data, $snmp_variables ],
			-varbindlist => [ 
				${$snmp_variables}{'sysUpTime'},
				${$snmp_variables}{'hostName'},
				${$snmp_variables}{'sysDescr'} ]);
	}
snmp_dispatcher();

foreach my $ip_address ( keys %{$current_ubrs} )
	{
	if ( !${$data}{$ip_address}{'sysUpTime'} ) 
		{ 
		$self->UBR_Remove($ip_address); 
		} 
	}

return 1;
}

sub Router_Test_Connection_Blocking
{
my $self = shift;
my $data = shift;

my $current_ubrs=$self->UBR_Return_All();

my $snmp_variables = Router::Statistics::OID->Host_populate_oid();

foreach my $ip_address ( keys %{$current_ubrs} )
	{
	next if !$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'};
	my $result = 
	$self->{_GLOBAL}{'Router'}{$ip_address}{'SESSION'}->
		get_request( 
			-varbindlist => [ 
				${$snmp_variables}{'sysUpTime'},
				${$snmp_variables}{'hostName'},
				${$snmp_variables}{'sysDescr'} ]);

	if ( $result->{${$snmp_variables}{'sysUpTime'}} )
		{
		${$data}{$ip_address}{'sysUpTime'}=$result->{${$snmp_variables}{'sysUpTime'}};
		${$data}{$ip_address}{'hostName'}=$result->{${$snmp_variables}{'hostName'}};
		${$data}{$ip_address}{'sysDescr'}=$result->{${$snmp_variables}{'sysDescr'}};
		}
		else
		{
		$self->UBR_Remove($ip_address);
		}
	}
return 1;
}

sub CPE_Test_Connection
{
my $self = shift;
my $data = shift;
my $current_cpes = $self ->CPE_Return_All();

my $snmp_variables = Router::Statistics::OID->Host_populate_oid();
foreach my $ip_address ( keys %{$current_cpes} )
        {
        next if !$self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'};
        $self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'}->
                get_request(
                        -callback       => [ \&validate_callback, $ip_address, $data, $snmp_variables ],
                        -varbindlist => [ ${$snmp_variables}{'sysUpTime'} ]);
        }
snmp_dispatcher();
foreach my $ip_address ( keys %{$current_cpes} )
        {
        if ( !${$data}{$ip_address}{'sysUpTime'} )
                {
                $self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'}->close();
                $self->{_GLOBAL}{'CPE'}{$ip_address}{'key'}="woofread";
                $self->CPE_Ready ( $ip_address );
                if ( $self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'} )
                        {
                        $self->{_GLOBAL}{'CPE'}{$ip_address}{'SESSION'}->
                                get_request(
                                        -callback       => [ \&validate_callback, $ip_address, $data, $snmp_variables ],
                                        -varbindlist => [ ${$snmp_variables}{'sysUpTime'} ] );
                        }
                }
        }
snmp_dispatcher();
foreach my $ip_address ( keys %{$current_cpes} )
        {
        if ( !${$data}{$ip_address}{'sysUpTime'} )
                {
                $self->CPE_Remove($ip_address);
                }
        }

return 1;
}

sub _convert_time_mask
{
my ($raw_input)=@_;
my ( $char1, $char2, $char3, $char4, $char5, $char6, $char7, $char8, $char9, $char10) = unpack ('nCCCCCCCCC', $raw_input);
my @months = qw [ Jan Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ];
return ( "$char1 ".sprintf("%.2d",$char3)." ".$months[$char2]." ".sprintf("%.2d:%.2d:%.2d",$char4,$char5,$char6));
}


sub _convert_mac_address
{
# this is a little bit of a mess and needs a tidy, but works round a bug that appears to be
# in the C lib for SNMP, which returns spurious entries every now and then ....
my ($raw_input)=@_;
my ( $char1, $char2, $char3, $char4, $char5, $char6) = unpack ('CCCCCC', $raw_input);
$char1=sprintf ("%#.2x",$char1); $char1=(split(/0x/,$char1))[1] if $char1=~/x/g;
$char2=sprintf ("%#.2x",$char2); $char2=(split(/0x/,$char2))[1] if $char2=~/x/g;
$char3=sprintf ("%#.2x",$char3); $char3=(split(/0x/,$char3))[1] if $char3=~/x/g;
$char4=sprintf ("%#.2x",$char4); $char4=(split(/0x/,$char4))[1] if $char4=~/x/g;
$char5=sprintf ("%#.2x",$char5); $char5=(split(/0x/,$char5))[1] if $char5=~/x/g;
$char6=sprintf ("%#.2x",$char6); $char6=(split(/0x/,$char6))[1] if $char6=~/x/g;
return ("$char1$char2.$char3$char4.$char5$char6");
}

sub validate_callback
{
my ($session, $ip_address, $table, $snmp_variables ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list})))
        {
	foreach my $attribute ( keys %{$snmp_variables} )
		{
		next if $attribute=~/^PRIVATE/;
		if ( $oid =~ /^${$snmp_variables}{$attribute}/)
			{
			${$table}{$ip_address}{$attribute}=$session->var_bind_list->{$oid}; }
			}
	delete ( $session->var_bind_list->{$oid} );
	}
return 1;
}

sub validate_one
{

my ($session, $table, $ip_address, $snmp_variables ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list}))) 
	{ 
        foreach my $attribute ( keys %{$snmp_variables} )
                {
                next if $attribute=~/^PRIVATE/;
                if ( $oid =~ /^${$snmp_variables}{$attribute}.(\d+)/)
                        {
			${$table}{$ip_address}{$1}{$attribute}=$session->var_bind_list->{$oid}; 
			}
                }
	delete ( $session->var_bind_list->{$oid} );
	}
	
return 1;
}

sub validate_one_cpe
{

my ($session, $table, $ip_address, $snmp_variables ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list}))) 
	{ 
        foreach my $attribute ( keys %{$snmp_variables} )
                {
                next if $attribute=~/^PRIVATE/;
                if ( $oid =~ /^${$snmp_variables}{$attribute}.(\d+)/)
                        {
			${$table}{$ip_address}{$attribute}=$session->var_bind_list->{$oid}; 
			}
                }
	delete ( $session->var_bind_list->{$oid} );
	}
	
return 1;
}

sub validate_two
{

my ($session, $table, $snmp_variables, $rev_data_pack ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list}))) 
	{ 
        foreach my $attribute ( keys %{$snmp_variables} )
                {
                next if $attribute=~/^PRIVATE/;
                if ( $oid =~ /^${$snmp_variables}{$attribute}.(\d+).(\d+)/)
                        { 
			my $cmindexcode="$1:$2";
			${$table}{$cmindexcode}{$attribute}=$session->var_bind_list->{$oid}; 
			}
                }
	delete ( $session->var_bind_list->{$oid} );
	}
	
return 1;
}

sub validate_two_rev
{

my ($session, $table, $ip_address, $snmp_variables ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list}))) 
	{ 
                if ( $oid =~ /^${$snmp_variables}{'docsIfCmtsServiceCmStatusIndex'}.(\d+).(\d+)/)
                        { 
			my $cmindexcode="$1:$2";
			${$table}{$ip_address}{$cmindexcode}=$session->var_bind_list->{$oid}; 
			}
	delete ( $session->var_bind_list->{$oid} );
	}
	
return 1;
}

sub validate_two_special
{

my ($session, $table, $ip_address, $snmp_variables, $rev_data_pack ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list}))) 
	{ 
        foreach my $attribute ( keys %{$snmp_variables} )
                {
                next if $attribute=~/^PRIVATE/;
                if ( $oid =~ /^${$snmp_variables}{$attribute}.(\d+).(\d+)/)
                        { 
			my $cmindexcode="$1:$2";  
			$cmindexcode=${$rev_data_pack}{$ip_address}{$cmindexcode};
			${$table}{$ip_address}{$cmindexcode}{$attribute}=$session->var_bind_list->{$oid}; 
			}
                }
	delete ( $session->var_bind_list->{$oid} );
	}
	
return 1;
}

sub validate_two_plain
{

my ($session, $table, $ip_address, $snmp_variables, $rev_data_pack ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list})))
        {
	foreach my $attribute ( keys %{$snmp_variables} )
		{
		next if $attribute=~/^PRIVATE/;
		if ( $oid =~ /^${$snmp_variables}{$attribute}.(\d+).(\d+)/)
			{
			my $cmindexcode="$1:$2";
			${$table}{$ip_address}{$cmindexcode}{$attribute}=$session->var_bind_list->{$oid};
			}
		}
	delete ( $session->var_bind_list->{$oid} );
	}
return 1;
}


sub validate_six
{
my ($session, $table, $snmp_variables ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list}))) 
	{ 
        foreach my $attribute ( keys %{$snmp_variables} )
                {
                next if $attribute=~/^PRIVATE/;
                if ( $oid =~ /^${$snmp_variables}{$attribute}.(\d+).(\d+).(\d+).(\d+).(\d+).(\d+)/)
                        { 
                	my $cmindexcode="$1.$2.$3.$4.$5.$6";
			${$table}{$cmindexcode}{$attribute}=$session->var_bind_list->{$oid}; 
			}
                }
	delete ( $session->var_bind_list->{$oid} );
	}
	
return 1;
}

sub validate_six_net
{
my ($session, $table, $router,  $snmp_variables ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list})))
        {
        foreach my $attribute ( keys %{$snmp_variables} )
                {
                next if $attribute=~/^PRIVATE/;
                if ( $oid =~ /^${$snmp_variables}{$attribute}.(\d+).(\d+).(\d+).(\d+).(\d+).(\d+)/)
                        {
                        my $index="$3.$4.$5.$6";
                        my $int_index=$1;
			${$table}{$router}{$int_index}{'address'}{$index}{$attribute}=$session->var_bind_list->{$oid};
			}
                }
        delete ( $session->var_bind_list->{$oid} );
        }

return 1;
}

sub validate_four_net
{
my ($session, $table, $router,  $snmp_variables ) = @_;
my (%temp);

foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list})))
	{
	foreach my $attribute ( keys %{$snmp_variables} )
		{
		if ( $attribute=~/ipAdEntIfIndex/i )
			{
			if ( $oid =~ /^${$snmp_variables}{$attribute}.(\d+).(\d+).(\d+).(\d+)/)
				{
				my $index="$1.$2.$3.$4";
				$temp{$index}=$session->var_bind_list->{$oid};
				}
			}
		}
	}

foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list})))
        {
        foreach my $attribute ( keys %{$snmp_variables} )
                {
                next if $attribute=~/^PRIVATE/;
                if ( $oid =~ /^${$snmp_variables}{$attribute}.(\d+).(\d+).(\d+).(\d+)/)
                        {
			my $index="$1.$2.$3.$4";
			my $int_index=$temp{$index};		
                        ${$table}{$router}{$int_index}{'address'}{$index}{$attribute}=$session->var_bind_list->{$oid};
                        }
                }
        delete ( $session->var_bind_list->{$oid} );
        }
return 1;
}

sub get_cpe_information
{
my ($session, $ip, $table, $snmp_variables ) = @_;
foreach my $oid (oid_lex_sort(keys(%{$session->var_bind_list}))) 
	{
	foreach my $attribute ( keys %{$snmp_variables} )
		{
		next if $attribute=~/^PRIVATE/;
		if ( $oid =~ /^${$snmp_variables}{$attribute}/)
			{
			${$table}{$ip}{$attribute}=$session->var_bind_list->{$oid};
			}
		}
	delete ( $session->var_bind_list->{$oid} );
	}
return 1;
}

sub _IpQuadToInt {
my $self = shift;
my($Quad) = @_; my($Ip1, $Ip2, $Ip3, $Ip4) = split(/\./, $Quad);
my($IpInt) = (($Ip1 << 24) | ($Ip2 << 16) | ($Ip3 << 8) | $Ip4);
return($IpInt);
}

sub _IpIntToQuad { my $self= shift; my($Int) = @_;
my($Ip1) = $Int & 0xFF; $Int >>= 8;
my($Ip2) = $Int & 0xFF; $Int >>= 8;
my($Ip3) = $Int & 0xFF; $Int >>= 8;
my($Ip4) = $Int & 0xFF; return("$Ip4.$Ip3.$Ip2.$Ip1");
}


1;

