finding busiest network port

Ever wanted to know which process is using the network bandwidth most? I googled and learned that, on Linux,  iftop seems to be able to tell which port is the busiest. But 'iftop' doesn't seems to be compilable on cygwin. So, I googled more and found several similar Windows GUI apps. But they are all shareware and they are overkill for my purpose anyway. So, I wrote a perl to parse tcpdump output to aggregate by local ports.

On Windows, it requires 'windump'.
WinDump: tcpdump for Windows
WinDump is the Windows version of tcpdump, the command line network analyzer for UNIX. WinDump is fully compatible with tcpdump

The output will look like this.
$ perl /c/e/tmp/active-port.pl 5 1000
962 packets     other, e.g.) arp                57850   bytes.
10 packets      220.14.81.26:1275               4526    bytes.
10 packets      220.14.81.26:1068               906     bytes.
10 packets      220.14.81.26:1256               570     bytes.
4 packets       220.14.81.26:1273               228     bytes.
2 packets       220.14.81.26:21         128     bytes.
1 packets       220.14.81.26:1026               636     bytes.
1 packets       other, e.g.)UDP broadcast               590     bytes.

Here's perl script. Borrowed code from here and here.
#!/usr/bin/perl -w
#
# Parse tcpdump and say which ports are more active
# Usage example: perl active-port.pl '\\\\Device\\\\NPF_{55899BD0-EC52-4066-ABA7-53849ACAA19A}' 100 | sort -t $'\\t' -k 3nr
use strict;

if ($#ARGV != 1) {
    die "$0: Need exactly two arguments. Interface name/# and packet count to capture.\\n";
}
my $tcpdump = "tcpdump";
my $index=0, my @local_ipaddrs, my $address;

if (defined $ENV{OS} && $ENV{OS} =~ "Windows_NT") {
    use Sys::Hostname;
    $tcpdump = "windump";
    my ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname hostname;
    foreach $address (@addrs) {
        my ($a,$b,$c,$d) = unpack('C4',$address);
        $local_ipaddrs[$index++] = "$a.$b.$c.$d";
    }
} else {
    require IO::Interface::Simple;
    my @interfaces = IO::Interface::Simple->interfaces;
  loop: for my $if (@interfaces) {
      next loop if ( !defined $if->address );
      $local_ipaddrs[$index++] = $if->address;
  }
}

open(TCPDUMP, "$tcpdump -i $ARGV[0] -c $ARGV[1] -nntqep 2>/dev/null |");
eof(TCPDUMP) && die "$0: Could not run $tcpdump: $?\\n";
my %activity, my %bytes;
while (<TCPDUMP>) {
    my ($link_level_length, $rest) = ($_ =~ /\^[0-9a-f:]{17}\\s>\\s[0-9a-f:]{17},\\s\\S+,\\slength\\s(\\d+):\\s(.\*)/);
    if (my ($addrport1,$addrport2) = ($rest =~ /(\\d+\\.\\d+\\.\\d+\\.\\d+\\.\\d+)\\s>\\s(\\d+\\.\\d+\\.\\d+\\.\\d+\\.\\d+):/)) {
        my $local;
      local_ipaddrses: foreach $address (@local_ipaddrs) {
          if ($addrport1 =~ /\^$address\\./) {
              $addrport1 =~ s/(.\*)\\./$1:/;
              $activity{$addrport1}++; $bytes{$addrport1}+=$link_level_length;
              $local = "true";
              last local_ipaddrses;
          }
      }
      local_ipaddrses: foreach $address (@local_ipaddrs) {
          if ($addrport2 =~ /\^$address\\./) {
              $addrport2 =~ s/(.\*)\\./$1:/;
              $activity{$addrport2}++; $bytes{$addrport2}+=$link_level_length;
              $local = "true";
              last local_ipaddrses;
          }
      }
        if (!defined $local) {
            $activity{"other, e.g.)UDP broadcast"}++; $bytes{"other, e.g.)UDP broadcast"}+=$link_level_length;
        }
    }
    else {
        $activity{"other, e.g.) arp"}++; $bytes{"other, e.g.) arp"}+=$link_level_length;
    }
}

foreach my $addr_n_port ( sort { $activity{$b} <=> $activity{$a} }  keys %activity) {
    print "$activity{$addr_n_port} packets\\t$addr_n_port\\t\\t$bytes{$addr_n_port}\\tbytes.\\n";
}
exit 0;
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.

Search

Archives
« May 2015
SunMonTueWedThuFriSat
     
2
3
5
8
9
10
12
13
14
16
17
23
24
25
26
27
28
29
30
31
      
Today