On 01/03/11 15:00 +0000, Nelson A. de Oliveira wrote:
[snip] 
> Indeed it was a wrong translation (see #615981 that I have opened right now).

Ok, great !

> It would be very good to have this implemented directly into
> paris-traceroute (and stop parsing ifconfig output) :-)

I have implemented the small I sent you earlier, would you like to test
the binary with this patch ?

Cheers !

-- 
Hervé Rousseau
This patch fixes local IP discovery using ifconfig that was broken on some locale.
It uses a less broken way by opening a connection to some public DNS Server
Index: paris-traceroute-0.92-dev/src/Util.cc
===================================================================
--- paris-traceroute-0.92-dev.orig/src/Util.cc	2011-03-01 16:33:33.000000000 +0100
+++ paris-traceroute-0.92-dev/src/Util.cc	2011-03-01 16:35:05.000000000 +0100
@@ -12,6 +12,8 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <assert.h>
+#include <iostream>
 #include <netdb.h>
 
 /**
@@ -21,40 +23,36 @@
  * @param addr The destination address
  * @return The source address
  */
-char*
-Util::getRoute (const char* dest) {
-  FILE * fd;
-  char buff[20];
-
-  // Ouvre un tube nommé
-
-
-#ifdef __APPLE__
-  fd = popen(" a=`/usr/sbin/netstat -rn | grep default`; /sbin/ifconfig `echo $a | cut -d ' ' -f 6` | grep \"inet \" | cut -d ' ' -f 2", "r");
-#endif
-
-#ifdef __FreeBSD__
-	fd = popen(" a=`netstat -rn | grep default`; /sbin/ifconfig `echo $a | cut -d ' ' -f 6` | grep \"inet \" | cut -d ' ' -f 2", "r");
+char* Util::getRoute(const char* dest).
+{
+    char buffer[20];
+
+    int sock = socket(AF_INET, SOCK_DGRAM, 0);
+    assert(sock != -1);
+
+    const char* kGoogleDnsIp = "8.8.8.8";
+    uint16_t kDnsPort = 53;
+    struct sockaddr_in serv;
+    memset(&serv, 0, sizeof(serv));
+    serv.sin_family = AF_INET;
+    serv.sin_addr.s_addr = inet_addr(kGoogleDnsIp);
+    serv.sin_port = htons(kDnsPort);
+
+    int err = connect(sock, (const sockaddr*) &serv, sizeof(serv));
+    assert(err != -1);
+
+    sockaddr_in name;
+    socklen_t namelen = sizeof(name);
+    err = getsockname(sock, (sockaddr*) &name, &namelen);
+    assert(err != -1);
 
-#endif
+    const char* p = inet_ntop(AF_INET, &name.sin_addr, buffer, 20);
+    close(sock);
 
-#ifdef __NetBSD__
-  
-  fd = popen(" a=`/usr/bin/netstat -rn | grep default`; /sbin/ifconfig `echo $a | cut -d ' ' -f 7` | grep \"inet \" | cut -d ' ' -f 2", "r");
-#endif
-	
-#ifdef __linux__
-  fd = popen(" a=`/sbin/route -n | grep default`; /sbin/ifconfig `echo $a | cut -d ' ' -f 8` | grep \"inet \" | cut -d ':' -f 2 | cut -d ' ' -f 1", "r");
-#endif
-
-  fscanf(fd, "%s", buff);
-  pclose(fd);
-
-  log(INFO, "Source address = %s\n", buff);
-
-  return strdup(buff);
+    return strdup(buffer);
 }
 
+
 /**
  * This function return the IP address of the interface through which
  * a packet destined for "addr" will go. This function uses libnetlink

Reply via email to