Files
conetadm 5718e70f15 init
2024-11-14 21:11:06 +01:00

80 lines
3.3 KiB
Perl
Executable File

#!/usr/bin/perl
use strict;
use warnings;
use Net::Flow qw(decode);
use Net::Flow::Constants qw( %informationElementsByName %informationElementsById );
use IO::Socket::INET;
my $receive_port = 44001; # IPFIX port
my $packet;
my %TemplateArrayRefs;
my $sock = IO::Socket::INET->new( LocalPort => $receive_port, Proto => 'udp' );
my $sender;
while ( $sender = $sock->recv( $packet, 0xFFFF ) ) {
my ($sender_port, $sender_addr) = unpack_sockaddr_in($sender); $sender_addr = inet_ntoa($sender_addr);
my ( $HeaderHashRef, $FlowArrayRef, $ErrorsArrayRef ) = ();
# template ids are per src, destination, and observation domain.
# Ideally the module will handle this, but the current API doesn't
# really allow for this. For now you are on your own.
my ($version, $observationDomainId, $sourceId) = unpack('nx10N2', $packet);
my $stream_id;
if ($version == 9) {
$stream_id = "$sender_port, $sender_addr, $sourceId";
} else {
$stream_id = "$sender_port, $sender_addr, $observationDomainId";
}
$TemplateArrayRefs{$stream_id} ||= [];
my $TemplateArrayRef = $TemplateArrayRefs{$stream_id};
( $HeaderHashRef, $TemplateArrayRef, $FlowArrayRef, $ErrorsArrayRef ) = Net::Flow::decode( \$packet, $TemplateArrayRef );
grep { print "$_\n" } @{$ErrorsArrayRef} if ( @{$ErrorsArrayRef} );
print "\n- Header Information -\n";
foreach my $Key ( sort keys %{$HeaderHashRef} ) {
printf ' %s = %3d' . "\n", $Key, $HeaderHashRef->{$Key};
}
foreach my $TemplateRef ( @{$TemplateArrayRef} ) {
print "\n-- Template Information --\n";
foreach my $TempKey ( sort keys %{$TemplateRef} ) {
if ( $TempKey eq 'Template' ) {
printf ' %s = ' . "\n", $TempKey;
foreach my $Ref ( @{ $TemplateRef->{Template} } ) {
foreach my $Key ( keys %{$Ref} ) {
printf ' %s=%s', $Key, $Ref->{$Key};
}
print "\n";
}
} else {
printf ' %s = %s' . "\n", $TempKey, $TemplateRef->{$TempKey};
}
}
}
foreach my $FlowRef ( @{$FlowArrayRef} ) {
print "\n-- Flow Information --\n";
foreach my $Id ( sort keys %{$FlowRef} ) {
my $name = $informationElementsById{$Id}->{name} // "$Id";
if ( $Id eq 'SetId' ) {
print " $Id=$FlowRef->{$Id}\n" if defined $FlowRef->{$Id};
} elsif ( ref $FlowRef->{$Id} ) {
printf ' Id=%s Value=', $name;
foreach my $Value ( @{ $FlowRef->{$Id} } ) {
printf '%s,', unpack( 'H*', $Value );
}
print "\n";
} else {
printf ' Id=%s Value=%s' . "\n", $name, unpack( 'H*', $FlowRef->{$Id} );
}
}
}
}
1;
__END__