Esempio n. 1
0
int
gethostent_r(struct hostent* hptr, char* buffer, size_t buflen,
             struct hostent** result, int* h_errnop) {
    struct hostent_data* hed;
    struct hostent he;
    res_state statp;
    statp = __res_state();

    if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
        RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
        *h_errnop = statp->res_h_errno;
        return (-1);
    }

    if ((hed = __hostent_data_init()) == NULL) {
        RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
        *h_errnop = statp->res_h_errno;
        return (-1);
    }

    if (gethostent_p(&he, hed, statp->options & RES_USE_INET6, statp) != 0) {
        return (-1);
    }

    if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
        return (-1);
    }

    *result = hptr;
    return (0);
}
Esempio n. 2
0
int
_ht_gethostbyaddr(void *rval, void *cb_data, va_list ap)
{
	const void *addr;
	socklen_t len;
	int af;
	char *buffer;
	size_t buflen;
	int *errnop, *h_errnop;
	struct hostent *hptr, he;
	struct hostent_data *hed;
	res_state statp;
	int error;

	addr = va_arg(ap, const void *);
	len = va_arg(ap, socklen_t);
	af = va_arg(ap, int);
	hptr = va_arg(ap, struct hostent *);
	buffer = va_arg(ap, char *);
	buflen = va_arg(ap, size_t);
	errnop = va_arg(ap, int *);
	h_errnop = va_arg(ap, int *);

	*((struct hostent **)rval) = NULL;

	statp = __res_state();
	if ((hed = __hostent_data_init()) == NULL) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_NOTFOUND);
	}

	_sethosthtent(0, hed);
	while ((error = gethostent_p(&he, hed, 0, statp)) == 0)
		if (he.h_addrtype == af && !bcmp(he.h_addr, addr, len)) {
			if (he.h_addrtype == AF_INET &&
			    statp->options & RES_USE_INET6) {
				_map_v4v6_address(he.h_addr, he.h_addr);
				he.h_length = IN6ADDRSZ;
				he.h_addrtype = AF_INET6;
			}
			break;
		}
	_endhosthtent(hed);

	if (error != 0)
		return (NS_NOTFOUND);
	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
		*errnop = errno;
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_RETURN);
	}
	*((struct hostent **)rval) = hptr;
	return (NS_SUCCESS);
}
Esempio n. 3
0
static struct netent *
fakeaddr(const char *name, int af, struct net_data *net_data) {
	struct pvt *pvt;
	const char *cp;
	u_long tmp;

	if (af != AF_INET) {
		/* XXX should support IPv6 some day */
		errno = EAFNOSUPPORT;
		RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
		return (NULL);
	}
	if (!isascii((unsigned char)(name[0])) ||
	    !isdigit((unsigned char)(name[0])))
		return (NULL);
	for (cp = name; *cp; ++cp)
		if (!isascii(*cp) || (!isdigit((unsigned char)*cp) && *cp != '.'))
			return (NULL);
	if (*--cp == '.')
		return (NULL);

	/* All-numeric, no dot at the end. */

	tmp = inet_network(name);
	if (tmp == INADDR_NONE) {
		RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
		return (NULL);
	}

	/* Valid network number specified.
	 * Fake up a netent as if we'd actually
	 * done a lookup.
	 */
	freepvt(net_data);
	net_data->nw_data = malloc(sizeof (struct pvt));
	if (!net_data->nw_data) {
		errno = ENOMEM;
		RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
		return (NULL);
	}
	pvt = net_data->nw_data;

	strncpy(pvt->name, name, MAXDNAME);
	pvt->name[MAXDNAME] = '\0';
	pvt->netent.n_name = pvt->name;
	pvt->netent.n_addrtype = AF_INET;
	pvt->netent.n_aliases = pvt->aliases;
	pvt->aliases[0] = NULL;
	pvt->netent.n_net = tmp;

	return (&pvt->netent);
}
Esempio n. 4
0
int
_ht_getnetbyname(void *rval, void *cb_data, va_list ap)
{
	const char *name;
	char *buffer;
	size_t buflen;
	int *errnop, *h_errnop;
	struct netent *nptr, ne;
	struct netent_data *ned;
	char **cp;
	res_state statp;
	int error;

	name = va_arg(ap, const char *);
	nptr = va_arg(ap, struct netent *);
	buffer = va_arg(ap, char *);
	buflen = va_arg(ap, size_t);
	errnop = va_arg(ap, int *);
	h_errnop = va_arg(ap, int *);

	statp = __res_state();
	if ((ned = __netent_data_init()) == NULL) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_UNAVAIL);
	}

	_setnethtent(ned->stayopen, ned);
	while ((error = getnetent_p(&ne, ned)) == 0) {
		if (strcasecmp(ne.n_name, name) == 0)
			break;
		for (cp = ne.n_aliases; *cp != 0; cp++)
			if (strcasecmp(*cp, name) == 0)
				goto found;
	}
found:
	if (!ned->stayopen)
		_endnethtent(ned);
	if (error != 0) {
		*h_errnop = statp->res_h_errno;
		return (NS_NOTFOUND);
	}
	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
		*errnop = errno;
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_RETURN);
	}
	*((struct netent **)rval) = nptr;
	return (NS_SUCCESS);
}
Esempio n. 5
0
int
_nis_gethostbyaddr(void *rval, void *cb_data, va_list ap)
{
#ifdef YP
	const void *addr;
	socklen_t len;
	int af;
	char *buffer;
	size_t buflen;
	int *errnop, *h_errnop;
	struct hostent *hptr, he;
	struct hostent_data *hed;
	res_state statp;

	addr = va_arg(ap, const void *);
	len = va_arg(ap, socklen_t);
	af = va_arg(ap, int);
	hptr = va_arg(ap, struct hostent *);
	buffer = va_arg(ap, char *);
	buflen = va_arg(ap, size_t);
	errnop = va_arg(ap, int *);
	h_errnop = va_arg(ap, int *);

	*((struct hostent **)rval) = NULL;

	statp = __res_state();
	if ((hed = __hostent_data_init()) == NULL) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_NOTFOUND);
	}

	if (_gethostbynisaddr_r(addr, len, af, &he, hed) != 0) {
		*h_errnop = statp->res_h_errno;
		return (NS_NOTFOUND);
	}
	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
		*errnop = errno;
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_RETURN);
	}
	*((struct hostent **)rval) = hptr;
	return (NS_SUCCESS);
#else
	*((struct hostent **)rval) = NULL;
	return (NS_UNAVAIL);
#endif
}
Esempio n. 6
0
struct hostent *
_gethostbynisaddr(const void *addr, socklen_t len, int af)
{
#ifdef YP
	struct hostent *he;
	struct hostent_data *hed;
	u_long oresopt;
	int error;
	res_state statp;

	statp = __res_state();
	if ((he = __hostent_init()) == NULL ||
	    (hed = __hostent_data_init()) == NULL) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		return (NULL);
	}

	oresopt = statp->options;
	statp->options &= ~RES_USE_INET6;
	error = _gethostbynisaddr_r(addr, len, af, he, hed);
	statp->options = oresopt;
	return (error == 0) ? he : NULL;
#else
	return (NULL);
#endif
}
Esempio n. 7
0
int
_ht_getnetbyaddr(void *rval, void *cb_data, va_list ap)
{
	uint32_t net;
	int type;
	char *buffer;
	size_t buflen;
	int *errnop, *h_errnop;
	struct netent *nptr, ne;
	struct netent_data *ned;
	res_state statp;
	int error;

	net = va_arg(ap, uint32_t);
	type = va_arg(ap, int);
	nptr = va_arg(ap, struct netent *);
	buffer = va_arg(ap, char *);
	buflen = va_arg(ap, size_t);
	errnop = va_arg(ap, int *);
	h_errnop = va_arg(ap, int *);

	statp = __res_state();
	if ((ned = __netent_data_init()) == NULL) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_UNAVAIL);
	}

	_setnethtent(ned->stayopen, ned);
	while ((error = getnetent_p(&ne, ned)) == 0)
		if (ne.n_addrtype == type && ne.n_net == net)
			break;
	if (!ned->stayopen)
		_endnethtent(ned);
	if (error != 0) {
		*h_errnop = statp->res_h_errno;
		return (NS_NOTFOUND);
	}
	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
		*errnop = errno;
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_RETURN);
	}
	*((struct netent **)rval) = nptr;
	return (NS_SUCCESS);
}
Esempio n. 8
0
int
_nis_getnetbyname(void *rval, void *cb_data, va_list ap)
{
#ifdef YP
	const char *name;
	char *buffer;
	size_t buflen;
	int *errnop, *h_errnop;
	struct netent *nptr, ne;
	struct netent_data *ned;
	res_state statp;

	name = va_arg(ap, const char *);
	nptr = va_arg(ap, struct netent *);
	buffer = va_arg(ap, char *);
	buflen = va_arg(ap, size_t);
	errnop = va_arg(ap, int *);
	h_errnop = va_arg(ap, int *);

	statp = __res_state();
	if ((ned = __netent_data_init()) == NULL) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_UNAVAIL);
	}

	if (_getnetbynis(name, "networks.byname", AF_INET, &ne, ned) != 0) {
		*h_errnop = statp->res_h_errno;
		return (NS_NOTFOUND);
	}
	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
		*errnop = errno;
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_RETURN);
	}
	*((struct netent **)rval) = nptr;
	return (NS_SUCCESS);
#else
	return (NS_UNAVAIL);
#endif

}
Esempio n. 9
0
int
getnetent_r(struct netent *nptr, char *buffer, size_t buflen,
    struct netent **result, int *h_errnop)
{
	struct netent_data *ned;
	struct netent ne;
	res_state statp;

	statp = __res_state();
	if ((ned = __netent_data_init()) == NULL) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (-1);
	}
	if (getnetent_p(&ne, ned) != 0)
		return (-1);
	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return ((errno != 0) ? errno : -1);
	}
	*result = nptr;
	return (0);
}
Esempio n. 10
0
static struct net_data *
init() {
	struct net_data *net_data;

	if (!(net_data = net_data_init(NULL)))
		goto error;
	if (!net_data->ho) {
		net_data->ho = (*net_data->irs->ho_map)(net_data->irs);
		if (!net_data->ho || !net_data->res) {
  error:
			errno = EIO;
			if (net_data && net_data->res)
				RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
			return (NULL);
		}
	
		(*net_data->ho->res_set)(net_data->ho, net_data->res, NULL);
	}
	
	return (net_data);
}
Esempio n. 11
0
static struct netent *
nw_to_net(struct nwent *nwent, struct net_data *net_data) {
	struct pvt *pvt;
	u_long addr = 0;
	int i;
	int msbyte;

	if (!nwent || nwent->n_addrtype != AF_INET)
		return (NULL);
	freepvt(net_data);
	net_data->nw_data = malloc(sizeof (struct pvt));
	if (!net_data->nw_data) {
		errno = ENOMEM;
		RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
		return (NULL);
	}
	pvt = net_data->nw_data;
	pvt->netent.n_name = nwent->n_name;
	pvt->netent.n_aliases = nwent->n_aliases;
	pvt->netent.n_addrtype = nwent->n_addrtype;

/*
 * What this code does: Converts net addresses from network to host form.
 *
 * msbyte: the index of the most significant byte in the n_addr array.
 *
 * Shift bytes in significant order into addr. When all signicant
 * bytes are in, zero out bits in the LSB that are not part of the network.
 */
	msbyte = nwent->n_length / 8 +
		((nwent->n_length % 8) != 0 ? 1 : 0) - 1;
	for (i = 0; i <= msbyte; i++)
		addr = (addr << 8) | ((unsigned char *)nwent->n_addr)[i];
	i = (32 - nwent->n_length) % 8;
	if (i != 0)
		addr &= ~((1 << (i + 1)) - 1);
	pvt->netent.n_net = addr;
	return (&pvt->netent);
}
Esempio n. 12
0
static int
_getnetbynis(const char *name, char *map, int af, struct netent *ne,
    struct netent_data *ned)
{
	char *p, *bp, *ep;
	char *cp, **q;
	char *result;
	int resultlen, len;
	char ypbuf[YPMAXRECORD + 2];

	switch(af) {
	case AF_INET:
		break;
	default:
	case AF_INET6:
		errno = EAFNOSUPPORT;
		return (-1);
	}

	if (ned->yp_domain == (char *)NULL)
		if (yp_get_default_domain (&ned->yp_domain))
			return (-1);

	if (yp_match(ned->yp_domain, map, name, strlen(name), &result,
	    &resultlen))
		return (-1);

	bcopy((char *)result, (char *)&ypbuf, resultlen);
	ypbuf[resultlen] = '\0';
	free(result);
	result = (char *)&ypbuf;

	if ((cp = index(result, '\n')))
		*cp = '\0';

	cp = strpbrk(result, " \t");
	*cp++ = '\0';
	bp = ned->netbuf;
	ep = ned->netbuf + sizeof ned->netbuf;
	len = strlen(result) + 1;
	if (ep - bp < len) {
		RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
		return (-1);
	}
	strlcpy(bp, result, ep - bp);
	ne->n_name = bp;
	bp += len;

	while (*cp == ' ' || *cp == '\t')
		cp++;

	ne->n_net = inet_network(cp);
	ne->n_addrtype = AF_INET;

	q = ne->n_aliases = ned->net_aliases;
	cp = strpbrk(cp, " \t");
	if (cp != NULL)
		*cp++ = '\0';
	while (cp && *cp) {
		if (*cp == ' ' || *cp == '\t') {
			cp++;
			continue;
		}
		if (q > &ned->net_aliases[_MAXALIASES - 1])
			break;
		p = strpbrk(cp, " \t");
		if (p != NULL)
			*p++ = '\0';
		len = strlen(cp) + 1;
		if (ep - bp < len)
			break;
		strlcpy(bp, cp, ep - bp);
		*q++ = bp;
		bp += len;
		cp = p;
	}
	*q = NULL;
	return (0);
}
Esempio n. 13
0
int
_nis_getnetbyaddr(void *rval, void *cb_data, va_list ap)
{
#ifdef YP
	uint32_t addr;
	int af;
	char *buffer;
	size_t buflen;
	int *errnop, *h_errnop;
	struct netent *nptr, ne;
	struct netent_data *ned;
	char *str, *cp;
	uint32_t net2;
	int nn;
	unsigned int netbr[4];
	char buf[MAXDNAME];
	res_state statp;

	addr = va_arg(ap, uint32_t);
	af = va_arg(ap, int);
	nptr = va_arg(ap, struct netent *);
	buffer = va_arg(ap, char *);
	buflen = va_arg(ap, size_t);
	errnop = va_arg(ap, int *);
	h_errnop = va_arg(ap, int *);

	statp = __res_state();
	if ((ned = __netent_data_init()) == NULL) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_UNAVAIL);
	}

	if (af != AF_INET) {
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		errno = EAFNOSUPPORT;
		return (NS_UNAVAIL);
	}

        for (nn = 4, net2 = addr; net2; net2 >>= 8) {
                netbr[--nn] = net2 & 0xff;
	}

	switch (nn) {
	case 3:		/* Class A */
		sprintf(buf, "%u", netbr[3]);
		break;
        case 2:		/* Class B */
		sprintf(buf, "%u.%u", netbr[2], netbr[3]);
		break;
        case 1:		/* Class C */
		sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]);
                break;
        case 0:		/* Class D - E */
		sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1],
			netbr[2], netbr[3]);
		break;
	}

	str = (char *)&buf;
	cp = str + (strlen(str) - 2);

	while(!strcmp(cp, ".0")) {
		*cp = '\0';
		cp = str + (strlen(str) - 2);
	}

	if (_getnetbynis(str, "networks.byaddr", af, &ne, ned) != 0) {
		*h_errnop = statp->res_h_errno;
		return (NS_NOTFOUND);
	}
	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
		*errnop = errno;
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		*h_errnop = statp->res_h_errno;
		return (NS_RETURN);
	}
	*((struct netent **)rval) = nptr;
	return (NS_SUCCESS);
#else
	return (NS_UNAVAIL);
#endif /* YP */
}
Esempio n. 14
0
int
res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
	ns_updrec *rrecp;
	u_char answer[PACKETSZ];
	u_char *packet;
	struct zonegrp *zptr, tgrp;
	LIST(struct zonegrp) zgrps;
	int nzones = 0, nscount = 0, n;
	union res_sockaddr_union nsaddrs[MAXNS];

	packet = malloc(NS_MAXMSG);
	if (packet == NULL) {
		DPRINTF(("malloc failed"));
		return (0);
	}
	/* Thread all of the updates onto a list of groups. */
	INIT_LIST(zgrps);
	memset(&tgrp, 0, sizeof (tgrp));
	for (rrecp = rrecp_in; rrecp;
	     rrecp = LINKED(rrecp, r_link) ? NEXT(rrecp, r_link) : NULL) {
		int nscnt;
		/* Find the origin for it if there is one. */
		tgrp.z_class = rrecp->r_class;
		nscnt = res_findzonecut2(statp, rrecp->r_dname, tgrp.z_class,
					 RES_EXHAUSTIVE, tgrp.z_origin,
					 sizeof tgrp.z_origin, 
					 tgrp.z_nsaddrs, MAXNS);
		if (nscnt <= 0) {
			DPRINTF(("res_findzonecut failed (%d)", nscnt));
			goto done;
		}
		tgrp.z_nscount = nscnt;
		/* Find the group for it if there is one. */
		for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link))
			if (ns_samename(tgrp.z_origin, zptr->z_origin) == 1 &&
			    tgrp.z_class == zptr->z_class)
				break;
		/* Make a group for it if there isn't one. */
		if (zptr == NULL) {
			zptr = malloc(sizeof *zptr);
			if (zptr == NULL) {
				DPRINTF(("malloc failed"));
				goto done;
			}
			*zptr = tgrp;
			zptr->z_flags = 0;
			INIT_LINK(zptr, z_link);
			INIT_LIST(zptr->z_rrlist);
			APPEND(zgrps, zptr, z_link);
		}
		/* Thread this rrecp onto the right group. */
		APPEND(zptr->z_rrlist, rrecp, r_glink);
	}

	for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link)) {
		/* Construct zone section and prepend it. */
		rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin,
				     zptr->z_class, ns_t_soa, 0);
		if (rrecp == NULL) {
			DPRINTF(("res_mkupdrec failed"));
			goto done;
		}
		PREPEND(zptr->z_rrlist, rrecp, r_glink);
		zptr->z_flags |= ZG_F_ZONESECTADDED;

		/* Marshall the update message. */
		n = res_nmkupdate(statp, HEAD(zptr->z_rrlist),
				  packet, NS_MAXMSG);
		DPRINTF(("res_mkupdate -> %d", n));
		if (n < 0)
			goto done;

		/* Temporarily replace the resolver's nameserver set. */
		nscount = res_getservers(statp, nsaddrs, MAXNS);
		res_setservers(statp, zptr->z_nsaddrs, zptr->z_nscount);

		/* Send the update and remember the result. */
		if (key != NULL) {
#ifdef _LIBC
			DPRINTF(("TSIG is not supported\n"));
			RES_SET_H_ERRNO(statp, NO_RECOVERY);
			goto done;
#else
			n = res_nsendsigned(statp, packet, n, key,
					    answer, sizeof answer);
#endif
		} else
			n = res_nsend(statp, packet, n, answer, sizeof answer);
		if (n < 0) {
			DPRINTF(("res_nsend: send error, n=%d (%s)\n",
				 n, strerror(errno)));
			goto done;
		}
		if (((HEADER *)answer)->rcode == NOERROR)
			nzones++;

		/* Restore resolver's nameserver set. */
		res_setservers(statp, nsaddrs, nscount);
		nscount = 0;
	}
 done:
	while (!EMPTY(zgrps)) {
		zptr = HEAD(zgrps);
		if ((zptr->z_flags & ZG_F_ZONESECTADDED) != 0)
			res_freeupdrec(HEAD(zptr->z_rrlist));
		UNLINK(zgrps, zptr, z_link);
		free(zptr);
	}
	if (nscount != 0)
		res_setservers(statp, nsaddrs, nscount);

	free(packet);
	return (nzones);
}
Esempio n. 15
0
static int
getnetent_p(struct netent *ne, struct netent_data *ned)
{
	char *p, *bp, *ep;
	char *cp, **q;
	int len;
	char line[BUFSIZ + 1];

	if (ned->netf == NULL &&
	    (ned->netf = fopen(_PATH_NETWORKS, "r")) == NULL)
		return (-1);
again:
	p = fgets(line, sizeof line, ned->netf);
	if (p == NULL)
		return (-1);
	if (*p == '#')
		goto again;
	cp = strpbrk(p, "#\n");
	if (cp != NULL)
		*cp = '\0';
	bp = ned->netbuf;
	ep = ned->netbuf + sizeof ned->netbuf;
	ne->n_name = bp;
	cp = strpbrk(p, " \t");
	if (cp == NULL)
		goto again;
	*cp++ = '\0';
	len = strlen(p) + 1;
	if (ep - bp < len) {
		RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
		return (-1);
	}
	strlcpy(bp, p, ep - bp);
	bp += len;
	while (*cp == ' ' || *cp == '\t')
		cp++;
	p = strpbrk(cp, " \t");
	if (p != NULL)
		*p++ = '\0';
	ne->n_net = inet_network(cp);
	ne->n_addrtype = AF_INET;
	q = ne->n_aliases = ned->net_aliases;
	if (p != NULL) {
		cp = p;
		while (cp && *cp) {
			if (*cp == ' ' || *cp == '\t') {
				cp++;
				continue;
			}
			if (q >= &ned->net_aliases[_MAXALIASES - 1])
				break;
			p = strpbrk(cp, " \t");
			if (p != NULL)
				*p++ = '\0';
			len = strlen(cp) + 1;
			if (ep - bp < len)
				break;
			strlcpy(bp, cp, ep - bp);
			*q++ = bp;
			bp += len;
			cp = p;
		}
	}
	*q = NULL;
	return (0);
}
Esempio n. 16
0
static int
gethostent_p(struct hostent* he, struct hostent_data* hed, int mapped,
             res_state statp) {
    char* p, *bp, *ep;
    char* cp, **q;
    int af, len;
    char hostbuf[BUFSIZ + 1];

    if (!hed->hostf && !(hed->hostf = fopen(_PATH_HOSTS, "r"))) {
        RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
        return (-1);
    }

again:

    if (!(p = fgets(hostbuf, sizeof hostbuf, hed->hostf))) {
        RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
        return (-1);
    }

    if (*p == '#') {
        goto again;
    }

    cp = strpbrk(p, "#\n");

    if (cp != NULL) {
        *cp = '\0';
    }

    if (!(cp = strpbrk(p, " \t"))) {
        goto again;
    }

    *cp++ = '\0';

    if (inet_pton(AF_INET6, p, hed->host_addr) > 0) {
        af = AF_INET6;
        len = IN6ADDRSZ;
    } else if (inet_pton(AF_INET, p, hed->host_addr) > 0) {
        if (mapped) {
            _map_v4v6_address((char*)hed->host_addr,
                              (char*)hed->host_addr);
            af = AF_INET6;
            len = IN6ADDRSZ;
        } else {
            af = AF_INET;
            len = INADDRSZ;
        }
    } else {
        goto again;
    }

    hed->h_addr_ptrs[0] = (char*)hed->host_addr;
    hed->h_addr_ptrs[1] = NULL;
    he->h_addr_list = hed->h_addr_ptrs;
    he->h_length = len;
    he->h_addrtype = af;

    while (*cp == ' ' || *cp == '\t') {
        cp++;
    }

    bp = hed->hostbuf;
    ep = hed->hostbuf + sizeof hed->hostbuf;
    he->h_name = bp;
    q = he->h_aliases = hed->host_aliases;

    if ((p = strpbrk(cp, " \t")) != NULL) {
        *p++ = '\0';
    }

    len = strlen(cp) + 1;

    if (ep - bp < len) {
        RES_SET_H_ERRNO(statp, NO_RECOVERY);
        return (-1);
    }

    strlcpy(bp, cp, ep - bp);
    bp += len;
    cp = p;

    while (cp && *cp) {
        if (*cp == ' ' || *cp == '\t') {
            cp++;
            continue;
        }

        if (q >= &hed->host_aliases[_MAXALIASES - 1]) {
            break;
        }

        if ((p = strpbrk(cp, " \t")) != NULL) {
            *p++ = '\0';
        }

        len = strlen(cp) + 1;

        if (ep - bp < len) {
            break;
        }

        strlcpy(bp, cp, ep - bp);
        *q++ = bp;
        bp += len;
        cp = p;
    }

    *q = NULL;
    RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
    return (0);
}
Esempio n. 17
0
int
_ht_gethostbyname(void* rval, void* cb_data, va_list ap) {
    const char* name;
    int af;
    char* buffer;
    size_t buflen;
    int* errnop, *h_errnop;
    struct hostent* hptr, he;
    struct hostent_data* hed;
    char** cp;
    res_state statp;
    int error;
    name = va_arg(ap, const char*);
    af = va_arg(ap, int);
    hptr = va_arg(ap, struct hostent*);
    buffer = va_arg(ap, char*);
    buflen = va_arg(ap, size_t);
    errnop = va_arg(ap, int*);
    h_errnop = va_arg(ap, int*);
    *((struct hostent**)rval) = NULL;
    statp = __res_state();

    if ((hed = __hostent_data_init()) == NULL) {
        RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
        *h_errnop = statp->res_h_errno;
        return (NS_NOTFOUND);
    }

    _sethosthtent(0, hed);

    while ((error = gethostent_p(&he, hed, 0, statp)) == 0) {
        if (he.h_addrtype != af) {
            continue;
        }

        if (he.h_addrtype == AF_INET &&
                statp->options & RES_USE_INET6) {
            _map_v4v6_address(he.h_addr, he.h_addr);
            he.h_length = IN6ADDRSZ;
            he.h_addrtype = AF_INET6;
        }

        if (strcasecmp(he.h_name, name) == 0) {
            break;
        }

        for (cp = he.h_aliases; *cp != 0; cp++)
            if (strcasecmp(*cp, name) == 0) {
                goto found;
            }
    }

found:
    _endhosthtent(hed);

    if (error != 0) {
        *h_errnop = statp->res_h_errno;
        return (NS_NOTFOUND);
    }

    if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
        *h_errnop = statp->res_h_errno;
        return (NS_NOTFOUND);
    }

    *((struct hostent**)rval) = hptr;
    return (NS_SUCCESS);
}
Esempio n. 18
0
/*% This function has to be reachable by res_data.c but not publically. */
int
__res_vinit(res_state statp, int preinit) {
	register FILE *fp;
	register char *cp, **pp;
	register int n;
	char path[PATH_MAX];
	char buf[BUFSIZ];
	int nserv = 0;    /*%< number of nameserver records read from file */
	int haveenv = 0;
	int havesearch = 0;
#ifdef RESOLVSORT
	int nsort = 0;
	char *net;
#endif
	int dots;
	union res_sockaddr_union u[2];
	int maxns = MAXNS;

	RES_SET_H_ERRNO(statp, 0);
	if (statp->_u._ext.ext != NULL)
		res_ndestroy(statp);

	if (!preinit) {
		statp->retrans = RES_TIMEOUT;
		statp->retry = RES_DFLRETRY;
		statp->options = RES_DEFAULT;
		res_rndinit(statp);
		statp->id = res_nrandomid(statp);
	}

	memset(u, 0, sizeof(u));
#ifdef USELOOPBACK
	u[nserv].sin.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
#else
	u[nserv].sin.sin_addr.s_addr = INADDR_ANY;
#endif
	u[nserv].sin.sin_family = AF_INET;
	u[nserv].sin.sin_port = htons(NAMESERVER_PORT);
#ifdef HAVE_SA_LEN
	u[nserv].sin.sin_len = sizeof(struct sockaddr_in);
#endif
	nserv++;
#ifdef HAS_INET6_STRUCTS
#ifdef USELOOPBACK
	u[nserv].sin6.sin6_addr = in6addr_loopback;
#else
	u[nserv].sin6.sin6_addr = in6addr_any;
#endif
	u[nserv].sin6.sin6_family = AF_INET6;
	u[nserv].sin6.sin6_port = htons(NAMESERVER_PORT);
#ifdef HAVE_SA_LEN
	u[nserv].sin6.sin6_len = sizeof(struct sockaddr_in6);
#endif
	nserv++;
#endif
	statp->nscount = 0;
	statp->ndots = 1;
	statp->pfcode = 0;
	statp->_vcsock = -1;
	statp->_flags = 0;
	statp->qhook = NULL;
	statp->rhook = NULL;
	statp->_u._ext.nscount = 0;
	statp->_u._ext.ext = malloc(sizeof(*statp->_u._ext.ext));
	if (statp->_u._ext.ext != NULL) {
	        memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext));
		statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
		strcpy(statp->_u._ext.ext->nsuffix, "ip6.arpa");
		strcpy(statp->_u._ext.ext->nsuffix2, "ip6.int");
	} else {
		/*
		 * Historically res_init() rarely, if at all, failed.
		 * Examples and applications exist which do not check
		 * our return code.  Furthermore several applications
		 * simply call us to get the systems domainname.  So
		 * rather then immediately fail here we store the
		 * failure, which is returned later, in h_errno.  And
		 * prevent the collection of 'nameserver' information
		 * by setting maxns to 0.  Thus applications that fail
		 * to check our return code wont be able to make
		 * queries anyhow.
		 */
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		maxns = 0;
	}
#ifdef RESOLVSORT
	statp->nsort = 0;
#endif
	res_setservers(statp, u, nserv);

#ifdef	SOLARIS2
	/*
	 * The old libresolv derived the defaultdomain from NIS/NIS+.
	 * We want to keep this behaviour
	 */
	{
		char buf[sizeof(statp->defdname)], *cp;
		int ret;

		if ((ret = sysinfo(SI_SRPC_DOMAIN, buf, sizeof(buf))) > 0 &&
			(unsigned int)ret <= sizeof(buf)) {
			if (buf[0] == '+')
				buf[0] = '.';
			cp = strchr(buf, '.');
			cp = (cp == NULL) ? buf : (cp + 1);
			strncpy(statp->defdname, cp,
				sizeof(statp->defdname) - 1);
			statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		}
	}
#endif	/* SOLARIS2 */

	/* Allow user to override the local domain definition */
	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
		(void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
		statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		haveenv++;

		/*
		 * Set search list to be blank-separated strings
		 * from rest of env value.  Permits users of LOCALDOMAIN
		 * to still have a search list, and anyone to set the
		 * one that they want to use as an individual (even more
		 * important now that the rfc1535 stuff restricts searches)
		 */
		cp = statp->defdname;
		pp = statp->dnsrch;
		*pp++ = cp;
		for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
			if (*cp == '\n')	/*%< silly backwards compat */
				break;
			else if (*cp == ' ' || *cp == '\t') {
				*cp = 0;
				n = 1;
			} else if (n) {
				*pp++ = cp;
				n = 0;
				havesearch = 1;
			}
		}
		/* null terminate last domain if there are excess */
		while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
			cp++;
		*cp = '\0';
		*pp++ = 0;
	}

#define	MATCH(line, name) \
	(!strncmp(line, name, sizeof(name) - 1) && \
	(line[sizeof(name) - 1] == ' ' || \
	 line[sizeof(name) - 1] == '\t'))

	if (find_directory(B_COMMON_SETTINGS_DIRECTORY, -1, false, path,
			sizeof(path)) == B_OK)
		strlcat(path, "/network/resolv.conf", sizeof(path));

	nserv = 0;
	if ((fp = fopen(path, "r")) != NULL) {
	    /* read the config file */
	    while (fgets(buf, sizeof(buf), fp) != NULL) {
		/* skip comments */
		if (*buf == ';' || *buf == '#')
			continue;
		/* read default domain name */
		if (MATCH(buf, "domain")) {
		    if (haveenv)	/*%< skip if have from environ */
			    continue;
		    cp = buf + sizeof("domain") - 1;
		    while (*cp == ' ' || *cp == '\t')
			    cp++;
		    if ((*cp == '\0') || (*cp == '\n'))
			    continue;
		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		    if ((cp = strpbrk(statp->defdname, " \t\n")) != NULL)
			    *cp = '\0';
		    havesearch = 0;
		    continue;
		}
		/* set search list */
		if (MATCH(buf, "search")) {
		    if (haveenv)	/*%< skip if have from environ */
			    continue;
		    cp = buf + sizeof("search") - 1;
		    while (*cp == ' ' || *cp == '\t')
			    cp++;
		    if ((*cp == '\0') || (*cp == '\n'))
			    continue;
		    strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1);
		    statp->defdname[sizeof(statp->defdname) - 1] = '\0';
		    if ((cp = strchr(statp->defdname, '\n')) != NULL)
			    *cp = '\0';
		    /*
		     * Set search list to be blank-separated strings
		     * on rest of line.
		     */
		    cp = statp->defdname;
		    pp = statp->dnsrch;
		    *pp++ = cp;
		    for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) {
			    if (*cp == ' ' || *cp == '\t') {
				    *cp = 0;
				    n = 1;
			    } else if (n) {
				    *pp++ = cp;
				    n = 0;
			    }
		    }
		    /* null terminate last domain if there are excess */
		    while (*cp != '\0' && *cp != ' ' && *cp != '\t')
			    cp++;
		    *cp = '\0';
		    *pp++ = 0;
		    havesearch = 1;
		    continue;
		}
		/* read nameservers to query */
		if (MATCH(buf, "nameserver") && nserv < maxns) {
		    struct addrinfo hints, *ai;
		    char sbuf[NI_MAXSERV];
		    const size_t minsiz =
		        sizeof(statp->_u._ext.ext->nsaddrs[0]);

		    cp = buf + sizeof("nameserver") - 1;
		    while (*cp == ' ' || *cp == '\t')
			cp++;
		    cp[strcspn(cp, ";# \t\n")] = '\0';
		    if ((*cp != '\0') && (*cp != '\n')) {
			memset(&hints, 0, sizeof(hints));
			hints.ai_family = PF_UNSPEC;
			hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
			hints.ai_flags = AI_NUMERICHOST;
			sprintf(sbuf, "%u", NAMESERVER_PORT);
			if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
			    ai->ai_addrlen <= minsiz) {
			    if (statp->_u._ext.ext != NULL) {
				memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
				    ai->ai_addr, ai->ai_addrlen);
			    }
			    if (ai->ai_addrlen <=
			        sizeof(statp->nsaddr_list[nserv])) {
				memcpy(&statp->nsaddr_list[nserv],
				    ai->ai_addr, ai->ai_addrlen);
			    } else
				statp->nsaddr_list[nserv].sin_family = 0;
			    freeaddrinfo(ai);
			    nserv++;
			}
		    }
		    continue;
		}
#ifdef RESOLVSORT
		if (MATCH(buf, "sortlist")) {
		    struct in_addr a;

		    cp = buf + sizeof("sortlist") - 1;
		    while (nsort < MAXRESOLVSORT) {
			while (*cp == ' ' || *cp == '\t')
			    cp++;
			if (*cp == '\0' || *cp == '\n' || *cp == ';')
			    break;
			net = cp;
			while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
			       isascii(*cp) && !isspace((unsigned char)*cp))
				cp++;
			n = *cp;
			*cp = 0;
			if (inet_aton(net, &a)) {
			    statp->sort_list[nsort].addr = a;
			    if (ISSORTMASK(n)) {
				*cp++ = n;
				net = cp;
				while (*cp && *cp != ';' &&
					isascii(*cp) &&
					!isspace((unsigned char)*cp))
				    cp++;
				n = *cp;
				*cp = 0;
				if (inet_aton(net, &a)) {
				    statp->sort_list[nsort].mask = a.s_addr;
				} else {
				    statp->sort_list[nsort].mask = 
					net_mask(statp->sort_list[nsort].addr);
				}
			    } else {
				statp->sort_list[nsort].mask = 
				    net_mask(statp->sort_list[nsort].addr);
			    }
			    nsort++;
			}
			*cp = n;
		    }
		    continue;
		}
#endif
		if (MATCH(buf, "options")) {
		    res_setoptions(statp, buf + sizeof("options") - 1, "conf");
		    continue;
		}
	    }
	    if (nserv > 0) 
		statp->nscount = nserv;
#ifdef RESOLVSORT
	    statp->nsort = nsort;
#endif
	    (void) fclose(fp);
	}
/*
 * Last chance to get a nameserver.  This should not normally
 * be necessary
 */
#ifdef NO_RESOLV_CONF
	if(nserv == 0)
		nserv = get_nameservers(statp);
#endif

	if (statp->defdname[0] == 0 &&
	    gethostname(buf, sizeof(statp->defdname) - 1) == 0 &&
	    (cp = strchr(buf, '.')) != NULL)
		strcpy(statp->defdname, cp + 1);

	/* find components of local domain that might be searched */
	if (havesearch == 0) {
		pp = statp->dnsrch;
		*pp++ = statp->defdname;
		*pp = NULL;

		dots = 0;
		for (cp = statp->defdname; *cp; cp++)
			dots += (*cp == '.');

		cp = statp->defdname;
		while (pp < statp->dnsrch + MAXDFLSRCH) {
			if (dots < LOCALDOMAINPARTS)
				break;
			cp = strchr(cp, '.') + 1;    /*%< we know there is one */
			*pp++ = cp;
			dots--;
		}
		*pp = NULL;
#ifdef DEBUG
		if (statp->options & RES_DEBUG) {
			printf(";; res_init()... default dnsrch list:\n");
			for (pp = statp->dnsrch; *pp; pp++)
				printf(";;\t%s\n", *pp);
			printf(";;\t..END..\n");
		}
#endif
	}

	if ((cp = getenv("RES_OPTIONS")) != NULL)
		res_setoptions(statp, cp, "env");
	statp->options |= RES_INIT;
	return (statp->res_h_errno);
}
Esempio n. 19
0
static int
_gethostbynis(const char *name, char *map, int af, struct hostent *he,
    struct hostent_data *hed)
{
	char *p, *bp, *ep;
	char *cp, **q;
	char *result;
	int resultlen, size, addrok = 0;
	char ypbuf[YPMAXRECORD + 2];
	res_state statp;

	statp = __res_state();
	switch(af) {
	case AF_INET:
		size = NS_INADDRSZ;
		break;
	case AF_INET6:
		size = NS_IN6ADDRSZ;
		break;
	default:
		errno = EAFNOSUPPORT;
		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
		return (-1);
	}

	if (hed->yp_domain == (char *)NULL)
		if (yp_get_default_domain (&hed->yp_domain)) {
			RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
			return (-1);
		}

	if (yp_match(hed->yp_domain, map, name, strlen(name), &result,
	    &resultlen)) {
		RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
		return (-1);
	}

	/* avoid potential memory leak */
	bcopy((char *)result, (char *)&ypbuf, resultlen);
	ypbuf[resultlen] = '\0';
	free(result);
	result = (char *)&ypbuf;

	if ((cp = strchr(result, '\n')))
		*cp = '\0';

	cp = strpbrk(result, " \t");
	*cp++ = '\0';
	he->h_addr_list = hed->h_addr_ptrs;
	he->h_addr = (char *)hed->host_addr;
	switch (af) {
	case AF_INET:
		addrok = inet_aton(result, (struct in_addr *)hed->host_addr);
		if (addrok != 1)
			break;
		if (statp->options & RES_USE_INET6) {
			_map_v4v6_address((char *)hed->host_addr,
			    (char *)hed->host_addr);
			af = AF_INET6;
			size = NS_IN6ADDRSZ;
		}
		break;
	case AF_INET6:
		addrok = inet_pton(af, result, hed->host_addr);
		break;
	}
	if (addrok != 1) {
		RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
		return (-1);
	}
	he->h_addr_list[1] = NULL;
	he->h_length = size;
	he->h_addrtype = af;
	while (*cp == ' ' || *cp == '\t')
		cp++;
	bp = hed->hostbuf;
	ep = hed->hostbuf + sizeof hed->hostbuf;
	he->h_name = bp;
	q = he->h_aliases = hed->host_aliases;
	p = strpbrk(cp, " \t");
	if (p != NULL)
		*p++ = '\0';
	size = strlen(cp) + 1;
	if (ep - bp < size) {
		RES_SET_H_ERRNO(statp, NO_RECOVERY);
		return (-1);
	}
	strlcpy(bp, cp, ep - bp);
	bp += size;
	cp = p;
	while (cp && *cp) {
		if (*cp == ' ' || *cp == '\t') {
			cp++;
			continue;
		}
		if (q >= &hed->host_aliases[_MAXALIASES - 1])
			break;
		p = strpbrk(cp, " \t");
		if (p != NULL)
			*p++ = '\0';
		size = strlen(cp) + 1;
		if (ep - bp < size)
			break;
		strlcpy(bp, cp, ep - bp);
		*q++ = bp;
		bp += size;
		cp = p;
	}
	*q = NULL;
	return (0);
}
Esempio n. 20
0
static struct hostent *
fakeaddr(const char *name, int af, struct net_data *net_data) {
	struct pvt *pvt;

	freepvt(net_data);
	net_data->ho_data = malloc(sizeof (struct pvt));
	if (!net_data->ho_data) {
		errno = ENOMEM;
		RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
		return (NULL);
	}
	pvt = net_data->ho_data;
#ifndef __bsdi__
	/*
	 * Unlike its forebear(inet_aton), our friendly inet_pton() is strict
	 * in its interpretation of its input, and it will only return "1" if
	 * the input string is a formally valid(and thus unambiguous with
	 * respect to host names) internet address specification for this AF.
	 *
	 * This means "telnet 0xdeadbeef" and "telnet 127.1" are dead now.
	 */
	if (inet_pton(af, name, pvt->addr) != 1) {
#else
	/* BSDI XXX
	 * We put this back to inet_aton -- we really want the old behavior
	 * Long live 127.1...
	 */
	if ((af != AF_INET ||
	    inet_aton(name, (struct in_addr *)pvt->addr) != 1) &&
	    inet_pton(af, name, pvt->addr) != 1) {
#endif
		RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
		return (NULL);
	}
	strncpy(pvt->name, name, NS_MAXDNAME);
	pvt->name[NS_MAXDNAME] = '\0';
	if (af == AF_INET && (net_data->res->options & RES_USE_INET6) != 0U) {
		map_v4v6_address(pvt->addr, pvt->addr);
		af = AF_INET6;
	}
	pvt->host.h_addrtype = af;
	switch(af) {
	case AF_INET:
		pvt->host.h_length = NS_INADDRSZ;
		break;
	case AF_INET6:
		pvt->host.h_length = NS_IN6ADDRSZ;
		break;
	default:
		errno = EAFNOSUPPORT;
		RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
		return (NULL);
	}
	pvt->host.h_name = pvt->name;
	pvt->host.h_aliases = pvt->aliases;
	pvt->aliases[0] = NULL;
	pvt->addrs[0] = (char *)pvt->addr;
	pvt->addrs[1] = NULL;
	pvt->host.h_addr_list = pvt->addrs;
	RES_SET_H_ERRNO(net_data->res, NETDB_SUCCESS);
	return (&pvt->host);
}

#ifdef grot	/*%< for future use in gethostbyaddr(), for "SUNSECURITY" */
	struct hostent *rhp;
	char **haddr;
	u_long old_options;
	char hname2[MAXDNAME+1];

	if (af == AF_INET) {
	    /*
	     * turn off search as the name should be absolute,
	     * 'localhost' should be matched by defnames
	     */
	    strncpy(hname2, hp->h_name, MAXDNAME);
	    hname2[MAXDNAME] = '\0';
	    old_options = net_data->res->options;
	    net_data->res->options &= ~RES_DNSRCH;
	    net_data->res->options |= RES_DEFNAMES;
	    if (!(rhp = gethostbyname(hname2))) {
		net_data->res->options = old_options;
		RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
		return (NULL);
	    }
	    net_data->res->options = old_options;
	    for (haddr = rhp->h_addr_list; *haddr; haddr++)
		if (!memcmp(*haddr, addr, INADDRSZ))
			break;
	    if (!*haddr) {
		RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
		return (NULL);
	    }
	}