Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/Makefile	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -76,5 +76,4 @@
 	app/nettest3 \
 	app/ping \
-	app/ping6 \
 	app/sysinfo \
 	app/mkbd \
Index: uspace/app/ping/ping.c
===================================================================
--- uspace/app/ping/ping.c	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/app/ping/ping.c	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -76,15 +76,18 @@
 };
 
-static addr32_t src;
-static addr32_t dest;
+static inet_addr_t src_addr;
+static inet_addr_t dest_addr;
 
 static bool repeat_forever = false;
 static size_t repeat_count = 1;
 
-static const char *short_options = "rn:";
+static const char *short_options = "46rn:";
 
 static void print_syntax(void)
 {
-	printf("Syntax: %s [-n <count>|-r] <host>\n", NAME);
+	printf("Syntax: %s [<options>] <host>\n", NAME);
+	printf("\t-n <count> Repeat the specified number of times\n");
+	printf("\t-r         Repeat forever\n");
+	printf("\t-4|-6      Use IPv4 or IPv6 destination host address\n");
 }
 
@@ -107,10 +110,4 @@
 static int ping_ev_recv(inetping_sdu_t *sdu)
 {
-	inet_addr_t src_addr;
-	inet_addr_set(sdu->src, &src_addr);
-	
-	inet_addr_t dest_addr;
-	inet_addr_set(sdu->dest, &dest_addr);
-	
 	char *asrc;
 	int rc = inet_addr_format(&src_addr, &asrc);
@@ -139,6 +136,6 @@
 	inetping_sdu_t sdu;
 	
-	sdu.src = src;
-	sdu.dest = dest;
+	sdu.src = src_addr;
+	sdu.dest = dest_addr;
 	sdu.seq_no = seq_no;
 	sdu.data = (void *) "foo";
@@ -221,4 +218,5 @@
 	char *adest = NULL;
 	char *sdest = NULL;
+	ip_ver_t ip_ver = ip_any;
 	
 	int rc = inetping_init(&ev_ops);
@@ -243,4 +241,10 @@
 			}
 			break;
+		case '4':
+			ip_ver = ip_v4;
+			break;
+		case '6':
+			ip_ver = ip_v6;
+			break;
 		default:
 			printf("Unknown option passed.\n");
@@ -257,9 +261,8 @@
 	
 	/* Parse destination address */
-	inet_addr_t dest_addr;
 	rc = inet_addr_parse(argv[optind], &dest_addr);
 	if (rc != EOK) {
 		/* Try interpreting as a host name */
-		rc = dnsr_name2host(argv[optind], &hinfo, ip_v4);
+		rc = dnsr_name2host(argv[optind], &hinfo, ip_ver);
 		if (rc != EOK) {
 			printf("Error resolving host '%s'.\n", argv[optind]);
@@ -270,20 +273,10 @@
 	}
 	
-	ip_ver_t ver = inet_addr_get(&dest_addr, &dest, NULL);
-	if (ver != ip_v4) {
-		printf("Destination '%s' is not an IPv4 address.\n",
-		    argv[optind]);
-		goto error;
-	}
-	
 	/* Determine source address */
-	rc = inetping_get_srcaddr(dest, &src);
+	rc = inetping_get_srcaddr(&dest_addr, &src_addr);
 	if (rc != EOK) {
 		printf("Failed determining source address.\n");
 		goto error;
 	}
-	
-	inet_addr_t src_addr;
-	inet_addr_set(src, &src_addr);
 	
 	rc = inet_addr_format(&src_addr, &asrc);
Index: uspace/app/ping6/Makefile
===================================================================
--- uspace/app/ping6/Makefile	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#
-# Copyright (c) 2013 Antonin Steinhauser
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-USPACE_PREFIX = ../..
-BINARY = ping6
-
-SOURCES = \
-	ping6.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/ping6/ping6.c
===================================================================
--- uspace/app/ping6/ping6.c	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ 	(revision )
@@ -1,351 +1,0 @@
-/*
- * Copyright (c) 2013 Antonin Steinhauser
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup ping6
- * @{
- */
-/** @file ICMPv6 echo utility.
- */
-
-#include <async.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <inet/dnsr.h>
-#include <inet/addr.h>
-#include <inet/inetping6.h>
-#include <io/console.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <str.h>
-#include <str_error.h>
-#include <sys/types.h>
-
-#define NAME "ping6"
-
-/** Delay between subsequent ping requests in microseconds */
-#define PING_DELAY (1000 * 1000)
-
-/** Ping request timeout in microseconds */
-#define PING_TIMEOUT (1000 * 1000)
-
-typedef enum {
-	RECEIVED_NONE,
-	RECEIVED_SUCCESS,
-	RECEIVED_INTERRUPT
-} received_t;
-
-static received_t received;
-static FIBRIL_CONDVAR_INITIALIZE(received_cv);
-static FIBRIL_MUTEX_INITIALIZE(received_lock);
-
-static bool quit = false;
-static FIBRIL_CONDVAR_INITIALIZE(quit_cv);
-static FIBRIL_MUTEX_INITIALIZE(quit_lock);
-
-static int ping_ev_recv(inetping6_sdu_t *);
-
-static inetping6_ev_ops_t ev_ops = {
-	.recv = ping_ev_recv
-};
-
-static addr128_t src;
-static addr128_t dest;
-
-static bool repeat_forever = false;
-static size_t repeat_count = 1;
-
-static const char *short_options = "rn:";
-
-static void print_syntax(void)
-{
-	printf("Syntax: %s [-n <count>|-r] <host>\n", NAME);
-}
-
-static void ping_signal_received(received_t value)
-{
-	fibril_mutex_lock(&received_lock);
-	received = value;
-	fibril_mutex_unlock(&received_lock);
-	fibril_condvar_broadcast(&received_cv);
-}
-
-static void ping_signal_quit(void)
-{
-	fibril_mutex_lock(&quit_lock);
-	quit = true;
-	fibril_mutex_unlock(&quit_lock);
-	fibril_condvar_broadcast(&quit_cv);
-}
-
-static int ping_ev_recv(inetping6_sdu_t *sdu)
-{
-	inet_addr_t src_addr;
-	inet_addr_set6(sdu->src, &src_addr);
-	
-	inet_addr_t dest_addr;
-	inet_addr_set6(sdu->dest, &dest_addr);
-	
-	char *asrc;
-	int rc = inet_addr_format(&src_addr, &asrc);
-	if (rc != EOK)
-		return ENOMEM;
-	
-	char *adest;
-	rc = inet_addr_format(&dest_addr, &adest);
-	if (rc != EOK) {
-		free(asrc);
-		return ENOMEM;
-	}
-	
-	printf("Received ICMPv6 echo reply: from %s to %s, seq. no %u, "
-	    "payload size %zu\n", asrc, adest, sdu->seq_no, sdu->size);
-	
-	ping_signal_received(RECEIVED_SUCCESS);
-	
-	free(asrc);
-	free(adest);
-	return EOK;
-}
-
-static int ping_send(uint16_t seq_no)
-{
-	inetping6_sdu_t sdu;
-	
-	addr128(src, sdu.src);
-	addr128(dest, sdu.dest);
-	sdu.seq_no = seq_no;
-	sdu.data = (void *) "foo";
-	sdu.size = 3;
-	
-	int rc = inetping6_send(&sdu);
-	if (rc != EOK)
-		printf("Failed sending echo request: %s (%d).\n",
-		    str_error(rc), rc);
-	
-	return rc;
-}
-
-static int transmit_fibril(void *arg)
-{
-	uint16_t seq_no = 0;
-	
-	while ((repeat_count--) || (repeat_forever)) {
-		fibril_mutex_lock(&received_lock);
-		received = RECEIVED_NONE;
-		fibril_mutex_unlock(&received_lock);
-		
-		(void) ping_send(++seq_no);
-		
-		fibril_mutex_lock(&received_lock);
-		int rc = fibril_condvar_wait_timeout(&received_cv, &received_lock,
-		    PING_TIMEOUT);
-		received_t recv = received;
-		fibril_mutex_unlock(&received_lock);
-		
-		if ((rc == ETIMEOUT) || (recv == RECEIVED_NONE))
-			printf("Echo request timed out (seq. no %u)\n", seq_no);
-		
-		if (recv == RECEIVED_INTERRUPT)
-			break;
-		
-		if ((repeat_count > 0) || (repeat_forever)) {
-			fibril_mutex_lock(&received_lock);
-			rc = fibril_condvar_wait_timeout(&received_cv, &received_lock,
-			    PING_DELAY);
-			recv = received;
-			fibril_mutex_unlock(&received_lock);
-			
-			if (recv == RECEIVED_INTERRUPT)
-				break;
-		}
-	}
-	
-	ping_signal_quit();
-	return 0;
-}
-
-static int input_fibril(void *arg)
-{
-	console_ctrl_t *con = console_init(stdin, stdout);
-	
-	while (true) {
-		cons_event_t ev;
-		if (!console_get_event(con, &ev))
-			break;
-		
-		if ((ev.type == CEV_KEY) && (ev.ev.key.type == KEY_PRESS) &&
-		    ((ev.ev.key.mods & (KM_ALT | KM_SHIFT)) == 0) &&
-		    ((ev.ev.key.mods & KM_CTRL) != 0)) {
-			/* Ctrl+key */
-			if (ev.ev.key.key == KC_Q) {
-				ping_signal_received(RECEIVED_INTERRUPT);
-				break;
-			}
-		}
-	}
-	
-	return 0;
-}
-
-int main(int argc, char *argv[])
-{
-	dnsr_hostinfo_t *hinfo = NULL;
-	char *asrc = NULL;
-	char *adest = NULL;
-	char *sdest = NULL;
-	
-	int rc = inetping6_init(&ev_ops);
-	if (rc != EOK) {
-		printf("Failed connecting to internet ping service: "
-		    "%s (%d).\n", str_error(rc), rc);
-		goto error;
-	}
-	
-	int c;
-	while ((c = getopt(argc, argv, short_options)) != -1) {
-		switch (c) {
-		case 'r':
-			repeat_forever = true;
-			break;
-		case 'n':
-			rc = str_size_t(optarg, NULL, 10, true, &repeat_count);
-			if (rc != EOK) {
-				printf("Invalid repeat count.\n");
-				print_syntax();
-				goto error;
-			}
-			break;
-		default:
-			printf("Unknown option passed.\n");
-			print_syntax();
-			goto error;
-		}
-	}
-	
-	if (optind >= argc) {
-		printf("IP address or host name not supplied.\n");
-		print_syntax();
-		goto error;
-	}
-	
-	/* Parse destination address */
-	inet_addr_t dest_addr;
-	rc = inet_addr_parse(argv[optind], &dest_addr);
-	if (rc != EOK) {
-		/* Try interpreting as a host name */
-		rc = dnsr_name2host(argv[optind], &hinfo, ip_v6);
-		if (rc != EOK) {
-			printf("Error resolving host '%s'.\n", argv[optind]);
-			goto error;
-		}
-		
-		dest_addr = hinfo->addr;
-	}
-	
-	ip_ver_t ver = inet_addr_get(&dest_addr, NULL, &dest);
-	if (ver != ip_v6) {
-		printf("Destination '%s' is not an IPv6 address.\n",
-		    argv[optind]);
-		goto error;
-	}
-	
-	/* Determine source address */
-	rc = inetping6_get_srcaddr(dest, src);
-	if (rc != EOK) {
-		printf("Failed determining source address.\n");
-		goto error;
-	}
-	
-	inet_addr_t src_addr;
-	inet_addr_set6(src, &src_addr);
-	
-	rc = inet_addr_format(&src_addr, &asrc);
-	if (rc != EOK) {
-		printf("Out of memory.\n");
-		goto error;
-	}
-	
-	rc = inet_addr_format(&dest_addr, &adest);
-	if (rc != EOK) {
-		printf("Out of memory.\n");
-		goto error;
-	}
-	
-	if (hinfo != NULL) {
-		rc = asprintf(&sdest, "%s (%s)", hinfo->cname, adest);
-		if (rc < 0) {
-			printf("Out of memory.\n");
-			goto error;
-		}
-	} else {
-		sdest = adest;
-		adest = NULL;
-	}
-	
-	printf("Sending ICMP echo request from %s to %s (Ctrl+Q to quit)\n",
-	    asrc, sdest);
-	
-	fid_t fid = fibril_create(transmit_fibril, NULL);
-	if (fid == 0) {
-		printf("Failed creating transmit fibril.\n");
-		goto error;
-	}
-	
-	fibril_add_ready(fid);
-	
-	fid = fibril_create(input_fibril, NULL);
-	if (fid == 0) {
-		printf("Failed creating input fibril.\n");
-		goto error;
-	}
-	
-	fibril_add_ready(fid);
-	
-	fibril_mutex_lock(&quit_lock);
-	while (!quit)
-		fibril_condvar_wait(&quit_cv, &quit_lock);
-	fibril_mutex_unlock(&quit_lock);
-	
-	free(asrc);
-	free(adest);
-	free(sdest);
-	dnsr_hostinfo_destroy(hinfo);
-	return 0;
-	
-error:
-	free(asrc);
-	free(adest);
-	free(sdest);
-	dnsr_hostinfo_destroy(hinfo);
-	return 1;
-}
-
-/** @}
- */
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/lib/c/Makefile	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -100,5 +100,4 @@
 	generic/inetcfg.c \
 	generic/inetping.c \
-	generic/inetping6.c \
 	generic/io/asprintf.c \
 	generic/io/input.c \
Index: uspace/lib/c/generic/inetping.c
===================================================================
--- uspace/lib/c/generic/inetping.c	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/lib/c/generic/inetping.c	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -1,4 +1,5 @@
 /*
- * Copyright (c) 2012 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
+ * Copyright (c) 2013 Martin Decky
  * All rights reserved.
  *
@@ -49,22 +50,22 @@
 
 	assert(inetping_sess == NULL);
-	
+
 	inetping_ev_ops = ev_ops;
-	
+
 	rc = loc_service_get_id(SERVICE_NAME_INETPING, &inetping_svc,
 	    IPC_FLAG_BLOCKING);
 	if (rc != EOK)
 		return ENOENT;
-	
+
 	inetping_sess = loc_service_connect(EXCHANGE_SERIALIZE, inetping_svc,
 	    IPC_FLAG_BLOCKING);
 	if (inetping_sess == NULL)
 		return ENOENT;
-	
+
 	async_exch_t *exch = async_exchange_begin(inetping_sess);
 
 	rc = async_connect_to_me(exch, 0, 0, 0, inetping_cb_conn, NULL);
 	async_exchange_end(exch);
-	
+
 	if (rc != EOK) {
 		async_hangup(inetping_sess);
@@ -72,5 +73,5 @@
 		return rc;
 	}
-	
+
 	return EOK;
 }
@@ -79,55 +80,126 @@
 {
 	async_exch_t *exch = async_exchange_begin(inetping_sess);
-	
+
 	ipc_call_t answer;
-	aid_t req = async_send_3(exch, INETPING_SEND, (sysarg_t) sdu->src,
-	    (sysarg_t) sdu->dest, sdu->seq_no, &answer);
-	sysarg_t retval = async_data_write_start(exch, sdu->data, sdu->size);
-	
+	aid_t req = async_send_1(exch, INETPING_SEND, sdu->seq_no, &answer);
+
+	int rc = async_data_write_start(exch, &sdu->src, sizeof(sdu->src));
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		async_forget(req);
+		return rc;
+	}
+
+	rc = async_data_write_start(exch, &sdu->dest, sizeof(sdu->dest));
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		async_forget(req);
+		return rc;
+	}
+
+	rc = async_data_write_start(exch, sdu->data, sdu->size);
+
 	async_exchange_end(exch);
-	
-	if (retval != EOK) {
-		async_forget(req);
-		return retval;
-	}
-	
+
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+
+	sysarg_t retval;
 	async_wait_for(req, &retval);
-	return retval;
-}
-
-int inetping_get_srcaddr(uint32_t remote, uint32_t *local)
+
+	return (int) retval;
+}
+
+int inetping_get_srcaddr(const inet_addr_t *remote, inet_addr_t *local)
 {
 	async_exch_t *exch = async_exchange_begin(inetping_sess);
-	
-	sysarg_t local_addr;
-	int rc = async_req_1_1(exch, INETPING_GET_SRCADDR, (sysarg_t) remote,
-	    &local_addr);
-	
+
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, INETPING_GET_SRCADDR, &answer);
+
+	int rc = async_data_write_start(exch, remote, sizeof(*remote));
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		async_forget(req);
+		return rc;
+	}
+
+	ipc_call_t answer_local;
+	aid_t req_local = async_data_read(exch, local, sizeof(*local),
+	    &answer_local);
+
 	async_exchange_end(exch);
-	
-	if (rc != EOK)
-		return rc;
-	
-	*local = (uint32_t) local_addr;
-	return EOK;
-}
-
-static void inetping_ev_recv(ipc_callid_t callid, ipc_call_t *call)
+
+	sysarg_t retval_local;
+	async_wait_for(req_local, &retval_local);
+
+	if (retval_local != EOK) {
+		async_forget(req);
+		return (int) retval_local;
+	}
+
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+
+	return (int) retval;
+}
+
+static void inetping_ev_recv(ipc_callid_t iid, ipc_call_t *icall)
 {
 	inetping_sdu_t sdu;
-	
-	sdu.src = IPC_GET_ARG1(*call);
-	sdu.dest = IPC_GET_ARG2(*call);
-	sdu.seq_no = IPC_GET_ARG3(*call);
-	
-	int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
+
+	sdu.seq_no = IPC_GET_ARG1(*icall);
+
+	ipc_callid_t callid;
+	size_t size;
+	if (!async_data_write_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(sdu.src)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(iid, EINVAL);
+		return;
+	}
+
+	int rc = async_data_write_finalize(callid, &sdu.src, size);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
-		return;
-	}
-	
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	if (!async_data_write_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(sdu.dest)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(iid, EINVAL);
+		return;
+	}
+
+	rc = async_data_write_finalize(callid, &sdu.dest, size);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
+	if (rc != EOK) {
+		async_answer_0(iid, rc);
+		return;
+	}
+
 	rc = inetping_ev_ops->recv(&sdu);
 	free(sdu.data);
-	async_answer_0(callid, rc);
+	async_answer_0(iid, rc);
 }
 
Index: uspace/lib/c/generic/inetping6.c
===================================================================
--- uspace/lib/c/generic/inetping6.c	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ 	(revision )
@@ -1,225 +1,0 @@
-/*
- * Copyright (c) 2013 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <async.h>
-#include <assert.h>
-#include <errno.h>
-#include <inet/inetping6.h>
-#include <ipc/inet.h>
-#include <ipc/services.h>
-#include <loc.h>
-#include <stdlib.h>
-#include <str.h>
-
-static void inetping6_cb_conn(ipc_callid_t, ipc_call_t *, void *);
-static void inetping6_ev_recv(ipc_callid_t, ipc_call_t *);
-
-static async_sess_t *inetping6_sess = NULL;
-static inetping6_ev_ops_t *inetping6_ev_ops;
-
-int inetping6_init(inetping6_ev_ops_t *ev_ops)
-{
-	assert(inetping6_sess == NULL);
-	
-	inetping6_ev_ops = ev_ops;
-	
-	service_id_t inetping6_svc;
-	int rc = loc_service_get_id(SERVICE_NAME_INETPING6, &inetping6_svc,
-	    IPC_FLAG_BLOCKING);
-	if (rc != EOK)
-		return ENOENT;
-	
-	inetping6_sess = loc_service_connect(EXCHANGE_SERIALIZE, inetping6_svc,
-	    IPC_FLAG_BLOCKING);
-	if (inetping6_sess == NULL)
-		return ENOENT;
-	
-	async_exch_t *exch = async_exchange_begin(inetping6_sess);
-	
-	rc = async_connect_to_me(exch, 0, 0, 0, inetping6_cb_conn, NULL);
-	async_exchange_end(exch);
-	
-	if (rc != EOK) {
-		async_hangup(inetping6_sess);
-		inetping6_sess = NULL;
-		return rc;
-	}
-	
-	return EOK;
-}
-
-int inetping6_send(inetping6_sdu_t *sdu)
-{
-	async_exch_t *exch = async_exchange_begin(inetping6_sess);
-	
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, INETPING6_SEND, sdu->seq_no, &answer);
-	
-	int rc = async_data_write_start(exch, &sdu->src, sizeof(addr128_t));
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		async_forget(req);
-		return rc;
-	}
-	
-	rc = async_data_write_start(exch, &sdu->dest, sizeof(addr128_t));
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		async_forget(req);
-		return rc;
-	}
-	
-	rc = async_data_write_start(exch, sdu->data, sdu->size);
-	
-	async_exchange_end(exch);
-	
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-	
-	sysarg_t retval;
-	async_wait_for(req, &retval);
-	
-	return (int) retval;
-}
-
-int inetping6_get_srcaddr(addr128_t remote, addr128_t local)
-{
-	async_exch_t *exch = async_exchange_begin(inetping6_sess);
-	
-	ipc_call_t answer;
-	aid_t req = async_send_0(exch, INETPING6_GET_SRCADDR, &answer);
-	
-	int rc = async_data_write_start(exch, remote, sizeof(addr128_t));
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		async_forget(req);
-		return rc;
-	}
-	
-	ipc_call_t answer_local;
-	aid_t req_local = async_data_read(exch, local, sizeof(addr128_t),
-	    &answer_local);
-	
-	async_exchange_end(exch);
-	
-	sysarg_t retval_local;
-	async_wait_for(req_local, &retval_local);
-	
-	if (retval_local != EOK) {
-		async_forget(req);
-		return (int) retval_local;
-	}
-	
-	sysarg_t retval;
-	async_wait_for(req, &retval);
-	
-	return (int) retval;
-}
-
-static void inetping6_ev_recv(ipc_callid_t iid, ipc_call_t *icall)
-{
-	inetping6_sdu_t sdu;
-	
-	sdu.seq_no = IPC_GET_ARG1(*icall);
-	
-	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		async_answer_0(callid, EREFUSED);
-		async_answer_0(iid, EREFUSED);
-		return;
-	}
-	
-	if (size != sizeof(addr128_t)) {
-		async_answer_0(callid, EINVAL);
-		async_answer_0(iid, EINVAL);
-		return;
-	}
-	
-	int rc = async_data_write_finalize(callid, &sdu.src, size);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		async_answer_0(iid, rc);
-		return;
-	}
-	
-	if (!async_data_write_receive(&callid, &size)) {
-		async_answer_0(callid, EREFUSED);
-		async_answer_0(iid, EREFUSED);
-		return;
-	}
-	
-	if (size != sizeof(addr128_t)) {
-		async_answer_0(callid, EINVAL);
-		async_answer_0(iid, EINVAL);
-		return;
-	}
-	
-	rc = async_data_write_finalize(callid, &sdu.dest, size);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		async_answer_0(iid, rc);
-		return;
-	}
-	
-	rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
-	if (rc != EOK) {
-		async_answer_0(iid, rc);
-		return;
-	}
-	
-	rc = inetping6_ev_ops->recv(&sdu);
-	free(sdu.data);
-	async_answer_0(iid, rc);
-}
-
-static void inetping6_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	while (true) {
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		
-		if (!IPC_GET_IMETHOD(call)) {
-			/* TODO: Handle hangup */
-			return;
-		}
-		
-		switch (IPC_GET_IMETHOD(call)) {
-		case INETPING6_EV_RECV:
-			inetping6_ev_recv(callid, &call);
-			break;
-		default:
-			async_answer_0(callid, ENOTSUP);
-		}
-	}
-}
-
-/** @}
- */
Index: uspace/lib/c/include/inet/inetping.h
===================================================================
--- uspace/lib/c/include/inet/inetping.h	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/lib/c/include/inet/inetping.h	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2012 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
  * All rights reserved.
  *
@@ -46,5 +46,5 @@
 extern int inetping_init(inetping_ev_ops_t *);
 extern int inetping_send(inetping_sdu_t *);
-extern int inetping_get_srcaddr(uint32_t, uint32_t *);
+extern int inetping_get_srcaddr(const inet_addr_t *, inet_addr_t *);
 
 #endif
Index: uspace/lib/c/include/inet/inetping6.h
===================================================================
--- uspace/lib/c/include/inet/inetping6.h	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * Copyright (c) 2013 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_INET_INETPING6_H_
-#define LIBC_INET_INETPING6_H_
-
-#include <inet/inet.h>
-#include <sys/types.h>
-#include <types/inetping6.h>
-
-typedef struct inetping6_ev_ops {
-	int (*recv)(inetping6_sdu_t *);
-} inetping6_ev_ops_t;
-
-extern int inetping6_init(inetping6_ev_ops_t *);
-extern int inetping6_send(inetping6_sdu_t *);
-extern int inetping6_get_srcaddr(addr128_t, addr128_t);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/ipc/inet.h
===================================================================
--- uspace/lib/c/include/ipc/inet.h	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/lib/c/include/ipc/inet.h	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -92,15 +92,4 @@
 } inetping_request_t;
 
-/** Events on Inet ping6 port */
-typedef enum {
-	INETPING6_EV_RECV = IPC_FIRST_USER_METHOD
-} inetping6_event_t;
-
-/** Requests on Inet ping6 port */
-typedef enum {
-	INETPING6_SEND = IPC_FIRST_USER_METHOD,
-	INETPING6_GET_SRCADDR
-} inetping6_request_t;
-
 #endif
 
Index: uspace/lib/c/include/types/inetping.h
===================================================================
--- uspace/lib/c/include/types/inetping.h	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/lib/c/include/types/inetping.h	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -38,9 +38,10 @@
 #define LIBC_TYPES_INETPING_H_
 
+#include <inet/addr.h>
 #include <sys/types.h>
 
 typedef struct {
-	uint32_t src;
-	uint32_t dest;
+	inet_addr_t src;
+	inet_addr_t dest;
 	uint16_t seq_no;
 	void *data;
Index: uspace/lib/c/include/types/inetping6.h
===================================================================
--- uspace/lib/c/include/types/inetping6.h	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2013 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libc
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef LIBC_TYPES_INETPING6_H_
-#define LIBC_TYPES_INETPING6_H_
-
-#include <inet/addr.h>
-#include <sys/types.h>
-
-typedef struct {
-	addr128_t src;
-	addr128_t dest;
-	uint16_t seq_no;
-	void *data;
-	size_t size;
-} inetping6_sdu_t;
-
-#endif
-
-/** @}
- */
Index: uspace/srv/net/inetsrv/Makefile
===================================================================
--- uspace/srv/net/inetsrv/Makefile	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/srv/net/inetsrv/Makefile	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -38,5 +38,4 @@
 	inetcfg.c \
 	inetping.c \
-	inetping6.c \
 	ndp.c \
 	ntrans.c \
Index: uspace/srv/net/inetsrv/icmp.c
===================================================================
--- uspace/srv/net/inetsrv/icmp.c	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/srv/net/inetsrv/icmp.c	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -130,12 +130,6 @@
 	inetping_sdu_t sdu;
 
-	ip_ver_t ver = inet_addr_get(&dgram->src, &sdu.src, NULL);
-	if (ver != ip_v4)
-		return EINVAL;
-
-	ver = inet_addr_get(&dgram->dest, &sdu.dest, NULL);
-	if (ver != ip_v4)
-		return EINVAL;
-
+	sdu.src = dgram->src;
+	sdu.dest = dgram->dest;
 	sdu.seq_no = uint16_t_be2host(reply->seq_no);
 	sdu.data = reply + sizeof(icmp_echo_t);
@@ -169,7 +163,6 @@
 	inet_dgram_t dgram;
 
-	inet_addr_set(sdu->src, &dgram.src);
-	inet_addr_set(sdu->dest, &dgram.dest);
-
+	dgram.src = sdu->src;
+	dgram.dest = sdu->dest;
 	dgram.iplink = 0;
 	dgram.tos = ICMP_TOS;
Index: uspace/srv/net/inetsrv/icmpv6.c
===================================================================
--- uspace/srv/net/inetsrv/icmpv6.c	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/srv/net/inetsrv/icmpv6.c	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -40,9 +40,9 @@
 #include <mem.h>
 #include <stdlib.h>
-#include <types/inetping6.h>
+#include <types/inetping.h>
 #include "icmpv6.h"
 #include "icmpv6_std.h"
 #include "inetsrv.h"
-#include "inetping6.h"
+#include "inetping.h"
 #include "pdu.h"
 
@@ -116,11 +116,8 @@
 		return EINVAL;
 	
-	inetping6_sdu_t sdu;
-	
-	ip_ver_t src_ver = inet_addr_get(&dgram->src, NULL, &sdu.src);
-	ip_ver_t dest_ver = inet_addr_get(&dgram->dest, NULL, &sdu.dest);
-	
-	if ((src_ver != dest_ver) || (src_ver != ip_v6))
-		return EINVAL;
+	inetping_sdu_t sdu;
+	
+	sdu.src = dgram->src;
+	sdu.dest = dgram->dest;
 	
 	icmpv6_message_t *reply = (icmpv6_message_t *) dgram->data;
@@ -132,5 +129,5 @@
 	uint16_t ident = uint16_t_be2host(reply->un.echo.ident);
 	
-	return inetping6_recv(ident, &sdu);
+	return inetping_recv(ident, &sdu);
 }
 
@@ -160,5 +157,5 @@
 }
 
-int icmpv6_ping_send(uint16_t ident, inetping6_sdu_t *sdu)
+int icmpv6_ping_send(uint16_t ident, inetping_sdu_t *sdu)
 {
 	size_t rsize = sizeof(icmpv6_message_t) + sdu->size;
@@ -179,6 +176,6 @@
 	inet_dgram_t dgram;
 	
-	inet_addr_set6(sdu->src, &dgram.src);
-	inet_addr_set6(sdu->dest, &dgram.dest);
+	dgram.src = sdu->src;
+	dgram.dest = sdu->dest;
 	dgram.iplink = 0;
 	dgram.tos = 0;
@@ -188,6 +185,9 @@
 	icmpv6_phdr_t phdr;
 	
-	host2addr128_t_be(sdu->src, phdr.src_addr);
-	host2addr128_t_be(sdu->dest, phdr.dest_addr);
+	assert(sdu->src.version == ip_v6);
+	assert(sdu->dest.version == ip_v6);
+	
+	host2addr128_t_be(sdu->src.addr6, phdr.src_addr);
+	host2addr128_t_be(sdu->dest.addr6, phdr.dest_addr);
 	phdr.length = host2uint32_t_be(dgram.size);
 	memset(phdr.zeroes, 0, 3);
Index: uspace/srv/net/inetsrv/icmpv6.h
===================================================================
--- uspace/srv/net/inetsrv/icmpv6.h	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/srv/net/inetsrv/icmpv6.h	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -38,9 +38,9 @@
 #define ICMPV6_H_
 
-#include <types/inetping6.h>
+#include <types/inetping.h>
 #include "inetsrv.h"
 
 extern int icmpv6_recv(inet_dgram_t *);
-extern int icmpv6_ping_send(uint16_t, inetping6_sdu_t *);
+extern int icmpv6_ping_send(uint16_t, inetping_sdu_t *);
 
 #endif
Index: uspace/srv/net/inetsrv/inetping.c
===================================================================
--- uspace/srv/net/inetsrv/inetping.c	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/srv/net/inetsrv/inetping.c	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -1,4 +1,5 @@
 /*
- * Copyright (c) 2012 Jiri Svoboda
+ * Copyright (c) 2013 Jiri Svoboda
+ * Copyright (c) 2013 Martin Decky
  * All rights reserved.
  *
@@ -45,4 +46,5 @@
 #include <types/inetping.h>
 #include "icmp.h"
+#include "icmpv6.h"
 #include "icmp_std.h"
 #include "inetsrv.h"
@@ -57,23 +59,21 @@
 static int inetping_send(inetping_client_t *client, inetping_sdu_t *sdu)
 {
-	return icmp_ping_send(client->ident, sdu);
-}
-
-static int inetping_get_srcaddr(inetping_client_t *client, addr32_t remote,
-    addr32_t *local)
-{
-	inet_addr_t remote_addr;
-	inet_addr_set(remote, &remote_addr);
-	
-	inet_addr_t local_addr;
-	int rc = inet_get_srcaddr(&remote_addr, ICMP_TOS, &local_addr);
-	if (rc != EOK)
-		return rc;
-	
-	ip_ver_t ver = inet_addr_get(&local_addr, local, NULL);
-	if (ver != ip_v4)
+	if (sdu->src.version != sdu->dest.version)
 		return EINVAL;
-	
-	return EOK;
+
+	switch (sdu->src.version) {
+	case ip_v4:
+		return icmp_ping_send(client->ident, sdu);
+	case ip_v6:
+		return icmpv6_ping_send(client->ident, sdu);
+	default:
+		return EINVAL;
+	}
+}
+
+static int inetping_get_srcaddr(inetping_client_t *client,
+    inet_addr_t *remote, inet_addr_t *local)
+{
+	return inet_get_srcaddr(remote, ICMP_TOS, local);
 }
 
@@ -81,5 +81,5 @@
 {
 	fibril_mutex_lock(&client_list_lock);
-	
+
 	list_foreach(client_list, client_list, inetping_client_t, client) {
 		if (client->ident == ident) {
@@ -88,5 +88,5 @@
 		}
 	}
-	
+
 	fibril_mutex_unlock(&client_list_lock);
 	return NULL;
@@ -100,60 +100,155 @@
 		return ENOENT;
 	}
-	
+
 	async_exch_t *exch = async_exchange_begin(client->sess);
-	
+
 	ipc_call_t answer;
-	aid_t req = async_send_3(exch, INETPING_EV_RECV, (sysarg_t) sdu->src,
-	    (sysarg_t) sdu->dest, sdu->seq_no, &answer);
-	int rc = async_data_write_start(exch, sdu->data, sdu->size);
-	
-	async_exchange_end(exch);
-	
-	if (rc != EOK) {
+	aid_t req = async_send_1(exch, INETPING_EV_RECV, sdu->seq_no, &answer);
+
+	int rc = async_data_write_start(exch, &sdu->src, sizeof(sdu->src));
+	if (rc != EOK) {
+		async_exchange_end(exch);
 		async_forget(req);
 		return rc;
 	}
-	
+
+	rc = async_data_write_start(exch, &sdu->dest, sizeof(sdu->dest));
+	if (rc != EOK) {
+		async_exchange_end(exch);
+		async_forget(req);
+		return rc;
+	}
+
+	rc = async_data_write_start(exch, sdu->data, sdu->size);
+
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+
 	sysarg_t retval;
 	async_wait_for(req, &retval);
-	
+
 	return (int) retval;
 }
 
-static void inetping_send_srv(inetping_client_t *client, ipc_callid_t callid,
-    ipc_call_t *call)
-{
+static void inetping_send_srv(inetping_client_t *client, ipc_callid_t iid,
+    ipc_call_t *icall)
+{
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_send_srv()");
+
 	inetping_sdu_t sdu;
 	int rc;
 
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_send_srv()");
+	sdu.seq_no = IPC_GET_ARG1(*icall);
+
+	ipc_callid_t callid;
+	size_t size;
+	if (!async_data_write_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(sdu.src)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(iid, EINVAL);
+		return;
+	}
+
+	rc = async_data_write_finalize(callid, &sdu.src, size);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	if (!async_data_write_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(sdu.dest)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(iid, EINVAL);
+		return;
+	}
+
+	rc = async_data_write_finalize(callid, &sdu.dest, size);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		async_answer_0(iid, rc);
+		return;
+	}
 
 	rc = async_data_write_accept((void **) &sdu.data, false, 0, 0, 0,
 	    &sdu.size);
 	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	sdu.src = IPC_GET_ARG1(*call);
-	sdu.dest = IPC_GET_ARG2(*call);
-	sdu.seq_no = IPC_GET_ARG3(*call);
+		async_answer_0(iid, rc);
+		return;
+	}
 
 	rc = inetping_send(client, &sdu);
 	free(sdu.data);
 
-	async_answer_0(callid, rc);
+	async_answer_0(iid, rc);
 }
 
 static void inetping_get_srcaddr_srv(inetping_client_t *client,
-    ipc_callid_t callid, ipc_call_t *call)
+    ipc_callid_t iid, ipc_call_t *icall)
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_get_srcaddr_srv()");
-	
-	uint32_t remote = IPC_GET_ARG1(*call);
-	uint32_t local = 0;
-	
-	int rc = inetping_get_srcaddr(client, remote, &local);
-	async_answer_1(callid, rc, (sysarg_t) local);
+
+	ipc_callid_t callid;
+	size_t size;
+
+	inet_addr_t local;
+	inet_addr_t remote;
+
+	if (!async_data_write_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(remote)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(iid, EINVAL);
+		return;
+	}
+
+	int rc = async_data_write_finalize(callid, &remote, size);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	rc = inetping_get_srcaddr(client, &remote, &local);
+	if (rc != EOK) {
+		async_answer_0(iid, rc);
+		return;
+	}
+
+	if (!async_data_read_receive(&callid, &size)) {
+		async_answer_0(callid, EREFUSED);
+		async_answer_0(iid, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(local)) {
+		async_answer_0(callid, EINVAL);
+		async_answer_0(iid, EINVAL);
+		return;
+	}
+
+	rc = async_data_read_finalize(callid, &local, size);
+	if (rc != EOK)
+		async_answer_0(callid, rc);
+
+	async_answer_0(iid, rc);
 }
 
@@ -163,13 +258,13 @@
 	if (sess == NULL)
 		return ENOMEM;
-	
+
 	client->sess = sess;
 	link_initialize(&client->client_list);
-	
+
 	fibril_mutex_lock(&client_list_lock);
 	client->ident = ++inetping_ident;
 	list_append(&client->client_list, &client_list);
 	fibril_mutex_unlock(&client_list_lock);
-	
+
 	return EOK;
 }
@@ -179,5 +274,5 @@
 	async_hangup(client->sess);
 	client->sess = NULL;
-	
+
 	fibril_mutex_lock(&client_list_lock);
 	list_remove(&client->client_list);
@@ -188,18 +283,18 @@
 {
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_conn()");
-	
+
 	/* Accept the connection */
 	async_answer_0(iid, EOK);
-	
+
 	inetping_client_t client;
 	int rc = inetping_client_init(&client);
 	if (rc != EOK)
 		return;
-	
+
 	while (true) {
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
 		sysarg_t method = IPC_GET_IMETHOD(call);
-		
+
 		if (!method) {
 			/* The other side has hung up */
@@ -207,5 +302,5 @@
 			break;
 		}
-		
+
 		switch (method) {
 		case INETPING_SEND:
@@ -219,5 +314,5 @@
 		}
 	}
-	
+
 	inetping_client_fini(&client);
 }
Index: uspace/srv/net/inetsrv/inetping6.c
===================================================================
--- uspace/srv/net/inetsrv/inetping6.c	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ 	(revision )
@@ -1,318 +1,0 @@
-/*
- * Copyright (c) 2013 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#include <async.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <io/log.h>
-#include <ipc/inet.h>
-#include <loc.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <types/inetping6.h>
-#include "icmpv6.h"
-#include "icmpv6_std.h"
-#include "inetsrv.h"
-#include "inetping6.h"
-
-static FIBRIL_MUTEX_INITIALIZE(client_list_lock);
-static LIST_INITIALIZE(client_list);
-
-/** Last used session identifier. Protected by @c client_list_lock */
-static uint16_t inetping6_ident = 0;
-
-static int inetping6_send(inetping6_client_t *client, inetping6_sdu_t *sdu)
-{
-	return icmpv6_ping_send(client->ident, sdu);
-}
-
-static int inetping6_get_srcaddr(inetping6_client_t *client, addr128_t remote,
-    addr128_t *local)
-{
-	inet_addr_t remote_addr;
-	inet_addr_set6(remote, &remote_addr);
-	
-	inet_addr_t local_addr;
-	int rc = inet_get_srcaddr(&remote_addr, ICMPV6_TOS, &local_addr);
-	if (rc != EOK)
-		return rc;
-	
-	ip_ver_t ver = inet_addr_get(&local_addr, NULL, local);
-	if (ver != ip_v6)
-		return EINVAL;
-	
-	return EOK;
-}
-
-static inetping6_client_t *inetping6_client_find(uint16_t ident)
-{
-	fibril_mutex_lock(&client_list_lock);
-	
-	list_foreach(client_list, client_list, inetping6_client_t, client) {
-		if (client->ident == ident) {
-			fibril_mutex_unlock(&client_list_lock);
-			return client;
-		}
-	}
-	
-	fibril_mutex_unlock(&client_list_lock);
-	return NULL;
-}
-
-int inetping6_recv(uint16_t ident, inetping6_sdu_t *sdu)
-{
-	inetping6_client_t *client = inetping6_client_find(ident);
-	if (client == NULL) {
-		log_msg(LOG_DEFAULT, LVL_DEBUG, "Unknown ICMP ident. Dropping.");
-		return ENOENT;
-	}
-	
-	async_exch_t *exch = async_exchange_begin(client->sess);
-	
-	ipc_call_t answer;
-	aid_t req = async_send_1(exch, INETPING6_EV_RECV, sdu->seq_no, &answer);
-	
-	int rc = async_data_write_start(exch, sdu->src, sizeof(addr128_t));
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		async_forget(req);
-		return rc;
-	}
-	
-	rc = async_data_write_start(exch, sdu->dest, sizeof(addr128_t));
-	if (rc != EOK) {
-		async_exchange_end(exch);
-		async_forget(req);
-		return rc;
-	}
-	
-	rc = async_data_write_start(exch, sdu->data, sdu->size);
-	
-	async_exchange_end(exch);
-	
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-	
-	sysarg_t retval;
-	async_wait_for(req, &retval);
-	
-	return (int) retval;
-}
-
-static void inetping6_send_srv(inetping6_client_t *client, ipc_callid_t iid,
-    ipc_call_t *icall)
-{
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping6_send_srv()");
-	
-	inetping6_sdu_t sdu;
-	
-	sdu.seq_no = IPC_GET_ARG1(*icall);
-	
-	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		async_answer_0(callid, EREFUSED);
-		async_answer_0(iid, EREFUSED);
-		return;
-	}
-	
-	if (size != sizeof(addr128_t)) {
-		async_answer_0(callid, EINVAL);
-		async_answer_0(iid, EINVAL);
-		return;
-	}
-	
-	int rc = async_data_write_finalize(callid, &sdu.src, size);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		async_answer_0(iid, rc);
-		return;
-	}
-	
-	if (!async_data_write_receive(&callid, &size)) {
-		async_answer_0(callid, EREFUSED);
-		async_answer_0(iid, EREFUSED);
-		return;
-	}
-	
-	if (size != sizeof(addr128_t)) {
-		async_answer_0(callid, EINVAL);
-		async_answer_0(iid, EINVAL);
-		return;
-	}
-	
-	rc = async_data_write_finalize(callid, &sdu.dest, size);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		async_answer_0(iid, rc);
-		return;
-	}
-	
-	rc = async_data_write_accept((void **) &sdu.data, false, 0, 0, 0,
-	    &sdu.size);
-	if (rc != EOK) {
-		async_answer_0(iid, rc);
-		return;
-	}
-	
-	rc = inetping6_send(client, &sdu);
-	free(sdu.data);
-	
-	async_answer_0(iid, rc);
-}
-
-static void inetping6_get_srcaddr_srv(inetping6_client_t *client,
-    ipc_callid_t iid, ipc_call_t *icall)
-{
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping6_get_srcaddr_srv()");
-	
-	ipc_callid_t callid;
-	size_t size;
-	if (!async_data_write_receive(&callid, &size)) {
-		async_answer_0(callid, EREFUSED);
-		async_answer_0(iid, EREFUSED);
-		return;
-	}
-	
-	if (size != sizeof(addr128_t)) {
-		async_answer_0(callid, EINVAL);
-		async_answer_0(iid, EINVAL);
-		return;
-	}
-	
-	addr128_t remote;
-	int rc = async_data_write_finalize(callid, &remote, size);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		async_answer_0(iid, rc);
-		return;
-	}
-	
-	addr128_t local;
-	rc = inetping6_get_srcaddr(client, remote, &local);
-	if (rc != EOK) {
-		async_answer_0(iid, rc);
-		return;
-	}
-	
-	if (!async_data_read_receive(&callid, &size)) {
-		async_answer_0(callid, EREFUSED);
-		async_answer_0(iid, EREFUSED);
-		return;
-	}
-	
-	if (size != sizeof(addr128_t)) {
-		async_answer_0(callid, EINVAL);
-		async_answer_0(iid, EINVAL);
-		return;
-	}
-	
-	rc = async_data_read_finalize(callid, &local, size);
-	if (rc != EOK)
-		async_answer_0(callid, rc);
-	
-	async_answer_0(iid, rc);
-}
-
-static int inetping6_client_init(inetping6_client_t *client)
-{
-	async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
-	if (sess == NULL)
-		return ENOMEM;
-	
-	client->sess = sess;
-	link_initialize(&client->client_list);
-	
-	fibril_mutex_lock(&client_list_lock);
-	client->ident = ++inetping6_ident;
-	list_append(&client->client_list, &client_list);
-	fibril_mutex_unlock(&client_list_lock);
-	
-	return EOK;
-}
-
-static void inetping6_client_fini(inetping6_client_t *client)
-{
-	async_hangup(client->sess);
-	client->sess = NULL;
-	
-	fibril_mutex_lock(&client_list_lock);
-	list_remove(&client->client_list);
-	fibril_mutex_unlock(&client_list_lock);
-}
-
-void inetping6_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping6_conn()");
-	
-	/* Accept the connection */
-	async_answer_0(iid, EOK);
-	
-	inetping6_client_t client;
-	int rc = inetping6_client_init(&client);
-	if (rc != EOK)
-		return;
-	
-	while (true) {
-		ipc_call_t call;
-		ipc_callid_t callid = async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
-		
-		if (!method) {
-			/* The other side has hung up */
-			async_answer_0(callid, EOK);
-			break;
-		}
-		
-		switch (method) {
-		case INETPING6_SEND:
-			inetping6_send_srv(&client, callid, &call);
-			break;
-		case INETPING6_GET_SRCADDR:
-			inetping6_get_srcaddr_srv(&client, callid, &call);
-			break;
-		default:
-			async_answer_0(callid, EINVAL);
-		}
-	}
-	
-	inetping6_client_fini(&client);
-}
-
-/** @}
- */
Index: uspace/srv/net/inetsrv/inetping6.h
===================================================================
--- uspace/srv/net/inetsrv/inetping6.h	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2013 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INETPING6_H_
-#define INETPING6_H_
-
-#include <types/inetping6.h>
-#include "inetsrv.h"
-
-extern void inetping6_conn(ipc_callid_t, ipc_call_t *, void *);
-extern int inetping6_recv(uint16_t, inetping6_sdu_t *);
-
-#endif
-
-/** @}
- */
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision 26de91ad6075a30c55e624bbca95373c9209119e)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision 9749e47d9efec6b7b9d27ae765528f534d823763)
@@ -54,5 +54,4 @@
 #include "inetcfg.h"
 #include "inetping.h"
-#include "inetping6.h"
 #include "inet_link.h"
 #include "reass.h"
@@ -111,11 +110,4 @@
 	rc = loc_service_register_with_iface(SERVICE_NAME_INETPING, &sid,
 	    INET_PORT_PING);
-	if (rc != EOK) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
-		return EEXIST;
-	}
-	
-	rc = loc_service_register_with_iface(SERVICE_NAME_INETPING6, &sid,
-	    INET_PORT_PING6);
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
@@ -452,7 +444,4 @@
 		inetping_conn(iid, icall, arg);
 		break;
-	case INET_PORT_PING6:
-		inetping6_conn(iid, icall, arg);
-		break;
 	default:
 		async_answer_0(iid, ENOTSUP);
