on gethostby* with NIS backend, make a lookup against ipnodes.{byname,byaddr}

for non-IPv4 address.  obeys solaris8 practice.

XXX does not support scoped address extension, as gethostby* are not
scope-aware.  always use getaddrinfo/getnameinfo.
XXX it is not very useful at this moment, if you define multiple entries for
single hostname.  see PR 10713 for detail.
This commit is contained in:
itojun 2000-07-30 03:01:01 +00:00
parent 31089a149f
commit 698d9a8d8b
1 changed files with 76 additions and 23 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: gethnamaddr.c,v 1.36 2000/07/30 02:44:36 itojun Exp $ */ /* $NetBSD: gethnamaddr.c,v 1.37 2000/07/30 03:01:01 itojun Exp $ */
/* /*
* ++Copyright++ 1985, 1988, 1993 * ++Copyright++ 1985, 1988, 1993
@ -61,7 +61,7 @@
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "Id: gethnamaddr.c,v 8.21 1997/06/01 20:34:37 vixie Exp "; static char rcsid[] = "Id: gethnamaddr.c,v 8.21 1997/06/01 20:34:37 vixie Exp ";
#else #else
__RCSID("$NetBSD: gethnamaddr.c,v 1.36 2000/07/30 02:44:36 itojun Exp $"); __RCSID("$NetBSD: gethnamaddr.c,v 1.37 2000/07/30 03:01:01 itojun Exp $");
#endif #endif
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
@ -1252,28 +1252,38 @@ _yphostent(line, af)
int af; int af;
{ {
static struct in_addr host_addrs[MAXADDRS]; static struct in_addr host_addrs[MAXADDRS];
static struct in6_addr host6_addrs[MAXADDRS];
char *p = line; char *p = line;
char *cp, **q; char *cp, **q;
char **hap; char **hap;
struct in_addr *buf; int addrok;
int more; int more;
int naddrs;
_DIAGASSERT(line != NULL); _DIAGASSERT(line != NULL);
host.h_name = NULL; host.h_name = NULL;
host.h_addr_list = h_addr_ptrs; host.h_addr_list = h_addr_ptrs;
host.h_length = sizeof(u_int32_t); host.h_addrtype = af;
host.h_addrtype = AF_INET; switch (af) {
case AF_INET:
host.h_length = INADDRSZ;
break;
case AF_INET6:
host.h_length = IN6ADDRSZ;
break;
default:
return (NULL);
}
hap = h_addr_ptrs; hap = h_addr_ptrs;
buf = host_addrs;
q = host.h_aliases = host_aliases; q = host.h_aliases = host_aliases;
naddrs = 0;
/*
* XXX: maybe support IPv6 parsing, based on 'af' setting
*/
nextline: nextline:
/* check for host_addrs overflow */ /* check for host_addrs overflow */
if (buf >= &host_addrs[sizeof(host_addrs) / sizeof(host_addrs[0])]) if (naddrs >= sizeof(host_addrs) / sizeof(host_addrs[0]))
goto done;
if (naddrs >= sizeof(host6_addrs) / sizeof(host6_addrs[0]))
goto done; goto done;
more = 0; more = 0;
@ -1282,8 +1292,36 @@ nextline:
goto done; goto done;
*cp++ = '\0'; *cp++ = '\0';
*hap++ = (char *)(void *)buf; /* p has should have an address */
(void) inet_aton(p, buf++); switch (af) {
case AF_INET:
addrok = inet_aton(p, &host_addrs[naddrs]);
break;
case AF_INET6:
addrok = inet_pton(af, p, &host6_addrs[naddrs]);
break;
}
if (addrok != 1) {
/* skip to the next line */
while (cp && *cp) {
if (*cp == '\n') {
cp++;
goto nextline;
}
cp++;
}
goto done;
}
switch (af) {
case AF_INET:
*hap++ = (char *)(void *)&host_addrs[naddrs++];
break;
case AF_INET6:
*hap++ = (char *)(void *)&host6_addrs[naddrs++];
break;
}
while (*cp == ' ' || *cp == '\t') while (*cp == ' ' || *cp == '\t')
cp++; cp++;
@ -1319,6 +1357,7 @@ nextline:
if (cp != NULL) if (cp != NULL)
*cp++ = '\0'; *cp++ = '\0';
} }
done: done:
if (host.h_name == NULL) if (host.h_name == NULL)
return (NULL); return (NULL);
@ -1337,9 +1376,10 @@ _yp_gethtbyaddr(rv, cb_data, ap)
struct hostent *hp = (struct hostent *)NULL; struct hostent *hp = (struct hostent *)NULL;
static char *__ypcurrent; static char *__ypcurrent;
int __ypcurrentlen, r; int __ypcurrentlen, r;
char name[sizeof("xxx.xxx.xxx.xxx") + 1]; char name[INET6_ADDRSTRLEN]; /* XXX enough? */
const unsigned char *uaddr; const unsigned char *uaddr;
int af; int af;
const char *map;
_DIAGASSERT(rv != NULL); _DIAGASSERT(rv != NULL);
@ -1352,19 +1392,23 @@ _yp_gethtbyaddr(rv, cb_data, ap)
return NS_UNAVAIL; return NS_UNAVAIL;
} }
/* /*
* XXX: based on the value of af, it would be possible to lookup * XXX unfortunately, we cannot support IPv6 extended scoped address
* IPv6 names in YP, by changing the following snprintf(). * notation here. gethostbyaddr() is not scope-aware. too bad.
* Is it worth it?
*/ */
(void)snprintf(name, sizeof name, "%u.%u.%u.%u", if (inet_ntop(af, uaddr, name, sizeof(name)) == NULL)
(uaddr[0] & 0xff), return NS_UNAVAIL;
(uaddr[1] & 0xff),
(uaddr[2] & 0xff),
(uaddr[3] & 0xff));
if (__ypcurrent) if (__ypcurrent)
free(__ypcurrent); free(__ypcurrent);
__ypcurrent = NULL; __ypcurrent = NULL;
r = yp_match(__ypdomain, "hosts.byaddr", name, switch (af) {
case AF_INET:
map = "hosts.byaddr";
break;
default:
map = "ipnodes.byaddr";
break;
}
r = yp_match(__ypdomain, map, name,
(int)strlen(name), &__ypcurrent, &__ypcurrentlen); (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
if (r==0) if (r==0)
hp = _yphostent(__ypcurrent, af); hp = _yphostent(__ypcurrent, af);
@ -1388,6 +1432,7 @@ _yp_gethtbyname(rv, cb_data, ap)
int __ypcurrentlen, r; int __ypcurrentlen, r;
const char *name; const char *name;
int af; int af;
const char *map;
_DIAGASSERT(rv != NULL); _DIAGASSERT(rv != NULL);
@ -1402,7 +1447,15 @@ _yp_gethtbyname(rv, cb_data, ap)
if (__ypcurrent) if (__ypcurrent)
free(__ypcurrent); free(__ypcurrent);
__ypcurrent = NULL; __ypcurrent = NULL;
r = yp_match(__ypdomain, "hosts.byname", name, switch (af) {
case AF_INET:
map = "hosts.byname";
break;
default:
map = "ipnodes.byname";
break;
}
r = yp_match(__ypdomain, map, name,
(int)strlen(name), &__ypcurrent, &__ypcurrentlen); (int)strlen(name), &__ypcurrent, &__ypcurrentlen);
if (r==0) if (r==0)
hp = _yphostent(__ypcurrent, af); hp = _yphostent(__ypcurrent, af);