tracemap

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