var traceRoutePolyine; var paths; // Static for fetchTraceRoute to store paths info function fetchTraceRoute(startDate, endDate) { // do a traceroute of the selected date, num selects the nth traceroute from the list, -1 means last // Prepare dates for query curTraceDate = new Date(); if( typeof(endDate) == "undefined" ) endDate = new Date(); // Default to today else { endDate = new Date(); endDate.setTime(endDate*1000); } if( typeof(startDate) == "undefined" ) { startDate = new Date(); startDate.setTime(endDate.getTime()-86400000*14)// Default to yesterday } else { startDate = newDate(); startDate.setTime(startDate*1000); } // Prepare date strings for xml query var startString = startDate.getFullYear().toString(); if( startDate.getMonth()+1 < 10 ) startString += "0" + (startDate.getMonth()+1).toString(); else startString += (startDate.getMonth()+1).toString(); if( startDate.getDate() < 10 ) startString += "0" + startDate.getDate().toString(); else startString += startDate.getDate().toString(); var endString = endDate.getFullYear().toString(); if( endDate.getMonth()+1 < 10 ) endString += "0" + (endDate.getMonth()+1).toString(); else endString += (endDate.getMonth()+1).toString(); if( endDate.getDate() < 10 ) endString += "0" + endDate.getDate().toString(); else endString += endDate.getDate().toString(); makeHideBox( "Traceroutes", "traceBox", "traceDiv" ); writit( "

Loading data...

", "traceDiv" ); try { // traceRoutePolyline might not be defined yet. map.removeOverlay(traceRoutePolyline); } catch (err) {} GDownloadUrl("http://www.ripe.net/ttm/Plots/ttmaps/routingXML.cgi?SRC=" + source[0] + "&DST=" + target[0] + "&date_start=" + startString + "&time_start=00%3A00&date_end=" + endString + "&time_end=00%3A00&sortmode=date&resolve=no&sdiff=no&type=IP&ipv=4&SUBMIT=Submit", function(data, responseCode) { if(responseCode == 200) { var xml = GXml.parse(data); paths = xml.documentElement.getElementsByTagName("path"); showTraceRoute(-1); } else { // No valid data writit('

Sorry, there is no traceroute data available for the pair of testboxes you selected.', "traceDiv" ); } }); } var oldNum; // Save oldNum to calculate diff function showTraceRoute(num, oldNum) { if( num < 0 || num > paths.length-1) num = paths.length-1; var hops = paths[num].getElementsByTagName("hop"); var points = new Array(); var current; var previous; var dist = source[1].distanceFrom(target[1]); var traceText = "

"; var start = new Date(); var end = new Date(); // First calculate the diffs if( typeof(oldNum) != "undefined" ){ var lost = new Array(); var found = new Array(); var ip; var f; var oldHops = paths[oldNum].getElementsByTagName("hop"); for( var i=1; i < oldHops.length-1; i++ ) { ip = oldHops[i].getAttribute("ip"); f = 0; for( var j=1; j < hops.length; j++ ) if( ip == hops[j].getAttribute("ip") ) f++ if( f == 0 ) // We didn't find the old IP in the new list, so it must have been lost lost.push( i ); } for( var i=1; i < hops.length-1; i++ ) { ip = hops[i].getAttribute("ip"); f = 0; for( var j=1; j < oldHops.length; j++ ) if( ip == oldHops[j].getAttribute("ip") ) f++ if( f == 0 ) // We didn't find the new IP in the old list, so it must be a new one found.push( i ); } } start.setTime(paths[num].getAttribute("start")*1000); end.setTime(paths[num].getAttribute("end")*1000); traceText += "From " + source[0] + " to " + target[0] + ", "; traceText += "between " + formatDate(start) + " and " + formatDate(end) + ".
"; if( num > 0 ) traceText += "[Earlier]"; if( num < paths.length-1 ) traceText += "[Later]"; traceText += "

"; // As first we use our source GPS coordinates points.push( source[1] ); var count = 0; for( var i=0; i < hops.length; i++ ) { // Write the text for the traceDiv traceText += ""; if( hops[i].getAttribute("ip") != "255.255.255.255" ) traceText += i+1 + ". " + hops[i].getAttribute("ip") + " (" + hops[i].getAttribute("as") + ") "; else { try { // We don't know if hops[i+1] will work if( hops[i+1].getAttribute("ip") == "255.255.255.255" ) { count++; // Count the number of unreachable hops, so we only show them in one line. continue; } else { if( count > 0 ) traceText += (i-count+1)+"-"+(i+1)+". "+(count+1)+" Unreachable Hops"; else traceText += i+1 + ". Unreachable Hop"; } } catch (err) { traceText += i+1 + ". Unreachable Hop"; } } if( i == 0 ) { traceText += "["+source[0]+"]"; } else if ( i == hops.length-1 ) { traceText += "["+target[0]+"]"; } traceText += "
"; // Only draw if a hop changed and we are not having an unknown IP. if( hops[i].getAttribute("lat") != "0" && hops[i].getAttribute("lng") != 0 && i!=0 && i!=hops.length-1 && hops[i].getAttribute("ip") != "255.255.255.255" ) { // First and last already taken care of previous = current; current = new GLatLng(parseFloat(hops[i].getAttribute("lat")), parseFloat(hops[i].getAttribute("lng"))); if( typeof(previous) == "undefined" || (previous != current && previous.distanceFrom(current) < dist*3) ) { // Also make sure unreasonably far away points are filter. points.push( current ); } } } traceText += "

"; traceText += "

Disclaimer: The geolocation data is based on the GeoLite database and might not be 100% correct.

"; // And for the final point of the tracePolyline our target points.push( target[1] ); // The following basically just handles the effect execution and overwriting // of the div in the middle of it. Also handles different cases if there happen to be no lost ones or it's the // first call of the tracerouter. if( typeof(oldNum) != "undefined" ) { if( lost.length != 0 ) { lost.each( function(hopNum) { if( hopNum != lost.last() ) { new Effect.Highlight('traceLine' + hopNum, {startcolor:'#FFFFFF', endcolor:'#FF0000'}); } else { //$('traceLine'+hopNum).backgroundColor = "#FFFFFF"; new Effect.Highlight('traceLine' + hopNum, {startcolor:'#FFFFFF', endcolor:'#FF0000', afterFinish: function(obj) { writit( traceText, "traceDiv" ); // And now do the effects for the newly found IPs already in the new div found.each( function(hopNum) { new Effect.Highlight('traceLine' + hopNum, {startcolor:'#FFFFFF', endcolor:'#00CC00'}); $('traceLine'+hopNum).style.backgroundColor = "#00CC00"; } ); } }); } } ); } else { writit( traceText, "traceDiv" ); // And now do the effects for the newly found IPs already in the new div found.each( function(hopNum) { new Effect.Highlight('traceLine' + hopNum, {startcolor:'#FFFFFF', endcolor:'#00CC00'}); $('traceLine'+hopNum).backgroundColor = "#00CC00"; } ); } } else { writit( traceText, "traceDiv" ); } if( typeof( traceRoutePolyline ) != "undefined" ) map.removeOverlay(traceRoutePolyline); traceRoutePolyline = new GPolyline(points, "#0000FF", 5); map.addOverlay(traceRoutePolyline); oldNum = num; }