#!/usr/athena/bin/perl
$show_proto = "\U$ARGV[0]";
($show_proto, $prefix) = split(/:/, $show_proto);
$count = $ARGV[1];

unless ($show_proto =~ /^(eth|ip)$/i) {
    print "Usage: traftop (eth|ip) [count]\n";
    print "Can specify optional subnet prefix with IP option,\n";
    print "for instance:  \"traftop ip:18.239\".\n";
    exit;
}

open(CAPTURE, "./traftop-cap $count |");
while(<CAPTURE>) {
    $delta_t = $1 if /^TIMEDIFF (\d+)$/;
    if (/^BYTES (\d+) (\w+)-(\w+) (.*)$/) {
	$bytes = $1;
	$proto = $2;
	$direction = $3;
	$addr = $4;

	if ($addr =~ /^$prefix/) {
	    $pd_bytes{$proto}{$direction}{$addr} += $bytes;
	    $pd_pkts{$proto}{$direction}{$addr} += 1;

	    $total_bytes{$proto}{$direction} += $bytes;
	    $total_pkts{$proto}{$direction}++;
	}
    }
}

$delta_t /= 1000 * 1000;

$show_direction = 'SRC';
@top_bps = sort by_bytes   keys %{$pd_pkts{$show_proto}{'SRC'}};
@top_pkt = sort by_packets keys %{$pd_pkts{$show_proto}{'SRC'}};

print	"\n";
printf	"%-38s %-38s\n", "Top sending hosts (Kbps):",
			 "Top sending hosts (packets/sec):";
printf	"%-38s %-38s\n", "=========================",
			 "================================";
&printTops();

$show_direction = 'DST';
@top_bps = sort by_bytes   keys %{$pd_pkts{$show_proto}{'DST'}};
@top_pkt = sort by_packets keys %{$pd_pkts{$show_proto}{'DST'}};

print	"\n";
printf	"%-38s %-38s\n", "Top receiving hosts (Kbps):",
			 "Top receiving hosts (packets/sec):";
printf	"%-38s %-38s\n", "===========================",
			 "==================================";
&printTops();

sub printTops {
    $total_bytes = $total_bytes{$show_proto}{$show_direction};
    $total_pkts  = $total_pkts {$show_proto}{$show_direction};

    for ($i=0; $i<9; $i++) {
	$addr = shift @top_bps;
	$rate = 8 * $pd_bytes{$show_proto}{$show_direction}{$addr};
	$frac = int ($rate * 12.5 / $total_bytes);
	$rate = int ($rate / 1000 / $delta_t);
	$paddr = print_addr($addr, $show_proto);
	$out1 = sprintf "%7d  %2d%%  %-24s", $rate, $frac, $paddr;

	$addr = shift @top_pkt;
	$rate = $pd_pkts{$show_proto}{$show_direction}{$addr};
	$frac = int ($rate * 100 / $total_pkts);
	$rate = int ($rate / $delta_t);
	$paddr = print_addr($addr, $show_proto);
	$out2 = sprintf "%7d  %2d%%  %-24s", $rate, $frac, $paddr;

	print "$out1 $out2\n";
    }
}

sub by_packets {
    return $pd_pkts{$show_proto}{$show_direction}{$b} <=>
	   $pd_pkts{$show_proto}{$show_direction}{$a};
}

sub by_bytes {
    return $pd_bytes{$show_proto}{$show_direction}{$b} <=>
	   $pd_bytes{$show_proto}{$show_direction}{$a};
}

sub print_addr {
    my ($addr, $proto) = @_;

    my @v = split(/:/, $addr);

    if ($proto eq 'ETH') {
	return sprintf "%02x:%02x:%02x:%02x:%02x:%02x", @v;
    }

    if ($proto eq 'IP') {
	return sprintf "%d.%d.%d.%d", @v;
    }

    return 'Unknown-Proto';
}
