Package: bing Version: 1.1.3-1 Tags: patch, ipv6 Hello,
Bing assumes that gethostbyname() returns IPv4 addresses. With "options inet6" in /etc/resolv.conf, or on IPv6-only hosts, this is no longer true and bing will segfault trying to fit a 128 bits address in a 32 bits buffer. The attached patch updates bing to use the modern getaddrinfo/getnameinfo resolver interfaces, which will ensure only AF_INET addresses are returned. Thanks for maintaining bing, -- Jeremie Koenig <j...@jk.fr.eu.org> http://jk.fr.eu.org
diff -ru bing-1.1.3.orig/bing.c bing-1.1.3/bing.c --- bing-1.1.3.orig/bing.c 2009-01-10 00:21:34.000000000 +0100 +++ bing-1.1.3/bing.c 2009-01-10 16:21:30.000000000 +0100 @@ -325,7 +325,6 @@ struct hoststats { /* Host info */ char *hostname; - struct sockaddr_in whereto; struct sockaddr_in *to; struct timestats *ts; }; @@ -368,31 +367,19 @@ struct hoststats *hs; char *target; { - struct hostent *hp; + struct addrinfo hints, *ai; + int r; - hs->to = &hs->whereto; - - memset((char *)hs->to, 0, sizeof(struct sockaddr_in)); - hs->to->sin_family = AF_INET; - hs->to->sin_addr.s_addr = inet_addr(target); - if (hs->to->sin_addr.s_addr != (u_int)-1) - hs->hostname = strdup(target); - else { - hp = gethostbyname(target); - if (!hp) { - (void)fprintf(stderr, - "bing: unknown host %s\n", target); - exit(1); - } - hs->to->sin_family = hp->h_addrtype; - memcpy((caddr_t)&hs->to->sin_addr, hp->h_addr, hp->h_length); - hs->hostname = strdup(hp->h_name); - if(!hs->hostname) { - (void)fprintf(stderr, - "bing: unable to allocate memory\n"); - exit(1); - } + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET; + hints.ai_flags = AI_CANONNAME; + if((r = getaddrinfo(target, NULL, &hints, &ai))) { + fprintf(stderr, "bing: couldn't resolve %s: %s\n", + target, gai_strerror(r)); + exit(1); } + hs->to = (struct sockaddr_in *) ai->ai_addr; + hs->hostname = ai->ai_canonname; } void randomfill(bp, len, seed) @@ -683,18 +670,22 @@ pr_addr(l) u_long l; { - struct hostent *hp; static char buf[MAXHOSTNAMELEN+19]; + struct sockaddr_in sa; + int r; - if ((options & F_NUMERIC) || - !(hp = gethostbyaddr((char *)&l, 4, AF_INET))) - (void)snprintf(snfargs(buf, sizeof(buf), "%s"), - inet_ntoa(*(struct in_addr *)&l)); - else - (void)snprintf(snfargs(buf, sizeof(buf), "%s (%s)"), - hp->h_name, - inet_ntoa(*(struct in_addr *)&l)); - return(buf); + sa.sin_family = AF_INET; + sa.sin_port = 0; + memcpy(&sa.sin_addr, &l, sizeof l); + + r = getnameinfo((struct sockaddr *) &sa, sizeof sa, buf, sizeof buf, + NULL, 0, (options & F_NUMERIC) ? NI_NUMERICHOST : 0); + if(r) { + fprintf(stderr, "bing: getaddrinfo: %s\n", gai_strerror(r)); + exit(1); + } + + return buf; } /*