tracemap

annotate tracemap.pl @ 0:0d498f80f832

Repository initialization.
author Igor Chubin <igor@chub.in>
date Sun Jun 29 17:36:44 2008 +0300 (2008-06-29)
parents
children
rev   line source
igor@0 1 #!/usr/bin/perl -w
igor@0 2 #
igor@0 3 use Net::IP qw(:PROC);
igor@0 4
igor@0 5 our $traceroute_options="-q1 -n -I";
igor@0 6 our $hops_to_highlight=4;
igor@0 7 our $verbose =1;
igor@0 8 our $prefixes="prefixes.txt";
igor@0 9 our $scale=1;
igor@0 10
igor@0 11 our $dot_file="tracemap.dot";
igor@0 12 our $svg_file="tracemap.svg";
igor@0 13 our $png_file="tracemap.png";
igor@0 14
igor@0 15 #our @printed_hops;
igor@0 16 our $graph="";
igor@0 17 our $hop_id = 0;
igor@0 18 our %hop_id;
igor@0 19
igor@0 20 our $previous_hop;
igor@0 21 our $previous_time;
igor@0 22 our $hop;
igor@0 23 our $time;
igor@0 24 our $ttl;
igor@0 25
igor@0 26 our %color_table=qw(
igor@0 27 194.150.0.0/16 red
igor@0 28 10.0.0.0/16 seagreen2
igor@0 29 10.1.0.0/16 seashell2
igor@0 30 10.2.0.0/16 sienna2
igor@0 31 10.3.0.0/16 skyblue2
igor@0 32 10.4.0.0/16 slateblue2
igor@0 33 10.5.0.0/16 slategray2
igor@0 34 10.6.0.0/16 snow1
igor@0 35 10.7.0.0/16 springgreen1
igor@0 36 10.8.0.0/16 steelblue1
igor@0 37 );
igor@0 38
igor@0 39 our @prefixes;
igor@0 40
igor@0 41 sub load_prefixes
igor@0 42 {
igor@0 43 my @prefixes=();
igor@0 44 open(PREFIXES, $prefixes);
igor@0 45 while (<PREFIXES>) { chomp; push @prefixes, $_;};
igor@0 46 close(PREFIXES);
igor@0 47 return @prefixes;
igor@0 48 }
igor@0 49
igor@0 50 sub ip_in_range
igor@0 51 {
igor@0 52 my $ip=shift;
igor@0 53 my $range_found=0;
igor@0 54 for my $range (@_) {
igor@0 55 my ($range_ip, $range_prefix) = split m@/@, $range;
igor@0 56 my ($ip1, $ip2) = ip_prefix_to_range($range_ip, $range_prefix,4);
igor@0 57 # print "$range\n";
igor@0 58 $range_found=ip_bincomp(ip_iptobin($ip1,4),'lt',ip_iptobin($ip,4))
igor@0 59 && ip_bincomp(ip_iptobin($ip,4),'lt',ip_iptobin($ip2,4));
igor@0 60 if ($range_found) {
igor@0 61 return $range;
igor@0 62 }
igor@0 63 }
igor@0 64 return 0;
igor@0 65 }
igor@0 66
igor@0 67 sub color_of_ip($)
igor@0 68 {
igor@0 69 my $ip = shift;
igor@0 70 for $range (keys %color_table) {
igor@0 71 if (ip_in_range($ip,$range)) {
igor@0 72 return $color_table{"$range"};
igor@0 73 }
igor@0 74 }
igor@0 75 return "indigo";
igor@0 76 }
igor@0 77
igor@0 78 sub print_hop($)
igor@0 79 {
igor@0 80 $hop = shift;
igor@0 81 unless (defined($hop_id{$hop})) {
igor@0 82 $hop_id++;
igor@0 83 $color="";
igor@0 84 $shape="";
igor@0 85 if (ip_in_range($hop, @prefixes)) {
igor@0 86 $color=",color=green"
igor@0 87 }
igor@0 88 $color=",color=".color_of_ip($hop);
igor@0 89 if ($ttl == $hops_to_highlight+1) {
igor@0 90 $shape=",shaper=rectangle"
igor@0 91 }
igor@0 92 $graph .= "hop$hop_id [ label=\"$hop\"$color$shape];";
igor@0 93 $hop_id{$hop} = $hop_id;
igor@0 94 }
igor@0 95 }
igor@0 96
igor@0 97 sub time_to_len($$)
igor@0 98 {
igor@0 99 $a=shift;
igor@0 100 $b=shift;
igor@0 101 $l=$a-$b;
igor@0 102 $l = 0.25 if $l<0.25;
igor@0 103 return (3+1.2*log($l))*0.3285*$scale;
igor@0 104 }
igor@0 105 sub say
igor@0 106 {
igor@0 107 print @_ if $verbose;
igor@0 108 }
igor@0 109
igor@0 110 sub ping_sweep($)
igor@0 111 {
igor@0 112 my $net = shift;
igor@0 113 my @res;
igor@0 114 say("Doing ping sweep of the $net IP-addresses block");
igor@0 115 open(NMAP, "nmap -sP $net|grep 'appears to be up' | awk '{print \$2}'|")
igor@0 116 or die "can't make ping sweep of $net. Have you nmap installed?\n$!";
igor@0 117 while (<NMAP>) {
igor@0 118 chomp;
igor@0 119 push (@res, ($_));
igor@0 120 say(".");
igor@0 121 }
igor@0 122 say("Done. $#res host(s) found.\n");
igor@0 123 return @res;
igor@0 124 }
igor@0 125
igor@0 126 sub dns_axfr($)
igor@0 127 {
igor@0 128 my @res;
igor@0 129 my ($zone,$ns) = split /@/;
igor@0 130 if ($ns eq '') {
igor@0 131 }
igor@0 132 else
igor@0 133 {
igor@0 134 say("Doing axfr of the zone $zone from the server $ns\n");
igor@0 135 open(DIG, "dig \@$ns axfr $zone | awk '/\tA\t/ {print \$1}' |")
igor@0 136 or die "can't make axfr of the zone $zone from the server $ns. Have you dig installed?\n$!";
igor@0 137 while (<DIG>) {
igor@0 138 chomp;
igor@0 139 push (@res, ($_));
igor@0 140 }
igor@0 141 say("Done. $#res host(s) found.\n");
igor@0 142 return @res;
igor@0 143 }
igor@0 144 }
igor@0 145
igor@0 146 my @dests=();
igor@0 147 while(<>)
igor@0 148 {
igor@0 149 chomp;
igor@0 150 next if /^#/;
igor@0 151 if (m@http:@) {
igor@0 152 }
igor@0 153 elsif (m@/@) {
igor@0 154 push(@dests,ping_sweep($_))
igor@0 155 }
igor@0 156 elsif (m'@') {
igor@0 157 push (@dests,dns_axfr($_))
igor@0 158 }
igor@0 159 else {
igor@0 160 push(@dests,($_));
igor@0 161 }
igor@0 162 }
igor@0 163
igor@0 164 @prefixes=load_prefixes();
igor@0 165
igor@0 166 for $dest (@dests)
igor@0 167 {
igor@0 168 say("Tracing path to $dest");
igor@0 169 open (TRACE,"traceroute $traceroute_options $dest|")
igor@0 170 or die "Can't run traceroute:$!";
igor@0 171 my $hop='';
igor@0 172 $ttl=0;
igor@0 173 my $total=0;
igor@0 174 while (<TRACE>) {
igor@0 175 chomp;
igor@0 176 next if not /ms/;
igor@0 177 say(".");
igor@0 178 $ttl++;
igor@0 179 s@^\s*@@;
igor@0 180 $previous_hop=$hop;
igor@0 181 $previous_time=$time;
igor@0 182 my $a;
igor@0 183 ($a, $hop, $time) = split(/\s+/, $_, 3);
igor@0 184 $time =~ s/\s*ms\s*$//;
igor@0 185 $total += $time;
igor@0 186 if ($previous_hop eq '') {
igor@0 187 print_hop($hop);
igor@0 188 $graph =~ s@color=[^],]*[],]@@;
igor@0 189 $graph =~ s@(\ label=\")[^"]*(\".*?)$@fontsize=10,color=red,style=filled,label="(YOU)$2@;
igor@0 190 }
igor@0 191 elsif (not defined $hop_id{$hop} ) {
igor@0 192 print_hop($previous_hop);
igor@0 193 print_hop($hop);
igor@0 194 $graph .= "hop".$hop_id{$previous_hop}." -- hop".$hop_id{$hop}.
igor@0 195 " [label=\"".sprintf("%1.2f",+$time-$previous_time)."\",len=".time_to_len($time,$previous_time)."];\n";
igor@0 196 }
igor@0 197 }
igor@0 198 $graph =~ s@(\ label=\")[^"]*(\".*?)$@fontsize=8,style=filled,label=\"$dest$2@;
igor@0 199 close(TRACE);
igor@0 200 say("Done [last $time, total $total]\n");
igor@0 201 }
igor@0 202 #$temp=rand.rand;
igor@0 203
igor@0 204 open (DOT, ">$dot_file")
igor@0 205 or die "can;t open dot file file for writing: $!";
igor@0 206 print DOT <<EOF;
igor@0 207 graph G {
igor@0 208 margin =1 ;
igor@0 209 node [fontname=times,fontsize=7,shape=circle,width=0.1,height=0.1,fixedsize=true,color=blue];
igor@0 210 edge [fontname=times,fontsize=5,color=black];
igor@0 211 $graph
igor@0 212 }
igor@0 213 EOF
igor@0 214 close(DOT);
igor@0 215
igor@0 216 print `neato -o $png_file -Tpng $dot_file > /dev/null 2>&1; neato -o $svg_file -Tsvg $dot_file > /dev/null 2>&1 `
igor@0 217 or die "can't run neato: $!;\ngraphviz is installed?\nYou can tracemap.dot to the hosts where graphviz in installed and run\nneato -o tracemap.png -Tpng tracemap.dot"
igor@0 218