示例#1
0
static NTSTATUS ipv6_tcp_connect(struct socket_context *sock,
				 const struct socket_address *my_address,
				 const struct socket_address *srv_address,
				 uint32_t flags)
{
	int ret;

	if (my_address && my_address->sockaddr) {
		ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
		if (ret == -1) {
			return map_nt_error_from_unix_common(errno);
		}
	} else if (my_address) {
		struct in6_addr my_ip;
		my_ip = interpret_addr6(my_address->addr);

		if (memcmp(&my_ip, &in6addr_any, sizeof(my_ip)) || my_address->port != 0) {
			struct sockaddr_in6 my_addr;
			ZERO_STRUCT(my_addr);
			my_addr.sin6_addr	= my_ip;
			my_addr.sin6_port	= htons(my_address->port);
			my_addr.sin6_family	= PF_INET6;
			
			ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
			if (ret == -1) {
				return map_nt_error_from_unix_common(errno);
			}
		}
	}

	if (srv_address->sockaddr) {
		ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen);
	} else {
		struct in6_addr srv_ip;
		struct sockaddr_in6 srv_addr;
		srv_ip = interpret_addr6(srv_address->addr);
		if (memcmp(&srv_ip, &in6addr_any, sizeof(srv_ip)) == 0) {
			return NT_STATUS_BAD_NETWORK_NAME;
		}
		
		ZERO_STRUCT(srv_addr);
		srv_addr.sin6_addr	= srv_ip;
		srv_addr.sin6_port	= htons(srv_address->port);
		srv_addr.sin6_family	= PF_INET6;
		
		ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
	}
	if (ret == -1) {
		return map_nt_error_from_unix_common(errno);
	}

	return ip_connect_complete(sock, flags);
}
示例#2
0
static NTSTATUS ipv6_sendto(struct socket_context *sock, 
			    const DATA_BLOB *blob, size_t *sendlen, 
			    const struct socket_address *dest_addr)
{
	ssize_t len;

	if (dest_addr->sockaddr) {
		len = sendto(sock->fd, blob->data, blob->length, 0, 
			     dest_addr->sockaddr, dest_addr->sockaddrlen);
	} else {
		struct sockaddr_in6 srv_addr;
		struct in6_addr addr;
		
		ZERO_STRUCT(srv_addr);
		addr                     = interpret_addr6(dest_addr->addr);
		if (addr.s6_addr == 0) {
			return NT_STATUS_HOST_UNREACHABLE;
		}
		srv_addr.sin6_addr = addr;
		srv_addr.sin6_port        = htons(dest_addr->port);
		srv_addr.sin6_family      = PF_INET6;
		
		*sendlen = 0;
		
		len = sendto(sock->fd, blob->data, blob->length, 0, 
			     (struct sockaddr *)&srv_addr, sizeof(srv_addr));
	}
	if (len == -1) {
		return map_nt_error_from_unix_common(errno);
	}	

	*sendlen = len;

	return NT_STATUS_OK;
}
示例#3
0
static NTSTATUS ipv6_listen(struct socket_context *sock,
			    const struct socket_address *my_address,
			    int queue_size, uint32_t flags)
{
	struct sockaddr_in6 my_addr;
	struct in6_addr ip_addr;
	int ret;

	socket_set_option(sock, "SO_REUSEADDR=1", NULL);

	if (my_address->sockaddr) {
		ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
	} else {
		int one = 1;
		ip_addr = interpret_addr6(my_address->addr);
		
		ZERO_STRUCT(my_addr);
		my_addr.sin6_addr	= ip_addr;
		my_addr.sin6_port	= htons(my_address->port);
		my_addr.sin6_family	= PF_INET6;
		fix_scope_id(&my_addr, my_address->addr);

		/* when binding on ipv6 we always want to only bind on v6 */
		ret = setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY,
				 (const void *)&one, sizeof(one));
		if (ret != -1) {
			ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
		}
	}

	if (ret == -1) {
		return map_nt_error_from_unix_common(errno);
	}

	if (sock->type == SOCKET_TYPE_STREAM) {
		ret = listen(sock->fd, queue_size);
		if (ret == -1) {
			return map_nt_error_from_unix_common(errno);
		}
	}

	if (!(flags & SOCKET_FLAG_BLOCK)) {
		ret = set_blocking(sock->fd, false);
		if (ret == -1) {
			return map_nt_error_from_unix_common(errno);
		}
	}

	sock->state= SOCKET_STATE_SERVER_LISTEN;

	return NT_STATUS_OK;
}
示例#4
0
static NTSTATUS ipv6_listen(struct socket_context *sock,
				const struct socket_address *my_address,
				int queue_size, uint32_t flags)
{
	struct sockaddr_in6 my_addr;
	struct in6_addr ip_addr;
	int ret;

	socket_set_option(sock, "SO_REUSEADDR=1", NULL);

	if (my_address->sockaddr) {
		ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
	} else {
		ip_addr = interpret_addr6(my_address->addr);
		
		ZERO_STRUCT(my_addr);
		my_addr.sin6_addr	= ip_addr;
		my_addr.sin6_port	= htons(my_address->port);
		my_addr.sin6_family	= PF_INET6;
		
		ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
	}

	if (ret == -1) {
		return map_nt_error_from_unix(errno);
	}

	if (sock->type == SOCKET_TYPE_STREAM) {
		ret = listen(sock->fd, queue_size);
		if (ret == -1) {
			return map_nt_error_from_unix(errno);
		}
	}

	if (!(flags & SOCKET_FLAG_BLOCK)) {
		ret = set_blocking(sock->fd, false);
		if (ret == -1) {
			return map_nt_error_from_unix(errno);
		}
	}

	sock->state= SOCKET_STATE_SERVER_LISTEN;

	return NT_STATUS_OK;
}