summaryrefslogtreecommitdiffstats
path: root/contrib/bind/lib/irs/nis_ho.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/lib/irs/nis_ho.c')
-rw-r--r--contrib/bind/lib/irs/nis_ho.c107
1 files changed, 87 insertions, 20 deletions
diff --git a/contrib/bind/lib/irs/nis_ho.c b/contrib/bind/lib/irs/nis_ho.c
index 72a8d17..7158f4c 100644
--- a/contrib/bind/lib/irs/nis_ho.c
+++ b/contrib/bind/lib/irs/nis_ho.c
@@ -16,7 +16,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$Id: nis_ho.c,v 1.18 2001/06/18 14:44:00 marka Exp $";
+static const char rcsid[] = "$Id: nis_ho.c,v 1.18.10.1 2003/06/02 05:50:57 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/* Imports */
@@ -87,6 +87,9 @@ static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
static /*const*/ char hosts_byname[] = "hosts.byname";
static /*const*/ char hosts_byaddr[] = "hosts.byaddr";
+static /*const*/ char ipnode_byname[] = "ipnode.byname";
+static /*const*/ char ipnode_byaddr[] = "ipnode.byaddr";
+static /*const*/ char yp_multi[] = "YP_MULTI_";
/* Forwards */
@@ -186,10 +189,33 @@ ho_byname2(struct irs_ho *this, const char *name, int af) {
return (NULL);
nisfree(pvt, do_val);
- DE_CONST(name, tmp);
- r = yp_match(pvt->nis_domain, hosts_byname, tmp,
+
+ strcpy(pvt->hostbuf, yp_multi);
+ strncat(pvt->hostbuf, name, sizeof(pvt->hostbuf) - sizeof(yp_multi));
+ pvt->hostbuf[sizeof(pvt->hostbuf) - 1] = '\0';
+ for (r = sizeof(yp_multi) - 1; pvt->hostbuf[r] != '\0'; r++)
+ if (isupper((unsigned char)pvt->hostbuf[r]))
+ tolower(pvt->hostbuf[r]);
+
+ tmp = pvt->hostbuf;
+ r = yp_match(pvt->nis_domain, ipnode_byname, tmp,
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
if (r != 0) {
+ tmp = pvt->hostbuf + sizeof(yp_multi) - 1;
+ r = yp_match(pvt->nis_domain, ipnode_byname, tmp,
+ strlen(tmp), &pvt->curval_data, &pvt->curval_len);
+ }
+ if (r != 0) {
+ tmp = pvt->hostbuf;
+ r = yp_match(pvt->nis_domain, hosts_byname, tmp,
+ strlen(tmp), &pvt->curval_data, &pvt->curval_len);
+ }
+ if (r != 0) {
+ tmp = pvt->hostbuf + sizeof(yp_multi) - 1;
+ r = yp_match(pvt->nis_domain, hosts_byname, tmp,
+ strlen(tmp), &pvt->curval_data, &pvt->curval_len);
+ }
+ if (r != 0) {
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
return (NULL);
}
@@ -220,8 +246,11 @@ ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
return (NULL);
}
nisfree(pvt, do_val);
- r = yp_match(pvt->nis_domain, hosts_byaddr, tmp, strlen(tmp),
+ r = yp_match(pvt->nis_domain, ipnode_byaddr, tmp, strlen(tmp),
&pvt->curval_data, &pvt->curval_len);
+ if (r != 0)
+ r = yp_match(pvt->nis_domain, hosts_byaddr, tmp, strlen(tmp),
+ &pvt->curval_data, &pvt->curval_len);
if (r != 0) {
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
return (NULL);
@@ -382,12 +411,35 @@ ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
/* Private */
+/*
+ipnodes:
+::1 localhost
+127.0.0.1 localhost
+1.2.3.4 FOO bar
+1.2.6.4 FOO bar
+1.2.6.5 host
+
+ipnodes.byname:
+YP_MULTI_localhost ::1,127.0.0.1 localhost
+YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar
+YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar
+host 1.2.6.5 host
+
+hosts.byname:
+localhost 127.0.0.1 localhost
+host 1.2.6.5 host
+YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar
+YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar
+*/
+
static struct hostent *
makehostent(struct irs_ho *this) {
struct pvt *pvt = (struct pvt *)this->private;
static const char spaces[] = " \t";
- char *cp, **q, *p;
- int af, len;
+ char *cp, **q, *p, *comma, *ap;
+ int af = 0, len = 0;
+ int multi = 0;
+ int addr = 0;
p = pvt->curval_data;
if ((cp = strpbrk(p, "#\n")) != NULL)
@@ -395,25 +447,40 @@ makehostent(struct irs_ho *this) {
if (!(cp = strpbrk(p, spaces)))
return (NULL);
*cp++ = '\0';
- if ((pvt->res->options & RES_USE_INET6) &&
- inet_pton(AF_INET6, p, pvt->host_addr) > 0) {
- af = AF_INET6;
- len = IN6ADDRSZ;
- } else if (inet_pton(AF_INET, p, pvt->host_addr) > 0) {
- if (pvt->res->options & RES_USE_INET6) {
- map_v4v6_address((char*)pvt->host_addr,
- (char*)pvt->host_addr);
+ ap = pvt->hostbuf;
+ do {
+ if ((comma = strchr(p, ',')) != NULL) {
+ *comma++ = '\0';
+ multi = 1;
+ }
+ if ((ap + IN6ADDRSZ) > (pvt->hostbuf + sizeof(pvt->hostbuf)))
+ break;
+ if ((pvt->res->options & RES_USE_INET6) &&
+ inet_pton(AF_INET6, p, ap) > 0) {
af = AF_INET6;
len = IN6ADDRSZ;
+ } else if (inet_pton(AF_INET, p, pvt->host_addr) > 0) {
+ if (pvt->res->options & RES_USE_INET6) {
+ map_v4v6_address((char*)pvt->host_addr, ap);
+ af = AF_INET6;
+ len = IN6ADDRSZ;
+ } else {
+ af = AF_INET;
+ len = INADDRSZ;
+ }
} else {
- af = AF_INET;
- len = INADDRSZ;
+ if (!multi)
+ return (NULL);
+ continue;
+ }
+ if (addr < MAXADDRS) {
+ pvt->h_addr_ptrs[addr++] = ap;
+ pvt->h_addr_ptrs[addr] = NULL;
+ ap += len;
}
- } else {
+ } while ((p = comma) != NULL);
+ if (ap == pvt->hostbuf)
return (NULL);
- }
- pvt->h_addr_ptrs[0] = (char *)pvt->host_addr;
- pvt->h_addr_ptrs[1] = NULL;
pvt->host.h_addr_list = pvt->h_addr_ptrs;
pvt->host.h_length = len;
pvt->host.h_addrtype = af;
OpenPOWER on IntegriCloud