Cisco-Accounting

 view release on metacpan or  search on metacpan

lib/Cisco/Accounting.pm  view on Meta::CPAN


require 5.002;

use Net::Telnet::Wrapper;

use Cisco::Accounting::Interface;	## object that represents a single interface
use Cisco::Accounting::Data;		## object that represents the parsed accounting data



sub new()  {
	my ($this, %parms) = @_;
	my  $class = ref($this) || $this;
	my  $self = {};	
	
	$self->{'session'} = '';	# this will contain our session to Net::Telnet::Wrapper
	
	$self->{'host'} = $parms{'host'} || "";		# router to connect to
	$self->{'user'} = $parms{'user'} || "";		# login username
	$self->{'pwd'} = $parms{'pwd'} || "";		# login password
	$self->{'tacacs'} = $parms{'tacacs'} || "";		# tacacs password

lib/Cisco/Accounting.pm  view on Meta::CPAN

sub _init  {
	my $class=shift;
}


##
## fetch all interfaces on a cisco device that support ip accounting
## returns array of Cisco::Accounting::Interface objects
## this procedured should be used with eval {}
##
sub get_interfaces()  {
	my ($self) = shift;
	
	my $disconnect;
	my @interfaces;	# resulting array of Cisco::Accounting::Interface objects
	
	eval {
		if (!$self->{'session'})  {
			$disconnect = 1;
			## make a connection to the device
			$self->_connect();

lib/Cisco/Accounting.pm  view on Meta::CPAN

	return @{$self->{'interfaces'}};
}


##
## Disable ip accounting on one or more interfaces
## parameters = array of interface id's as known in $self->{'interfaces'}
## ** this assumes you've run get_interfaces first ! **
## ** this assumes that you have enough rights to go to config mode **
##
sub enable_accounting()  {
	my ($self) = shift;
	my (@int_id) = @_;
	
	$self->_modify_accounting_settings(1, @int_id);
}


##
## Disable ip accounting on one or more interfaces
## parameters = array of interface id's as known in $self->{'interfaces'}
## ** this assumes you've run get_interfaces first ! **
## ** this assumes that you have enough rights to go to config mode **
##
sub disable_accounting()  {
	my ($self) = shift;
	my (@int_id) = @_;
	
	$self->_modify_accounting_settings(0, @int_id);
}



##
## parse output of 1 poll (show ip accounting) and update $self->{'data'}
## returns the reference to the output
## this procedure should be used with eval{}
##
sub do_accounting()  {
	my ($self) = shift;

	my (@output);
	my $disconnect = 0;

	# if the connection is not yet active then we assume that it has to be closed again 
	if (!$self->{'session'})  {
		$disconnect = 1;
		eval {
			$self->_connect();

lib/Cisco/Accounting.pm  view on Meta::CPAN

		$self->_disconnect();
	}
	
	return $self->{'data'}->get_data();
}


##
## returns a reference to the output
##
sub get_output()  {
	my ($self) = shift;
	
	if ($self->{'data'})  {
		return $self->{'data'}->get_data();
	}
	else  {
		return 0;
	}
}


##
## returns a reference to the output
##
sub get_lastpoll_output()  {
	my ($self) = shift;
	
	if ($self->{'lastpoll_data'})  {
		return $self->{'lastpoll_data'}->get_data();
	}
	else  {
		return 0;
	}
}

##
## return reference to hash with polling statistics
##
sub get_statistics()  {
	my ($self) = shift;
	
	if ($self->{'data'})  {
		return	$self->{'data'}->get_stats();
	}
	else  {
		return 0;
	}
}


##
## return reference to hash with polling statistics
##
sub get_history()  {
	my ($self) = shift;
	
	if ($self->{'data'})  {
		return	$self->{'data'}->get_history();
	}
	else  {
		return 0;
	}
}

##
## clears the output buffer
##
sub clear_output()  {
	my ($self) = shift;
	
	$self->{'data'} = '';
}


##
## clears ip accounting information on the remote device
## this procedure should be used with eval {}
##
sub clear_accounting()  {
	my ($self) = shift;
	
	my $disconnect = 0;
	
	# if the connection is not yet active then we assume that it has to be closed again 
	if (!$self->{'session'})  {
		$disconnect = 1;
		eval {
			$self->_connect();
		};

lib/Cisco/Accounting.pm  view on Meta::CPAN

	if ( ($disconnect > 0) && ($self->{'persistent'} <= 0) )  {
		$self->_disconnect();
	}
}


##
## Send a keepalive (new line character), do not do any error checking here
## Useful if 'persistent' is enabled, but still it's up to you to call the keepalive in time before session times out
##
sub keepalive()  {
	my ($self) = shift;
	
	if ($self->{'session'})  {
		eval  {
			$self->{'session'}->cmd(" ");
		};
	}
}




### TODO: do not go to config mode unless really needed

##
## Enable (1) or Disable (0) ip accounting depending on $status
##
sub _modify_accounting_settings()  {
	my ($self) = shift;
	my ($status) = shift;
	my (@int_id) = @_;
	
	## IPCAD interfaces are always enabled
	if ($self->{'acct_type'} =~ /ipcad/i)  {
		## nothing to do
		return;
	}
	

lib/Cisco/Accounting.pm  view on Meta::CPAN

	
	if ( ($disconnect > 0) && ($self->{'persistent'} <= 0) )  {
		$self->_disconnect();
	}	
}


##
## open a new telnet connection, login and save session in $self->{'session'}
##
sub _connect()  {
	my ($self) = shift;
	
	my $device_class;
	my $enable = 1;
	
	if ($self->{'acct_type'} =~ /cisco/i)  {
		$device_class = "Cisco::IOS";
		$enable = 1;
	}
	elsif ($self->{'acct_type'} =~ /ipcad/i)  {

lib/Cisco/Accounting.pm  view on Meta::CPAN

	};
	if ($@)  {
		croak "Unable to login to device ".$self->{'host'};
	}
}


##
## close telnet connection, remove session from $self->{'session'}
##
sub _disconnect()  {
	my ($self) = shift;
	
	return unless ($self->{'session'});
	
	eval {
		$self->Quit();
	};
	
	$self->{'session'} = '';
}



##
## fetch all interfaces on a cisco device that support ip accounting
## returns array of Cisco::Accounting::Interface objects
##
sub _parse_cisco_interfaces()  {
	my ($interfaces) = shift;
	
	my ($int);
	my (@result);
	my ($current_int);
	my ($current_enabled);
	my ($id) = 0;
	
	foreach $int (@{$interfaces})  {
		$int =~ s/\n//;

lib/Cisco/Accounting.pm  view on Meta::CPAN

	
	return @result;
}



##
## fetch all interfaces from a host running IPCAD
## returns array of Cisco::Accounting::Interface objects
##
sub _parse_ipcad_interfaces()  {
	my ($interfaces) = shift;

	my ($int);
	my (@result);
	my ($current_int);
	my ($current_enabled);
	my ($id) = 0;

	foreach $int (@{$interfaces})  {
		$int =~ s/\n//;

lib/Cisco/Accounting/Data.pm  view on Meta::CPAN

	## update stats
	$self->{'stats'}->{'totalpolls'} ++;

	return $self->{'data'};
}

##
## parses a single row of data, returns array of (source, destination, packets, bytes)
## dies otherwise
##
sub _parse_row()  {
	my ($row) = shift;
	
	my (@cols);
	
	## remove leading and trailing spaces, eol characters
	## split row in columns delimited by spaces
	$row =~ s/^ *(.*)[ \n]*$/$1/;
	@cols = split(/ +/,$row);
	
	## die unless we've got 4 columns

lib/Cisco/Accounting/Data.pm  view on Meta::CPAN

	
	## everything is ok, we got (source, destination, packets, bytes)
	return @cols;
}


##
## validate a single column
##  parameters =   column => $col,  ip => 0|1
##
sub _validate_column()  {
	my (%parms) = @_;
	
	my $column = $parms{'column'};
	my $is_ip = $parms{'ip'} || 0;
	
	if (!$column)  {
		croak("column does not contain a value ($column)");
	}
	
	## check if it's an ip address

lib/Cisco/Accounting/Data.pm  view on Meta::CPAN

		unless ($column =~ /^[0-9]+$/)  {
			croak("expecting positive number but not found in column \"$column\"");
		}
	}
}


##
## returns reference to array with the default headers for the columns
##
sub get_headers()  {
	my ($self) = shift;
	return $self->{'headers'};
}


##
## return reference to output hash,  hash contains reference to array of columns
##
sub get_data()  {
	my ($self) = shift;
	return $self->{'data'};
}

##
## return reference to hash with statistics
##
sub get_stats()  {
	my ($self) = shift;
	
	return $self->{'stats'};
}

##
## return reference to hash with statistics
##
sub get_history()  {
	my ($self) = shift;
	
	return $self->{'historical'};
}

sub get_total_polls()  {
	my ($self) = shift;
	return $self->{'stats'}->{'totalpolls'};
}

sub get_total_polled_lines()  {
	my ($self) = shift;
	return $self->{'stats'}->{'totalpolledlines'};
}

sub get_total_bytes()  {
	my ($self) = shift;
	return $self->{'stats'}->{'totalbytes'};
}

sub get_total_packets()  {
	my ($self) = shift;
	return $self->{'stats'}->{'totalpackets'};
}

sub get_last_poll_time()  {
	my ($self) = shift;
	return $self->{'stats'}->{'lastpolltime'};
}

sub get_first_poll_time()  {
	my ($self) = shift;
	return $self->{'stats'}->{'starttime'};
}

1;


__END__


lib/Cisco/Accounting/Interface.pm  view on Meta::CPAN



# initialization : set up logging  
sub _init  {
	my $class=shift;
}

##
## return the interface name
##
sub get_interface()  {
	my $self = shift;
	return $self->{'interface'};
}

##
## return the interface status : IP Accounting enabled or disabled ?
##
sub get_accounting_status()  {
	my $self = shift;
	return $self->{'accounting_status'};
}


##
## set the name of the interface
##
sub set_interface()  {
	my $self = shift;
	my $int = shift;
	
	$self->{'interface'} = $int;
}

##
## set the interface status : IP Accounting enabled or disabled
##
sub set_accounting_status()  {
	my $self = shift;
	my $status = shift;
	
	$self->{'set_accounting_status'} = $status;
}

##
## get the id of this interface
##
sub get_id()  {
	my $self = shift;
	
	return $self->{'id'};
}

##
## set the id of this interface
##
sub set_id()  {
	my $self = shift;
	my $id = shift;
	
	$self->{'id'} = $id;
}

##
## get the description if it exists
##
sub get_description()  {
	my $self = shift;
	
	return $self->{'description'};
}

##
## set the interface description if it exists
##
sub set_description()  {
	my $self = shift;
	my $descr = shift;
	
	$self->{'description'} = $descr;
}

1;


__END__



( run in 0.289 second using v1.01-cache-2.11-cpan-1f129e94a17 )