diff options
author | pdw <> | 2011-10-02 21:41:47 +0000 |
---|---|---|
committer | pdw <> | 2011-10-02 21:41:47 +0000 |
commit | 120a1b2c5393fc63e2c9bf81d6adb55a6acd4ed2 (patch) | |
tree | a50dc5cf8eb811798d815c928e1fd09ccbd7c4fc | |
parent | 3e90c6b54712eb4e361edc31526c058712df7988 (diff) | |
download | iftop-120a1b2c5393fc63e2c9bf81d6adb55a6acd4ed2.zip |
FreeBSD patch from Frederic Perrin <frederic.perrin@resel.fr> plus fix for
compile error in gethostbyaddr resolver.
Order of pcap.h vs bpf.h switched, to fix compilation on Mac OS X.
-rw-r--r-- | config/int_ghba_r.c | 1 | ||||
-rw-r--r-- | iftop.c | 14 | ||||
-rw-r--r-- | resolver.c | 54 |
3 files changed, 42 insertions, 27 deletions
diff --git a/config/int_ghba_r.c b/config/int_ghba_r.c index 7a3a3c1..6801a94 100644 --- a/config/int_ghba_r.c +++ b/config/int_ghba_r.c @@ -6,6 +6,7 @@ static const char rcsid[] = "$Id$"; +#include <sys/socket.h> #include <sys/types.h> #include <errno.h> @@ -5,13 +5,6 @@ #include "integers.h" -#if defined(HAVE_PCAP_H) -# include <pcap.h> -#elif defined(HAVE_PCAP_PCAP_H) -# include <pcap/pcap.h> -#else -# error No pcap.h -#endif #include <stdio.h> #include <stdlib.h> #include <time.h> @@ -20,6 +13,13 @@ #include <sys/socket.h> #include <net/if.h> #include <net/bpf.h> +#if defined(HAVE_PCAP_H) +# include <pcap.h> +#elif defined(HAVE_PCAP_PCAP_H) +# include <pcap/pcap.h> +#else +# error No pcap.h +#endif #include <pthread.h> #include <curses.h> @@ -37,6 +37,22 @@ int tail; extern options_t options; +int guess_af(struct in6_addr *addr) +{ + /* If the upper three (network byte order) uint32-parts + * are null, then there ought to be an IPv4 address here. + * Any such IPv6 would have to be 'xxxx::'. Neglectable? */ + uint32_t* probe; + int af; + + probe = (uint32_t *) addr; + return (probe[1] || probe[2] || probe[3]) ? AF_INET6 : AF_INET; +} + +socklen_t aflength(int af) +{ + return af == AF_INET6 ? sizeof(struct in6_addr) : sizeof(struct in_addr); +} /* * We have a choice of resolver methods. Real computers have getnameinfo or @@ -60,18 +76,11 @@ char *do_resolve(struct in6_addr *addr) { struct sockaddr_in6 sin6; char buf[NI_MAXHOST]; /* 1025 */ int res, af; - uint32_t* probe; memset(&sin, '\0', sizeof(sin)); memset(&sin6, '\0', sizeof(sin6)); - /* If the upper three (network byte order) uint32-parts - * are null, then there ought to be an IPv4 address here. - * Any such IPv6 would have to be 'xxxx::'. Neglectable? */ - probe = (uint32_t *) addr; - af = (probe[1] || probe[2] || probe[3]) ? AF_INET6 : AF_INET; - - switch (af) { + switch (guess_af(addr)) { case AF_INET: sin.sin_family = af; sin.sin_port = 0; @@ -106,26 +115,29 @@ char *do_resolve(struct in6_addr *addr) { * Some implementations of libc choose to implement gethostbyaddr_r as * a non thread-safe wrapper to gethostbyaddr. An interesting choice... */ -char* do_resolve(struct in_addr * addr) { +char* do_resolve(struct in6_addr * addr) { struct hostent hostbuf, *hp; size_t hstbuflen = 1024; char *tmphstbuf; int res; int herr; + int af; char * ret = NULL; /* Allocate buffer, remember to free it to avoid memory leakage. */ tmphstbuf = xmalloc (hstbuflen); + af = guess_af(addr); + /* Some machines have gethostbyaddr_r returning an integer error code; on * others, it returns a struct hostent*. */ #ifdef GETHOSTBYADDR_R_RETURNS_INT - while ((res = gethostbyaddr_r((char*)addr, sizeof(struct in_addr), AF_INET, + while ((res = gethostbyaddr_r((char*)addr, aflength(af), af, &hostbuf, tmphstbuf, hstbuflen, &hp, &herr)) == ERANGE) #else /* ... also assume one fewer argument.... */ - while ((hp = gethostbyaddr_r((char*)addr, sizeof(struct in_addr), AF_INET, + while ((hp = gethostbyaddr_r((char*)addr, aflength(af), af, &hostbuf, tmphstbuf, hstbuflen, &herr)) == NULL && errno == ERANGE) #endif @@ -152,22 +164,24 @@ char* do_resolve(struct in_addr * addr) { #elif defined(USE_GETHOSTBYADDR) /** - * Implementation using gethostbyname. Since this is nonreentrant, we have to + * Implementation using gethostbyaddr. Since this is nonreentrant, we have to * wrap it in a mutex, losing all benefit of multithreaded resolution. */ -char *do_resolve(struct in_addr *addr) { +char *do_resolve(struct in6_addr *addr) { static pthread_mutex_t ghba_mtx = PTHREAD_MUTEX_INITIALIZER; char *s = NULL; struct hostent *he; + int af; + af = guess_af(addr); + pthread_mutex_lock(&ghba_mtx); - he = gethostbyaddr((char*)addr, sizeof *addr, AF_INET); + he = gethostbyaddr((char*)addr, aflength(af), af); if (he) s = xstrdup(he->h_name); pthread_mutex_unlock(&ghba_mtx); return s; } - #elif defined(USE_LIBRESOLV) #include <arpa/nameser.h> @@ -177,7 +191,7 @@ char *do_resolve(struct in_addr *addr) { * libresolv implementation * resolver functions may not be thread safe */ -char* do_resolve(struct in_addr * addr) { +char* do_resolve(struct in6_addr * addr) { char msg[PACKETSZ]; char s[35]; int l; @@ -242,7 +256,7 @@ static void do_resolve_ares_callback(void *arg, int status, unsigned char *abuf, } } -char *do_resolve(struct in_addr * addr) { +char *do_resolve(struct in6_addr * addr) { struct ares_callback_comm C; char s[35]; unsigned char *a; @@ -299,7 +313,7 @@ char *do_resolve(struct in_addr * addr) { #elif defined(USE_FORKING_RESOLVER) /** - * Resolver which forks a process, then uses gethostbyname. + * Resolver which forks a process, then uses gethostbyaddr. */ #include <signal.h> @@ -323,7 +337,7 @@ int forking_resolver_worker(int fd) { } } -char *do_resolve(struct in_addr *addr) { +char *do_resolve(struct in6_addr *addr) { struct { int fd; pid_t child; @@ -388,7 +402,7 @@ char *do_resolve(struct in_addr *addr) { # warning No name resolution method specified; name resolution will not work -char *do_resolve(struct in_addr *addr) { +char *do_resolve(struct in6_addr *addr) { return NULL; } |