#!/usr/local/bin/perl
# traceroute2dav.pl, v1.0, (c) 1997 Nick Waterman of Nilex.
#
# Takes the output of one, or preferably MANY "traceroute" commands, and
# converts them into a term representation for daVinci, so you can
# quickly and easily produce pretty maps of your connection to the
# internet - simply do something like this:
#
#   traceroute my.favourite.host >ROUTES
#   traceroute and.another.good.host >>ROUTES
#   traceroute and a few more >>ROUTES
#   ...
#   traceroute2dav.pl ROUTES > ROUTES.daVinci
#   daVinci ROUTES.daVinci
#
# You may distribute this program as freely as you wish.  You may modify
# it, but this copyright notice must remain intact, details of your
# modification must be made in tyhe space below, and a copy of your
# modified version must be sent to me once you've finished it.
# (nick@nilex.u-net.com).
# 
######################################################################
# MODIFICATION HISTORY:
# 1997-10-29  Written by Nick Waterman of Nilex
# 1997-10-29  Released v1.0
######################################################################

$last   = "localhost";
$name{"localhost"} = "localhost";

# loop through all files given as args, or stdin.
while (<>) {
    # extract hop count
    s/^ *([0-9]*) *//;
    # if hop count is "1", reset.
    if ($1 == 1) {
        # create a dummy link to "" to make sure a node IS actually created.
        $links{$last}{""} = "";
        $last   = "localhost";
    }
    
    # remove timings, dead sites, and extra spacing
    s/[0-9]* ms//g;
    s/\*/ /g;
    s/ +/ /g;
    s/ *$//;
    s/^ +//g;
    
    # find a hostname and IP address, or invent a pretend one for "*"
    if (/^([^ ]*) \(([0-9.]*)\)/) {
        $host = "$2";
        $name{$2} = $1;
    } else {
        # don't make huge chains of "*" - collapse them all into 1.
        $null++ unless ($last =~ /NULL[0-9]*/);
        # invent a hostname
        $host = "NULL$null";
        $name{$host} = "*";
    }
    
    # store the links and the names
    $links{$last}{$host} = 1;
    $last = $host;
}
# create final dummy link
$links{$host}{""} = "";

# spew out a daVinci node representation whatsit.
printf "[\n";
# create each node in turn...
foreach $site (keys %links) {
    print "  l(\"$site\", n(\"\", [a(\"OBJECT\",\"$name{$site}\")], [\n";
    # and a list of edges to references to it's children.
    foreach $child (keys %{$links{$site}}) {
        if ($child) { print "    e(\"\", [], r(\"$child\")),\n"; }
    }
    print "  ])),\n";
}
print "]\n";

# the end!
