[smokeping-users] IPv6/traceroute6 patch for SmokeTrace/smokeping-2.4.2

Steven Bytnar smbsmokepingusers at bytnar.net
Sun Dec 7 16:59:29 CET 2008


Hi,

Attached is a patch that adds IPv6 (traceroute6) support to SmokeTrace.

Release notes:
* If Socket6 is not installed, don't attempt to do IPv6 lookups.
* When the host is a FQDN and the info from getaddrinfo resolves
to an IPv6 address, traceroute6 is used on that FQDN. Therefore,
the code prefers IPv6 addresses. It may be that some people may
prefer an IPv4 traceroute instead of IPv6 traceroute6 when a host
returns both an IPv4 and IPv6 address.
* When an IPv6 address is specified, an IPv6 traceroute6 is provided.
* When an IPv4 address or IPv4 only FQDN is used, an IPv4 traceroute
is provided.
* I'm not a perl master (yet), so there might be a better way to
write this line of code to remove the variable declarations before it:
($family, $socktype, $proto, $saddr, $canonname, @res) = @res;

Tested on Mac OS X 10.5.5.

Enjoy!
--Steve

-------------- next part --------------
--- Tr.pm-orig	2008-12-06 19:04:59.000000000 -0600
+++ Tr.pm	2008-12-07 09:55:32.000000000 -0600
@@ -12,6 +12,7 @@ sub launch {
      my $rounds = shift;
      my $delay = shift;
      my $host = shift;
+     my $ipv6host = shift;
      defined(my $pid = fork) or do { $error->set_error(101,"Can't fork: $!");return $error};
      if ($pid){
         open my $x, ">/tmp/tr_session.$pid" or do {
@@ -31,7 +32,11 @@ sub launch {
      open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
      for (my $i = 0; $i<$rounds;$i++){
          my $start = time;
-         system "traceroute","-I","-q","1",$host;        
+         if ($ipv6host) {
+             system "traceroute6","-l","-q","1",$host;        
+         } else {
+             system "traceroute","-I","-q","1",$host;        
+         }
          my $wait = $delay - (time - $start);
          if ($wait > 0 and $i+1< $rounds){
              print "SLEEP $wait\n";
@@ -76,6 +81,7 @@ sub method_run_tr
     my $handle = get_number($error,$arg->{handle});
     my $point = get_number($error,$arg->{point});
     my @array;
+    my $ipv6host = 0;
     if ($arg->{host}){
         my $host = $arg->{host};
         if ( my @addresses = gethostbyname($host) ){
@@ -85,11 +91,36 @@ sub method_run_tr
                  push @array, ['INFO',"Found $#addresses addresses for $arg->{host}. Using $host."];
              }
         }
+
+        my $has_socket6;
+        if (eval {require Socket6;}) {
+               import Socket6;
+               $has_socket6 = 1;
+        } else {
+               $has_socket6 = 0;
+        }
+
+        if ($has_socket6) {
+            my @res;
+            @res = getaddrinfo($host, 'http', AF_UNSPEC, SOCK_STREAM);
+            while (scalar(@res) >= 5) {
+                my $family = -1;
+                my $socktype;
+                my $proto;
+                my $saddr;
+                my $canonname;
+                ($family, $socktype, $proto, $saddr, $canonname, @res) = @res;
+                if ($family == AF_INET6()) {
+                        $ipv6host = 1;
+                }
+            }
+        }
+
         my $delay = get_number($error,$arg->{delay});
         return $delay if ref $delay;
         my $rounds = get_number($error,$arg->{rounds});
         return $rounds if ref $rounds;
-        $handle = launch ($error,$rounds,$delay,$host);
+        $handle = launch ($error,$rounds,$delay,$host,$ipv6host);
         $point = 0;
     }
     return $point if ref $point;
@@ -114,7 +145,7 @@ sub method_run_tr
         if (seek $fh, $point,0){
             while (<$fh>){
                 #print STDERR ">$_<";
-		next if /^\s*$/ or /traceroute to/;
+		next if /^\s*$/ or /traceroute to/ or /traceroute6 to/;
                 if (/^\s*(\d+)\s+(\S+)\s+\((\S+?)\)\s+(\S+)\s+ms/){
                     my ($hop,$host,$ip,$value) = ($1,$2,$3,$4);
                     $value = undef unless $value =~ /^\d+(\.\d+)?$/;
@@ -126,6 +157,9 @@ sub method_run_tr
                 elsif (/^SLEEP\s+(\d+)/){
                     push @array, ['SLEEP',$1];
                 }
+                elsif (s/traceroute6:\s*//g or /\n$/){
+                    push @array, ['INFO',$_];
+                }
                 elsif (s/traceroute:\s*//g or /\n$/){
                     push @array, ['INFO',$_];
                 }


More information about the smokeping-users mailing list