view release on metacpan or search on metacpan
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);