summaryrefslogtreecommitdiff
path: root/resolver.c
diff options
context:
space:
mode:
authorpdw <>2011-10-02 21:41:47 +0000
committerpdw <>2011-10-02 21:41:47 +0000
commit120a1b2c5393fc63e2c9bf81d6adb55a6acd4ed2 (patch)
treea50dc5cf8eb811798d815c928e1fd09ccbd7c4fc /resolver.c
parent3e90c6b54712eb4e361edc31526c058712df7988 (diff)
downloadiftop-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.
Diffstat (limited to 'resolver.c')
-rw-r--r--resolver.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/resolver.c b/resolver.c
index 17aa9fe..3a9d191 100644
--- a/resolver.c
+++ b/resolver.c
@@ -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;
}