query ip6.arpa then ip6.int for IPv6 reverse lookup. follows RFC3152.

Obtained from:	KAME
MFC after:	1 week
This commit is contained in:
Hajimu UMEMOTO 2002-10-23 10:45:09 +00:00
parent f2c1ea8152
commit aadad92276
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=105783

View File

@ -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;
}
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);
#if 0
errno = ERANGE; /* XXX is it OK to set errno here? */
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
*errp = NETDB_INTERNAL;
return NS_UNAVAIL;
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) {
*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? */
#endif
*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