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 af;
int *errp; int *errp;
int n; int n;
int err;
struct hostent *hp; struct hostent *hp;
u_char c, *cp; u_char c, *cp;
char *bp; char *bp;
@ -1540,6 +1541,9 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap)
querybuf *buf; querybuf *buf;
char qbuf[MAXDNAME+1]; char qbuf[MAXDNAME+1];
char *hlist[2]; char *hlist[2];
char *tld6[] = { "ip6.arpa", "ip6.int", NULL };
char *tld4[] = { "in-addr.arpa", NULL };
char **tld;
addr = va_arg(ap, const void *); addr = va_arg(ap, const void *);
addrlen = va_arg(ap, int); addrlen = va_arg(ap, int);
@ -1554,6 +1558,19 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap)
return NS_NOTFOUND; return NS_NOTFOUND;
#endif #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.options & RES_INIT) == 0) {
if (res_init() < 0) { if (res_init() < 0) {
*errp = h_errno; *errp = h_errno;
@ -1566,67 +1583,76 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap)
hbuf.h_length = addrlen; hbuf.h_length = addrlen;
na = 0; 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)); buf = malloc(sizeof(*buf));
if (buf == NULL) { if (buf == NULL) {
*errp = NETDB_INTERNAL; *errp = NETDB_INTERNAL;
return NS_UNAVAIL; return NS_UNAVAIL;
} }
err = NS_SUCCESS;
n = res_query(qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf); for (/* nothing */; *tld; tld++) {
if (n < 0) { /*
free(buf); * XXX assumes that MAXDNAME is big enough - error checks
*errp = h_errno; * has been made by callers
return NS_UNAVAIL; */
} else if (n > sizeof(buf->buf)) { n = 0;
free(buf); bp = qbuf;
#if 0 cp = (u_char *)addr+addrlen-1;
errno = ERANGE; /* XXX is it OK to set errno here? */ 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 #endif
*errp = NETDB_INTERNAL; case AF_INET:
return NS_UNAVAIL; 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); free(buf);
if (!hp) return err;
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;
} }
static void static void