summary refs log tree commit diff
path: root/resolv/nss_dns/dns-host.c
diff options
context:
space:
mode:
Diffstat (limited to 'resolv/nss_dns/dns-host.c')
-rw-r--r--resolv/nss_dns/dns-host.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index bde45ca873..ab6cc792b8 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -298,6 +298,8 @@ _nss_dns_gethostbyaddr_r (const void *addr, socklen_t len, int af,
       return NSS_STATUS_UNAVAIL;
     }
 
+  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
+
   switch (af)
     {
     case AF_INET:
@@ -305,29 +307,38 @@ _nss_dns_gethostbyaddr_r (const void *addr, socklen_t len, int af,
 	       (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff));
       break;
     case AF_INET6:
-      /* XXX Maybe we need an option to select whether to use the nibble
-	 or the bitfield form.  The RFC requires the bitfield form so
-	 we use it.  */
+      /* Only lookup with the byte string format if the user wants it.  */
+      if (__builtin_expect (_res.options & RES_USEBSTRING, 0))
+	{
+	  qp = stpcpy (qbuf, "\\[x");
+	  for (n = 0; n < IN6ADDRSZ; ++n)
+	    qp += sprintf (qp, "%02hhx", uaddr[n]);
+	  strcpy (qp, "].ip6.arpa");
+	  n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
+				 host_buffer.buf->buf, 1024, &host_buffer.ptr);
+	  if (n >= 0)
+	    goto got_it_already;
+	}
       qp = qbuf;
-      qp = stpcpy (qbuf, "\\[x");
-      for (n = 0; n < IN6ADDRSZ; ++n)
-	qp += sprintf (qp, "%02hhx", uaddr[n]);
-      strcpy (qp, "].ip6.arpa");
+      for (n = IN6ADDRSZ - 1; n >= 0; n--)
+	{
+	  static const char nibblechar[16] = "0123456789abcdef";
+	  *qp++ = nibblechar[uaddr[n] & 0xf];
+	  *qp++ = '.';
+	  *qp++ = nibblechar[(uaddr[n] >> 4) & 0xf];
+	  *qp++ = '.';
+	}
+      strcpy(qp, "ip6.arpa");
       break;
     default:
       /* Cannot happen.  */
       break;
     }
 
-  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
-
   n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
 			 1024, &host_buffer.ptr);
   if (n < 0 && af == AF_INET6)
     {
-      qp = qbuf;
-      for (n = IN6ADDRSZ - 1; n >= 0; n--)
-	qp += sprintf (qp, "%x.%x.", uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf);
       strcpy (qp, "ip6.int");
       n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
 			     host_buffer.buf != orig_host_buffer
@@ -342,6 +353,7 @@ _nss_dns_gethostbyaddr_r (const void *addr, socklen_t len, int af,
       return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
     }
 
+ got_it_already:
   status = getanswer_r (host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen,
 			errnop, h_errnop, 0 /* XXX */);
   if (host_buffer.buf != orig_host_buffer)