Index: uspace/srv/net/udp/sock.c
===================================================================
--- uspace/srv/net/udp/sock.c	(revision 257feec9d30b7aa8ced34c0ef045309a9cc98d3c)
+++ uspace/srv/net/udp/sock.c	(revision 98abd409db889cb4a1e3a865f6034f5a68f66184)
@@ -159,31 +159,27 @@
 static void udp_sock_bind(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	int rc;
-	struct sockaddr_in *addr;
-	size_t addr_size;
-	socket_core_t *sock_core;
-	udp_sockdata_t *socket;
-	udp_sock_t fsock;
-	udp_error_t urc;
-
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_bind()");
 	log_msg(LOG_DEFAULT, LVL_DEBUG, " - async_data_write_accept");
-
-	addr = NULL;
-
-	rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_size);
+	
+	struct sockaddr_in6 *addr6 = NULL;
+	size_t addr_len;
+	int rc = async_data_write_accept((void **) &addr6, false, 0, 0, 0, &addr_len);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
-		goto out;
-	}
-	
-	if (addr_size != sizeof(struct sockaddr_in)) {
+		return;
+	}
+	
+	if ((addr_len != sizeof(struct sockaddr_in)) &&
+	    (addr_len != sizeof(struct sockaddr_in6))) {
 		async_answer_0(callid, EINVAL);
 		goto out;
 	}
 	
+	struct sockaddr_in *addr = (struct sockaddr_in *) addr6;
+	
 	log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_bind");
+	
 	rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
-	    addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
+	    addr6, addr_len, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
 	    last_used_port);
 	if (rc != EOK) {
@@ -193,17 +189,33 @@
 	
 	log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_cores_find");
-	sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call));
+	
+	socket_core_t *sock_core = socket_cores_find(&client->sockets,
+	    SOCKET_GET_SOCKET_ID(call));
 	if (sock_core == NULL) {
 		async_answer_0(callid, ENOENT);
 		goto out;
 	}
-
-	socket = (udp_sockdata_t *) sock_core->specific_data;
-	
-	inet_addr_unpack(uint32_t_be2host(addr->sin_addr.s_addr),
-	    &fsock.addr);
-	fsock.port = sock_core->port;
-	urc = udp_uc_set_local(socket->assoc, &fsock);
-
+	
+	udp_sockdata_t *socket =
+	    (udp_sockdata_t *) sock_core->specific_data;
+	
+	udp_sock_t fsocket;
+	
+	fsocket.port = sock_core->port;
+	
+	switch (addr->sin_family) {
+	case AF_INET:
+		inet_sockaddr_in_addr(addr, &fsocket.addr);
+		break;
+	case AF_INET6:
+		inet_sockaddr_in6_addr(addr6, &fsocket.addr);
+		break;
+	default:
+		async_answer_0(callid, EINVAL);
+		goto out;
+	}
+	
+	udp_error_t urc = udp_uc_set_local(socket->assoc, &fsocket);
+	
 	switch (urc) {
 	case UDP_EOK:
@@ -225,7 +237,8 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, " - success");
 	async_answer_0(callid, rc);
+	
 out:
-	if (addr != NULL)
-		free(addr);
+	if (addr6 != NULL)
+		free(addr6);
 }
 
@@ -252,28 +265,42 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_send()");
 	
-	struct sockaddr_in *addr = NULL;
-	udp_sock_t fsock;
-	udp_sock_t *fsock_ptr;
+	struct sockaddr_in6 *addr6 = NULL;
+	struct sockaddr_in *addr;
+	udp_sock_t fsocket;
+	udp_sock_t *fsocket_ptr;
 	
 	if (IPC_GET_IMETHOD(call) == NET_SOCKET_SENDTO) {
-		size_t addr_size;
-		int rc = async_data_write_accept((void **) &addr, false,
-		    0, 0, 0, &addr_size);
+		size_t addr_len;
+		int rc = async_data_write_accept((void **) &addr6, false,
+		    0, 0, 0, &addr_len);
 		if (rc != EOK) {
 			async_answer_0(callid, rc);
-			goto out;
-		}
-		
-		if (addr_size != sizeof(struct sockaddr_in)) {
+			return;
+		}
+		
+		if ((addr_len != sizeof(struct sockaddr_in)) &&
+		    (addr_len != sizeof(struct sockaddr_in6))) {
 			async_answer_0(callid, EINVAL);
 			goto out;
 		}
 		
-		inet_addr_unpack(uint32_t_be2host(addr->sin_addr.s_addr),
-		    &fsock.addr);
-		fsock.port = uint16_t_be2host(addr->sin_port);
-		fsock_ptr = &fsock;
+		addr = (struct sockaddr_in *) addr6;
+		
+		switch (addr->sin_family) {
+		case AF_INET:
+			inet_sockaddr_in_addr(addr, &fsocket.addr);
+			break;
+		case AF_INET6:
+			inet_sockaddr_in6_addr(addr6, &fsocket.addr);
+			break;
+		default:
+			async_answer_0(callid, EINVAL);
+			goto out;
+		}
+		
+		fsocket.port = uint16_t_be2host(addr->sin_port);
+		fsocket_ptr = &fsocket;
 	} else
-		fsock_ptr = NULL;
+		fsocket_ptr = NULL;
 	
 	int socket_id = SOCKET_GET_SOCKET_ID(call);
@@ -321,5 +348,5 @@
 		inet_addr_t rem_addr;
 		
-		rem_addr = fsock_ptr ? fsock.addr :
+		rem_addr = fsocket_ptr ? fsocket.addr :
 		    socket->assoc->ident.foreign.addr;
 		
@@ -361,5 +388,5 @@
 		
 		udp_error_t urc =
-		    udp_uc_send(socket->assoc, fsock_ptr, buffer, length, 0);
+		    udp_uc_send(socket->assoc, fsocket_ptr, buffer, length, 0);
 		
 		switch (urc) {
@@ -396,35 +423,24 @@
 	
 out:
-	if (addr != NULL)
-		free(addr);
+	if (addr6 != NULL)
+		free(addr6);
 }
 
 static void udp_sock_recvfrom(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	int socket_id;
-	int flags;
-	size_t addr_length, length;
-	socket_core_t *sock_core;
-	udp_sockdata_t *socket;
-	ipc_call_t answer;
-	ipc_callid_t rcallid;
-	size_t data_len;
-	udp_error_t urc;
-	udp_sock_t *rsock;
-	struct sockaddr_in addr;
-	int rc;
-
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: udp_sock_recv[from]()", client);
-
-	socket_id = SOCKET_GET_SOCKET_ID(call);
-	flags = SOCKET_GET_FLAGS(call);
-
-	sock_core = socket_cores_find(&client->sockets, socket_id);
+	
+	int socket_id = SOCKET_GET_SOCKET_ID(call);
+	
+	socket_core_t *sock_core =
+	    socket_cores_find(&client->sockets, socket_id);
 	if (sock_core == NULL) {
 		async_answer_0(callid, ENOTSOCK);
 		return;
 	}
-
-	socket = (udp_sockdata_t *)sock_core->specific_data;
+	
+	udp_sockdata_t *socket =
+	    (udp_sockdata_t *) sock_core->specific_data;
+	
 	fibril_mutex_lock(&socket->lock);
 	
@@ -434,10 +450,11 @@
 		return;
 	}
-
-	(void)flags;
-
+	
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): lock recv_buffer lock");
+	
 	fibril_mutex_lock(&socket->recv_buffer_lock);
-	while (socket->recv_buffer_used == 0 && socket->recv_error == UDP_EOK) {
+	
+	while ((socket->recv_buffer_used == 0) &&
+	    (socket->recv_error == UDP_EOK)) {
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): wait for cv");
 		fibril_condvar_wait(&socket->recv_buffer_cv,
@@ -446,11 +463,12 @@
 	
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer");
-
-	rsock = &socket->recv_fsock;
-	data_len = socket->recv_buffer_used;
-	urc = socket->recv_error;
-
+	
+	size_t data_len = socket->recv_buffer_used;
+	udp_error_t urc = socket->recv_error;
+	
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv data_len=%zu", data_len);
-
+	
+	int rc;
+	
 	switch (urc) {
 	case UDP_EOK:
@@ -476,22 +494,72 @@
 		return;
 	}
-
+	
+	ipc_callid_t rcallid;
+	size_t addr_size = 0;
+	
 	if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) {
 		/* Fill address */
-		uint32_t rsock_addr;
-		int rc = inet_addr_pack(&rsock->addr, &rsock_addr);
-		if (rc != EOK) {
-			fibril_mutex_unlock(&socket->recv_buffer_lock);
-			fibril_mutex_unlock(&socket->lock);
-			async_answer_0(callid, rc);
-			return;
-		}
-		
-		addr.sin_family = AF_INET;
-		addr.sin_addr.s_addr = host2uint32_t_be(rsock_addr);
-		addr.sin_port = host2uint16_t_be(rsock->port);
-
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
-		if (!async_data_read_receive(&rcallid, &addr_length)) {
+		udp_sock_t *rsock = &socket->recv_fsock;
+		struct sockaddr_in addr;
+		struct sockaddr_in6 addr6;
+		size_t addr_length;
+		
+		uint16_t addr_af = inet_addr_sockaddr_in(&rsock->addr, &addr,
+		    &addr6);
+		
+		switch (addr_af) {
+		case AF_INET:
+			addr.sin_port = host2uint16_t_be(rsock->port);
+			
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
+			if (!async_data_read_receive(&rcallid, &addr_length)) {
+				fibril_mutex_unlock(&socket->recv_buffer_lock);
+				fibril_mutex_unlock(&socket->lock);
+				async_answer_0(callid, EINVAL);
+				return;
+			}
+			
+			if (addr_length > sizeof(addr))
+				addr_length = sizeof(addr);
+			
+			addr_size = sizeof(addr);
+			
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
+			rc = async_data_read_finalize(rcallid, &addr, addr_length);
+			if (rc != EOK) {
+				fibril_mutex_unlock(&socket->recv_buffer_lock);
+				fibril_mutex_unlock(&socket->lock);
+				async_answer_0(callid, EINVAL);
+				return;
+			}
+			
+			break;
+		case AF_INET6:
+			addr6.sin6_port = host2uint16_t_be(rsock->port);
+			
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read receive");
+			if (!async_data_read_receive(&rcallid, &addr_length)) {
+				fibril_mutex_unlock(&socket->recv_buffer_lock);
+				fibril_mutex_unlock(&socket->lock);
+				async_answer_0(callid, EINVAL);
+				return;
+			}
+			
+			if (addr_length > sizeof(addr6))
+				addr_length = sizeof(addr6);
+			
+			addr_size = sizeof(addr6);
+			
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read finalize");
+			rc = async_data_read_finalize(rcallid, &addr6, addr_length);
+			if (rc != EOK) {
+				fibril_mutex_unlock(&socket->recv_buffer_lock);
+				fibril_mutex_unlock(&socket->lock);
+				async_answer_0(callid, EINVAL);
+				return;
+			}
+			
+			break;
+		default:
 			fibril_mutex_unlock(&socket->recv_buffer_lock);
 			fibril_mutex_unlock(&socket->lock);
@@ -499,19 +567,9 @@
 			return;
 		}
-
-		if (addr_length > sizeof(addr))
-			addr_length = sizeof(addr);
-
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
-		rc = async_data_read_finalize(rcallid, &addr, addr_length);
-		if (rc != EOK) {
-			fibril_mutex_unlock(&socket->recv_buffer_lock);
-			fibril_mutex_unlock(&socket->lock);
-			async_answer_0(callid, EINVAL);
-			return;
-		}
-	}
-
+	}
+	
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive");
+	
+	size_t length;
 	if (!async_data_read_receive(&rcallid, &length)) {
 		fibril_mutex_unlock(&socket->recv_buffer_lock);
@@ -525,13 +583,17 @@
 	
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize");
+	
 	rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
-
-	if (length < data_len && rc == EOK)
+	
+	if ((length < data_len) && (rc == EOK))
 		rc = EOVERFLOW;
 	
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "read_data_length <- %zu", length);
+	
+	ipc_call_t answer;
+	
 	IPC_SET_ARG2(answer, 0);
 	SOCKET_SET_READ_DATA_LENGTH(answer, length);
-	SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(addr));
+	SOCKET_SET_ADDRESS_LENGTH(answer, addr_size);
 	async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
 	    IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
@@ -634,4 +696,5 @@
 			log_msg(LOG_DEFAULT, LVL_DEBUG, "[] urc != UDP_EOK, break");
 			fibril_condvar_broadcast(&sock->recv_buffer_cv);
+			fibril_mutex_unlock(&sock->recv_buffer_lock);
 			break;
 		}
