From ee778b56b7de06512c2539184f6a256b4efff848 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 15 Jan 2004 09:46:50 +0000 Subject: Update. 2004-01-15 Ulrich Drepper * resolv/resolv.h: Add RES_USEBSTRING. * resolv/res_debug.c (p_option): Add handling for RES_USE_INET6, RES_ROTATE, RES_NOCHECKNAME, and RES_USEBSTRING. * resolv/res_init.c (res_setioptions): Recognize ip6-bytestring. * resolv/nss_dns/dns-host.c (_nss_dns_gethostbyaddr_r): Only perform bytestring IPv6 lookup with RES_USEBSTRING option is selected. Otherwise use the two nibble formats. --- resolv/nss_dns/dns-host.c | 38 +++++++++++++++++++++++++------------- resolv/res_debug.c | 4 ++++ resolv/res_init.c | 3 +++ resolv/resolv.h | 2 ++ 4 files changed, 34 insertions(+), 13 deletions(-) (limited to 'resolv') 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 , 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) diff --git a/resolv/res_debug.c b/resolv/res_debug.c index 7887dc26a0..bd1fd3388f 100644 --- a/resolv/res_debug.c +++ b/resolv/res_debug.c @@ -572,6 +572,10 @@ p_option(u_long option) { case RES_DNSRCH: return "dnsrch"; case RES_INSECURE1: return "insecure1"; case RES_INSECURE2: return "insecure2"; + case RES_USE_INET6: return "inet6"; + case RES_ROTATE: return "rotate"; + case RES_NOCHECKNAME: return "no-check-names"; + case RES_USEBSTRING: return "ip6-bytstring"; /* XXX nonreentrant */ default: sprintf(nbuf, "?0x%lx?", (u_long)option); return (nbuf); diff --git a/resolv/res_init.c b/resolv/res_init.c index e563dcfb03..cbab7cada5 100644 --- a/resolv/res_init.c +++ b/resolv/res_init.c @@ -489,6 +489,9 @@ res_setoptions(res_state statp, const char *options, const char *source) { #endif } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) { statp->options |= RES_USE_INET6; + } else if (!strncmp(cp, "ip6-bytestring", + sizeof("ip6-bytestring") - 1)) { + statp->options |= RES_USEBSTRING; } else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) { statp->options |= RES_ROTATE; } else if (!strncmp(cp, "no-check-names", diff --git a/resolv/resolv.h b/resolv/resolv.h index e8f384db92..8d37d420e0 100644 --- a/resolv/resolv.h +++ b/resolv/resolv.h @@ -199,6 +199,8 @@ struct res_sym { #define RES_NOCHECKNAME 0x00008000 /* do not check names for sanity. */ #define RES_KEEPTSIG 0x00010000 /* do not strip TSIG records */ #define RES_BLAST 0x00020000 /* blast all recursive servers */ +#define RES_USEBSTRING 0x00040000 /* IPv6 reverse lookup with byte + strings */ #define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) -- cgit v1.2.3