From ba20c3c6e30c3e8201fe1ef1b8efc9e7265cdb7d Mon Sep 17 00:00:00 2001 From: ume Date: Wed, 23 Oct 2002 10:45:09 +0000 Subject: query ip6.arpa then ip6.int for IPv6 reverse lookup. follows RFC3152. Obtained from: KAME MFC after: 1 week --- lib/libc/net/name6.c | 128 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 51 deletions(-) (limited to 'lib/libc/net/name6.c') diff --git a/lib/libc/net/name6.c b/lib/libc/net/name6.c index 3840052..ca4acb3 100644 --- a/lib/libc/net/name6.c +++ b/lib/libc/net/name6.c @@ -1529,6 +1529,7 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap) int af; int *errp; int n; + int err; struct hostent *hp; u_char c, *cp; char *bp; @@ -1540,6 +1541,9 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap) querybuf *buf; char qbuf[MAXDNAME+1]; char *hlist[2]; + char *tld6[] = { "ip6.arpa", "ip6.int", NULL }; + char *tld4[] = { "in-addr.arpa", NULL }; + char **tld; addr = va_arg(ap, const void *); addrlen = va_arg(ap, int); @@ -1554,6 +1558,19 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap) return NS_NOTFOUND; #endif + switch (af) { +#ifdef INET6 + case AF_INET6: + tld = tld6; + break; +#endif + case AF_INET: + tld = tld4; + break; + default: + return NS_NOTFOUND; + } + if ((_res.options & RES_INIT) == 0) { if (res_init() < 0) { *errp = h_errno; @@ -1566,67 +1583,76 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap) hbuf.h_length = addrlen; na = 0; - /* XXX assumes that MAXDNAME is big enough */ - n = 0; - bp = qbuf; - cp = (u_char *)addr+addrlen-1; - switch (af) { -#ifdef INET6 - case AF_INET6: - for (; n < addrlen; n++, cp--) { - c = *cp; - *bp++ = hex[c & 0xf]; - *bp++ = '.'; - *bp++ = hex[c >> 4]; - *bp++ = '.'; - } - strcpy(bp, "ip6.int"); - break; -#endif - default: - for (; n < addrlen; n++, cp--) { - c = *cp; - if (c >= 100) - *bp++ = '0' + c / 100; - if (c >= 10) - *bp++ = '0' + (c % 100) / 10; - *bp++ = '0' + c % 10; - *bp++ = '.'; - } - strcpy(bp, "in-addr.arpa"); - break; - } - buf = malloc(sizeof(*buf)); if (buf == NULL) { *errp = NETDB_INTERNAL; return NS_UNAVAIL; } + err = NS_SUCCESS; + for (/* nothing */; *tld; tld++) { + /* + * XXX assumes that MAXDNAME is big enough - error checks + * has been made by callers + */ + n = 0; + bp = qbuf; + cp = (u_char *)addr+addrlen-1; + switch (af) { +#ifdef INET6 + case AF_INET6: + for (; n < addrlen; n++, cp--) { + c = *cp; + *bp++ = hex[c & 0xf]; + *bp++ = '.'; + *bp++ = hex[c >> 4]; + *bp++ = '.'; + } + strcpy(bp, *tld); + break; +#endif + case AF_INET: + for (; n < addrlen; n++, cp--) { + c = *cp; + if (c >= 100) + *bp++ = '0' + c / 100; + if (c >= 10) + *bp++ = '0' + (c % 100) / 10; + *bp++ = '0' + c % 10; + *bp++ = '.'; + } + strcpy(bp, *tld); + break; + } - n = res_query(qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf); - if (n < 0) { - free(buf); - *errp = h_errno; - return NS_UNAVAIL; - } else if (n > sizeof(buf->buf)) { - free(buf); + n = res_query(qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf); + if (n < 0) { + *errp = h_errno; + err = NS_UNAVAIL; + continue; + } else if (n > sizeof(buf->buf)) { #if 0 - errno = ERANGE; /* XXX is it OK to set errno here? */ + errno = ERANGE; /* XXX is it OK to set errno here? */ #endif - *errp = NETDB_INTERNAL; - return NS_UNAVAIL; + *errp = NETDB_INTERNAL; + err = NS_UNAVAIL; + continue; + } + hp = getanswer(buf, n, qbuf, T_PTR, &hbuf, errp); + if (!hp) { + err = NS_NOTFOUND; + continue; + } + free(buf); + hbuf.h_addrtype = af; + hbuf.h_length = addrlen; + hbuf.h_addr_list = hlist; + hlist[0] = (char *)addr; + hlist[1] = NULL; + *(struct hostent **)rval = _hpcopy(&hbuf, errp); + return NS_SUCCESS; } - hp = getanswer(buf, n, qbuf, T_PTR, &hbuf, errp); free(buf); - if (!hp) - return NS_NOTFOUND; - hbuf.h_addrtype = af; - hbuf.h_length = addrlen; - hbuf.h_addr_list = hlist; - hlist[0] = (char *)addr; - hlist[1] = NULL; - *(struct hostent **)rval = _hpcopy(&hbuf, errp); - return NS_SUCCESS; + return err; } static void -- cgit v1.1