IPDR

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

0.17	26/08/2009
	Another bug in the Cisco module (you probably do not believe I 
	tested this extensively)
0.16	24/08/2009
	Bug in the Cisco module causing the DOCSIS parser to fail
	Thanks to Rui Dias for providing debug and comms to track it down
0.15	20/07/2009
	IP ownership resolved and now release under the artistic_2 license.
0.14	17/07/2009
	Made DataHandler fork when processing data. The time between
	pass off to external function and keep alive timeout could be
	exceeded, so to prevent stall fork applied.
0.13	16/07/2009
	Added keep alive to after session stop, otherwise IPDR exporter
	reported timeout. Session stop is not a disconnect state, so
	collector needs to send keepalive to maintain an open session.
	Fixed CMcpeIpv4List so at LEAST the first entry in the list is
	shown. Checking for more entries should work however there is
	no data available to be 100%
0.12	12/07/2009
	Changed some of the debug error messages to be more meaningful.
	template_value_definitions needs some work. Getting a clearly defined
	valueset is proving very difficult so more vendors required.
	Added some attributes for TCP extensions, so the data is sent to
	third party servers, if needed.
0.11	03/02/2009

lib/IPDR/Collection/Cisco.pm  view on Meta::CPAN


An example configuration for Motorola BSR is

    ipdr enable
    ipdr collector 192.168.1.1 5000 3
    ipdr collector 192.168.1.2 4000 2

The IP addresses and ports specicified are those of a collector that will
connect to the CMTS. You can have multiple collectors connected but only
the highest priority collector will receive data, all others will received
keep alives.
The Client module makes a connection to the destination IP/Port specified.

An example on how to use this module is shown below. It is relatively simple
use the different module for Cisco, all others use Client.


    #!/usr/local/bin/perl

    use strict;
    use IPDR::Collection::Cisco;

lib/IPDR/Collection/Client.pm  view on Meta::CPAN


An example configuration for Motorola BSR is    

    ipdr enable
    ipdr collector 192.168.1.1 5000 3
    ipdr collector 192.168.1.2 4000 2

The IP addresses and ports specicified are those of a collector that will 
connect to the CMTS. You can have multiple collectors connected but only
the highest priority collector will receive data, all others will received
keep alives. 
The Client module makes a connection to the destination IP/Port specified.

An example on how to use this module is shown below. It is relatively simple 
use the different module for Cisco, all others use Client.

    #!/usr/local/bin/perl

    use strict;
    use IPDR::Collection::Client;

lib/IPDR/Collection/Client.pm  view on Meta::CPAN

	$self->{_GLOBAL}{'template'}= \%template;
	$self->{_GLOBAL}{'sessioninfo'}= \%session;
	$self->{_GLOBAL}{'current_data'}= \%current_data;
        $self->{_GLOBAL}{'complete_decoded_data'} = \%complete_decoded_data;

	$self->{_GLOBAL}{'AckTime'}=0;
	$self->{_GLOBAL}{'AckSequence'}=0;
	$self->{_GLOBAL}{'data_capture_running'}=0;
	$self->{_GLOBAL}{'data_capture_running_time'}=0;
	$self->{_GLOBAL}{'data_capture_data_count'}=0;
	$self->{_GLOBAL}{'data_capture_keep_alive'}=0;
	$self->{_GLOBAL}{'Session'}=0;

        return $self;
}

sub return_keep_alive
{
my ( $self ) = shift;
return $self->{_GLOBAL}{'KeepAlive'};
}

sub construct_capabilities
{
my ( $self ) = shift;
my ( $required_capabilities ) = shift;

lib/IPDR/Collection/Client.pm  view on Meta::CPAN

print "Length of data after new block is '".length( $self->{_GLOBAL}{'data_received'} )."'\n" if $self->{_GLOBAL}{'DEBUG'}>0;
if ( length($message)>${$decode_data}{'Length'} )
	{
	$self->{_GLOBAL}{'data_processing'}=1;
	}

$message=substr($message,8,length($message)-8);

if ( ${$decode_data}{'Type'}=~/^connect_response$/i )
	{
	my ( $caps, $keepalive ) = unpack ( "SN",$message );
	my ( $vendor ) = substr($message,6,length($message)-6);
	${$decode_data}{'Capabilities'}=$caps;
	${$decode_data}{'KeepAlive'}=$keepalive;
	${$decode_data}{'VendorID'}=$vendor;
	if ( $self->{_GLOBAL}{'DEBUG'}>0 )
		{
		print "Connect response decoded.\n";
		foreach my $key ( keys %{$decode_data} )
			{
			next if $key=~/^RAWDATARETURNED$/i;
			next if $key=~/^Next_Message$/i;
			print "Variable is '$key' value is '${$decode_data}{$key}'\n";
			}

lib/IPDR/Collection/Client.pm  view on Meta::CPAN

	return 1;
	}

if ( ${$decode_data}{'Type'}=~/^data$/i )
	{
	if ( !$self->{_GLOBAL}{'data_capture_running'} )
		{
		$self->{_GLOBAL}{'data_capture_running_time'}=time();
		$self->{_GLOBAL}{'data_capture_running'}=0;
		}
	if ( !$self->{_GLBOAL}{'data_capture_keep_alive'} )
		{
		$self->{_GLBOAL}{'data_capture_keep_alive'}=time();
		}

	$self->{_GLOBAL}{'data_capture_running'}++;
	$self->{_GLOBAL}{'data_capture_data_count'}++;
	my ( $template_id, $config_id, $flags ) = unpack("SSC",$message);
	$message = substr($message,5,length($message)-5);
	my ( $sequence_num ) = decode_64bit_number($message); $message = substr($message,8,length($message)-8);
	my ( $record_type );
	${$decode_data}{'DATA_TemplateID'}=$template_id;
	${$decode_data}{'DATA_ConfigID'}=$config_id;

lib/IPDR/Collection/Client.pm  view on Meta::CPAN

			);
		waitpid($child,0);
		exit(0);
		}
$self->{_GLOBAL}{'current_data'}={};
$self->{_GLOBAL}{'complete_decoded_data'}={};
return 1;
}


sub send_get_keepalive
{
my ( $self ) = shift;
my ( $data ) = shift;
if ( $self->get_internal_value('data_ack') )
	{
	print "Data ACK is set\n" if $self->{_GLOBAL}{'DEBUG'}>0;
	$self->send_data_ack( 
		$self->get_internal_value('dsn_configID'), 
		$self->get_internal_value('dsn_sequence') 
		);

lib/IPDR/Collection/Client.pm  view on Meta::CPAN

			);
		waitpid($child,0);
		exit(0);
		}

	$self->{_GLOBAL}{'complete_decoded_data'}={};
	$self->set_internal_value('data_ack',0);
	$self->{_GLOBAL}{'current_data'}={};
	}

my ( $result ) = $self->send_message( $self->construct_get_keepalive() );
return $result;
}

sub send_get_sessions
{
my ( $self ) = shift;
my ( $data ) = shift;
my ( $result ) = $self->send_message( $self->construct_get_sessions() );
return $result;
}

lib/IPDR/Collection/Client.pm  view on Meta::CPAN

sub construct_get_sessions
{
my ( $self ) = shift;
my ( $message ) = pack("S",4096);
my ( $header ) = $self->generate_ipdr_message_header(
                        2,"GET_SESSIONS",length($message));
$header.=$message;
return $header;
}

sub construct_get_keepalive
{
my ( $self ) = shift;
my ( $header ) = $self->generate_ipdr_message_header(
                        2,"KEEP_ALIVE",0);
return $header;
}


sub construct_flow_start
{

lib/IPDR/Collection/Client.pm  view on Meta::CPAN

$self->{_GLOBAL}{'template'}= {};
$self->{_GLOBAL}{'sessioninfo'}= {};
$self->{_GLOBAL}{'current_data'}= {};
$self->{_GLOBAL}{'complete_decoded_data'} = {};

$self->{_GLOBAL}{'AckTime'}=0;
$self->{_GLOBAL}{'AckSequence'}=0;
$self->{_GLOBAL}{'data_capture_running'}=0;
$self->{_GLOBAL}{'data_capture_running_time'}=0;
$self->{_GLOBAL}{'data_capture_data_count'}=0;
$self->{_GLOBAL}{'data_capture_keep_alive'}=0;
$self->{_GLOBAL}{'Session'}=0;

if ( $self->{_GLOBAL}{'DEBUG'} > 0 )
	{
	my $test = $self->{_GLOBAL};
	foreach my $setting ( keys %{$test} )
		{
		print "Global setting '$setting' value is '${$test}{$setting}'\n";
		}
	}

lib/IPDR/Collection/Client.pm  view on Meta::CPAN


        # If the message is a template data, store the template
        # and ack the template
        if ( $last_message=~/^TEMPLATE_DATA$/i )
                {
		$self->log("TEMPLATE_DATA");
		$self->send_final_template_data_ack(); 
		}

        # If the message is a session_start just send a keep
        # alive.
        if ( $last_message=~/^SESSION_START$/i )
                { 
		$self->log("SESSION_START");
		$self->send_get_keepalive(); 
		}

        # If the message is a keep alive, send one back.
        # This function does a little more, but has been
        # made a wrapper to keep the code clean.
        if ( $self->return_current_type()=~/^KEEP_ALIVE$/i )
                { 
		$self->log("KEEP_ALIVE");
		$self->send_get_keepalive(); 
		}

        # If the message is a data message, process it.
        # This also sends one keepalive upon receipt
        # of the first data segment, so keeping to the
        # specification and allowing DSN generation.
        if ( $self->return_current_type()=~/^DATA$/i )
                {
		$self->decode_data( );
                }

	# We need to make sure we decoded the last message
	# before checking if we can throw it out.
        if ( $self->{_GLOBAL}{'data_capture_running'}>=$self->{_GLOBAL}{'MaxRecords'}
                && $self->{_GLOBAL}{'MaxRecords'}>0)
                {
		print "Max records reached was '".$self->{_GLOBAL}{'data_capture_running'}."'\n";
		print "Max records limit   was '".$self->{_GLOBAL}{'MaxRecords'}."\n\n" if $self->{_GLOBAL}{'DEBUG'}>0;
                $self->{_GLOBAL}{'data_capture_running'}=0;
                $self->max_records_segment();
                }

	# so if you are receiving more data than a keepalive you may need
	# to send a data_ack
        if ( ((time()-$self->{_GLOBAL}{'data_capture_running_time'})
                        > $self->{_GLOBAL}{'AckTime'})
			&& $self->return_current_type()=~/^DATA$/i )
                {
                if ( defined( $self->get_internal_value('dsn_sequence')) )
                        {
                        $self->{_GLOBAL}{'data_capture_running_time'}=time();
			$self->{_GLOBAL}{'data_capture_data_count'}=0;
			print "Sending AckTime data ack.\n\n" if $self->{_GLOBAL}{'DEBUG'}>0;

lib/IPDR/Collection/Client.pm  view on Meta::CPAN

			{
			$self->{_GLOBAL}{'data_capture_data_count'}=0;
			print "Sending AckSequence data ack.\n\n" if $self->{_GLOBAL}{'DEBUG'}>0;
			$self->send_data_ack(
				$self->get_internal_value('dsn_configID'),
				$self->get_internal_value('dsn_sequence')
					);
			}
		}
	
	if ( (time()-$self->{_GLOBAL}{'data_capture_keep_alive'})
			> $self->{_GLOBAL}{'KeepAlive'} )
		{
		$self->send_message( $self->construct_get_keepalive() );
		$self->{_GLOBAL}{'data_capture_keep_alive'}=time();
		}

        # If the message is a session_stop, we should probably
        # send a disconnect, but we dont as yet.
	# with session stop you need to send a keepalive, as
	# session stop is not always a disconnect.
        if ( $self->return_current_type()=~/^SESSION_STOP$/i )
                {
		$self->log("SESSION_STOP");
		$self->send_get_keepalive();
                #$ipdr_client->{_GLOBAL}{'Selector'}->remove( $ipdr_client->{_GLOBAL}{'Handle'} );
                }

        # If the message is an error message, stop, something
        # went wrong somewhere.
        if ( $self->return_current_type()=~/^ERROR$/i )
                {
		$self->log("ERROR");
		print "Disconnect and closed TCP.\n" if $self->{_GLOBAL}{'DEBUG'}>0;
                return 0;

lib/IPDR/Collection/Client.pm  view on Meta::CPAN

	print __PACKET_DATA $data;
	close (__PACKET_DATA);
	}

$self->set_internal_value('dsn_sequence',${$record}{'DATA_Sequence'} );
$self->set_internal_value('dsn_configID',${$record}{'DATA_ConfigID'} );

if ( !$self->get_internal_value('data_ack') )
	{
	$self->set_internal_value('data_ack',1);
	$self->send_message( $self->construct_get_keepalive() );
	}

my ( $int_or_dir ) = unpack("N",$data);

# If you can figure out the first line, better person than I
# All i figured out was 'possibly' direction, but this
# might also be interface number so it has not been added 

$data = substr($data,4,length($data)-4);



( run in 1.167 second using v1.01-cache-2.11-cpan-39bf76dae61 )