Пример #1
0
/*% Stub function.  Always returns failure. */
struct hostent *
lwres_gethostent(void) {
	if (he != NULL)
		lwres_freehostent(he);

	return (NULL);
}
Пример #2
0
/* Return values:
 * 	0 : host found listed in dnsbl
 * 	1 : host not found listed in dnsbl
 */
int
check_dnsbl(int a, int b, int c, int d, char *dnsbl)
{
	char *name;
	int l, herr;
	struct hostent *he;

	/* An IPv4 address is max 15 chars long (xxx.xxx.xxx.xxx) */
	l = 18 + strlen(dnsbl);
	name = (char *)malloc(l);
	if (name == NULL) {
		syslog(LOG_INFO, "check_dnsbl(): malloc() error: aborting");
		return(0);
	}
	memset(name, '\0', l);
	if (*dnsbl == '.') {
		sprintf(name, "%d.%d.%d.%d%s", d, c, b, a, dnsbl);
	} else {
		sprintf(name, "%d.%d.%d.%d.%s", d, c, b, a, dnsbl);
	}

	he = lwres_getipnodebyname(name, AF_INET, 0, &herr);
	free(name);
	if (he == NULL) {
		return(1);
	}

	lwres_freehostent(he);
	return(0);
}
Пример #3
0
/*% Looks for either an IPv4 or IPv6 address. */
struct hostent *
lwres_gethostbyname2(const char *name, int af) {
	if (he != NULL)
		lwres_freehostent(he);

	he = lwres_getipnodebyname(name, af, 0, &lwres_h_errno);
	return (he);
}
Пример #4
0
/*% Reverse lookup of addresses. */
struct hostent *
lwres_gethostbyaddr(const char *addr, int len, int type) {

	if (he != NULL)
		lwres_freehostent(he);

	he = lwres_getipnodebyaddr(addr, len, type, &lwres_h_errno);
	return (he);
}
Пример #5
0
/*% Always looks for an IPv4 address. */
struct hostent *
lwres_gethostbyname(const char *name) {

	if (he != NULL)
		lwres_freehostent(he);

	he = lwres_getipnodebyname(name, AF_INET, 0, &lwres_h_errno);
	return (he);
}
Пример #6
0
/*% Thread-safe function for forward lookups. */
struct hostent *
lwres_gethostbyname_r(const char *name, struct hostent *resbuf,
		char *buf, int buflen, int *error)
{
	struct hostent *he;
	int res;

	he = lwres_getipnodebyname(name, AF_INET, 0, error);
	if (he == NULL)
		return (NULL);
	res = copytobuf(he, resbuf, buf, buflen);
	lwres_freehostent(he);
	if (res != 0) {
		errno = ERANGE;
		return (NULL);
	}
	return (resbuf);
}
Пример #7
0
/*% Thread-safe reverse lookup. */
struct hostent  *
lwres_gethostbyaddr_r(const char *addr, int len, int type,
		      struct hostent *resbuf, char *buf, int buflen,
		      int *error)
{
	struct hostent *he;
	int res;

	he = lwres_getipnodebyaddr(addr, len, type, error);
	if (he == NULL)
		return (NULL);
	res = copytobuf(he, resbuf, buf, buflen);
	lwres_freehostent(he);
	if (res != 0) {
		errno = ERANGE;
		return (NULL);
	}
	return (resbuf);
}
Пример #8
0
/*% performs a reverse lookup of address src which is len bytes long. af denotes the protocol family, typically #PF_INET or PF_INET6. */
struct hostent *
lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
	struct hostent *he1, *he2;
	lwres_context_t *lwrctx = NULL;
	lwres_gnbaresponse_t *by = NULL;
	lwres_result_t n;
	union {
		const void *konst;
		struct in6_addr *in6;
	} u;

	/*
	 * Sanity checks.
	 */
	if (src == NULL) {
		*error_num = NO_RECOVERY;
		return (NULL);
	}

	switch (af) {
	case AF_INET:
		if (len != (unsigned int)INADDRSZ) {
			*error_num = NO_RECOVERY;
			return (NULL);
		}
		break;
	case AF_INET6:
		if (len != (unsigned int)IN6ADDRSZ) {
			*error_num = NO_RECOVERY;
			return (NULL);
		}
		break;
	default:
		*error_num = NO_RECOVERY;
		return (NULL);
	}

	/*
	 * The de-"const"-ing game is done because at least one
	 * vendor's system (RedHat 6.0) defines the IN6_IS_ADDR_*
	 * macros in such a way that they discard the const with
	 * internal casting, and gcc ends up complaining.  Rather
	 * than replacing their own (possibly optimized) definitions
	 * with our own, cleanly discarding the const is the easiest
	 * thing to do.
	 */
	u.konst = src;

	/*
	 * Look up IPv4 and IPv4 mapped/compatible addresses.
	 */
	if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT(u.in6)) ||
	    (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED(u.in6)) ||
	    (af == AF_INET)) {
		const unsigned char *cp = src;

		if (af == AF_INET6)
			cp += 12;
		n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
		if (n == LWRES_R_SUCCESS)
			(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
		if (n == LWRES_R_SUCCESS)
			n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V4,
						INADDRSZ, cp, &by);
		if (n != LWRES_R_SUCCESS) {
			lwres_conf_clear(lwrctx);
			lwres_context_destroy(&lwrctx);
			if (n == LWRES_R_NOTFOUND)
				*error_num = HOST_NOT_FOUND;
			else
				*error_num = NO_RECOVERY;
			return (NULL);
		}
		he1 = hostfromaddr(by, AF_INET, cp);
		lwres_gnbaresponse_free(lwrctx, &by);
		lwres_conf_clear(lwrctx);
		lwres_context_destroy(&lwrctx);
		if (af != AF_INET6)
			return (he1);

		/*
		 * Convert from AF_INET to AF_INET6.
		 */
		he2 = copyandmerge(he1, NULL, af, error_num);
		lwres_freehostent(he1);
		if (he2 == NULL)
			return (NULL);
		/*
		 * Restore original address.
		 */
		memcpy(he2->h_addr, src, len);
		return (he2);
	}

	/*
	 * Lookup IPv6 address.
	 */
	if (memcmp(src, &in6addr_any, IN6ADDRSZ) == 0) {
		*error_num = HOST_NOT_FOUND;
		return (NULL);
	}

	n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
	if (n == LWRES_R_SUCCESS)
		(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
	if (n == LWRES_R_SUCCESS)
		n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V6, IN6ADDRSZ,
					src, &by);
	if (n != 0) {
		lwres_conf_clear(lwrctx);
		lwres_context_destroy(&lwrctx);

		if (n == LWRES_R_NOTFOUND)
		       *error_num = HOST_NOT_FOUND;
		else
		       *error_num = NO_RECOVERY;

		return (NULL);
	}

	he1 = hostfromaddr(by, AF_INET6, src);
	lwres_gnbaresponse_free(lwrctx, &by);
	if (he1 == NULL)
		*error_num = NO_RECOVERY;
	lwres_conf_clear(lwrctx);
	lwres_context_destroy(&lwrctx);
	return (he1);
}
Пример #9
0
struct hostent *
lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
	int have_v4 = 1, have_v6 = 1;
	struct in_addr in4;
	struct in6_addr in6;
	struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL;
	int v4 = 0, v6 = 0;
	int tmp_err = 0;
	lwres_context_t *lwrctx = NULL;
	lwres_gabnresponse_t *by = NULL;
	int n;

	/*
	 * If we care about active interfaces then check.
	 */
	if ((flags & AI_ADDRCONFIG) != 0)
		if (scan_interfaces(&have_v4, &have_v6) == -1) {
			*error_num = NO_RECOVERY;
			return (NULL);
		}

	/* Check for literal address. */
	if ((v4 = lwres_net_pton(AF_INET, name, &in4)) != 1)
		v6 = lwres_net_pton(AF_INET6, name, &in6);

	/*
	 * Impossible combination?
	 */
	if ((af == AF_INET6 && (flags & AI_V4MAPPED) == 0 && v4 == 1) ||
	    (af == AF_INET && v6 == 1) ||
	    (have_v4 == 0 && v4 == 1) ||
	    (have_v6 == 0 && v6 == 1) ||
	    (have_v4 == 0 && af == AF_INET) ||
	    (have_v6 == 0 && af == AF_INET6 &&
	     (((flags & AI_V4MAPPED) != 0 && have_v4) ||
	      (flags & AI_V4MAPPED) == 0))) {
		*error_num = HOST_NOT_FOUND;
		return (NULL);
	}

	/*
	 * Literal address?
	 */
	if (v4 == 1 || v6 == 1) {
		char *addr_list[2];
		char *aliases[1];
		char mappedname[sizeof("::ffff:123.123.123.123")];
		union {
			const char *const_name;
			char *deconst_name;
		} u;

		u.const_name = name;
		if (v4 == 1 && af == AF_INET6) {
			strcpy(mappedname, "::ffff:");
			lwres_net_ntop(AF_INET, (char *)&in4,
				       mappedname + sizeof("::ffff:") - 1,
				       sizeof(mappedname) - sizeof("::ffff:")
				       + 1);
			he.h_name = mappedname;
		} else
			he.h_name = u.deconst_name;
		he.h_addr_list = addr_list;
		he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6;
		he.h_addr_list[1] = NULL;
		he.h_aliases = aliases;
		he.h_aliases[0] = NULL;
		he.h_length = (v4 == 1) ? INADDRSZ : IN6ADDRSZ;
		he.h_addrtype = (v4 == 1) ? AF_INET : AF_INET6;
		return (copyandmerge(&he, NULL, af, error_num));
	}

	n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
	if (n != 0) {
		*error_num = NO_RECOVERY;
		goto cleanup;
	}
	(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
	tmp_err = NO_RECOVERY;
	if (have_v6 && af == AF_INET6) {
		n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by);
		if (n == 0) {
			he1 = hostfromname(by, AF_INET6);
			lwres_gabnresponse_free(lwrctx, &by);
			if (he1 == NULL) {
				*error_num = NO_RECOVERY;
				goto cleanup;
			}
		} else {
			if (n == LWRES_R_NOTFOUND)
				tmp_err = HOST_NOT_FOUND;
			else {
				*error_num = NO_RECOVERY;
				goto cleanup;
			}
		}
	}

	if (have_v4 &&
	    ((af == AF_INET) ||
	     (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 &&
	      (he1 == NULL || (flags & AI_ALL) != 0)))) {
		n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V4, &by);
		if (n == 0) {
			he2 = hostfromname(by, AF_INET);
			lwres_gabnresponse_free(lwrctx, &by);
			if (he2 == NULL) {
				*error_num = NO_RECOVERY;
				goto cleanup;
			}
		} else if (he1 == NULL) {
			if (n == LWRES_R_NOTFOUND)
				*error_num = HOST_NOT_FOUND;
			else
				*error_num = NO_RECOVERY;
			goto cleanup;
		}
	} else
		*error_num = tmp_err;

	he3 = copyandmerge(he1, he2, af, error_num);

 cleanup:
	if (he1 != NULL)
		lwres_freehostent(he1);
	if (he2 != NULL)
		lwres_freehostent(he2);
	if (lwrctx != NULL) {
		lwres_conf_clear(lwrctx);
		lwres_context_destroy(&lwrctx);
	}
	return (he3);
}