contribs/toptraffic.pl


#!/usr/local/bin/perl
use Socket;

# George Pallas 2001(c) All rights(& lefts) reserved.

$timeoutalarm = 1;

if ($#ARGV < 8) {
err:  print "\nUsage   : toptraffic DATAFILE [SRC|DEST] PORT MIN_MB MIN_FLOWS TOP_X [FLOWS|BYTES] [RES_Y|RES_N] [ANLZ_PORT_Y|ANLZ_PORT_N]";
  print "\n          [SRC|DEST] specifies whether you want outgoing or incoming traffic respectively";
  print "\n          PORT takes the obvious value ALL (sums the traffic of all ports";
  print "\n          or you can instead specify a port of interest";
  print "\n          MIN_MB is the desired traffic threshold wanted";
  print "\n          MIN_FLOWS is the desired flow threshold wanted";
  print "\n          TOP_X specifies how many ip are to be presented";
  print "\n          [FLOWS|BYTES] specifies whether to sort results by flows or bytes";
  print "\n          [RES_Y|RES_N] specifies whether you want the DNS of the IPs presented or not";
  print "\n          [ANLZ_PORT_Y|ANLZ_PORT_N] specifies whether you want a per port traffic analysis or not";
  print "\nExample : toptraffic 155.207.199.100.1000 SRC ALL 150 800 10 BYTES RES_Y ANLZ_PORT_N";
  print "\n          (To check which 10 hosts !in AUTH! have more than 150 MB outgoing traffic in more than 800 flows\n\n";
  exit;
}

$port_to_check = $ARGV[2];
if ($port_to_check eq "ALL"){
  $will_check_port = 0;
} else {
 $will_check_port = 1;  
}

$TOP_X = $ARGV[5];
$MIN_MB = $ARGV[3];
$MIN_FLOWS = $ARGV[4];
$threshold_bytes = 1024*1024*$MIN_MB;
$SORT_BY = $ARGV[6];
if     ($ARGV[7] eq "RES_Y"){
  $will_resolve = 1;
}elsif ($ARGV[7] eq "RES_N"){
  $will_resolve = 0;
}else{
  print " RESOLVE parameter wrong defined... see the options...\n";
  goto err;
} 
if     ($ARGV[8] eq "ANLZ_PORT_Y"){
  $will_analyze = 1;
}elsif ($ARGV[8] eq "ANLZ_PORT_N"){
  $will_analyze = 0;
}else{
  print "Analyze port  parameter wrong defined... see the options...\n";
  goto err;
}
if (($SORT_BY ne "FLOWS") && ($SORT_BY ne "BYTES")){
  print "[FLOWS|BYTES] field wrong defined, use FLOWS or BYTES...\n";
  goto err;
}

# Show info
#print "Analyzing file ",$ARGV[0], "\n";
#print "checking traffic on port ",$port_to_check,"\n" if ($will_check_port == 1);
$direction = $ARGV[1];
#print "consider only ";
if ($direction eq "SRC"){
#  print "outgoing ";
}elsif 
   ($direction eq "DEST"){
#  print "incoming ";
} else{
  print "!!!ERROR IN SYNTAX!!!\n";
  goto err;
}

#print "traffic\n";
#print "Flow    threshold is ",$MIN_FLOWS," flows\n";
#print "Traffic threshold is ",$MIN_MB,"    MB\n\n";

if (-e $ARGV[0]){
  open DF,$ARGV[0];
}else{
  print "File not found...\n";
  exit;
}

beg:while ($line = ){     # SAROSH TOU ARXEIOU
  if ($line =~ /SOURCE/){ #prokeitai gia tin proti grammi, den tin theloume
   next beg;
  }

  @fields = split(/\|/,$line);
  $source =      $fields[0];
  $destination = $fields[1];
  if ($direction eq "DEST"){  
    $port =      $fields[7];
  }else{
    $port =      $fields[6];
  }
  $bytes =       $fields[10];
  $flows =       $fields[11];
  chomp($flows);

  if (($will_check_port == 1) && ($port ne $port_to_check)){
    next beg; # efoson exei dothei san parametros to port, discard lines with NOT that port
  }

  if ($direction eq "DEST"){
    $ip = $destination;
  }else{
    $ip = $source;
  }
  
  if (($ip =~ /155\.207/) && ($ip ne "155.207.0.31") && ($ip ne "155.207.0.32") && ($ip ne "155.207.199.31") && ($ip ne "155.207.199.32")){
    # @traffic_table : pinakas me tis IP kai tin kinisi pou mas endiaferoun
    push(@traffic_table, $ip."|".$bytes."|".$flows);
    push(@traffic_table_with_port, $ip.":".$port."|".$bytes."|".$flows) if ($will_analyze == 1);
  }
}

close(DF);

@sorted = sort @traffic_table;
@sorted_with_port = sort @traffic_table_with_port if ($will_analyze == 1);

# Apo ton @sorted tha sygxoneusoume ta omoia ip's (pou einai dipla-dipla
# logo sorted)

($tmp_ip2, $tmp_bytes2, $tmp_flows2) = split(/\|/,$sorted[0]); # diavazoume tin proti grammi, tin kratame


$flows = $tmp_flows2; # exoume idi mia diavasei
$i = 1; # index gia ton sorted
while ($i < @sorted){
  ($tmp_ip, $tmp_bytes, $tmp_flows2) = split(/\|/,$sorted[$i]); # diavazoume mia grammi
  if ($tmp_ip eq $tmp_ip2){ # brikame idia IP
    $tmp_bytes2 += $tmp_bytes;
    $flows += $tmp_flows2; # makes sense, huh;!
  }else{
    push(@merged, $tmp_bytes2."|".$tmp_ip2."|".$flows); # grafoume tin kratimeni
   $flows = $tmp_flows2; #xmmm, 1, oxi 0, afou idi diavase mia (kataramena bugs)
    $tmp_ip2 = $tmp_ip; $tmp_bytes2 = $tmp_bytes; # kai san kratimeni kratame tin nea
  }
  $i++; 
}
push(@merged, $tmp_bytes2."|".$tmp_ip2."|".$flows); # grafoume tin (teleutaia) kratimeni


if ($will_analyze == 1){

# Apo ton @sorted_with_port tha sygxoneusoume ta omoia ip's and ports (pou einai dipla-dipla
# logo sorted)

($tmp_ip2, $tmp_bytes2, $tmp_flows2) = split(/\|/,$sorted_with_port[0]); # diavazoume tin proti grammi, tin kratame


$flows = $tmp_flows2; # exoume idi mia diavasei
$i = 1; # index gia ton sorted_with_port
while ($i < @sorted_with_port){
  ($tmp_ip, $tmp_bytes, $tmp_flows2) = split(/\|/,$sorted_with_port[$i]); # diavazoume mia grammi
  if ($tmp_ip eq $tmp_ip2){ # brikame idia IP
    $tmp_bytes2 += $tmp_bytes;
    $flows += $tmp_flows2; # makes sense, huh;!
  }else{
    push(@merged_with_port, $tmp_bytes2."|".$tmp_ip2."|".$flows); # grafoume tin kratimeni
   $flows = $tmp_flows2; #xmmm, 1, oxi 0, afou idi diavase mia (kataramena bugs)
    $tmp_ip2 = $tmp_ip; $tmp_bytes2 = $tmp_bytes; # kai san kratimeni kratame tin nea
  }
  $i++;
}
push(@merged_with_port, $tmp_bytes2."|".$tmp_ip2."|".$flows); # grafoume tin (teleutaia) kratimeni

} # if will_analyze == 1


if ($SORT_BY eq "BYTES"){    
  @merged_sorted = sort by_bytes @merged;
}elsif ($SORT_BY eq "FLOWS"){
  @merged_sorted = sort by_flows @merged;
}

# Efoson $will_analyze == 1 exoume ta eksis :
# O pinakas @merged_sorted exei ton pinaka me (bytes, ip, flows) kata fthinousa diataksi (eite kata bytes, eite flows)
# o pinakas @merged_with_port exei ton pinaka me (bytes, ip:port, flows) xwris diataksi, aplws symbainei to eksis :
# o @merged_with_port einai taksinomimenos alfabitika me to pedio "ip:port" diladi oles oi idies ip einai geitonikes
# example : @merged_sorted
#879972888|155.207.39.59|1020
#476341590|155.207.34.135|10168
#450490749|155.207.196.224|1476
#390111150|155.207.25.136|577
#317619969|155.207.11.246|2834
#312360184|155.207.130.36|44
#295554676|155.207.118.6|435
#
# example : @merged_with_port
#48720|155.207.39.59:0|38  
#658|155.207.39.59:137|2  
#34|155.207.39.59:1K_91K_Port_Range|1  
#852979138|155.207.39.59:1K_9K_Port_Range|968
#1827|155.207.39.59:371|1 
#26942511|155.207.39.59:40K_49K_Port_Range|10 


# Print results
if ($will_analyze == 0){
  print "            Bytes                IP              Number of Flows\n\n" if ($will_resolve == 0);
  print "            Bytes                IP                 DNS                Number of Flows\n\n" if ($will_resolve == 1);
}

$count = 0;
for ($i=0; $i < $TOP_X; $i++) {
  last if ($i == @merged_sorted); # exei teleiwsei o pinakas, prin kan teleiwsei i for -> bgainoume
  ($m_bytes, $m_ip, $m_flows) = split(/\|/,$merged_sorted[$i]);
   if (($m_flows >= $MIN_FLOWS) && ($m_bytes >= $threshold_bytes)){
     $count++;
     if ($will_analyze == 1){
       print "            Bytes                IP              Number of Flows\n\n" if ($will_resolve == 0);
       print "            Bytes                IP                 DNS                Number of Flows\n\n" if ($will_resolve == 1);
     }
     $line = sprintf "%2s.     %10s         %-15s         %6s", $count,$m_bytes, $m_ip, $m_flows if ($will_resolve == 0);
     $line = sprintf "%2s.     %10s         %-15s   %-25s    %6s", $count,$m_bytes, $m_ip,resolv($m_ip), $m_flows if ($will_resolve == 1);
     print $line,"\n";

     if ($will_analyze == 1){ # tha psaksoume ston @merged_with_port gia tin $m_ip gia na ektypwsoume tin per port analysis
       print "\n         PORT                BYTES           FLOWS\n";
       $t = 0;
       while ($t < @merged_with_port){
            @fields = split(/\|/,$merged_with_port[$t]); # apo ta fields mas endiaferei mono to mesaio
            @fields2 = split(/:/,$fields[1]); 
            last if ($fields2[0] eq $m_ip);
            $t++; 
       } # while
       # brikame tin $m_ip sti thesi $t tou @merged_with_port, twra tha ektypwsoume
       while ($t < @merged_with_port){
            @fields = split(/\|/,$merged_with_port[$t]); # apo ta fields mas endiaferei mono to mesaio    
            @fields2 = split(/:/,$fields[1]);
            last if ($fields2[0] ne $m_ip);
            $line = sprintf "%18s        %10s        %7s\n", $fields2[1], $fields[0], $fields[2];
            print $line;
            $t++;
       } # while
     print "-----------------------------------------------------------------------------------------\n\n";         
     } # if ($will_analyze == 1)
   } # if thresholds...
} # for


# TELOS KWDIKA ...


# Kai mia-dyo synartisoules gia to sorting...

sub by_bytes{
   @a1 = split(/\|/,$a);
   @b1 = split(/\|/,$b);
   $b1[0] <=> $a1[0];  
}

sub by_flows{
   @a1 = split(/\|/,$a);
   @b1 = split(/\|/,$b);
   $b1[2] <=> $a1[2];
}

sub resolv #resolv and cache a host name
{
#local $mname,$miaddr,$mhost;
$mhost=shift;

        $miaddr = inet_aton($mhost); # or whatever address
        if (! $HOSTS{$mhost} ) {
		alarm( $timeoutalarm );
		$mname='';
                $mname  = gethostbyaddr($miaddr, AF_INET);
        	alarm( 0 );
                if  ( $mname =~ /^$/ )  {
                        $mname=$mhost;
                }
                $HOSTS{$mhost}=$mname;
        }
  return $HOSTS{$mhost}
}    


sub cannotresolv 
{
	print "cannot resolve\n";
	alarm($timeoutalarm);
	return 1;
}