package TopCapture; use strict; use warnings; use AnyEvent::DNS; use AnyEvent::Run; use Moo; ###########################################i sub reset { ########################################### my( $self ) = @_; $self->{ ip_counts } = {}; $self->{ packet_count } = 0; } ########################################### sub start { ########################################### my( $self ) = @_; $self->reset; $self->{ dns_cache } = {} if !exists $self->{ dns_cache }; my @tshark_cmd = qw( tshark -q - i any -T fields - e ip.src -e ip.dst ); $self->{ runner } = AnyEvent::Run->new( cmd => \@tshark_cmd, on_read => sub { my( $handle ) = @_; $handle->push_read( line => sub { my( $handle, $line ) = @_; $self->line_process( $line ); } ) }, on_error => sub { die "CapError: $!" } ); } ########################################### sub line_process { ########################################### my( $self, $line ) = @_; my @ips = split ' ', $line; return 1 if scalar @ips != 2; $self->{ packet_count }++; for my $ip ( @ips ) { $self->{ ip_counts }->{ $ip }++; my $dns = $self->{ dns_cache }; next if exists $dns->{ $ip }; $dns->{ $ip } = $ip; AnyEvent::DNS::reverse_lookup( $ip, sub { my( $hostname ) = @_; return if !defined $hostname or $hostname eq "unknown"; $dns->{ $ip } = "$hostname"; } ); } } ########################################### sub stats { ########################################### my( $self ) = @_; return ( $self->{ packet_count }, { map { $self->{ dns_cache }->{ $_ } => $self->{ ip_counts }->{ $_ } } sort keys %{ $self->{ ip_counts } } } ); } 1;