#!/usr/local/bin/perl # # Pablo Molinero-Fernández 10/XI/00 # # script for finding different routes in a series of traceroute samples # # Copyright 2000 The Board of Trustees of the Leland Stanford Junior # University; All Rights Reserved # # Use the companion perl script # download_traces_from_traceroute_repository.pl # to get traceroute samples from NLANR # To convert a fig file into ps: # fig2dev -L ps -m 0.40 -x -200 -y -1500 -M -e -z Letter kk.fig kk.ps;psnup -2 kk.ps >kk2.ps; gv -media Letter kk2.ps #foreach file (`ls -d *.fig`) # file3=`echo $file|sed 's/\.fig//g'` # fig2dev -L ps -m 0.40 -x -200 -y -1500 -M -e -z Letter $file3.fig $file3.time.ps # psnup -2 $file3.time.ps >$file3.time.2.ps; # #gv -media Letter $file3.time.ps #end #to use this script recursively over several traceroute samples #foreach dir1 (`ls -d rout*/`) # (cd $dir1; foreach dir2 (`ls -d *`) # (cd $dir2; dir3=`echo $dir2|sed 's/\///g'`;~/TCPSwitch/detect_route_changes_in_traceroute.pl >../$dir3.fig) # end) #end use strict; use File::Basename; ###################################################################### # Definition of parameters my $basex = 0; #base for all plots of the traceroute route tree my $basey = 0; my $stepx = 500; my $stepy = 900; my $radius= 200; my $offsetTextx = 7000; my $offsetTexty = 500; my @listOfFamilies = ( "alaska", "fsu", "hawaii", "mit", "ncsa", "slac", "stanford", "ucboulder", "ucla", "ucsd", "wustl", "fnal", "montana", "mt_woodson", "ncar", "ncren", "ncsa-dca", "psc", "sdsc", "startap", "thor", "uwashington" ); #@listOfFamilies = ("ucboulder"); #@listOfFamilies = ("hawaii"); #@listOfFamilies = ("alaska"); # "adv", "austr", "austr2", "bnl", "bsdi", "connix", # "inria", "lbl", "mid", "mit", "ncar", "near", "nrao", # "oce", "ort", "panix", "pubnix", "rain", "sdsc", # "sintef1", "sintef2", "ucl", "ucla", "umann", "umont", # "ustutt", "wustl" # "wustl-slac" # "wayne-hawaii" # "alaska-slac" # "kk2" ###################################################################### #global vars my (@arrayOfDates, @arrayOfRoutes, %hashOfRoutes, %hashOfRoutesList, %arrayOfDefectsByDate); my (@listOfRouters, @stringOfRouters); my ($maxRoutes, $sumRoutes, $errorInTrace); my (%edge, %x, %y, %error, %name, %domain); #data about each router [node] and link [edge] in the graph my (%miniEdge, @miniRouter); #same but for the timed graphs my ($source, $destination); #source and destination nodes my $family="hola"; #destination my $dir; #source my $maxy; my ($widthWeigth); my ($xfigSummaryTreeWithDomains, $xfigSummaryTree, $xfigTimedTree, $printTableWithAllAnomalies, $nodebug); ###################################################################### #start my $cwd; chomp($cwd = `pwd`); $dir = basename($cwd); &getParams(); #go over all families &goOverAllFamilies(); ###################################################################### sub usage() { print STDERR "Usage:\n"; print STDERR "\t$0 [-nodebug|-nd] [-printTableWithAllAnomalies|-pa]\n"; print STDERR "\t$0 [-nodebug|-nd] ([-xfigSummaryTree|-xs] | [-xfigTimedTree|-xt] | [-xfigSummaryTreeWithDomains|-xd])\n"; print STDERR "\n"; print STDERR "Run this program in the directory where your traceroute samples are located\n"; print STDERR "It will process the files named .*, where family is one of the following:\n"; foreach $family (@listOfFamilies) { print STDERR "$family\t"; } print STDERR "\n"; print STDERR "\n"; print STDERR '$Id$'."\n"; print STDERR "Pablo Molinero-Fernández\n"; print STDERR "/*\n"; print STDERR "* Copyright 1997 The Board of Trustees of the Leland Stanford Junior\n"; print STDERR "* University; All Rights Reserved\n"; print STDERR "*/\n"; print STDERR "\n"; print STDERR "Note: the debug information appears in STDERR\n"; print STDERR "\n"; } ###################################################################### sub printDebug { if (!$nodebug) { print STDERR "@_"; } } ###################################################################### sub getParams() { if ($#ARGV == -1) { &usage(); die; } if (($ARGV[0] eq "-nd") || ($ARGV[0] eq "-nodebug")) { $nodebug = 1; shift @ARGV; } else { $nodebug = 0; } if (("$ARGV[0]" eq "-pa") || ($ARGV[0] eq "-printTableWithAllAnomalies")) { $printTableWithAllAnomalies = 1; shift @ARGV; } else { $printTableWithAllAnomalies = 0; if (($ARGV[0] eq "-xd") || ($ARGV[0] eq "-xfigSummaryTreeWithDomains")) { $xfigSummaryTreeWithDomains = 1; shift @ARGV; } else { $xfigSummaryTreeWithDomains = 0; } if (($ARGV[0] eq "-xs") || ($ARGV[0] eq "-xfigSummaryTree")) { $xfigSummaryTree = 1; shift @ARGV; } else { $xfigSummaryTree = 0; } if (($ARGV[0] eq "-xt") || ($ARGV[0] eq "-xfigTimedTree")) { $xfigTimedTree = 1; shift @ARGV; } else { $xfigTimedTree = 0; } } if ($#ARGV != -1) { &usage(); die; } } ###################################################################### #go over all families sub goOverAllFamilies() { if (($xfigSummaryTreeWithDomains) || ($xfigSummaryTree) || ($xfigTimedTree)) { &printXFigHeader(); } my $myfamily; foreach $myfamily (@listOfFamilies) { $family = $myfamily; my @listOfFiles = `ls $family.100*`; my @listOfFiles = `ls $family.*`; undef @arrayOfDates; undef @arrayOfRoutes; undef %hashOfRoutes; undef %hashOfRoutesList; undef %arrayOfDefectsByDate; $maxRoutes = 0; $sumRoutes = 0; $errorInTrace = 0; my $file; my $routerNum; my $router; my $date; #go over all files foreach $file (@listOfFiles) { chop($file); open(IN, "<$file"); &ClearListOfRouters(); my $lineNum=0; my $line; while ($line=) { $lineNum++; if($lineNum > 10000) {last;} if ($line =~ /!/) { printDebug "TRACEROUTE ERROR REPORT => $line ($date)\n\n"; } if ($line =~ /traceroute/) { next; } elsif (($line =~ /\d.*\w{3}\s+(\w{3}\s+\d+\s+\d+:\d+:\d+)/) || ($line =~ /^\d+\s+(\d+\.\d+\.\d+\.\d+).*[s\s]\d+\s+(\d+\.\d+\.\d+\.\d+)/) || ($line =~ /\s\d+\s+(\d+\.\d+\.\d+\.\d+).*[s\s]\d+\s+(\d+\.\d+\.\d+\.\d+)/)) { #there is an error in the traces if (!$errorInTrace) { &ThereWasAnError($date, $line, $routerNum-1, -1); } } elsif ($line =~ /^\w{3}\s+(\w{3}\s+\d+\s+\d+:\d+:\d+)/) { #this is a new trace $routerNum = 1; if (!$errorInTrace && ($stringOfRouters[0] ne "")) { &SetArrayOfRoutes("$date"); } &ClearListOfRouters(); $date = $1; # chop($date = $1); if ($errorInTrace) {printDebug "clearing up the error ($date)\n\n"; } $errorInTrace = 0; next; } elsif ($errorInTrace) { } elsif ($line =~ /^\s*(\d+)\s+(\*\s+\*\s+\*)/) { #this is TTL that did not get any report back $routerNum++; $router="X$1X.X$1X.X$1X.X$1X"; &InsertRouter($router, -1); } elsif ($line =~ /^(\d+).*\s(\d+\.\d+\.\d+\.\d+).*\s(\d+\.\d+\.\d+\.\d+).*\s(\d+\.\d+\.\d+\.\d+)/) { #there have been three route changes in a single sample!! if ($1 != $routerNum++) {ThereWasAnError($date, $line, $routerNum-1, $1);} &InsertRouter($2, 0); &InsertRouter($3, 1); &InsertRouter($4, 2); printDebug "3 routers in a line => $line ($date)\n\n"; } elsif ($line =~ /^\s*(\d+).*\s(\d+\.\d+\.\d+\.\d+).*\s(\d+\.\d+\.\d+\.\d+)/) { #there have been two route changes in a single sample!! if ($1 != $routerNum++) {ThereWasAnError($date, $line, $routerNum-1, $1);} &InsertRouter($2, 0); &InsertRouter($3, 1); &InsertRouter($2, 2); printDebug "2 routers in a line => $line ($date)\n\n"; } elsif ($line =~ /^\s*(\d+).*\s(\d+\.\d+\.\d+\.\d+)/) { if ($1 != $routerNum++) {ThereWasAnError($date, $line, $routerNum-1, $1);} &InsertRouter($2, -1); if ($line =~ /(![A-Z]).*![A-Z].*![A-Z]/) { &InsertRouter("$1.ERROR.ERROR.$1", -1); } } } # &SetArrayOfRoutes("UNDEF"); } &calculateEdges($date); if ($xfigSummaryTreeWithDomains) { &xfigSummaryTreeWithDomains(); } if ($xfigSummaryTree) { &xfigSummaryTree(); } if ($xfigTimedTree) { &xfigTimedTree(); } if ($printTableWithAllAnomalies){ &calculateAllAnomalies(); &printTableWithAllAnomalies(); } } } ###################################################################### sub printXFigHeader() { print "#FIG 3.1\n". # "Landscape\n". "Portrait\n". "Center\n". "Inches\n". "1200 2\n"; } ###################################################################### sub ThereWasAnError() { my ($date, $line, $expectedRouterNum, $actualRouterNum) = @_; chop ($line); printDebug "ERROR: in the traces => $line ($date)\n"; if ($expectedRouterNum != $actualRouterNum){ printDebug "I was expecting router: $expectedRouterNum, but I saw $actualRouterNum \n"; } printDebug "I am ignoring it, but you should correct it manually!!\n\n"; $errorInTrace = 1; ${$arrayOfDefectsByDate{$date}}{"BadTrace"}++; my ($month,$day,$hour) = split(/ +/, $date); ${$arrayOfDefectsByDate{$date}}{"StartMonth"} = $month; ${$arrayOfDefectsByDate{$date}}{"StartDay"} = $day; ${$arrayOfDefectsByDate{$date}}{"StartHour"} = $hour; ${$arrayOfDefectsByDate{$date}}{"EndMonth"} = $month; ${$arrayOfDefectsByDate{$date}}{"EndDay"} = $day; ${$arrayOfDefectsByDate{$date}}{"EndHour"} = $hour; } ###################################################################### sub SetArrayOfRoutes() { my ($date) =@_; my ($i, $myStringOfRouters, $myStringOfRouters0); for ($i=0; $i < 3; $i++) { $myStringOfRouters = $stringOfRouters[$i]; $myStringOfRouters0 = $stringOfRouters[0]; if (($i == 0) || ($myStringOfRouters ne $myStringOfRouters0)) { $arrayOfDates[$sumRoutes] = "$date"; $arrayOfRoutes[$sumRoutes] = $myStringOfRouters; $hashOfRoutes{$myStringOfRouters}++; $sumRoutes++; $hashOfRoutesList{$myStringOfRouters}= \@{$listOfRouters[$i]}; if ($maxRoutes < $hashOfRoutes{$myStringOfRouters}) { $maxRoutes = $hashOfRoutes{$myStringOfRouters}; } # printDebug "router: $myStringOfRouters=> $hashOfRoutes{$myStringOfRouters}\n"; } } } ###################################################################### sub GetRouterName() { my ($router) = @_; my ($nslookup,$name,$domain,$line); chop($nslookup=`nslookup $router 2>/dev/null`); $name="UNDEFINED"; $domain="UNDEFINED"; foreach $line (split(/\n/, $nslookup)) { if ($line =~ /Name.\s+([\w\.-]+)/) {$name = $1;last;} } if ($name =~ /\.([-\w]+)\.(\w+)$/) {$domain = lc("$1");} if ($router eq "137.229.71.34") {$name = "alaska.edu";$domain = "alaska";} if ($router =~ /(![A-Z])\.ERROR\.ERROR\.(![A-Z])/) {$name = "ERROR.$1";$domain = "ERROR-$1";} # printDebug "$router \"$name\" \"$domain\"\n"; return ($domain, $name); } ###################################################################### sub ClearListOfRouters() { my $i; for ($i=0; $i <= 3; $i++) { @{$listOfRouters[$i]}= (); $stringOfRouters[$i]=""; } } ###################################################################### sub InsertRouter() { my ($router, $listNum) = @_; my $i; # printDebug "router: $router\n"; if ($listNum >= 0 ) { push(@{$listOfRouters[$listNum]}, "$router"); if ($stringOfRouters[$listNum] ne "") { $stringOfRouters[$listNum] .= "-"; } $stringOfRouters[$listNum] .= "$router"; } else { for ($i=0; $i <= $#listOfRouters; $i++) { push(@{$listOfRouters[$i]}, "$router"); if ($stringOfRouters[$i] ne "") { $stringOfRouters[$i] .= "-"; } $stringOfRouters[$i] .= "$router"; } } } ###################################################################### sub calculateEdges() { my ($date) = @_; my ($router, $end, $i); my ($key); undef %edge; undef %x; undef %y; undef %error; undef %name; undef %domain; # %edge = %x = %y = (); my $y=0; my ($x, $first, $previous); if ($maxRoutes > 20) {$widthWeigth = 20/$maxRoutes;} else {$widthWeigth=1;} $maxy=0; $destination = ""; my (@routes); #now print the results of all the files if (%hashOfRoutes !=()) { my $mostCommmonRoute =1; foreach $key (sort { $hashOfRoutes{$b} <=> $hashOfRoutes{$a} } keys %hashOfRoutes) { # printDebug "router: $key=> $hashOfRoutes{$key}\n"; @routes = split(/-/, $key); if ($mostCommmonRoute) { $mostCommmonRoute=0; $source = $routes[0]; $destination = $routes[$#routes]; } $first =1; $maxy = ++$y; $x=0; foreach $router (@routes) { $x++; # printDebug "router: $router ($x, $y)\n"; if ($first) { $first=0; $previous = "$router"; if (! defined $x{"$router"}) { ($domain{"$router"}, $name{"$router"})= &GetRouterName($router); $x{"$router"}=$x; $y{"$router"}=$y; printDebug "$router ($x, $y, $name{$router}, $domain{$router})\n"; } next; } ${$edge{"$router"}}{"$previous"}+=$hashOfRoutes{"$key"}; if (! defined $x{"$router"}) { ($domain{"$router"}, $name{"$router"})= &GetRouterName($router); $x{"$router"}=$x; $y{"$router"}=$y; printDebug "$router ($x, $y, $name{$router}, $domain{$router})\n"; } $previous = "$router"; } if ("$router" ne "$destination") { $error{"$router"}++; printDebug "$router error: ".$error{"$router"}."\n"; ${$arrayOfDefectsByDate{$date}}{"NotEndingInDestination"}++; } # printDebug "$router $destination\n"; } $maxy = $y; } } ###################################################################### sub xfigSummaryTree() { my ($centerx, $centery, $borderx, $bordery, $width); my ($startx, $starty, $endx, $endy); my ($labelx, $labely, $label, $textx, $texty); my ($router, $end); my ($sumEdges); if (%hashOfRoutes !=()) { foreach $router (sort { $y{$b} <=> $y{$a} } keys %y) { $centerx=$basex+$x{"$router"}*$stepx; $centery=$basey+$y{"$router"}*$stepy; $borderx=$centerx-$radius; $bordery=$centery-$radius; $width=1+$error{"$router"}*5; print "1 3 0 $width -1 7 0 0 -1 0.000 1 0.0000 $centerx $centery ". "$radius $radius $borderx $bordery $borderx $bordery\n"; $labelx=$centerx-$radius; $labely=$centery-$radius; if ($router =~ /(\w+)\.(\w+)\.(\w+)\.(\w+)/) { $label="$4"; } print "4 0 0 2 0 0 12 0.0000 4 135 360 $labelx $labely $label \\001\n\n"; $sumEdges=0; foreach $end ( keys %{$edge{"$router"}}) { $startx=$centerx; $starty=$centery; $endx=$basex+$x{"$end"}*$stepx; $endy=$basey+$y{"$end"}*$stepy; $width=int(${$edge{"$router"}}{"$end"}*$widthWeigth); $width=($width?$width:1); $sumEdges+=${$edge{"$router"}}{"$end"}; if (($startx == $endx) && ($starty == $endy)) { #this is looping into itself $endx=$startx-$radius; $endy=$starty+$radius*1.5; } print "2 1 0 $width -1 7 0 0 -1 0.000 0 0 -1 0 0 2\n". " $startx $starty $endx $endy\n"; # printDebug "$router $end 2 1 0 $width -1 7 0 0 -1 0.000 0 0 -1 0 0 2\n". # " $startx $starty $endx (=$basex+".$x{"$end"}."*$stepx) $endy \n"; } $labelx=$centerx+$radius*0; $labely=$centery+$radius+200; $label=(int($sumEdges/$sumRoutes*100))."%"; if ($label eq "0%") { $label=(int($sumEdges/$sumRoutes*1000))."%%"; } if ($label eq "0%%") { $label=".".(int($sumEdges/$sumRoutes*10000))."%%"; } print "4 0 1 2 0 0 12 0.0000 4 135 360 $labelx $labely $label \\001\n\n"; } $textx = $offsetTextx+$basex; $texty = $offsetTexty+$basey; print "4 0 -1 0 0 0 32 0.0000 4 135 360 $textx $texty TOTAL: $dir => $family; $sumRoutes routes\\001\n\n"; printDebug "#END OF RESULTS: ($dir => $family) \n"; # print "\n\n************************************************\n\n"; #exit; $basey += ($maxy+1)*$stepy; } } ###################################################################### sub xfigSummaryTreeWithDomains() { my ($centerx, $centery, $borderx, $bordery, $width); my ($startx, $starty, $endx, $endy); my ($labelx, $labely, $label, $textx, $texty); my ($router, $domain, %domainColors); my $color = 0; my $i = 0; if (%hashOfRoutes !=()) { foreach $domain (sort values %domain) { if ($domainColors{"$domain"} eq "") { $domainColors{"$domain"} = $color++; } } foreach $router (sort { $y{$b} <=> $y{$a} } keys %y) { $centerx=$basex+$x{"$router"}*$stepx; $centery=$basey+$y{"$router"}*$stepy; $borderx=$centerx-$radius; $bordery=$centery-$radius; $width=3+$error{"$router"}*5; $color=$domainColors{$domain{$router}}; print "1 3 0 $width $color 7 0 0 -1 0.000 1 0.0000 $centerx $centery ". "$radius $radius $borderx $bordery $borderx $bordery\n"; $labelx=$centerx-int($radius/2); $labely=$centery+int($radius/2); $label=++$i; print "4 0 0 2 0 0 12 0.0000 4 135 360 $labelx $labely $label \\001\n\n"; $labelx=$centerx-$radius; $labely=$centery-$radius; if ($router =~ /(\w+)\.(\w+)\.(\w+)\.(\w+)/) { $label="$4"; } print "4 0 0 2 0 0 12 0.0000 4 135 360 $labelx $labely $label \\001\n\n"; $textx = $offsetTextx*2+$basex+int($radius/4); $texty = $offsetTexty+$basey+$i*int($stepy/2); print "4 0 -1 0 0 0 12 0.0000 4 135 360 $textx $texty $i=>$name{$router} ($router)\\001\n\n"; $startx=$offsetTextx*2+$basex; $starty=$offsetTexty+$basey+$i*int($stepy/2)-int($stepy/10); $endx=$offsetTextx*2+$basex; $endy=$offsetTexty+$basey+$i*int($stepy/2)+int($stepy/10); $width=3+$error{"$router"}*5; print "2 1 0 $width $color 7 0 0 -1 0.000 0 0 -1 0 0 2\n". " $startx $starty $endx $endy\n"; } $textx = $offsetTextx+$basex; $texty = $offsetTexty+$basey; print "4 0 -1 0 0 0 32 0.0000 4 135 360 $textx $texty TOTAL: $dir => $family; $sumRoutes routes\\001\n\n"; printDebug "#END OF RESULTS: ($dir => $family) \n"; # print "\n\n************************************************\n\n"; #exit; my $myMaxY = $i/2; if ($myMaxY < $maxy) {$myMaxY = $maxy;} $basey += ($myMaxY+1)*$stepy; } } ###################################################################### sub calculateMiniEdges() { my ($path, $numPaths) = @_; # printDebug "$path=> $numPaths\n"; undef %miniEdge; undef @miniRouter; &recalculateMiniEdges($path, $numPaths); } ###################################################################### sub recalculateMiniEdges() { my ($path, $numPaths) = @_; my ($router); my ($first, $previous); # printDebug "$path=> $numPaths\n"; #now print the results of all the files if (%hashOfRoutes !=()) { $first =1; foreach $router (split(/-/, $path)) { # printDebug "router: $router ($x, $y)\n"; push (@miniRouter, "$router"); if ($first) { $first=0; $previous = "$router"; next; } ${$miniEdge{"$router"}}{"$previous"}+=$numPaths; # printDebug "$router ($x, $y)\n"; $previous = "$router"; } } } ###################################################################### sub xfigTimedTree() { my ($centerx, $centery, $borderx, $bordery, $width); my ($startx, $starty, $endx, $endy); my ($labelx, $labely, $label, $textx, $texty); my ($router, $end, $i); my ($sumEdges, $firstDate); if (%hashOfRoutes !=()) { my $numPaths=1; for ($i=0; $i<=$#arrayOfRoutes; $i++) { #printDebug "path=> $arrayOfRoutes[$i] \n****** $arrayOfRoutes[$i+1]\n"; if ($numPaths==1) { $firstDate=$arrayOfDates[$i]; } if (((($i+1)<=$#arrayOfRoutes) && ("$arrayOfRoutes[$i]" eq "$arrayOfRoutes[$i+1]")) && ((($i+2)<=$#arrayOfRoutes) && ("$arrayOfDates[$i+1]" ne "$arrayOfDates[$i+2]"))) { $numPaths++; next; } if ((($i+1)<=$#arrayOfRoutes) && ("$arrayOfDates[$i]" eq "$arrayOfDates[$i+1]")) { &calculateMiniEdges($arrayOfRoutes[$i], 1); &recalculateMiniEdges($arrayOfRoutes[$i+1], 1); #printDebug "path=> $arrayOfRoutes[$i] \n****** $arrayOfRoutes[$i+1]\n"; $i++; } elsif ((($i+2)<=$#arrayOfRoutes) && ("$arrayOfDates[$i]" eq "$arrayOfDates[$i+2]")) { &calculateMiniEdges($arrayOfRoutes[$i], 1); &recalculateMiniEdges($arrayOfRoutes[$i+1], 1); &recalculateMiniEdges($arrayOfRoutes[$i+2], 1); $i++; $i++; } else { &calculateMiniEdges($arrayOfRoutes[$i], $numPaths); } $maxy=0; foreach $router (@miniRouter) { $centerx=$basex+$x{"$router"}*$stepx; $centery=$basey+$y{"$router"}*$stepy; if ($maxy < $y{"$router"}) {$maxy = $y{"$router"};}; # printDebug "router: $router ($centerx, $centery)\n"; $borderx=$centerx-$radius; $bordery=$centery-$radius; $width=1; print "1 3 0 $width -1 7 0 0 -1 0.000 1 0.0000 $centerx $centery ". "$radius $radius $borderx $bordery $borderx $bordery\n"; $labelx=$centerx-$radius; $labely=$centery-$radius; if ($router =~ /(\w+)\.(\w+)\.(\w+)\.(\w+)/) { $label="$4"; } print "4 0 0 2 0 0 12 0.0000 4 135 360 $labelx $labely $label\\001\n\n"; $sumEdges=0; foreach $end ( keys %{$miniEdge{"$router"}}) { $startx=$centerx; $starty=$centery; $endx=$basex+$x{"$end"}*$stepx; $endy=$basey+$y{"$end"}*$stepy; $width=int(${$miniEdge{"$router"}}{"$end"}*$widthWeigth); $width=($width?$width:1); $sumEdges+=${$miniEdge{"$router"}}{"$end"}; if (($startx == $endx) && ($starty == $endy)) { #this is looping into itself $endx=$startx-$radius; $endy=$starty+$radius*1.5; } print "2 1 0 $width -1 7 0 0 -1 0.000 0 0 -1 0 0 2\n". " $startx $starty $endx $endy\n"; # printDebug "$router $end 2 1 0 $width -1 7 0 0 -1 0.000 0 0 -1 0 0 2\n". # " $startx $starty $endx (=$basex+".$x{"$end"}."*$stepx) $endy \n"; } $labelx=$centerx+$radius*0; $labely=$centery+$radius+200; $label=(int($sumEdges/$sumRoutes*100))."%"; if ($label eq "0%") { $label=(int($sumEdges/$sumRoutes*1000))."%%"; } if ($label eq "0%%") { $label=".".(int($sumEdges/$sumRoutes*10000))."%%"; } print "4 0 1 2 0 0 12 0.0000 4 135 360 $labelx $labely $label \\001\n\n"; } $textx = $offsetTextx+$basex; $texty = $offsetTexty+$basey; print "4 0 -1 0 0 0 32 0.0000 4 135 360 $textx $texty $dir => $family; $numPaths routes ($firstDate - $arrayOfDates[$i])\\001\n\n"; printDebug "#END OF RESULTS: ($dir => $family) \n"; # print "\n\n************************************************\n\n"; #exit; $basey += ($maxy+1)*$stepy; $numPaths=1; #exit; } } } ###################################################################### sub setArrayOfDefectsByDate() { my ($date,$error) = @_; ${$arrayOfDefectsByDate{$date}}{"$error"}++; } ###################################################################### sub checkIfRouteLoop() { my ($thisRoute,$date) = @_; my @route = reverse split(/-/, $thisRoute); my ($r,$router); if ($thisRoute =~ /$route[1]-$route[0]-$route[1]-$route[0]-$route[1]-$route[0]$/) { printDebug "route LOOP ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"RouteLoop"}++; # printDebug "$route \n\n"; } } ###################################################################### sub checkIfLoopback() { my ($thisRoute,$date) = @_; my @routes = (split(/-/, $thisRoute)); my %marked; %marked = (); my @duplicates = grep { $marked{$_}++ == 1;} @routes; my $r; if ($#duplicates > -1) { printDebug "route LOOPBACK ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"LoopBack"}++; # printDebug "$thisRoute (@routes => @duplicates)\n\n"; } } ###################################################################### sub checkIfRouteFailure() { my ($thisRoute,$date) = @_; my @duplicates = grep { /ERROR.![A-Z]/ } split(/-/, $thisRoute); if ($#duplicates > -1) { printDebug "route FAILURE $duplicates[0] ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"RouteFailure"}++; } } ###################################################################### sub checkIfRerouteInTransit() { my ($thisRoute1,$date1,$thisRoute2,$date2) = @_; if (($thisRoute1 ne $thisRoute2) && ($date1 eq $date2)) { printDebug "route CHANGE IN TRANSIT ($date1)\n"; ${$arrayOfDefectsByDate{$date1}}{"RerouteInTransit"}++; } } ###################################################################### sub checkIfDestNotResponding() { my ($thisRoute,$date) = @_; my @route = reverse split(/-/, $thisRoute); my ($r,$router); if ($route[0] !~ /X\d+X\.X\d+X\.X\d+X\.X\d+X/) {return;} foreach $r ( @route) { # printDebug "[$r]\t"; if ($r !~ /X\d+X\.X\d+X\.X\d+X\.X\d+X/) {$router = $r;last;} } if ($domain{$router} eq $domain{$destination}) { printDebug "destination NOT RESPONDING ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"DestinationNotresponding"}++; # printDebug "$route [$router]\n\n"; } else { printDebug "connectivity LOST ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"LostConnectivity"}++; # printDebug "$domain{$router} eq $domain{$destination}\n"; # printDebug "$route [$router]\n\n"; } return -1; } ###################################################################### sub findIndexRouter() { my ($router,$arrayRouters) = @_; my $i; for ($i=0; $i <= $#{$arrayRouters}; $i++) { #printDebug "$router eq ".${$arrayRouters}[$i]." ($i)\n"; if ($router eq ${$arrayRouters}[$i]) {return $i;} } return $#{$arrayRouters}+1; } ###################################################################### sub checkRouteDifferences() { my ($oldroute,$newroute,$date) = @_; my @oldRoute = split(/-/, $oldroute); my @newRoute = split(/-/, $newroute); my ($i1,$i2,$j,$k,$l,$router,$oldDomain, $newDomain, @aux); my @listOfNewDomains = (); my @listOfOldDomains = (); my @listOfNewRouters = (); my @listOfOldRouters = (); for ($i1=0, $i2=0; $i1 <= $#newRoute; $i1++) { if ($newRoute[$i1] ne $oldRoute[$i2]) { #there is a difference #printDebug "$i1->$newRoute[$i1]; $i2->$oldRoute[$i2]\n"; $k=$#newRoute; for ($j=$i1; $j <= $#newRoute; $j++) { # if (grep (/^$newRoute[$j]$/, @oldRoute[($i2+1)..$#oldRoute]) ne "") { @aux = grep (/^$newRoute[$j]$/, @oldRoute[($i2+1)..$#oldRoute]); if ($#aux != -1) { $k=$j; last; } #printDebug "newRouter: $j->$newRoute[$j]\n"; $newDomain = $domain{$newRoute[$j]}; push(@listOfNewRouters, $newRoute[$j]); if ($listOfNewDomains[$#listOfNewDomains] ne $newDomain) {push(@listOfNewDomains, $newDomain);} } $i1=$k; #printDebug "newRouter(2): $k->$newRoute[$k]\n"; # $l = $i2 + 1 + &findIndexRouter($newRoute[$k], \@oldRoute[($i2+1)..$#oldRoute]); $l = &findIndexRouter($newRoute[$k], \@oldRoute); #printDebug "oldRouter(2): $l->$oldRoute[$l]\n"; for ($j=$i2; $j < $l; $j++) { #printDebug "oldRouter: $j->$oldRoute[$j]\n"; $oldDomain = $domain{$oldRoute[$j]}; push(@listOfOldRouters, $oldRoute[$j]); if ($listOfOldDomains[$#listOfOldDomains] ne $oldDomain) {push(@listOfOldDomains, $oldDomain);} } $i2=$j+1; } else { $i2++; } } if (($#listOfOldDomains != -1) || ($#listOfNewDomains != -1)) { if (($#listOfOldDomains == 0) && ($#listOfNewDomains == 0)) { #check if it is an overloaded router not responding to the ping my @aux1 = grep (/\d+\.\d+\.\d+\.\d+/, @listOfNewRouters); my @aux2 = grep (/\d+\.\d+\.\d+\.\d+/, @listOfOldRouters); if (($#listOfNewRouters == $#listOfOldRouters) && ($listOfNewDomains[0] eq "UNDEFINED") && ($#aux1 ==-1)) { printDebug "OVERLOADED router not responding to the pings ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"OverloadedRouter"}+=$#listOfNewRouters+1; } elsif (($#listOfNewRouters == $#listOfOldRouters) && ($listOfOldDomains[0] eq "UNDEFINED") && ($#aux2 == -1)) { printDebug "recovery from an OVERLOADED router ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"OverloadedRouter"}=0; } #check if route change in destination elsif (($listOfNewDomains[$#listOfNewDomains] eq $domain{$destination}) && ($listOfOldDomains[$#listOfNewDomains] eq $domain{$destination})) { printDebug "ROUTE change in the destination network ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"RerouteInDestinationNetwork"}++; #printDebug "$listOfNewDomains[$#listOfNewDomains] eq $domain{$destination} ($destination)\n"; } #check if route change in source elsif (($listOfNewDomains[0] eq $domain{$source}) && ($listOfNewDomains[0] eq $domain{$source})) { printDebug "ROUTE change in the source network ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"RerouteInSourceNetwork"}++; printDebug "$listOfNewDomains[0] eq $domain{$source} ($source)\n"; } #check if change in a single transit network elsif ($listOfOldDomains[0] eq $listOfNewDomains[0]) { # printDebug "ROUTE change in a single transit network ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"RerouteInsideOneTransitDomain"}++; } } if (${$arrayOfDefectsByDate{$date}}{"OverloadedRouter"} eq "") { # printDebug "ROUTE change ($date)\n"; ${$arrayOfDefectsByDate{$date}}{"Reroute"}++; #printDebug "$oldroute ==> $newroute\n"; foreach $router (@listOfOldDomains) { ${$arrayOfDefectsByDate{$date}}{"Comment"} .= "$router-"; } ${$arrayOfDefectsByDate{$date}}{"Comment"} .= "->"; foreach $router (@listOfNewDomains) { ${$arrayOfDefectsByDate{$date}}{"Comment"} .= "$router-"; } ${$arrayOfDefectsByDate{$date}}{"Comment"} .= ","; #printDebug " ($date)\n\n"; } } } ###################################################################### sub printOneAnomaly() { my ($from, $to, $anomaly) = @_; print STDOUT "\n\n$from\t"."$to\t". ${$anomaly}{"StartMonth"}."\t". ${$anomaly}{"StartDay"}."\t". ${$anomaly}{"StartHour"}."\t". ${$anomaly}{"EndMonth"}."\t". ${$anomaly}{"EndDay"}."\t". ${$anomaly}{"EndHour"}."\t". #"$date\t". #"\t". ${$anomaly}{"RerouteInSourceNetwork"}."\t". ${$anomaly}{"Reroute"}."\t". ${$anomaly}{"RerouteInsideOneTransitDomain"}."\t". ${$anomaly}{"RerouteInDestinationNetwork"}."\t". ${$anomaly}{"RouteFailure"}."\t". ${$anomaly}{"DestinationNotresponding"}."\t". ${$anomaly}{"LoopBack"}."\t". ${$anomaly}{"RouteLoop"}."\t". #"\t". ${$anomaly}{"LostConnectivity"}."\t". ${$anomaly}{"RerouteInTransit"}."\t". ${$anomaly}{"OverloadedRouter"}."\t". ${$anomaly}{"NotEndingInDestination"}."\t". ${$anomaly}{"BadTrace"}."\t". ${$anomaly}{"Comment"}."\t". "\t". "\n"; } ###################################################################### sub printTableWithAllAnomalies() { my @list = sort keys %arrayOfDefectsByDate; my %totalAnomalies; my %titleAnomalies; $totalAnomalies{"StartMonth"} = "$dir"; $totalAnomalies{"StartDay"} = "$family"; $totalAnomalies{"StartHour"} = " "; $totalAnomalies{"EndMonth"} = ($#arrayOfRoutes +1); $totalAnomalies{"EndDay"} = ($#list+0); $totalAnomalies{"EndHour"} = " "; $totalAnomalies{"BadTrace"} = 0; $totalAnomalies{"NotEndingInDestination"} = 0; $totalAnomalies{"RouteLoop"} = 0; $totalAnomalies{"LoopBack"} = 0; $totalAnomalies{"RouteFailure"} = 0; $totalAnomalies{"RerouteInTransit"} = 0; $totalAnomalies{"DestinationNotresponding"} = 0; $totalAnomalies{"LostConnectivity"} = 0; $totalAnomalies{"RerouteInDestinationNetwork"} = 0; $totalAnomalies{"RerouteInSourceNetwork"} = 0; $totalAnomalies{"Reroute"} = 0; $totalAnomalies{"OverloadedRouter"} = 0; $totalAnomalies{"RerouteInsideOneTransitDomain"} = 0; $titleAnomalies{"StartMonth"} = "StaMon"; $titleAnomalies{"StartDay"} = "StaDay"; $titleAnomalies{"StartHour"} = "StaHour "; $titleAnomalies{"EndMonth"} = "EndMon"; $titleAnomalies{"EndDay"} = "EndDay"; $titleAnomalies{"EndHour"} = "EndHour "; $titleAnomalies{"BadTrace"} = "BadTrac"; $titleAnomalies{"NotEndingInDestination"} = "End!Dst"; $titleAnomalies{"RouteLoop"} = "RLoop"; $titleAnomalies{"LoopBack"} = "LoopBak"; $titleAnomalies{"RouteFailure"} = "RFail"; $titleAnomalies{"RerouteInTransit"} = "RRTrace"; $titleAnomalies{"DestinationNotresponding"} = "Dst!Res"; $titleAnomalies{"LostConnectivity"} = "Lost"; $titleAnomalies{"RerouteInDestinationNetwork"} = "RRDst"; $titleAnomalies{"RerouteInSourceNetwork"} = "RRSrc"; $titleAnomalies{"Reroute"} = "RR"; $titleAnomalies{"OverloadedRouter"} = "Overloa"; $titleAnomalies{"RerouteInsideOneTransitDomain"} = "RR1Tran"; $titleAnomalies{"Comment"} = "Comment"; my $date; if (%hashOfRoutes !=()) { print STDOUT "\n======================================================================\n\n"; print STDOUT "Total number of routes: \t".($#arrayOfRoutes +1)."\n"; print STDOUT "Total number of routes with problems: \t".($#list+0)." \n"; &printOneAnomaly("From","To",\%titleAnomalies); foreach $date (@list) { # printDebug "\n\n ($date):\n"; if (${$arrayOfDefectsByDate{$date}}{"BadTrace"} ne "") { # printDebug "\tBAD TRACEROUTE SAMPLE\n"; $totalAnomalies{"BadTrace"} += ${$arrayOfDefectsByDate{$date}}{"BadTrace"}; } if (${$arrayOfDefectsByDate{$date}}{"NotEndingInDestination"} ne "") { # printDebug "\troute NOT ENDING IN THE DESTINATION\n"; $totalAnomalies{"NotEndingInDestination"} += ${$arrayOfDefectsByDate{$date}}{"NotEndingInDestination"}; } if (${$arrayOfDefectsByDate{$date}}{"RouteLoop"} ne "") { # printDebug "\troute LOOP\n"; $totalAnomalies{"RouteLoop"} += ${$arrayOfDefectsByDate{$date}}{"RouteLoop"}; } if (${$arrayOfDefectsByDate{$date}}{"LoopBack"} ne "") { # printDebug "\troute LOOPBACK\n"; $totalAnomalies{"LoopBack"} += ${$arrayOfDefectsByDate{$date}}{"LoopBack"}; } if (${$arrayOfDefectsByDate{$date}}{"RouteFailure"} ne "") { # printDebug "\troute FAILURE\n"; $totalAnomalies{"RouteFailure"} += ${$arrayOfDefectsByDate{$date}}{"RouteFailure"}; } if (${$arrayOfDefectsByDate{$date}}{"RerouteInTransit"} ne "") { # printDebug "\troute CHANGE IN TRANSIT\n"; $totalAnomalies{"RerouteInTransit"} += ${$arrayOfDefectsByDate{$date}}{"RerouteInTransit"}; } if (${$arrayOfDefectsByDate{$date}}{"DestinationNotresponding"} ne "") { # printDebug "\tdestination NOT RESPONDING\n"; $totalAnomalies{"DestinationNotresponding"} += ${$arrayOfDefectsByDate{$date}}{"DestinationNotresponding"}; } if (${$arrayOfDefectsByDate{$date}}{"LostConnectivity"} ne "") { # printDebug "\tconnectivity LOST\n"; $totalAnomalies{"LostConnectivity"} += ${$arrayOfDefectsByDate{$date}}{"LostConnectivity"}; } if (${$arrayOfDefectsByDate{$date}}{"RerouteInDestinationNetwork"} ne "") { # printDebug "\tREROUTE in DESTINATION network\n"; $totalAnomalies{"RerouteInDestinationNetwork"} += ${$arrayOfDefectsByDate{$date}}{"RerouteInDestinationNetwork"}; } if (${$arrayOfDefectsByDate{$date}}{"RerouteInSourceNetwork"} ne "") { # printDebug "\tREROUTE in DESTINATION network\n"; $totalAnomalies{"RerouteInSourceNetwork"} += ${$arrayOfDefectsByDate{$date}}{"RerouteInSourceNetwork"}; } if (${$arrayOfDefectsByDate{$date}}{"Reroute"} ne "") { # printDebug "\tREROUTE \n"; $totalAnomalies{"Reroute"} += ${$arrayOfDefectsByDate{$date}}{"Reroute"}; } if (${$arrayOfDefectsByDate{$date}}{"OverloadedRouter"} ne "") { # printDebug "\tOVERLOADED ROUTER \n"; $totalAnomalies{"OverloadedRouter"} += ${$arrayOfDefectsByDate{$date}}{"OverloadedRouter"}; } if (${$arrayOfDefectsByDate{$date}}{"RerouteInsideOneTransitDomain"} ne "") { # printDebug "\tREROUTE \n"; $totalAnomalies{"RerouteInsideOneTransitDomain"} += ${$arrayOfDefectsByDate{$date}}{"RerouteInsideOneTransitDomain"}; } &printOneAnomaly("$dir","$family",$arrayOfDefectsByDate{$date}); } &printOneAnomaly("From","To",\%titleAnomalies); print STDOUT "----------------------------------------------------------------------\n"; $titleAnomalies{"StartMonth"} = "From"; $titleAnomalies{"StartDay"} = "To"; $titleAnomalies{"StartHour"} = " "; $titleAnomalies{"EndMonth"} = ""; $titleAnomalies{"EndDay"} = "Nroute"; $titleAnomalies{"EndHour"} = "Nanomalies "; $titleAnomalies{"Comment"} = ""; &printOneAnomaly("From","To",\%titleAnomalies); &printOneAnomaly("TOTAL:"," ",\%totalAnomalies); print STDOUT "\n======================================================================\n\n"; } } ###################################################################### sub calculateAllAnomalies() { my ($centerx, $centery, $borderx, $bordery, $width); my ($startx, $starty, $endx, $endy); my ($labelx, $labely, $label, $textx, $texty); my ($router, $end, $i); my ($sumEdges, $firstDate); my $date = $arrayOfDates[0]; if (%hashOfRoutes !=()) { my $numPaths=1; for ($i=0; $i<=$#arrayOfRoutes; $i++) { #printDebug "path=> $arrayOfRoutes[$i] \n****** $arrayOfRoutes[$i+1]\n"; if ($numPaths==1) { $firstDate=$arrayOfDates[$i]; my ($month,$day,$hour) = split(/ +/, $firstDate); ${$arrayOfDefectsByDate{$firstDate}}{"StartMonth"} = $month; ${$arrayOfDefectsByDate{$firstDate}}{"StartDay"} = $day; ${$arrayOfDefectsByDate{$firstDate}}{"StartHour"} = $hour; } &checkIfDestNotResponding("$arrayOfRoutes[$i]",$arrayOfDates[$i]); &checkIfRouteLoop("$arrayOfRoutes[$i]",$arrayOfDates[$i]); &checkIfLoopback("$arrayOfRoutes[$i]",$arrayOfDates[$i]); &checkIfRouteFailure("$arrayOfRoutes[$i]",$arrayOfDates[$i]); &checkIfRerouteInTransit("$arrayOfRoutes[$i]",$arrayOfDates[$i],"$arrayOfRoutes[$i+1]",$arrayOfDates[$i+1]); if (((($i+1)<=$#arrayOfRoutes) && ("$arrayOfRoutes[$i]" eq "$arrayOfRoutes[$i+1]")) && ((($i+2)<=$#arrayOfRoutes) && ("$arrayOfDates[$i+1]" ne "$arrayOfDates[$i+2]"))) { $numPaths++; next; } if ($arrayOfDates[$i+1] eq "") {next;} &checkRouteDifferences("$arrayOfRoutes[$i]","$arrayOfRoutes[$i+1]",$arrayOfDates[$i+1]); #put end dates if ($arrayOfDefectsByDate{$date} ne "") { my ($month,$day,$hour) = split(/ +/, $arrayOfDates[$i+1]); ${$arrayOfDefectsByDate{$arrayOfDates[$i+1]}}{"StartMonth"} = $month; ${$arrayOfDefectsByDate{$arrayOfDates[$i+1]}}{"StartDay"} = $day; ${$arrayOfDefectsByDate{$arrayOfDates[$i+1]}}{"StartHour"} = $hour; my ($month,$day,$hour) = split(/ +/, $arrayOfDates[$i]); ${$arrayOfDefectsByDate{$date}}{"EndMonth"} = $month; ${$arrayOfDefectsByDate{$date}}{"EndDay"} = $day; ${$arrayOfDefectsByDate{$date}}{"EndHour"} = $hour; } if ($i != $#arrayOfRoutes) {$date = $arrayOfDates[$i+1];} next; } my ($month,$day,$hour) = split(/ +/, $arrayOfDates[$#arrayOfRoutes]); ${$arrayOfDefectsByDate{$date}}{"EndMonth"} = $month; ${$arrayOfDefectsByDate{$date}}{"EndDay"} = $day; ${$arrayOfDefectsByDate{$date}}{"EndHour"} = $hour; } }