Esempio n. 1
0
/* Get IP addresses for host, both IPv4 and IPv6 if possible.
   If ip->family is 0, the address wasn't found.
   Returns 0 = ok, others = error code for net_gethosterror() */
int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6)
{
#ifdef HAVE_IPV6
	union sockaddr_union *so;
	struct addrinfo hints, *ai, *ailist;
	int ret, count;
#else
	struct hostent *hp;
#endif

	g_return_val_if_fail(addr != NULL, -1);

	memset(ip4, 0, sizeof(IPADDR));
	memset(ip6, 0, sizeof(IPADDR));

#ifdef HAVE_IPV6
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_socktype = SOCK_STREAM;

	/* save error to host_error for later use */
	ret = getaddrinfo(addr, NULL, &hints, &ailist);
	if (ret != 0)
		return ret;

        count = 0;
	for (ai = ailist; ai != NULL && count < 2; ai = ai->ai_next) {
		so = (union sockaddr_union *) ai->ai_addr;

		if (ai->ai_family == AF_INET6 && ip6->family == 0) {
			sin_get_ip(so, ip6);
                        count++;
		} else if (ai->ai_family == AF_INET && ip4->family == 0) {
			sin_get_ip(so, ip4);
                        count++;
		}
	}
	freeaddrinfo(ailist);
	return count > 0 ? 0 : 1;
#else
	hp = gethostbyname(addr);
	if (hp == NULL)
                return -1;
		//return h_errno;

	ip4->family = AF_INET;
	memcpy(&ip4->ip, hp->h_addr, 4);

	return 0;
#endif
}
Esempio n. 2
0
/* Get socket address/port */
int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port)
{
	union sockaddr_union so;
	socklen_t addrlen;

	g_return_val_if_fail(handle != NULL, -1);
	g_return_val_if_fail(addr != NULL, -1);

	addrlen = sizeof(so);
	if (getsockname(g_io_channel_unix_get_fd(handle),
			(struct sockaddr *) &so, &addrlen) == -1)
		return -1;

        sin_get_ip(&so, addr);
	if (port) *port = sin_get_port(&so);

	return 0;
}
Esempio n. 3
0
/* Accept a connection on a socket */
int net_accept(int handle, IPADDR *addr, int *port)
{
	union sockaddr_union so;
	int ret;
	socklen_t addrlen;

	g_return_val_if_fail(handle != -1, -1);

	addrlen = sizeof(so);
	ret = accept(handle, &so.sa, &addrlen);

	if (ret < 0)
		return -1;

	if (addr != NULL) sin_get_ip(&so, addr);
	if (port != NULL) *port = sin_get_port(&so);

	fcntl(ret, F_SETFL, O_NONBLOCK);
	return ret;
}
Esempio n. 4
0
/* Accept a connection on a socket */
GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port)
{
	union sockaddr_union so;
	int ret;
	socklen_t addrlen;

	g_return_val_if_fail(handle != NULL, NULL);

	addrlen = sizeof(so);
	ret = accept(g_io_channel_unix_get_fd(handle), &so.sa, &addrlen);

	if (ret < 0)
		return NULL;

	if (addr != NULL) sin_get_ip(&so, addr);
	if (port != NULL) *port = sin_get_port(&so);

#ifndef WIN32
	fcntl(ret, F_SETFL, O_NONBLOCK);
#endif
	return g_io_channel_new(ret);
}
Esempio n. 5
0
/* Get IP address for host, returns 0 = ok,
   others = error code for net_gethosterror() */
int net_gethostbyname(const char *addr, IPADDR *ip)
{
#ifdef HAVE_IPV6
	union sockaddr_union *so;
	struct addrinfo req, *ai;
	char hbuf[NI_MAXHOST];
	int host_error;
#else
	struct hostent *hp;
#endif

	g_return_val_if_fail(addr != NULL, -1);

#ifdef HAVE_IPV6
	memset(ip, 0, sizeof(IPADDR));
	memset(&req, 0, sizeof(struct addrinfo));
	req.ai_socktype = SOCK_STREAM;

	/* save error to host_error for later use */
	host_error = getaddrinfo(addr, NULL, &req, &ai);
	if (host_error != 0)
		return host_error;

	if (getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
		return 1;

	so = (union sockaddr_union *) ai->ai_addr;
        sin_get_ip(so, ip);
	freeaddrinfo(ai);
#else
	hp = gethostbyname(addr);
	if (hp == NULL) return -1;

	ip->family = AF_INET;
	memcpy(&ip->addr, hp->h_addr, 4);
#endif

	return 0;
}
Esempio n. 6
0
/* Get socket address/port */
int net_getsockname(int handle, IPADDR *addr, int *port)
{
	union sockaddr_union so;
#ifdef HAVE_IPV6
	socklen_t len = sizeof(so.sin6);
#else
	socklen_t len = sizeof(so.sin);
#endif

	g_return_val_if_fail(handle != -1, -1);
	g_return_val_if_fail(addr != NULL, -1);

#ifdef HAVE_IPV6
	if (getsockname(handle, &so.sin6, &len) == -1)
#else
	if (getsockname(handle, &so.sin, &len) == -1)
#endif
		return -1;

        sin_get_ip(&so, addr);
	if (port) *port = sin_get_port(&so);

	return 0;
}
Esempio n. 7
0
File: network.c Progetto: GPF/irssi
/* Get IP addresses for host, both IPv4 and IPv6 if possible.
   If ip->family is 0, the address wasn't found.
   Returns 0 = ok, others = error code for net_gethosterror() */
int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6)
{
#ifdef HAVE_IPV6
	union sockaddr_union *so;
	struct addrinfo hints, *ai, *ailist;
	int ret, count_v4, count_v6, use_v4, use_v6;
#else
	struct hostent *hp;
	int count;
#endif

	g_return_val_if_fail(addr != NULL, -1);

	memset(ip4, 0, sizeof(IPADDR));
	memset(ip6, 0, sizeof(IPADDR));

#ifdef HAVE_IPV6
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_socktype = SOCK_STREAM;

	/* save error to host_error for later use */
	ret = getaddrinfo(addr, NULL, &hints, &ailist);
	if (ret != 0)
		return ret;

	/* count IPs */
        count_v4 = count_v6 = 0;
	for (ai = ailist; ai != NULL; ai = ai->ai_next) {
		if (ai->ai_family == AF_INET)
			count_v4++;
		else if (ai->ai_family == AF_INET6)
			count_v6++;
	}

	if (count_v4 == 0 && count_v6 == 0)
		return HOST_NOT_FOUND; /* shouldn't happen? */

	/* if there are multiple addresses, return random one */
	use_v4 = count_v4 <= 1 ? 0 : rand() % count_v4;
	use_v6 = count_v6 <= 1 ? 0 : rand() % count_v6;

	count_v4 = count_v6 = 0;
	for (ai = ailist; ai != NULL; ai = ai->ai_next) {
		so = (union sockaddr_union *) ai->ai_addr;

		if (ai->ai_family == AF_INET) {
			if (use_v4 == count_v4)
				sin_get_ip(so, ip4);
                        count_v4++;
		} else if (ai->ai_family == AF_INET6) {
			if (use_v6 == count_v6)
				sin_get_ip(so, ip6);
			count_v6++;
		}
	}
	freeaddrinfo(ailist);
	return 0;
#else
	hp = gethostbyname(addr);
	if (hp == NULL)
		return h_errno;

	/* count IPs */
	count = 0;
	while (hp->h_addr_list[count] != NULL)
		count++;

	if (count == 0)
		return HOST_NOT_FOUND; /* shouldn't happen? */

	/* if there are multiple addresses, return random one */
	ip4->family = AF_INET;
	memcpy(&ip4->ip, hp->h_addr_list[rand() % count], 4);

	return 0;
#endif
}