si_item_t *
si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err)
{
	if (si == NULL) return NULL;

	switch (call)
	{
		case SI_CALL_USER_BYNAME: return si_user_byname(si, str1);
		case SI_CALL_USER_BYUID: return si_user_byuid(si, (uid_t)num1);
		case SI_CALL_GROUP_BYNAME: return si_group_byname(si, str1);
		case SI_CALL_GROUP_BYGID: return si_group_bygid(si, (gid_t)num1);
		case SI_CALL_GROUPLIST: return si_grouplist(si, str1, (int) num1);
		case SI_CALL_ALIAS_BYNAME: return si_alias_byname(si, str1);
		case SI_CALL_HOST_BYNAME: return si_host_byname(si, str1, num1, str3, err);
		case SI_CALL_HOST_BYADDR: return si_host_byaddr(si, (void *)str1, num1, str3, err);
		case SI_CALL_NETWORK_BYNAME: return si_network_byname(si, str1);
		case SI_CALL_NETWORK_BYADDR: return si_network_byaddr(si, num1);
		case SI_CALL_SERVICE_BYNAME: return si_service_byname(si, str1, str2);
		case SI_CALL_SERVICE_BYPORT: return si_service_byport(si, num1, str2);
		case SI_CALL_PROTOCOL_BYNAME: return si_protocol_byname(si, str1);
		case SI_CALL_PROTOCOL_BYNUMBER: return si_protocol_bynumber(si, num1);
		case SI_CALL_RPC_BYNAME: return si_network_byname(si, str1);
		case SI_CALL_RPC_BYNUMBER: return si_rpc_bynumber(si, num1);
		case SI_CALL_FS_BYSPEC: return si_fs_byspec(si, str1);
		case SI_CALL_FS_BYFILE: return si_fs_byfile(si, str1);
		case SI_CALL_NAMEINFO: return si_nameinfo(si, (const struct sockaddr *)str1, num1, str3, err);
		case SI_CALL_IPNODE_BYNAME: return si_ipnode_byname(si, (const char *)str1, num1, num2, str3, err);
		case SI_CALL_MAC_BYNAME: return si_mac_byname(si, (const char *)str1);
		case SI_CALL_MAC_BYMAC: return si_mac_bymac(si, (const char *)str1);

		/* Support for DNS async calls */
		case SI_CALL_DNS_QUERY:
		case SI_CALL_DNS_SEARCH:
		{
			if (si->vtable->sim_item_call == NULL) return NULL;
			return si->vtable->sim_item_call(si, call, str1, str2, str3, num1, num2, err);
		}

		default: return NULL;
	}

	return NULL;
}
Esempio n. 2
0
/* _gai_simple
 * Simple lookup via gethostbyname2(3) mechanism.
 */
si_list_t *
_gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
{
	si_item_t *h4_item = NULL, *h6_item = NULL;
	struct hostent *h4 = NULL, *h6 = NULL;
	si_list_t *out = NULL;
	uint16_t port = 0;

	if ((flags & AI_NUMERICSERV) != 0 && servptr != NULL)
	{
		port = *(uint16_t*)servptr;
	}
	else if (servptr != NULL)
	{
		if (_gai_serv_to_port(servptr, proto, &port) != 0)
		{
			if (err) *err = SI_STATUS_EAI_NONAME;
			return NULL;
		}
	}

	if ((flags & AI_NUMERICHOST) != 0)
	{
		if (family == AF_INET)
		{
			h4_item = si_host_byaddr(si, nodeptr, AF_INET, interface, NULL);
		}
		else if (family == AF_INET6)
		{
			h6_item = si_host_byaddr(si, nodeptr, AF_INET6, interface, NULL);
		}
	}
	else
	{
		if ((family == AF_INET) || (family == AF_UNSPEC))
		{
			h4_item = si_host_byname(si, nodeptr, AF_INET, interface, NULL);
		}

		if ((family == AF_INET6) || (family == AF_UNSPEC))
		{
			h6_item = si_host_byname(si, nodeptr, AF_INET6, interface, NULL);
		}
	}

	if (h4_item != NULL)
	{
		h4 = (struct hostent *)((uintptr_t)h4_item + sizeof(si_item_t));
	}

	if (h6_item != NULL)
	{
		h6 = (struct hostent *)((uintptr_t)h6_item + sizeof(si_item_t));
	}

	out = si_addrinfo_list_from_hostent(si, flags, socktype, proto, port, 0, h4, h6);
	si_item_release(h4_item);
	si_item_release(h6_item);

	return _gai_sort_list(out, flags);
}
Esempio n. 3
0
si_item_t *
si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err)
{
	int i, status, want;
	uint32_t if4, if6;
	struct in_addr addr4;
	struct in6_addr addr6;
	si_item_t *item4, *item6;
	build_hostent_t *out;
	struct hostent *h;
	uint32_t unused;

	memset(&addr4, 0, sizeof(struct in_addr));
	memset(&addr6, 0, sizeof(struct in6_addr));

	if (err != NULL) *err = 0;

	if (family == AF_INET)
	{
		status = inet_aton(name, &addr4);
		if (status == 1)
		{
			/* create a host entry */
			item4 = make_hostent(si, name, addr4);
			if (item4 == NULL)
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
				return NULL;
			}

			return item4;
		}
	}
	else if (family == AF_INET6)
	{
		status = inet_pton(family, name, &addr6);
		if (status == 1)
		{
			/* create a host entry */
			item6 = make_hostent6(si, name, addr6);
			if (item6 == NULL)
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
				return NULL;
			}

			return item6;
		}

		status = inet_aton(name, &addr4);
		if (status == 1)
		{
			if (!(flags & (AI_V4MAPPED | AI_V4MAPPED_CFG)))
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
				return NULL;
			}

			addr6.__u6_addr.__u6_addr32[0] = 0x00000000;
			addr6.__u6_addr.__u6_addr32[1] = 0x00000000;
			addr6.__u6_addr.__u6_addr32[2] = htonl(0x0000ffff);
			memmove(&(addr6.__u6_addr.__u6_addr32[3]), &(addr4.s_addr), IPV4_ADDR_LEN);

			/* create a host entry */
			item6 = make_hostent6(si, name, addr6);
			if (item6 == NULL)
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
				return NULL;
			}

			return item6;
		}
	}
	else
	{
		if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
		return NULL;
	}

	/*
	 * IF AI_ADDRCONFIG is set, we need to know what interface flavors we really have.
	 */

	if4 = 0;
	if6 = 0;

	if (flags & AI_ADDRCONFIG)
	{
		if (si_inet_config(&if4, &if6) < 0)
		{
			if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
			return NULL;
		}

		/* Bail out if there are no interfaces */
		if ((if4 == 0) && (if6 == 0))
		{
			if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
			return NULL;
		}
	}

	/*
	 * Figure out what we want.
	 * If user asked for AF_INET, we only want V4 addresses.
	 */
	want = WANT_A4_ONLY;

	if (family == AF_INET)
	{
		if ((flags & AI_ADDRCONFIG) && (if4 == 0))
		{
			if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
			return NULL;
		}
	}
	else if (family == AF_INET6)
	{
		/* family == AF_INET6 */
		want = WANT_A6_ONLY;

		if (flags & (AI_V4MAPPED | AI_V4MAPPED_CFG))
		{
			if (flags & AI_ALL)
			{
				want = WANT_A6_PLUS_MAPPED_A4;
			}
			else
			{
				want = WANT_A6_OR_MAPPED_A4_IF_NO_A6;
			}
		}
		else
		{
			if ((flags & AI_ADDRCONFIG) && (if6 == 0)) 
			{
				if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
				return NULL;
			}
		}
	}
	else
	{
		if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
		return NULL;
	}

	item6 = NULL;
	item4 = NULL;

	/* fetch IPv6 data if required */
	if ((want == WANT_A6_ONLY) || (want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) || (want == WANT_A6_PLUS_MAPPED_A4))
	{
		item6 = si_host_byname(si, name, AF_INET6, interface, (uint32_t *)err);
	}

	/* fetch IPv4 data if required */
	if ((want == WANT_A4_ONLY) || (want == WANT_A6_PLUS_MAPPED_A4) || ((want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) && (item6 == NULL)))
	{
		item4 = si_host_byname(si, name, AF_INET, interface, (uint32_t *)err);
	}

	if (want == WANT_A4_ONLY)
	{
		si_item_release(item6);
		if ((item4 == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
		return item4;
	}

	if (want == WANT_A6_ONLY)
	{
		si_item_release(item4);
		if ((item6 == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
		return item6;
	}

	if ((item6 == NULL) && (item4 == NULL))
	{
		if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
		return NULL;
	}

	/* output item will have IPv6 + mapped IPv4 addresses */

	out = (build_hostent_t *)calloc(1, sizeof(build_hostent_t));
	if (out == NULL)
	{
		si_item_release(item4);
		si_item_release(item6);
		if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
		return NULL;
	}

	if (item4 != NULL)
	{
		h = (struct hostent *)((uintptr_t)item4 + sizeof(si_item_t));

		out->host.h_name = lower_case(h->h_name);

		if (h->h_aliases != NULL)
		{
			for (i = 0; h->h_aliases[i] != NULL; i++) merge_alias(h->h_aliases[i], out);
		}

		for (i = 0; h->h_addr_list[i] != 0; i++)
		{
			addr6.__u6_addr.__u6_addr32[0] = 0x00000000;
			addr6.__u6_addr.__u6_addr32[1] = 0x00000000;
			addr6.__u6_addr.__u6_addr32[2] = htonl(0x0000ffff);
			memmove(&(addr6.__u6_addr.__u6_addr32[3]), h->h_addr_list[i], IPV4_ADDR_LEN);
			append_addr((const char *)&addr6, IPV6_ADDR_LEN, out);
		}
	}

	if (item6 != NULL)
	{
		h = (struct hostent *)((uintptr_t)item6 + sizeof(si_item_t));

		if (out->host.h_name == NULL) out->host.h_name = lower_case(h->h_name);

		if (h->h_aliases != NULL)
		{
			for (i = 0; h->h_aliases[i] != NULL; i++) merge_alias(h->h_aliases[i], out);
		}

		for (i = 0; h->h_addr_list[i] != 0; i++) append_addr(h->h_addr_list[i], IPV6_ADDR_LEN, out);
	}

	si_item_release(item4);
	si_item_release(item6);

	unused = 0;

	item6 = (si_item_t *)LI_ils_create("L4444s*44c", (unsigned long)si, CATEGORY_HOST_IPV6, 1, unused, unused, out->host.h_name, out->host.h_aliases, AF_INET6, IPV6_ADDR_LEN, out->host.h_addr_list);

	free_build_hostent(out);

	return item6;
}