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