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