in reply to How to generate network topology with perl ?

GraphViz is probably the way to go. I used it and Net::Traceroute to generate a picture of the intermediate routers between our colo equipment and field locations at $previous_jobs[-1].

Update: AH HAH. Knew it was around here somewhere. Code follows.

#!/usr/bin/perl use strict; ## Wait 10 seconds for traceroutes to finish use constant TIMEOUT => 5; use Net::DNS (); use Net::Traceroute (); use GraphViz (); use Memoize qw( memoize ); use DB_File (); use Fcntl; die "usage: $0 hostfile\n" unless @ARGV; my $file = shift; my %dns_cache; tie %dns_cache, DB_File => ".trmap_dns_cache", O_RDWR|O_CREAT, 0666 or die "Can't tie dns cache hash: $!\n"; memoize( 'lookup_host', SCALAR_CACHE => [ HASH => \%dns_cache ] ); END { untie %dns_cache } my @hosts; open( HOST, $file ) or die "Can't open `$file': $!\n"; while( <HOST> ) { chomp; push @hosts, $_; } close( HOST ); my %host_addrs; $host_addrs{ lookup_host( $_ ) } = $_ foreach @hosts; my %hops; my %edges; my $tr = Net::Traceroute->new( timeout => TIMEOUT ); foreach my $host ( @hosts ) { my $t = $tr->clone( host => $host ); unless( $t->found ) { warn "Problem tracerouting to $host\n"; next; } print STDERR "## $host: ", $t->hops(), " hops\n"; my @rtrs; push @rtrs, $t->hop_query_host( $_, 0 ) for 1 .. $t->hops; $hops{ $_ }++ for @rtrs; my $cur = shift @rtrs; while( @rtrs ) { $edges{ $cur . "=>" . $rtrs[0] }++; $cur = shift @rtrs } } print STDERR "##\n## done traceroute'ing, frobnicating graph\n##\n"; my $g = GraphViz->new( directed => 0, width => 16, height => 10, pagewidth => 8.5, pageheight => 11 ); for( keys %hops ) { my $host = lookup_host( $_ ); my @extra; if( $host =~ /main-router\.example\.com/ ) { push @extra, style => filled => color => ".5 .5 .5"; } if( $host =~ /^et-/ ) { push @extra, style => filled => color => ".75 .75 .75"; } $g->add_node( $_, fontsize=> 10, label => $host, @extra ) } for my $hop ( map { [ split( /=>/ ), $edges{$_} ] } keys %edges ) { $g->add_edge( @{$hop}[0,1], label => $hop->[2] ) } print $g->as_canon; exit 0; { ## $r holds our Net::DNS::Resolver instance between calls my $r; sub lookup_host { my $host = shift; $r ||= Net::DNS::Resolver->new(); return $host_addrs{ $host } if exists $host_addrs{ $host }; my $q = $r->search( $host ); unless( defined( $q ) ) { warn "Couldn't resolve `$host'\n"; return $host } my $ans = ($q->answer())[0]; return $ans->type eq "PTR" ? $ans->ptrdname : $ans->address; } } __END__

Replies are listed 'Best First'.
Re: Re: How to generate network topology with perl ?
by halley (Prior) on Apr 29, 2004 at 16:32 UTC
    I'll definitely be checking this out. A couple style nits:

    Strategy in comments. Tactics in code.
    Don't mention any actual numbers, operators or data types in a comment, and you're less likely to get out of sync.

    use constant TIMEOUT => 5; # seconds, for traceroutes

    Think higher.
    If you think about the problem in strategy terms, you won't micromanage your tactics.

    open(HOST, $file ) or die "Can't open `$file': $!\n"; my @hosts = <HOST>; close(HOST); chomp @hosts;

    --
    [ e d @ h a l l e y . c c ]

      The while loop was that way for a reason because at one time it was going to possibly deal with comments (I just never stuck the next if /^\s*#/; et al in there); other things changed (moved into Postgres) and the list-o-hosts wound up not being commented.

      Guilty as charged on the first count, though. %)

Re: Re: How to generate network topology with perl ?
by iwanthome (Beadle) on Apr 30, 2004 at 09:21 UTC

    Fletch,

    thanks for your reply.Could you give me some guide about how to install the grahpviz c module (not cpan module) ? I have spend two days to install and always fail.

    thanks!

      Not particularly. I've always used either the RedHat RPM or the tarball the dot people provide (way back when when dinosaurs roamed the earth and 9600 baud was blazing fast) and never had any problems. Your best bet is to seek the assistance of your friendly neightborhood sysadmin (or more likely your curmudgeonly neighborhood sysadmin).