#!/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; # port my $packet; my %TemplateArrayRefs; my $sock = IO::Socket::INET->new( LocalPort => $receive_port, Proto => 'udp' ); my $sender; my $reporting_device; while ( $sender = $sock->recv( $packet, 0xFFFF ) ) { my ($sender_port, $sender_addr) = unpack_sockaddr_in($sender); $sender_addr = inet_ntoa($sender_addr); $reporting_device=$sender_addr; my ( $HeaderHashRef, $FlowArrayRef, $ErrorsArrayRef ) = (); 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}; } } } my ($in,$out,$dport,$sport,$dip,$sip,$dmask,$smask,$doct,$dpack,$prot,$cos,$next,$tcb,$sas,$das,$fstart,$fend); printf "\n%-15s %-5s %-5s %-5s %-15s %-4s %-5s %-2s %-15s %-4s %-5s %-2s\n", "Reporter", "In", "Out", "Bytes", "IP", "Mask", "Port", "->", "IP", "Mask", "Port", "Pro"; foreach my $FlowRef ( @{$FlowArrayRef} ) { print "\n-- Flow Information --\n"; print "Reporter $reporting_device\n"; my $value; my $name; foreach my $Id ( sort keys %{$FlowRef} ) { $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} } ) { $value = unpack( 'H*', $value ); printf '%s,', $value; } print "\n"; } else { $value = unpack( 'H*', $FlowRef->{$Id} ); printf ' Id=%s Value=%s' . "\n", $name, $value; } my $tmp; if ( $name eq "octetDeltaCount" ) { # printf "%-30s %d\n", $name, hex($value); $doct=hex($value); } if ( $name eq "ingressInterface" ) { # printf "%-30s %d\n", $name, hex($value); $in=hex($value); } if ( $name eq "destinationTransportPort" ) { # printf "%-30s %d\n", $name, hex($value); $dport=hex($value); } if ( $name eq "destinationIPv4Address" ) { # printf "%-30s %s\n", $name, hex2ip($value); $dip=hex2ip($value); } if ( $name eq "destinationIPv4PrefixLength" ) { # printf "%-30s /%d\n", $name, hex($value); $dmask=hex($value); } if ( $name eq "egressInterface" ) { # printf "%-30s %d\n", $name, hex($value); $out=hex($value); } if ( $name eq "ipNextHopIPv4Address" ) { # printf "%-30s %s\n", $name, hex2ip($value); $next=hex2ip($value); } if ( $name eq "bgpSourceAsNumber" ) { # printf "%-30s %d\n", $name, hex($value); $sas=hex($value); } if ( $name eq "bgpDestinationAsNumber" ) { # printf "%-30s %d\n", $name, hex($value); $das=hex($value); } if ( $name eq "packetDeltaCount" ) { # printf "%-30s %d\n", $name, hex($value); $dpack=hex($value); } if ( $name eq "flowEndSysUpTime" ) { # printf "%-30s %d\n", $name, hex($value); $fend=hex($value); } if ( $name eq "flowStartSysUpTime" ) { # printf "%-30s %d\n", $name, hex($value); $fstart=hex($value); } if ( $name eq "protocolIdentifier" ) { # printf "%-30s %d\n", $name, hex($value); $prot=hex($value); } if ( $name eq "ipClassOfService" ) { # printf "%-30s %d\n", $name, hex($value); $cos=hex($value); } if ( $name eq "tcpControlBits" ) { # print "$name $value\n"; $tcb=hex($value); } if ( $name eq "sourceTransportPort" ) { # printf "%-30s %d\n", $name, hex($value); $sport=hex($value); } if ( $name eq "sourceIPv4Address" ) { # printf "%-30s %s\n", $name, hex2ip($value); $sip=hex2ip($value); } if ( $name eq "sourceIPv4PrefixLength" ) { # printf "%-30s /%d\n", $name, hex($value); $smask=hex($value); } } printf "\n%-15s %-5s %-5s %-5s %-15s %-4s %-5s %-2s %-15s %-4s %-5s %-2s\n", "Reporter", "In", "Out", "Bytes", "IP", "Mask", "Port", "->", "IP", "Mask", "Port", "Pro"; printf "%-15s %-5s %-5s %-5s %-15s %-4s %-5s %-2s %-15s %-4s %-5s %-2s\n", "$reporting_device", "$in", "$out", "$doct", "$sip", "$smask", "$sport", "->", "$dip", "$dmask", "$dport", "$prot"; } } sub hex2ip { my ($h, @o, $i); $h=shift; @o=$h=~/([0-9a-z]{2})([0-9a-z]{2})([0-9a-z]{2})([0-9a-z]{2})/i; foreach (@o) { $_=hex($_); } $i="$o[0].$o[1].$o[2].$o[3]"; return $i; }