Пример #1
0
struct hostent *
gethostent_r(FILE *hf, struct hostent *hent, char *buf, size_t buflen, int *he)
{
	char *p, *name;
	char *cp, **q;
	int af, len;
	size_t llen, anum;
	char *aliases[MAXALIASES];
	struct in6_addr host_addr;

	if (hf == NULL) {
		*he = NETDB_INTERNAL;
		errno = EINVAL;
		return NULL;
	}
 again:
	if ((p = fgetln(hf, &llen)) == NULL) {
		*he = HOST_NOT_FOUND;
		return NULL;
	}
	if (llen < 1)
		goto again;
	if (*p == '#')
		goto again;
	p[llen] = '\0';
	if (!(cp = strpbrk(p, "#\n")))
		goto again;
	*cp = '\0';
	if (!(cp = strpbrk(p, " \t")))
		goto again;
	*cp++ = '\0';
	if (inet_pton(AF_INET6, p, &host_addr) > 0) {
		af = AF_INET6;
		len = NS_IN6ADDRSZ;
	} else if (inet_pton(AF_INET, p, &host_addr) > 0) {
#if 0
		res_state res = __res_get_state();
		if (res == NULL)
			return NULL;
		if (res->options & RES_USE_INET6) {
			map_v4v6_address(buf, buf);
			af = AF_INET6;
			len = NS_IN6ADDRSZ;
		} else {
#endif
			af = AF_INET;
			len = NS_INADDRSZ;
#if 0
		}
		__res_put_state(res);
#endif
	} else {
		goto again;
	}
	/* if this is not something we're looking for, skip it. */
	if (hent->h_addrtype != 0 && hent->h_addrtype != af)
		goto again;
	if (hent->h_length != 0 && hent->h_length != len)
		goto again;

	while (*cp == ' ' || *cp == '\t')
		cp++;
	if ((cp = strpbrk(name = cp, " \t")) != NULL)
		*cp++ = '\0';
	q = aliases;
	while (cp && *cp) {
		if (*cp == ' ' || *cp == '\t') {
			cp++;
			continue;
		}
		if (q >= &aliases[__arraycount(aliases)])
			goto nospc;
		*q++ = cp;
		if ((cp = strpbrk(cp, " \t")) != NULL)
			*cp++ = '\0';
	}
	hent->h_length = len;
	hent->h_addrtype = af;
	HENT_ARRAY(hent->h_addr_list, 1, buf, buflen);
	anum = (size_t)(q - aliases);
	HENT_ARRAY(hent->h_aliases, anum, buf, buflen);
	HENT_COPY(hent->h_addr_list[0], &host_addr, hent->h_length, buf,
	    buflen);
	hent->h_addr_list[1] = NULL;

	HENT_SCOPY(hent->h_name, name, buf, buflen);
	for (size_t i = 0; i < anum; i++)
		HENT_SCOPY(hent->h_aliases[i], aliases[i], buf, buflen);
	hent->h_aliases[anum] = NULL;

	*he = NETDB_SUCCESS;
	return hent;
nospc:
	errno = ENOSPC;
	*he = NETDB_INTERNAL;
	return NULL;
}
Пример #2
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);
	    }
	}