#!/usr/bin/perl

require "flush.pl";

# Parse traceroute output and determine for each hop:
#	MIN MAX AVG X/Y PCT
#
# Where:
#	MIN	Minimum delay
#	MAX	Maximum delay
#	AVG	Average delay (mean)
#	X/Y	X packets succeeded, Y packets total
#	PCT	Percentage (100X/Y)
#
$MSCALE=25;	 # Scale for MEAN latency
$MMAX=2000;	 # Maximum Value of  MEAN latency (ms)
$RSCALE=2;	 # Scale for success RATE
$RMAX=100; 	 # Maximum Value of  success RATE (%)
$HWID=20;	 # Max width of non-verbose Host name/IP (characters)

$verb="No";
$unfm="No";
$graph="Yes";

$n=1;
for (@ARGV)
{
	if (/-v/)
	{
		$verb=$ARGV[$n];
	}
	if (/-u/)
	{
		$unfm=$ARGV[$n];
	}
	if (/-g/)
	{
		$graph=$ARGV[$n];
	}
	# Ignore any other commandline arguments
	$n++;
}
for (@ARGV) { shift };

# Force STDOUT flushes on line basis
select((select(STDOUT), $|=1)[0]);

while (<>)
{
    $DATA.=$_;
    chop;
    if (/^[ 0-9]/)	# Make sure it's a hop, not fluff.
    {
	$line=$_;
	@line=split;

	# New line, reset all the variables
	$min="never";
	$max="never";
	$nsamp=0;
	$nsucc=0;
	$accum=0;
	$host="";
	$ip="";
	$times="";
	
	# Parse each field
	for (@line)
	{
		if (/^[0-9][0-9]*\.[0-9][0-9][0-9]$/)
		{
			# Parse ms value
			$times=sprintf("%s %s", $times, $_);
			if ($_ < $min || $min eq "never") { $min=$_ };
			if ($_ > $max) { $max=$_ };
			$accum+=$_;
			$nsamp++;
			$nsucc++;

		} elsif (/^[(][0-9.]*[)]$/) {
			# Parse IP address
			if ($ip) {
				$ip=sprintf("%s*", $ip);
			}
			else { $ip=$_ }
		} elsif (/^[0-9 ][0-9]*$/) {
			# Parse line number
			$seq=$_
		} elsif (/^[*]$/) {
			# Parse as unreturned probe
			$nsamp++;
		} elsif (/^ms$/) {
			# Ignore, simply means milliseconds
		} elsif (/^!/) {
			# Parse as ICMP Error Message (!H/!N/etc.)
			$error=$error." ".$_;
		} else {
			# Parse as hostname
			if ($host) {
				$host=sprintf("%s*", $host);
			}
			else { $host=$_ }
		}
	}

	printf("%4d ", $seq);

	if ($nsucc == 0) {
		$mean="never";
		$host=$ip="*";
	}
	else
	{
		$mean=$accum/$nsucc;
	}

	$rate=100*$nsucc/$nsamp;

     if ($graph eq "Yes")
     {
	if ($mean eq "never")
	{
	    printf("<IMG SRC=\042/bar.gif\042 WIDTH=%d HEIGHT=%d>",
		$MMAX/$MSCALE+1, 9);
		$min=$max=$mean=-1;
	    printf("|");
	    printf("<IMG SRC=\042/wbar.gif\042 WIDTH=%d HEIGHT=%d>",
		$RMAX/$RSCALE+1, 9);
	}
	else
	{
	    $mbar=int($mean/$MSCALE);
	    $rbar=int($rate/$RSCALE);
	    if ($mbar<1) { $mbar=1 }
	    if ($rbar<1) { $rbar=1 }
	    $mspace=($MMAX/$MSCALE)-$mbar;
	    $rspace=($RMAX/$RSCALE)-$rbar;
	    if ($mspace<1) { $mspace=1 }
	    if ($rspace<1) { $rspace=1 }
	    while (($mbar+$mspace)<($MMAX/$MSCALE)+1) { $mspace++ }
	    while (($rbar+$rspace)<($RMAX/$RSCALE)+1) { $rspace++ }
	    printf("<IMG SRC=\042/bar.gif\042 WIDTH=%d HEIGHT=%d>",
		$mbar, 9);
	    printf("<IMG SRC=\042/wbar.gif\042 WIDTH=%d HEIGHT=%d>",
		$mspace, 9);
	    printf("|");
	    printf("<IMG SRC=\042/wbar.gif\042 WIDTH=%d HEIGHT=%d>",
		$rspace, 9);
	    printf("<IMG SRC=\042/cbar.gif\042 WIDTH=%d HEIGHT=%d>",
		$rbar, 9);
	}
     } #Graphics print ($graph eq Yes)
#	printf("%4d ", $seq);

	if ($verb eq "Yes") {
		printf(" %-35s %-18s %s (%8.3f/%8.3f/%8.3f) %d/%d %6.1f%% %s %s %s\n",
			$host, $ip, $times,
			$min, $mean, $max,
			$nsucc, $nsamp, $rate, $error);
	} else {
		printf(" %-".$HWID."s %-18s (%8.3f/%8.3f/%8.3f) %d/%d ".
			"%6.1f%% %s %s %s\n",
			substr($host,0,$HWID), $ip,
			$min, $mean, $max,
			$nsucc, $nsamp, $rate, $error);
	}
	$error="";
    }
    flush(STDOUT);
}

if ($unfm eq "Yes") { print "\n\n\n$DATA\n"; }

flush(STDOUT);
