#!/usr/bin/perl
$|=1 ;
# trmap.pl
# Andrew Daviel <advax@triumf.ca> Jan 1997
# do traceroute to nodes listed in arg[0] and generate NDT output
# Usage: trmap.pl nodes.dat > nodes.ndt
# nodes.dat is a list of ip addresses, one per line

$debug = $ARGV[1] ; 
$tracelog = 1 ; # true to log trace
# traceroute parameters
$npkt = 10 ; # no. of packets
$wait = 3 ; # seconds to wait
$maxhop = 24 ; # max no. hops
$src = `hostname` ; chop($src) ;
($name,$aliases,$addrtype,$length,@addrs) =gethostbyname($src) ;
@f = unpack('C4',$addrs[0]);
$myhost = join('.',@f) ;
if (!$myhost) { $myhost = "127.0.0.1" ; }
foreach $sig (TERM,INT,QUIT,ILL,TRAP,IOT,SEGV,HUP,ALRM) {
  $SIG{$sig} = "clean" ;
}


open (IN,$ARGV[0])|| die "Can't open input file \"$ARGV[0]\"\n";
$debug = $ARGV[1] ;
while (<IN>) {
  chop ; $now = time ;
  if (/^#/) { next ; } # comment
  s/ .*// ;
  if ($debug) { print STDERR "trace to $_\n"; }
  $hostname = $_ ;
  unless (dbmopen(%NODE,"nodenames",0644)) { print STDERR "Couldn't open nodenames database\n"; }
  ($name,$aliases,$addrtype,$length,@addrs) =gethostbyname($_) ;
  if (!$length) {
    $host = $NODE{$_} ; 
    if (!$host) { print STDERR "Couldn't resolve address for $_\n"; }
  } else {
    @f = unpack('C4',$addrs[0]);
    $host = join('.',@f) ;
    $NODE{$_} = $host ;
  }
  dbmclose(%NODE) ;
  if ($tracelog) {
    open (TR,">>trace/$host") || print STDERR "Can't append trace/$host" ;
    $date = `date` ; chop($date) ;
    print TR "# Trace to $hostname ($host) at $date\n"; 
  }
  $_ = `/usr/etc/traceroute -w $wait -n -q $npkt -m $maxhop $host 2>/dev/null` ;
  unless (/$host/) { $_ .= "99 $host\n" ; }
  if ($debug>1) { print STDERR "$_\n"; }
  $src = $myhost ;
  @line = split(/\n/) ;
  foreach $_ (@line) {
    if (/^traceroute to/) { last ; }
    s/\([^\\)]*\)//g ; # remove e.g. "(ttl=29!)"
    tr/*//d ; s/ ms//g ; tr/ / /s ; s/^ //; 
    #if ($debug) { print "$_\n"; }
    ($hop,$dest,@ms) = split(/ /) ;
    if (!$dest) { last ; }
    $link = $src."-".$dest ;
    ($nsent,$nack,$sum,$sumsq) = split(/;/,$data{$link}) ;
    $nsent = $nsent + $npkt ;
    for ($i=0;$i<@ms;$i++) {
      $nack++ ;
      $sum = $sum + $ms[$i] ;
      $sumsq = $sumsq + $ms[$i]*$ms[$i] ;
    }
    $nk = @ms ;
      if ($tracelog) { print TR "$hop $dest $nk\n" ; }
    $src = $dest ;
    $data{$link} = join(';',$nsent,$nack,$sum,$sumsq) ;
  }
    if ($tracelog) { close(TR) ; }
}
&clean ;

sub clean {
 while (($link,$_) = each (%data)) {
  ($src,$dest) = split(/-/,$link) ;
  ($nsent,$nack,$sum,$sumsq) = split(/;/) ;
  if ($nack<2) {
    $var = 0 ;
  } else {
    $var = sqrt(($nack * $sumsq - $sum*$sum)/($nack*($nack-1))) ;
  }
  if ($nack>0) {
    $dly = sprintf("%.4f",$sum/$nack) ; 
  } else {
    $dly = 0 ;
  }
  $acked= $nack/$nsent ;
  $var = sprintf("%.4f",$var) ; $acked= sprintf("%.4f",$acked) ;
  print "(\"srcip=$src\",\"dstip=$dest\",\"acked=$acked\"," ;
  print "\"variation=$var\",\"samples=$nsent\",\"timestamp=$now\",\"delay=$dly\")\n";
 }
}
