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;
 }
 
 /*

Reply via email to