Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ boot/Makefile.common	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -107,5 +107,5 @@
 	$(USPACE_PATH)/srv/hid/remcons/remcons \
 	$(USPACE_PATH)/srv/net/ethip/ethip \
-	$(USPACE_PATH)/srv/net/inet/inet \
+	$(USPACE_PATH)/srv/net/inetsrv/inetsrv \
 	$(USPACE_PATH)/srv/net/loopip/loopip \
 	$(USPACE_PATH)/srv/net/tcp/tcp \
@@ -158,5 +158,5 @@
 	$(USPACE_PATH)/app/edit/edit \
 	$(USPACE_PATH)/app/ext2info/ext2info \
-	$(USPACE_PATH)/app/inetcfg/inetcfg \
+	$(USPACE_PATH)/app/inet/inet \
 	$(USPACE_PATH)/app/kill/kill \
 	$(USPACE_PATH)/app/killall/killall \
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ uspace/Makefile	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -42,5 +42,5 @@
 	app/getterm \
 	app/init \
-	app/inetcfg \
+	app/inet \
 	app/kill \
 	app/killall \
@@ -76,5 +76,5 @@
 	srv/loader \
 	srv/net/ethip \
-	srv/net/inet \
+	srv/net/inetsrv \
 	srv/net/loopip \
 	srv/net/tcp \
Index: uspace/app/inet/Makefile
===================================================================
--- uspace/app/inet/Makefile	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/app/inet/Makefile	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2012 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = inet
+
+SOURCES = \
+	inet.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/inet/inet.c
===================================================================
--- uspace/app/inet/inet.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/app/inet/inet.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,514 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/** @file Internet configuration utility.
+ *
+ * Controls the internet service (@c inet).
+ */
+
+#include <errno.h>
+#include <inet/inetcfg.h>
+#include <loc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str_error.h>
+#include <sys/types.h>
+
+#define NAME "inet"
+
+static void print_syntax(void)
+{
+	printf("syntax:\n");
+	printf("\t" NAME " create <addr>/<width> <link-name> <addr-name>\n");
+	printf("\t" NAME " delete <link-name> <addr-name>\n");
+	printf("\t" NAME " add-sr <dest-addr>/<width> <router-addr> <route-name>\n");
+	printf("\t" NAME " del-sr <route-name>\n");
+}
+
+static int naddr_parse(const char *text, inet_naddr_t *naddr)
+{
+	unsigned long a[4], bits;
+	char *cp = (char *)text;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		a[i] = strtoul(cp, &cp, 10);
+		if (*cp != '.')
+			return EINVAL;
+		++cp;
+	}
+
+	a[3] = strtoul(cp, &cp, 10);
+	if (*cp != '/')
+		return EINVAL;
+	++cp;
+
+	bits = strtoul(cp, &cp, 10);
+	if (*cp != '\0')
+		return EINVAL;
+
+	naddr->ipv4 = 0;
+	for (i = 0; i < 4; i++) {
+		if (a[i] > 255)
+			return EINVAL;
+		naddr->ipv4 = (naddr->ipv4 << 8) | a[i];
+	}
+
+	if (bits > 31)
+		return EINVAL;
+
+	naddr->bits = bits;
+	return EOK;
+}
+
+static int addr_parse(const char *text, inet_addr_t *addr)
+{
+	unsigned long a[4];
+	char *cp = (char *)text;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		a[i] = strtoul(cp, &cp, 10);
+		if (*cp != '.')
+			return EINVAL;
+		++cp;
+	}
+
+	a[3] = strtoul(cp, &cp, 10);
+	if (*cp != '\0')
+		return EINVAL;
+
+	addr->ipv4 = 0;
+	for (i = 0; i < 4; i++) {
+		if (a[i] > 255)
+			return EINVAL;
+		addr->ipv4 = (addr->ipv4 << 8) | a[i];
+	}
+
+	return EOK;
+}
+
+static int naddr_format(inet_naddr_t *naddr, char **bufp)
+{
+	int rc;
+
+	rc = asprintf(bufp, "%d.%d.%d.%d/%d", naddr->ipv4 >> 24,
+	    (naddr->ipv4 >> 16) & 0xff, (naddr->ipv4 >> 8) & 0xff,
+	    naddr->ipv4 & 0xff, naddr->bits);
+
+	if (rc < 0)
+		return ENOMEM;
+
+	return EOK;
+}
+
+static int addr_format(inet_addr_t *addr, char **bufp)
+{
+	int rc;
+
+	rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
+	    (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
+	    addr->ipv4 & 0xff);
+
+	if (rc < 0)
+		return ENOMEM;
+
+	return EOK;
+}
+
+static int addr_create_static(int argc, char *argv[])
+{
+	char *aobj_name;
+	char *addr_spec;
+	char *link_name;
+
+	inet_naddr_t naddr;
+	sysarg_t link_id;
+	sysarg_t addr_id;
+	int rc;
+
+	if (argc < 3) {
+		printf(NAME ": Missing arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	if (argc > 3) {
+		printf(NAME ": Too many arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	addr_spec = argv[0];
+	link_name = argv[1];
+	aobj_name = argv[2];
+
+	rc = loc_service_get_id(link_name, &link_id, 0);
+	if (rc != EOK) {
+		printf(NAME ": Service '%s' not found (%d).\n", link_name, rc);
+		return ENOENT;
+	}
+
+	rc = naddr_parse(addr_spec, &naddr);
+	if (rc != EOK) {
+		printf(NAME ": Invalid network address format '%s'.\n",
+		    addr_spec);
+		return EINVAL;
+	}
+
+	rc = inetcfg_addr_create_static(aobj_name, &naddr, link_id, &addr_id);
+	if (rc != EOK) {
+		printf(NAME ": Failed creating static address '%s' (%d)\n",
+		    aobj_name, rc);
+		return EIO;
+	}
+
+	return EOK;
+}
+
+static int addr_delete(int argc, char *argv[])
+{
+	char *aobj_name;
+	char *link_name;
+	sysarg_t link_id;
+	sysarg_t addr_id;
+	int rc;
+
+	if (argc < 2) {
+		printf(NAME ": Missing arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	if (argc > 2) {
+		printf(NAME ": Too many arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	link_name = argv[0];
+	aobj_name = argv[1];
+
+	rc = loc_service_get_id(link_name, &link_id, 0);
+	if (rc != EOK) {
+		printf(NAME ": Service '%s' not found (%d).\n", link_name, rc);
+		return ENOENT;
+	}
+
+	rc = inetcfg_addr_get_id(aobj_name, link_id, &addr_id);
+	if (rc != EOK) {
+		printf(NAME ": Address '%s' not found (%d).\n", aobj_name, rc);
+		return ENOENT;
+	}
+
+	rc = inetcfg_addr_delete(addr_id);
+	if (rc != EOK) {
+		printf(NAME ": Failed deleting address '%s' (%d)\n", aobj_name,
+		    rc);
+		return EIO;
+	}
+
+	return EOK;
+}
+
+static int sroute_create(int argc, char *argv[])
+{
+	char *dest_str;
+	char *router_str;
+	char *route_name;
+
+	inet_naddr_t dest;
+	inet_addr_t router;
+	sysarg_t sroute_id;
+	int rc;
+
+	if (argc < 3) {
+		printf(NAME ": Missing arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	if (argc > 3) {
+		printf(NAME ": Too many arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	dest_str   = argv[0];
+	router_str = argv[1];
+	route_name = argv[2];
+
+	rc = naddr_parse(dest_str, &dest);
+	if (rc != EOK) {
+		printf(NAME ": Invalid network address format '%s'.\n",
+		    dest_str);
+		return EINVAL;
+	}
+
+	rc = addr_parse(router_str, &router);
+	if (rc != EOK) {
+		printf(NAME ": Invalid address format '%s'.\n", router_str);
+		return EINVAL;
+	}
+
+	rc = inetcfg_sroute_create(route_name, &dest, &router, &sroute_id);
+	if (rc != EOK) {
+		printf(NAME ": Failed creating static route '%s' (%d)\n",
+		    route_name, rc);
+		return EIO;
+	}
+
+	return EOK;
+}
+
+static int sroute_delete(int argc, char *argv[])
+{
+	char *route_name;
+	sysarg_t sroute_id;
+	int rc;
+
+	if (argc < 1) {
+		printf(NAME ": Missing arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	if (argc > 1) {
+		printf(NAME ": Too many arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	route_name = argv[0];
+
+	rc = inetcfg_sroute_get_id(route_name, &sroute_id);
+	if (rc != EOK) {
+		printf(NAME ": Static route '%s' not found (%d).\n",
+		    route_name, rc);
+		return ENOENT;
+	}
+
+	rc = inetcfg_sroute_delete(sroute_id);
+	if (rc != EOK) {
+		printf(NAME ": Failed deleting static route '%s' (%d)\n",
+		    route_name, rc);
+		return EIO;
+	}
+
+	return EOK;
+}
+
+static int addr_list(void)
+{
+	sysarg_t *addr_list;
+	inet_addr_info_t ainfo;
+	inet_link_info_t linfo;
+
+	size_t count;
+	size_t i;
+	int rc;
+	char *astr;
+
+	rc = inetcfg_get_addr_list(&addr_list, &count);
+	if (rc != EOK) {
+		printf(NAME ": Failed getting address list.\n");
+		return rc;
+	}
+
+	printf("Configured addresses:\n");
+
+	ainfo.name = linfo.name = astr = NULL;
+
+	for (i = 0; i < count; i++) {
+		rc = inetcfg_addr_get(addr_list[i], &ainfo);
+		if (rc != EOK) {
+			printf("Failed getting properties of address %zu.\n",
+			    (size_t)addr_list[i]);
+			ainfo.name = NULL;
+			continue;
+		}
+
+		rc = inetcfg_link_get(ainfo.ilink, &linfo);
+		if (rc != EOK) {
+			printf("Failed getting properties of link %zu.\n",
+			    (size_t)ainfo.ilink);
+			linfo.name = NULL;
+			continue;
+		}
+
+		rc = naddr_format(&ainfo.naddr, &astr);
+		if (rc != EOK) {
+			printf("Memory allocation failed.\n");
+			astr = NULL;
+			goto out;
+		}
+
+		printf("    %s %s %s %zu\n", astr, linfo.name,
+		    ainfo.name, linfo.def_mtu);
+
+		free(ainfo.name);
+		free(linfo.name);
+		free(astr);
+
+		ainfo.name = linfo.name = astr = NULL;
+	}
+
+	if (count == 0)
+		printf("    None\n");
+out:
+	if (ainfo.name != NULL)
+		free(ainfo.name);
+	if (linfo.name != NULL)
+		free(linfo.name);
+	if (astr != NULL)
+		free(astr);
+
+	free(addr_list);
+
+	return EOK;
+}
+
+static int sroute_list(void)
+{
+	sysarg_t *sroute_list;
+	inet_sroute_info_t srinfo;
+
+	size_t count;
+	size_t i;
+	int rc;
+	char *dest_str;
+	char *router_str;
+
+	rc = inetcfg_get_sroute_list(&sroute_list, &count);
+	if (rc != EOK) {
+		printf(NAME ": Failed getting address list.\n");
+		return rc;
+	}
+
+	printf("Static routes:\n");
+
+	srinfo.name = dest_str = router_str = NULL;
+
+	for (i = 0; i < count; i++) {
+		rc = inetcfg_sroute_get(sroute_list[i], &srinfo);
+		if (rc != EOK) {
+			printf("Failed getting properties of static route %zu.\n",
+			    (size_t)sroute_list[i]);
+			srinfo.name = NULL;
+			continue;
+		}
+
+		rc = naddr_format(&srinfo.dest, &dest_str);
+		if (rc != EOK) {
+			printf("Memory allocation failed.\n");
+			dest_str = NULL;
+			goto out;
+		}
+
+		rc = addr_format(&srinfo.router, &router_str);
+		if (rc != EOK) {
+			printf("Memory allocation failed.\n");
+			router_str = NULL;
+			goto out;
+		}
+
+		printf("    %s %s %s\n", dest_str, router_str, srinfo.name);
+
+		free(srinfo.name);
+		free(dest_str);
+		free(router_str);
+
+		router_str = srinfo.name = dest_str = NULL;
+	}
+
+	if (count == 0)
+		printf("    None\n");
+out:
+	if (srinfo.name != NULL)
+		free(srinfo.name);
+	if (dest_str != NULL)
+		free(dest_str);
+	if (router_str != NULL)
+		free(router_str);
+
+	free(sroute_list);
+
+	return EOK;
+}
+
+int main(int argc, char *argv[])
+{
+	int rc;
+
+	rc = inetcfg_init();
+	if (rc != EOK) {
+		printf(NAME ": Failed connecting to internet service (%d).\n",
+		    rc);
+		return 1;
+	}
+
+	if (argc < 2) {
+		rc = addr_list();
+		if (rc != EOK)
+			return 1;
+		rc = sroute_list();
+		if (rc != EOK)
+			return 1;
+		return 0;
+	}
+
+	if (str_cmp(argv[1], "create") == 0) {
+		rc = addr_create_static(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
+	} else if (str_cmp(argv[1], "delete") == 0) {
+		rc = addr_delete(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
+	} else if (str_cmp(argv[1], "add-sr") == 0) {
+		rc = sroute_create(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
+	} else if (str_cmp(argv[1], "del-sr") == 0) {
+		rc = sroute_delete(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
+	} else {
+		printf(NAME ": Unknown command '%s'.\n", argv[1]);
+		print_syntax();
+		return 1;
+	}
+
+	return 0;
+}
+
+/** @}
+ */
Index: pace/app/inetcfg/Makefile
===================================================================
--- uspace/app/inetcfg/Makefile	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#
-# Copyright (c) 2012 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.
-#
-
-USPACE_PREFIX = ../..
-BINARY = inetcfg
-
-SOURCES = \
-	inetcfg.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/app/inetcfg/inetcfg.c
===================================================================
--- uspace/app/inetcfg/inetcfg.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,514 +1,0 @@
-/*
- * Copyright (c) 2012 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 inetcfg
- * @{
- */
-/** @file Internet configuration utility.
- *
- * Controls the internet service (@c inet).
- */
-
-#include <errno.h>
-#include <inet/inetcfg.h>
-#include <loc.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <str_error.h>
-#include <sys/types.h>
-
-#define NAME "inetcfg"
-
-static void print_syntax(void)
-{
-	printf("syntax:\n");
-	printf("\t" NAME " create <addr>/<width> <link-name> <addr-name>\n");
-	printf("\t" NAME " delete <link-name> <addr-name>\n");
-	printf("\t" NAME " add-sr <dest-addr>/<width> <router-addr> <route-name>\n");
-	printf("\t" NAME " del-sr <route-name>\n");
-}
-
-static int naddr_parse(const char *text, inet_naddr_t *naddr)
-{
-	unsigned long a[4], bits;
-	char *cp = (char *)text;
-	int i;
-
-	for (i = 0; i < 3; i++) {
-		a[i] = strtoul(cp, &cp, 10);
-		if (*cp != '.')
-			return EINVAL;
-		++cp;
-	}
-
-	a[3] = strtoul(cp, &cp, 10);
-	if (*cp != '/')
-		return EINVAL;
-	++cp;
-
-	bits = strtoul(cp, &cp, 10);
-	if (*cp != '\0')
-		return EINVAL;
-
-	naddr->ipv4 = 0;
-	for (i = 0; i < 4; i++) {
-		if (a[i] > 255)
-			return EINVAL;
-		naddr->ipv4 = (naddr->ipv4 << 8) | a[i];
-	}
-
-	if (bits > 31)
-		return EINVAL;
-
-	naddr->bits = bits;
-	return EOK;
-}
-
-static int addr_parse(const char *text, inet_addr_t *addr)
-{
-	unsigned long a[4];
-	char *cp = (char *)text;
-	int i;
-
-	for (i = 0; i < 3; i++) {
-		a[i] = strtoul(cp, &cp, 10);
-		if (*cp != '.')
-			return EINVAL;
-		++cp;
-	}
-
-	a[3] = strtoul(cp, &cp, 10);
-	if (*cp != '\0')
-		return EINVAL;
-
-	addr->ipv4 = 0;
-	for (i = 0; i < 4; i++) {
-		if (a[i] > 255)
-			return EINVAL;
-		addr->ipv4 = (addr->ipv4 << 8) | a[i];
-	}
-
-	return EOK;
-}
-
-static int naddr_format(inet_naddr_t *naddr, char **bufp)
-{
-	int rc;
-
-	rc = asprintf(bufp, "%d.%d.%d.%d/%d", naddr->ipv4 >> 24,
-	    (naddr->ipv4 >> 16) & 0xff, (naddr->ipv4 >> 8) & 0xff,
-	    naddr->ipv4 & 0xff, naddr->bits);
-
-	if (rc < 0)
-		return ENOMEM;
-
-	return EOK;
-}
-
-static int addr_format(inet_addr_t *addr, char **bufp)
-{
-	int rc;
-
-	rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
-	    (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
-	    addr->ipv4 & 0xff);
-
-	if (rc < 0)
-		return ENOMEM;
-
-	return EOK;
-}
-
-static int addr_create_static(int argc, char *argv[])
-{
-	char *aobj_name;
-	char *addr_spec;
-	char *link_name;
-
-	inet_naddr_t naddr;
-	sysarg_t link_id;
-	sysarg_t addr_id;
-	int rc;
-
-	if (argc < 3) {
-		printf(NAME ": Missing arguments.\n");
-		print_syntax();
-		return EINVAL;
-	}
-
-	if (argc > 3) {
-		printf(NAME ": Too many arguments.\n");
-		print_syntax();
-		return EINVAL;
-	}
-
-	addr_spec = argv[0];
-	link_name = argv[1];
-	aobj_name = argv[2];
-
-	rc = loc_service_get_id(link_name, &link_id, 0);
-	if (rc != EOK) {
-		printf(NAME ": Service '%s' not found (%d).\n", link_name, rc);
-		return ENOENT;
-	}
-
-	rc = naddr_parse(addr_spec, &naddr);
-	if (rc != EOK) {
-		printf(NAME ": Invalid network address format '%s'.\n",
-		    addr_spec);
-		return EINVAL;
-	}
-
-	rc = inetcfg_addr_create_static(aobj_name, &naddr, link_id, &addr_id);
-	if (rc != EOK) {
-		printf(NAME ": Failed creating static address '%s' (%d)\n",
-		    aobj_name, rc);
-		return EIO;
-	}
-
-	return EOK;
-}
-
-static int addr_delete(int argc, char *argv[])
-{
-	char *aobj_name;
-	char *link_name;
-	sysarg_t link_id;
-	sysarg_t addr_id;
-	int rc;
-
-	if (argc < 2) {
-		printf(NAME ": Missing arguments.\n");
-		print_syntax();
-		return EINVAL;
-	}
-
-	if (argc > 2) {
-		printf(NAME ": Too many arguments.\n");
-		print_syntax();
-		return EINVAL;
-	}
-
-	link_name = argv[0];
-	aobj_name = argv[1];
-
-	rc = loc_service_get_id(link_name, &link_id, 0);
-	if (rc != EOK) {
-		printf(NAME ": Service '%s' not found (%d).\n", link_name, rc);
-		return ENOENT;
-	}
-
-	rc = inetcfg_addr_get_id(aobj_name, link_id, &addr_id);
-	if (rc != EOK) {
-		printf(NAME ": Address '%s' not found (%d).\n", aobj_name, rc);
-		return ENOENT;
-	}
-
-	rc = inetcfg_addr_delete(addr_id);
-	if (rc != EOK) {
-		printf(NAME ": Failed deleting address '%s' (%d)\n", aobj_name,
-		    rc);
-		return EIO;
-	}
-
-	return EOK;
-}
-
-static int sroute_create(int argc, char *argv[])
-{
-	char *dest_str;
-	char *router_str;
-	char *route_name;
-
-	inet_naddr_t dest;
-	inet_addr_t router;
-	sysarg_t sroute_id;
-	int rc;
-
-	if (argc < 3) {
-		printf(NAME ": Missing arguments.\n");
-		print_syntax();
-		return EINVAL;
-	}
-
-	if (argc > 3) {
-		printf(NAME ": Too many arguments.\n");
-		print_syntax();
-		return EINVAL;
-	}
-
-	dest_str   = argv[0];
-	router_str = argv[1];
-	route_name = argv[2];
-
-	rc = naddr_parse(dest_str, &dest);
-	if (rc != EOK) {
-		printf(NAME ": Invalid network address format '%s'.\n",
-		    dest_str);
-		return EINVAL;
-	}
-
-	rc = addr_parse(router_str, &router);
-	if (rc != EOK) {
-		printf(NAME ": Invalid address format '%s'.\n", router_str);
-		return EINVAL;
-	}
-
-	rc = inetcfg_sroute_create(route_name, &dest, &router, &sroute_id);
-	if (rc != EOK) {
-		printf(NAME ": Failed creating static route '%s' (%d)\n",
-		    route_name, rc);
-		return EIO;
-	}
-
-	return EOK;
-}
-
-static int sroute_delete(int argc, char *argv[])
-{
-	char *route_name;
-	sysarg_t sroute_id;
-	int rc;
-
-	if (argc < 1) {
-		printf(NAME ": Missing arguments.\n");
-		print_syntax();
-		return EINVAL;
-	}
-
-	if (argc > 1) {
-		printf(NAME ": Too many arguments.\n");
-		print_syntax();
-		return EINVAL;
-	}
-
-	route_name = argv[0];
-
-	rc = inetcfg_sroute_get_id(route_name, &sroute_id);
-	if (rc != EOK) {
-		printf(NAME ": Static route '%s' not found (%d).\n",
-		    route_name, rc);
-		return ENOENT;
-	}
-
-	rc = inetcfg_sroute_delete(sroute_id);
-	if (rc != EOK) {
-		printf(NAME ": Failed deleting static route '%s' (%d)\n",
-		    route_name, rc);
-		return EIO;
-	}
-
-	return EOK;
-}
-
-static int addr_list(void)
-{
-	sysarg_t *addr_list;
-	inet_addr_info_t ainfo;
-	inet_link_info_t linfo;
-
-	size_t count;
-	size_t i;
-	int rc;
-	char *astr;
-
-	rc = inetcfg_get_addr_list(&addr_list, &count);
-	if (rc != EOK) {
-		printf(NAME ": Failed getting address list.\n");
-		return rc;
-	}
-
-	printf("Configured addresses:\n");
-
-	ainfo.name = linfo.name = astr = NULL;
-
-	for (i = 0; i < count; i++) {
-		rc = inetcfg_addr_get(addr_list[i], &ainfo);
-		if (rc != EOK) {
-			printf("Failed getting properties of address %zu.\n",
-			    (size_t)addr_list[i]);
-			ainfo.name = NULL;
-			continue;
-		}
-
-		rc = inetcfg_link_get(ainfo.ilink, &linfo);
-		if (rc != EOK) {
-			printf("Failed getting properties of link %zu.\n",
-			    (size_t)ainfo.ilink);
-			linfo.name = NULL;
-			continue;
-		}
-
-		rc = naddr_format(&ainfo.naddr, &astr);
-		if (rc != EOK) {
-			printf("Memory allocation failed.\n");
-			astr = NULL;
-			goto out;
-		}
-
-		printf("    %s %s %s %zu\n", astr, linfo.name,
-		    ainfo.name, linfo.def_mtu);
-
-		free(ainfo.name);
-		free(linfo.name);
-		free(astr);
-
-		ainfo.name = linfo.name = astr = NULL;
-	}
-
-	if (count == 0)
-		printf("    None\n");
-out:
-	if (ainfo.name != NULL)
-		free(ainfo.name);
-	if (linfo.name != NULL)
-		free(linfo.name);
-	if (astr != NULL)
-		free(astr);
-
-	free(addr_list);
-
-	return EOK;
-}
-
-static int sroute_list(void)
-{
-	sysarg_t *sroute_list;
-	inet_sroute_info_t srinfo;
-
-	size_t count;
-	size_t i;
-	int rc;
-	char *dest_str;
-	char *router_str;
-
-	rc = inetcfg_get_sroute_list(&sroute_list, &count);
-	if (rc != EOK) {
-		printf(NAME ": Failed getting address list.\n");
-		return rc;
-	}
-
-	printf("Static routes:\n");
-
-	srinfo.name = dest_str = router_str = NULL;
-
-	for (i = 0; i < count; i++) {
-		rc = inetcfg_sroute_get(sroute_list[i], &srinfo);
-		if (rc != EOK) {
-			printf("Failed getting properties of static route %zu.\n",
-			    (size_t)sroute_list[i]);
-			srinfo.name = NULL;
-			continue;
-		}
-
-		rc = naddr_format(&srinfo.dest, &dest_str);
-		if (rc != EOK) {
-			printf("Memory allocation failed.\n");
-			dest_str = NULL;
-			goto out;
-		}
-
-		rc = addr_format(&srinfo.router, &router_str);
-		if (rc != EOK) {
-			printf("Memory allocation failed.\n");
-			router_str = NULL;
-			goto out;
-		}
-
-		printf("    %s %s %s\n", dest_str, router_str, srinfo.name);
-
-		free(srinfo.name);
-		free(dest_str);
-		free(router_str);
-
-		router_str = srinfo.name = dest_str = NULL;
-	}
-
-	if (count == 0)
-		printf("    None\n");
-out:
-	if (srinfo.name != NULL)
-		free(srinfo.name);
-	if (dest_str != NULL)
-		free(dest_str);
-	if (router_str != NULL)
-		free(router_str);
-
-	free(sroute_list);
-
-	return EOK;
-}
-
-int main(int argc, char *argv[])
-{
-	int rc;
-
-	rc = inetcfg_init();
-	if (rc != EOK) {
-		printf(NAME ": Failed connecting to internet service (%d).\n",
-		    rc);
-		return 1;
-	}
-
-	if (argc < 2) {
-		rc = addr_list();
-		if (rc != EOK)
-			return 1;
-		rc = sroute_list();
-		if (rc != EOK)
-			return 1;
-		return 0;
-	}
-
-	if (str_cmp(argv[1], "create") == 0) {
-		rc = addr_create_static(argc - 2, argv + 2);
-		if (rc != EOK)
-			return 1;
-	} else if (str_cmp(argv[1], "delete") == 0) {
-		rc = addr_delete(argc - 2, argv + 2);
-		if (rc != EOK)
-			return 1;
-	} else if (str_cmp(argv[1], "add-sr") == 0) {
-		rc = sroute_create(argc - 2, argv + 2);
-		if (rc != EOK)
-			return 1;
-	} else if (str_cmp(argv[1], "del-sr") == 0) {
-		rc = sroute_delete(argc - 2, argv + 2);
-		if (rc != EOK)
-			return 1;
-	} else {
-		printf(NAME ": Unknown command '%s'.\n", argv[1]);
-		print_syntax();
-		return 1;
-	}
-
-	return 0;
-}
-
-/** @}
- */
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ uspace/app/init/init.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -307,5 +307,5 @@
 	spawn("/srv/loopip");
 	spawn("/srv/ethip");
-	spawn("/srv/inet");
+	spawn("/srv/inetsrv");
 	spawn("/srv/tcp");
 	spawn("/srv/udp");
Index: pace/srv/net/inet/Makefile
===================================================================
--- uspace/srv/net/inet/Makefile	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,44 +1,0 @@
-#
-# Copyright (c) 2012 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.
-#
-
-USPACE_PREFIX = ../../..
-BINARY = inet
-
-SOURCES = \
-	addrobj.c \
-	icmp.c \
-	inet.c \
-	inet_link.c \
-	inet_util.c \
-	inetcfg.c \
-	inetping.c \
-	pdu.c \
-	reass.c \
-	sroute.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/srv/net/inet/addrobj.c
===================================================================
--- uspace/srv/net/inet/addrobj.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,229 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#include <bitops.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <io/log.h>
-#include <ipc/loc.h>
-#include <stdlib.h>
-#include <str.h>
-
-#include "addrobj.h"
-#include "inet.h"
-#include "inet_link.h"
-#include "inet_util.h"
-
-static FIBRIL_MUTEX_INITIALIZE(addr_list_lock);
-static LIST_INITIALIZE(addr_list);
-static sysarg_t addr_id = 0;
-
-inet_addrobj_t *inet_addrobj_new(void)
-{
-	inet_addrobj_t *addr = calloc(1, sizeof(inet_addrobj_t));
-
-	if (addr == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating address object. "
-		    "Out of memory.");
-		return NULL;
-	}
-
-	link_initialize(&addr->addr_list);
-	fibril_mutex_lock(&addr_list_lock);
-	addr->id = ++addr_id;
-	fibril_mutex_unlock(&addr_list_lock);
-
-	return addr;
-}
-
-void inet_addrobj_delete(inet_addrobj_t *addr)
-{
-	if (addr->name != NULL)
-		free(addr->name);
-	free(addr);
-}
-
-void inet_addrobj_add(inet_addrobj_t *addr)
-{
-	fibril_mutex_lock(&addr_list_lock);
-	list_append(&addr->addr_list, &addr_list);
-	fibril_mutex_unlock(&addr_list_lock);
-}
-
-void inet_addrobj_remove(inet_addrobj_t *addr)
-{
-	fibril_mutex_lock(&addr_list_lock);
-	list_remove(&addr->addr_list);
-	fibril_mutex_unlock(&addr_list_lock);
-}
-
-/** Find address object matching address @a addr.
- *
- * @param addr	Address
- * @oaram find	iaf_net to find network (using mask),
- *		iaf_addr to find local address (exact match)
- */
-inet_addrobj_t *inet_addrobj_find(inet_addr_t *addr, inet_addrobj_find_t find)
-{
-	uint32_t mask;
-
-	log_msg(LVL_DEBUG, "inet_addrobj_find(%x)", (unsigned)addr->ipv4);
-
-	fibril_mutex_lock(&addr_list_lock);
-
-	list_foreach(addr_list, link) {
-		inet_addrobj_t *naddr = list_get_instance(link,
-		    inet_addrobj_t, addr_list);
-
-		mask = inet_netmask(naddr->naddr.bits);
-		if ((naddr->naddr.ipv4 & mask) == (addr->ipv4 & mask)) {
-			fibril_mutex_unlock(&addr_list_lock);
-			log_msg(LVL_DEBUG, "inet_addrobj_find: found %p",
-			    naddr);
-			return naddr;
-		}
-	}
-
-	log_msg(LVL_DEBUG, "inet_addrobj_find: Not found");
-	fibril_mutex_unlock(&addr_list_lock);
-
-	return NULL;
-}
-
-/** Find address object on a link, with a specific name.
- *
- * @param name	Address object name
- * @param ilink	Inet link
- * @return	Address object
- */
-inet_addrobj_t *inet_addrobj_find_by_name(const char *name, inet_link_t *ilink)
-{
-	log_msg(LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')",
-	    name, ilink->svc_name);
-
-	fibril_mutex_lock(&addr_list_lock);
-
-	list_foreach(addr_list, link) {
-		inet_addrobj_t *naddr = list_get_instance(link,
-		    inet_addrobj_t, addr_list);
-
-		if (naddr->ilink == ilink && str_cmp(naddr->name, name) == 0) {
-			fibril_mutex_unlock(&addr_list_lock);
-			log_msg(LVL_DEBUG, "inet_addrobj_find_by_name: found %p",
-			    naddr);
-			return naddr;
-		}
-	}
-
-	log_msg(LVL_DEBUG, "inet_addrobj_find_by_name: Not found");
-	fibril_mutex_unlock(&addr_list_lock);
-
-	return NULL;
-}
-
-/** Find address object with the given ID.
- *
- * @param id	Address object ID
- * @return	Address object
- */
-inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t id)
-{
-	log_msg(LVL_DEBUG, "inet_addrobj_get_by_id(%zu)", (size_t)id);
-
-	fibril_mutex_lock(&addr_list_lock);
-
-	list_foreach(addr_list, link) {
-		inet_addrobj_t *naddr = list_get_instance(link,
-		    inet_addrobj_t, addr_list);
-
-		if (naddr->id == id) {
-			fibril_mutex_unlock(&addr_list_lock);
-			return naddr;
-		}
-	}
-
-	fibril_mutex_unlock(&addr_list_lock);
-
-	return NULL;
-}
-
-/** Send datagram from address object */
-int inet_addrobj_send_dgram(inet_addrobj_t *addr, inet_addr_t *ldest,
-    inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
-{
-	inet_addr_t lsrc_addr;
-	inet_addr_t *ldest_addr;
-
-	lsrc_addr.ipv4 = addr->naddr.ipv4;
-	ldest_addr = &dgram->dest;
-
-	return inet_link_send_dgram(addr->ilink, &lsrc_addr, ldest_addr, dgram,
-	    proto, ttl, df);
-}
-
-/** Get IDs of all address objects. */
-int inet_addrobj_get_id_list(sysarg_t **rid_list, size_t *rcount)
-{
-	sysarg_t *id_list;
-	size_t count, i;
-
-	fibril_mutex_lock(&addr_list_lock);
-	count = list_count(&addr_list);
-
-	id_list = calloc(count, sizeof(sysarg_t));
-	if (id_list == NULL) {
-		fibril_mutex_unlock(&addr_list_lock);
-		return ENOMEM;
-	}
-
-	i = 0;
-	list_foreach(addr_list, link) {
-		inet_addrobj_t *addr = list_get_instance(link,
-		    inet_addrobj_t, addr_list);
-
-		id_list[i++] = addr->id;
-	}
-
-	fibril_mutex_unlock(&addr_list_lock);
-
-	*rid_list = id_list;
-	*rcount = count;
-
-	return EOK;
-}
-
-/** @}
- */
Index: pace/srv/net/inet/addrobj.h
===================================================================
--- uspace/srv/net/inet/addrobj.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,65 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INET_ADDROBJ_H_
-#define INET_ADDROBJ_H_
-
-#include <sys/types.h>
-#include "inet.h"
-
-typedef enum {
-	/* Find matching network address (using mask) */
-	iaf_net,
-	/* Find exact local address (not using mask) */
-	iaf_addr
-} inet_addrobj_find_t;
-
-extern inet_addrobj_t *inet_addrobj_new(void);
-extern void inet_addrobj_delete(inet_addrobj_t *);
-extern void inet_addrobj_add(inet_addrobj_t *);
-extern void inet_addrobj_remove(inet_addrobj_t *);
-extern inet_addrobj_t *inet_addrobj_find(inet_addr_t *, inet_addrobj_find_t);
-extern inet_addrobj_t *inet_addrobj_find_by_name(const char *, inet_link_t *);
-extern inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t);
-extern int inet_addrobj_send_dgram(inet_addrobj_t *, inet_addr_t *,
-    inet_dgram_t *, uint8_t, uint8_t, int);
-extern int inet_addrobj_get_id_list(sysarg_t **, size_t *);
-
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/icmp.c
===================================================================
--- uspace/srv/net/inet/icmp.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,183 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#include <byteorder.h>
-#include <errno.h>
-#include <io/log.h>
-#include <mem.h>
-#include <stdlib.h>
-
-#include "icmp.h"
-#include "icmp_std.h"
-#include "inet.h"
-#include "inetping.h"
-#include "pdu.h"
-
-/* XXX */
-#define INET_TTL_MAX 255
-
-static int icmp_recv_echo_request(inet_dgram_t *);
-static int icmp_recv_echo_reply(inet_dgram_t *);
-
-int icmp_recv(inet_dgram_t *dgram)
-{
-	uint8_t type;
-
-	log_msg(LVL_DEBUG, "icmp_recv()");
-
-	if (dgram->size < 1)
-		return EINVAL;
-
-	type = *(uint8_t *)dgram->data;
-
-	switch (type) {
-	case ICMP_ECHO_REQUEST:
-		return icmp_recv_echo_request(dgram);
-	case ICMP_ECHO_REPLY:
-		return icmp_recv_echo_reply(dgram);
-	default:
-		break;
-	}
-
-	return EINVAL;
-}
-
-static int icmp_recv_echo_request(inet_dgram_t *dgram)
-{
-	icmp_echo_t *request, *reply;
-	uint16_t checksum;
-	size_t size;
-	inet_dgram_t rdgram;
-	int rc;
-
-	log_msg(LVL_DEBUG, "icmp_recv_echo_request()");
-
-	if (dgram->size < sizeof(icmp_echo_t))
-		return EINVAL;
-
-	request = (icmp_echo_t *)dgram->data;
-	size = dgram->size;
-
-	reply = calloc(size, 1);
-	if (reply == NULL)
-		return ENOMEM;
-
-	memcpy(reply, request, size);
-
-	reply->type = ICMP_ECHO_REPLY;
-	reply->code = 0;
-	reply->checksum = 0;
-
-	checksum = inet_checksum_calc(INET_CHECKSUM_INIT, reply, size);
-	reply->checksum = host2uint16_t_be(checksum);
-
-	rdgram.src = dgram->dest;
-	rdgram.dest = dgram->src;
-	rdgram.tos = ICMP_TOS;
-	rdgram.data = reply;
-	rdgram.size = size;
-
-	rc = inet_route_packet(&rdgram, IP_PROTO_ICMP, INET_TTL_MAX, 0);
-
-	free(reply);
-
-	return rc;
-}
-
-static int icmp_recv_echo_reply(inet_dgram_t *dgram)
-{
-	icmp_echo_t *reply;
-	inetping_sdu_t sdu;
-	uint16_t ident;
-
-	log_msg(LVL_DEBUG, "icmp_recv_echo_reply()");
-
-	if (dgram->size < sizeof(icmp_echo_t))
-		return EINVAL;
-
-	reply = (icmp_echo_t *)dgram->data;
-
-	sdu.src = dgram->src;
-	sdu.dest = dgram->dest;
-	sdu.seq_no = uint16_t_be2host(reply->seq_no);
-	sdu.data = reply + sizeof(icmp_echo_t);
-	sdu.size = dgram->size - sizeof(icmp_echo_t);
-	ident = uint16_t_be2host(reply->ident);
-
-	return inetping_recv(ident, &sdu);
-}
-
-int icmp_ping_send(uint16_t ident, inetping_sdu_t *sdu)
-{
-	inet_dgram_t dgram;
-	icmp_echo_t *request;
-	void *rdata;
-	size_t rsize;
-	uint16_t checksum;
-	int rc;
-
-	rsize = sizeof(icmp_echo_t) + sdu->size;
-	rdata = calloc(rsize, 1);
-	if (rdata == NULL)
-		return ENOMEM;
-
-	request = (icmp_echo_t *)rdata;
-
-	request->type = ICMP_ECHO_REQUEST;
-	request->code = 0;
-	request->checksum = 0;
-	request->ident = host2uint16_t_be(ident);
-	request->seq_no = host2uint16_t_be(sdu->seq_no);
-
-	memcpy(rdata + sizeof(icmp_echo_t), sdu->data, sdu->size);
-
-	checksum = inet_checksum_calc(INET_CHECKSUM_INIT, rdata, rsize);
-	request->checksum = host2uint16_t_be(checksum);
-
-	dgram.src = sdu->src;
-	dgram.dest = sdu->dest;
-	dgram.tos = ICMP_TOS;
-	dgram.data = rdata;
-	dgram.size = rsize;
-
-	rc = inet_route_packet(&dgram, IP_PROTO_ICMP, INET_TTL_MAX, 0);
-
-	free(rdata);
-	return rc;
-}
-
-/** @}
- */
Index: pace/srv/net/inet/icmp.h
===================================================================
--- uspace/srv/net/inet/icmp.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef ICMP_H_
-#define ICMP_H_
-
-#include "inet.h"
-
-extern int icmp_recv(inet_dgram_t *);
-extern int icmp_ping_send(uint16_t, inetping_sdu_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/icmp_std.h
===================================================================
--- uspace/srv/net/inet/icmp_std.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,70 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file ICMP standard definitions
- *
- */
-
-#ifndef ICMP_STD_H_
-#define ICMP_STD_H_
-
-#include <sys/types.h>
-
-#define IP_PROTO_ICMP 1
-
-/** Type of service used for ICMP */
-#define ICMP_TOS	0
-
-/** ICMP message type */
-enum icmp_type {
-	ICMP_ECHO_REPLY   = 0,
-	ICMP_ECHO_REQUEST = 8
-};
-
-/** ICMP Echo Request or Reply message header */
-typedef struct {
-	/** ICMP message type */
-	uint8_t type;
-	/** Code (0) */
-	uint8_t code;
-	/** Internet checksum of the ICMP message */
-	uint16_t checksum;
-	/** Indentifier */
-	uint16_t ident;
-	/** Sequence number */
-	uint16_t seq_no;
-} icmp_echo_t;
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/inet.c
===================================================================
--- uspace/srv/net/inet/inet.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,450 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief Internet Protocol service
- */
-
-#include <adt/list.h>
-#include <async.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <io/log.h>
-#include <ipc/inet.h>
-#include <ipc/services.h>
-#include <loc.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-
-#include "addrobj.h"
-#include "icmp.h"
-#include "icmp_std.h"
-#include "inet.h"
-#include "inetcfg.h"
-#include "inetping.h"
-#include "inet_link.h"
-#include "reass.h"
-#include "sroute.h"
-
-#define NAME "inet"
-
-static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
-
-static FIBRIL_MUTEX_INITIALIZE(client_list_lock);
-static LIST_INITIALIZE(client_list);
-
-static int inet_init(void)
-{
-	service_id_t sid;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inet_init()");
-
-	async_set_client_connection(inet_client_conn);
-
-	rc = loc_server_register(NAME);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering server (%d).", rc);
-		return EEXIST;
-	}
-
-	rc = loc_service_register_with_iface(SERVICE_NAME_INET, &sid,
-	    INET_PORT_DEFAULT);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering service (%d).", rc);
-		return EEXIST;
-	}
-
-	rc = loc_service_register_with_iface(SERVICE_NAME_INETCFG, &sid,
-	    INET_PORT_CFG);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering service (%d).", rc);
-		return EEXIST;
-	}
-
-	rc = loc_service_register_with_iface(SERVICE_NAME_INETPING, &sid,
-	    INET_PORT_PING);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering service (%d).", rc);
-		return EEXIST;
-	}
-
-	rc = inet_link_discovery_start();
-	if (rc != EOK)
-		return EEXIST;
-
-	return EOK;
-}
-
-static void inet_callback_create_srv(inet_client_t *client, ipc_callid_t callid,
-    ipc_call_t *call)
-{
-	log_msg(LVL_DEBUG, "inet_callback_create_srv()");
-
-	async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
-	if (sess == NULL) {
-		async_answer_0(callid, ENOMEM);
-		return;
-	}
-
-	client->sess = sess;
-	async_answer_0(callid, EOK);
-}
-
-static int inet_find_dir(inet_addr_t *src, inet_addr_t *dest, uint8_t tos,
-    inet_dir_t *dir)
-{
-	inet_sroute_t *sr;
-
-	/* XXX Handle case where source address is specified */
-	(void) src;
-
-	dir->aobj = inet_addrobj_find(dest, iaf_net);
-	if (dir->aobj != NULL) {
-		dir->ldest = *dest;
-		dir->dtype = dt_direct;
-	} else {
-		/* No direct path, try using a static route */
-		sr = inet_sroute_find(dest);
-		if (sr != NULL) {
-			dir->aobj = inet_addrobj_find(&sr->router, iaf_net);
-			dir->ldest = sr->router;
-			dir->dtype = dt_router;
-		}
-	}
-
-	if (dir->aobj == NULL) {
-		log_msg(LVL_DEBUG, "inet_send: No route to destination.");
-		return ENOENT;
-	}
-
-	return EOK;
-}
-
-int inet_route_packet(inet_dgram_t *dgram, uint8_t proto, uint8_t ttl,
-    int df)
-{
-	inet_dir_t dir;
-	int rc;
-
-	rc = inet_find_dir(&dgram->src, &dgram->dest, dgram->tos, &dir);
-	if (rc != EOK)
-		return rc;
-
-	return inet_addrobj_send_dgram(dir.aobj, &dir.ldest, dgram,
-	    proto, ttl, df);
-}
-
-static int inet_send(inet_client_t *client, inet_dgram_t *dgram,
-    uint8_t proto, uint8_t ttl, int df)
-{
-	return inet_route_packet(dgram, proto, ttl, df);
-}
-
-int inet_get_srcaddr(inet_addr_t *remote, uint8_t tos, inet_addr_t *local)
-{
-	inet_dir_t dir;
-	int rc;
-
-	rc = inet_find_dir(NULL, remote, tos, &dir);
-	if (rc != EOK)
-		return rc;
-
-	/* XXX dt_local? */
-
-	/* Take source address from the address object */
-	local->ipv4 = dir.aobj->naddr.ipv4;
-	return EOK;
-}
-
-static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t callid,
-    ipc_call_t *call)
-{
-	inet_addr_t remote;
-	uint8_t tos;
-	inet_addr_t local;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inet_get_srcaddr_srv()");
-
-	remote.ipv4 = IPC_GET_ARG1(*call);
-	tos = IPC_GET_ARG2(*call);
-	local.ipv4 = 0;
-
-	rc = inet_get_srcaddr(&remote, tos, &local);
-	async_answer_1(callid, rc, local.ipv4);
-}
-
-static void inet_send_srv(inet_client_t *client, ipc_callid_t callid,
-    ipc_call_t *call)
-{
-	inet_dgram_t dgram;
-	uint8_t ttl;
-	int df;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inet_send_srv()");
-
-	dgram.src.ipv4 = IPC_GET_ARG1(*call);
-	dgram.dest.ipv4 = IPC_GET_ARG2(*call);
-	dgram.tos = IPC_GET_ARG3(*call);
-	ttl = IPC_GET_ARG4(*call);
-	df = IPC_GET_ARG5(*call);
-
-	rc = async_data_write_accept(&dgram.data, false, 0, 0, 0, &dgram.size);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	rc = inet_send(client, &dgram, client->protocol, ttl, df);
-
-	free(dgram.data);
-	async_answer_0(callid, rc);
-}
-
-static void inet_set_proto_srv(inet_client_t *client, ipc_callid_t callid,
-    ipc_call_t *call)
-{
-	sysarg_t proto;
-
-	proto = IPC_GET_ARG1(*call);
-	log_msg(LVL_DEBUG, "inet_set_proto_srv(%lu)", (unsigned long) proto);
-
-	if (proto > UINT8_MAX) {
-		async_answer_0(callid, EINVAL);
-		return;
-	}
-
-	client->protocol = proto;
-	async_answer_0(callid, EOK);
-}
-
-static void inet_client_init(inet_client_t *client)
-{
-	client->sess = NULL;
-
-	fibril_mutex_lock(&client_list_lock);
-	list_append(&client->client_list, &client_list);
-	fibril_mutex_unlock(&client_list_lock);
-}
-
-static void inet_client_fini(inet_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);
-}
-
-static void inet_default_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	inet_client_t client;
-
-	log_msg(LVL_DEBUG, "inet_default_conn()");
-
-	/* Accept the connection */
-	async_answer_0(iid, EOK);
-
-	inet_client_init(&client);
-
-	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);
-			return;
-		}
-
-		switch (method) {
-		case INET_CALLBACK_CREATE:
-			inet_callback_create_srv(&client, callid, &call);
-			break;
-		case INET_GET_SRCADDR:
-			inet_get_srcaddr_srv(&client, callid, &call);
-			break;
-		case INET_SEND:
-			inet_send_srv(&client, callid, &call);
-			break;
-		case INET_SET_PROTO:
-			inet_set_proto_srv(&client, callid, &call);
-			break;
-		default:
-			async_answer_0(callid, EINVAL);
-		}
-	}
-
-	inet_client_fini(&client);
-}
-
-static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	sysarg_t port;
-
-	port = IPC_GET_ARG1(*icall);
-
-	switch (port) {
-	case INET_PORT_DEFAULT:
-		inet_default_conn(iid, icall, arg);
-		break;
-	case INET_PORT_CFG:
-		inet_cfg_conn(iid, icall, arg);
-		break;
-	case INET_PORT_PING:
-		inetping_conn(iid, icall, arg);
-		break;
-	default:
-		async_answer_0(iid, ENOTSUP);
-		break;
-	}
-}
-
-static inet_client_t *inet_client_find(uint8_t proto)
-{
-	fibril_mutex_lock(&client_list_lock);
-
-	list_foreach(client_list, link) {
-		inet_client_t *client = list_get_instance(link, inet_client_t,
-		    client_list);
-
-		if (client->protocol == proto) {
-			fibril_mutex_unlock(&client_list_lock);
-			return client;
-		}
-	}
-
-	fibril_mutex_unlock(&client_list_lock);
-	return NULL;
-}
-
-int inet_ev_recv(inet_client_t *client, inet_dgram_t *dgram)
-{
-	async_exch_t *exch = async_exchange_begin(client->sess);
-
-	ipc_call_t answer;
-	aid_t req = async_send_3(exch, INET_EV_RECV, dgram->src.ipv4,
-	    dgram->dest.ipv4, dgram->tos, &answer);
-	int rc = async_data_write_start(exch, dgram->data, dgram->size);
-	async_exchange_end(exch);
-
-	if (rc != EOK) {
-		async_forget(req);
-		return rc;
-	}
-
-	sysarg_t retval;
-	async_wait_for(req, &retval);
-	if (retval != EOK)
-		return retval;
-
-	return EOK;
-}
-
-int inet_recv_dgram_local(inet_dgram_t *dgram, uint8_t proto)
-{
-	inet_client_t *client;
-
-	log_msg(LVL_DEBUG, "inet_recv_dgram_local()");
-
-	/* ICMP messages are handled internally */
-	if (proto == IP_PROTO_ICMP)
-		return icmp_recv(dgram);
-
-	client = inet_client_find(proto);
-	if (client == NULL) {
-		log_msg(LVL_DEBUG, "No client found for protocol 0x%" PRIx8,
-		    proto);
-		return ENOENT;
-	}
-
-	return inet_ev_recv(client, dgram);
-}
-
-int inet_recv_packet(inet_packet_t *packet)
-{
-	inet_addrobj_t *addr;
-	inet_dgram_t dgram;
-
-	addr = inet_addrobj_find(&packet->dest, iaf_addr);
-	if (addr != NULL) {
-		/* Destined for one of the local addresses */
-
-		/* Check if packet is a complete datagram */
-		if (packet->offs == 0 && !packet->mf) {
-			/* It is complete deliver it immediately */
-			dgram.src = packet->src;
-			dgram.dest = packet->dest;
-			dgram.tos = packet->tos;
-			dgram.data = packet->data;
-			dgram.size = packet->size;
-
-			return inet_recv_dgram_local(&dgram, packet->proto);
-		} else {
-			/* It is a fragment, queue it for reassembly */
-			inet_reass_queue_packet(packet);
-		}
-	}
-
-	return ENOENT;
-}
-
-int main(int argc, char *argv[])
-{
-	int rc;
-
-	printf(NAME ": HelenOS Internet Protocol service\n");
-
-	if (log_init(NAME, LVL_WARN) != EOK) {
-		printf(NAME ": Failed to initialize logging.\n");
-		return 1;
-	}
-
-	rc = inet_init();
-	if (rc != EOK)
-		return 1;
-
-	printf(NAME ": Accepting connections.\n");
-	task_retval(0);
-	async_manager();
-
-	/* Not reached */
-	return 0;
-}
-
-/** @}
- */
Index: pace/srv/net/inet/inet.h
===================================================================
--- uspace/srv/net/inet/inet.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,202 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INET_H_
-#define INET_H_
-
-#include <adt/list.h>
-#include <bool.h>
-#include <inet/iplink.h>
-#include <ipc/loc.h>
-#include <sys/types.h>
-#include <async.h>
-
-/** Inet Client */
-typedef struct {
-	async_sess_t *sess;
-	uint8_t protocol;
-	link_t client_list;
-} inet_client_t;
-
-/** Inetping Client */
-typedef struct {
-	/** Callback session */
-	async_sess_t *sess;
-	/** Session identifier */
-	uint16_t ident;
-	/** Link to client list */
-	link_t client_list;
-} inetping_client_t;
-
-/** Host address */
-typedef struct {
-	uint32_t ipv4;
-} inet_addr_t;
-
-/** Network address */
-typedef struct {
-	/** Address */
-	uint32_t ipv4;
-	/** Number of valid bits in @c ipv4 */
-	int bits;
-} inet_naddr_t;
-
-/** Address object info */
-typedef struct {
-	/** Network address */
-	inet_naddr_t naddr;
-	/** Link service ID */
-	sysarg_t ilink;
-	/** Address object name */
-	char *name;
-} inet_addr_info_t;
-
-/** IP link info */
-typedef struct {
-	/** Link service name */
-	char *name;
-	/** Default MTU */
-	size_t def_mtu;
-} inet_link_info_t;
-
-/** Static route info */
-typedef struct {
-	/** Destination network address */
-	inet_naddr_t dest;
-	/** Router address */
-	inet_addr_t router;
-	/** Static route name */
-	char *name;
-} inet_sroute_info_t;
-
-typedef struct {
-	/** Source address */
-	inet_addr_t src;
-	/** Destination address */
-	inet_addr_t dest;
-	/** Type of service */
-	uint8_t tos;
-	/** Protocol */
-	uint8_t proto;
-	/** Time to live */
-	uint8_t ttl;
-	/** Identifier */
-	uint16_t ident;
-	/** Do not fragment */
-	bool df;
-	/** More fragments */
-	bool mf;
-	/** Offset of fragment into datagram, in bytes */
-	size_t offs;
-	/** Packet data */
-	void *data;
-	/** Packet data size in bytes */
-	size_t size;
-} inet_packet_t;
-
-typedef struct {
-	inet_addr_t src;
-	inet_addr_t dest;
-	uint8_t tos;
-	void *data;
-	size_t size;
-} inet_dgram_t;
-
-typedef struct {
-	link_t link_list;
-	service_id_t svc_id;
-	char *svc_name;
-	async_sess_t *sess;
-	iplink_t *iplink;
-	size_t def_mtu;
-} inet_link_t;
-
-typedef struct {
-	link_t addr_list;
-	sysarg_t id;
-	inet_naddr_t naddr;
-	inet_link_t *ilink;
-	char *name;
-} inet_addrobj_t;
-
-/** Static route configuration */
-typedef struct {
-	link_t sroute_list;
-	sysarg_t id;
-	/** Destination network */
-	inet_naddr_t dest;
-	/** Router via which to route packets */
-	inet_addr_t router;
-	char *name;
-} inet_sroute_t;
-
-typedef enum {
-	/** Destination is on this network node */
-	dt_local,
-	/** Destination is directly reachable */
-	dt_direct,
-	/** Destination is behind a router */
-	dt_router
-} inet_dir_type_t;
-
-/** Direction (next hop) to a destination */
-typedef struct {
-	/** Route type */
-	inet_dir_type_t dtype;
-	/** Address object (direction) */
-	inet_addrobj_t *aobj;
-	/** Local destination address */
-	inet_addr_t ldest;
-} inet_dir_t;
-
-typedef struct {
-	inet_addr_t src;
-	inet_addr_t dest;
-	uint16_t seq_no;
-	void *data;
-	size_t size;
-} inetping_sdu_t;
-
-extern int inet_ev_recv(inet_client_t *, inet_dgram_t *);
-extern int inet_recv_packet(inet_packet_t *);
-extern int inet_route_packet(inet_dgram_t *, uint8_t, uint8_t, int);
-extern int inet_get_srcaddr(inet_addr_t *, uint8_t, inet_addr_t *);
-extern int inet_recv_dgram_local(inet_dgram_t *, uint8_t);
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/inet_link.c
===================================================================
--- uspace/srv/net/inet/inet_link.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,309 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#include <bool.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <inet/iplink.h>
-#include <io/log.h>
-#include <loc.h>
-#include <stdlib.h>
-#include <str.h>
-
-#include "addrobj.h"
-#include "inet.h"
-#include "inet_link.h"
-#include "pdu.h"
-
-static int inet_link_open(service_id_t sid);
-static int inet_iplink_recv(iplink_t *ilink, iplink_sdu_t *sdu);
-
-static iplink_ev_ops_t inet_iplink_ev_ops = {
-	.recv = inet_iplink_recv
-};
-
-static LIST_INITIALIZE(inet_link_list);
-static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
-
-static int inet_iplink_recv(iplink_t *iplink, iplink_sdu_t *sdu)
-{
-	inet_packet_t packet;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inet_iplink_recv()");
-	rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
-	if (rc != EOK) {
-		log_msg(LVL_DEBUG, "failed decoding PDU");
-		return rc;
-	}
-
-	log_msg(LVL_DEBUG, "call inet_recv_packet()");
-	rc = inet_recv_packet(&packet);
-	log_msg(LVL_DEBUG, "call inet_recv_packet -> %d", rc);
-	free(packet.data);
-
-	return rc;
-}
-
-static int inet_link_check_new(void)
-{
-	bool already_known;
-	category_id_t iplink_cat;
-	service_id_t *svcs;
-	size_t count, i;
-	int rc;
-
-	fibril_mutex_lock(&inet_discovery_lock);
-
-	rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed resolving category 'iplink'.");
-		fibril_mutex_unlock(&inet_discovery_lock);
-		return ENOENT;
-	}
-
-	rc = loc_category_get_svcs(iplink_cat, &svcs, &count);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed getting list of IP links.");
-		fibril_mutex_unlock(&inet_discovery_lock);
-		return EIO;
-	}
-
-	for (i = 0; i < count; i++) {
-		already_known = false;
-
-		list_foreach(inet_link_list, ilink_link) {
-			inet_link_t *ilink = list_get_instance(ilink_link,
-			    inet_link_t, link_list);
-			if (ilink->svc_id == svcs[i]) {
-				already_known = true;
-				break;
-			}
-		}
-
-		if (!already_known) {
-			log_msg(LVL_DEBUG, "Found IP link '%lu'",
-			    (unsigned long) svcs[i]);
-			rc = inet_link_open(svcs[i]);
-			if (rc != EOK)
-				log_msg(LVL_ERROR, "Could not open IP link.");
-		}
-	}
-
-	fibril_mutex_unlock(&inet_discovery_lock);
-	return EOK;
-}
-
-static inet_link_t *inet_link_new(void)
-{
-	inet_link_t *ilink = calloc(1, sizeof(inet_link_t));
-
-	if (ilink == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating link structure. "
-		    "Out of memory.");
-		return NULL;
-	}
-
-	link_initialize(&ilink->link_list);
-
-	return ilink;
-}
-
-static void inet_link_delete(inet_link_t *ilink)
-{
-	if (ilink->svc_name != NULL)
-		free(ilink->svc_name);
-	free(ilink);
-}
-
-static int inet_link_open(service_id_t sid)
-{
-	inet_link_t *ilink;
-	iplink_addr_t iaddr;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inet_link_open()");
-	ilink = inet_link_new();
-	if (ilink == NULL)
-		return ENOMEM;
-
-	ilink->svc_id = sid;
-	ilink->iplink = NULL;
-
-	rc = loc_service_get_name(sid, &ilink->svc_name);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed getting service name.");
-		goto error;
-	}
-
-	ilink->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid, 0);
-	if (ilink->sess == NULL) {
-		log_msg(LVL_ERROR, "Failed connecting '%s'", ilink->svc_name);
-		goto error;
-	}
-
-	rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, &ilink->iplink);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed opening IP link '%s'",
-		    ilink->svc_name);
-		goto error;
-	}
-
-	rc = iplink_get_mtu(ilink->iplink, &ilink->def_mtu);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed determinning MTU of link '%s'",
-		    ilink->svc_name);
-		goto error;
-	}
-
-	log_msg(LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
-	list_append(&ilink->link_list, &inet_link_list);
-
-	inet_addrobj_t *addr;
-
-	static int first = 1;
-	/* XXX For testing: set static IP address 192.168.0.4/24 */
-	addr = inet_addrobj_new();
-	if (first) {
-		addr->naddr.ipv4 = (127 << 24) + (0 << 16) + (0 << 8) + 1;
-		first = 0;
-	} else {
-		addr->naddr.ipv4 = (192 << 24) + (168 << 16) + (0 << 8) + 4;
-	}
-	addr->naddr.bits = 24;
-	addr->ilink = ilink;
-	addr->name = str_dup("v4a");
-	inet_addrobj_add(addr);
-
-	iaddr.ipv4 = addr->naddr.ipv4;
-	rc = iplink_addr_add(ilink->iplink, &iaddr);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed setting IP address on internet link.");
-		/* XXX Roll back */
-		return rc;
-	}
-
-	return EOK;
-
-error:
-	if (ilink->iplink != NULL)
-		iplink_close(ilink->iplink);
-	inet_link_delete(ilink);
-	return rc;
-}
-
-static void inet_link_cat_change_cb(void)
-{
-	(void) inet_link_check_new();
-}
-
-int inet_link_discovery_start(void)
-{
-	int rc;
-
-	rc = loc_register_cat_change_cb(inet_link_cat_change_cb);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering callback for IP link "
-		    "discovery (%d).", rc);
-		return rc;
-	}
-
-	return inet_link_check_new();
-}
-
-/** Send datagram over Internet link */
-int inet_link_send_dgram(inet_link_t *ilink, inet_addr_t *lsrc,
-    inet_addr_t *ldest, inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
-{
-	iplink_sdu_t sdu;
-	inet_packet_t packet;
-	int rc;
-	size_t offs, roffs;
-
-	/*
-	 * Fill packet structure. Fragmentation is performed by
-	 * inet_pdu_encode().
-	 */
-	packet.src = dgram->src;
-	packet.dest = dgram->dest;
-	packet.tos = dgram->tos;
-	packet.proto = proto;
-	packet.ttl = ttl;
-	packet.df = df;
-	packet.data = dgram->data;
-	packet.size = dgram->size;
-
-	sdu.lsrc.ipv4 = lsrc->ipv4;
-	sdu.ldest.ipv4 = ldest->ipv4;
-
-	offs = 0;
-	do {
-		/* Encode one fragment */
-		rc = inet_pdu_encode(&packet, offs, ilink->def_mtu, &sdu.data,
-		    &sdu.size, &roffs);
-		if (rc != EOK)
-			return rc;
-
-		/* Send the PDU */
-		rc = iplink_send(ilink->iplink, &sdu);
-		free(sdu.data);
-
-		offs = roffs;
-	} while (offs < packet.size);
-
-	return rc;
-}
-
-inet_link_t *inet_link_get_by_id(sysarg_t link_id)
-{
-	fibril_mutex_lock(&inet_discovery_lock);
-
-	list_foreach(inet_link_list, elem) {
-		inet_link_t *ilink = list_get_instance(elem, inet_link_t,
-		    link_list);
-
-		if (ilink->svc_id == link_id) {
-			fibril_mutex_unlock(&inet_discovery_lock);
-			return ilink;
-		}
-	}
-
-	fibril_mutex_unlock(&inet_discovery_lock);
-	return NULL;
-}
-
-/** @}
- */
Index: pace/srv/net/inet/inet_link.h
===================================================================
--- uspace/srv/net/inet/inet_link.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INET_LINK_H_
-#define INET_LINK_H_
-
-#include <sys/types.h>
-#include "inet.h"
-
-extern int inet_link_discovery_start(void);
-extern int inet_link_send_dgram(inet_link_t *, inet_addr_t *,
-    inet_addr_t *, inet_dgram_t *, uint8_t, uint8_t, int);
-extern inet_link_t *inet_link_get_by_id(sysarg_t);
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/inet_std.h
===================================================================
--- uspace/srv/net/inet/inet_std.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,98 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file IP header definitions
- *
- */
-
-#ifndef INET_STD_H_
-#define INET_STD_H_
-
-#include <sys/types.h>
-
-/** Internet Datagram header (fixed part) */
-typedef struct {
-	/** Version, Internet Header Length */
-	uint8_t ver_ihl;
-	/* Type of Service */
-	uint8_t tos;
-	/** Total Length */
-	uint16_t tot_len;
-	/** Identification */
-	uint16_t id;
-	/** Flags, Fragment Offset */
-	uint16_t flags_foff;
-	/** Time to Live */
-	uint8_t ttl;
-	/** Protocol */
-	uint8_t proto;
-	/** Header Checksum */
-	uint16_t chksum;
-	/** Source Address */
-	uint32_t src_addr;
-	/** Destination Address */
-	uint32_t dest_addr;
-} ip_header_t;
-
-/** Bits in ip_header_t.ver_ihl */
-enum ver_ihl_bits {
-	/** Version, highest bit */
-	VI_VERSION_h = 7,
-	/** Version, lowest bit */
-	VI_VERSION_l = 4,
-	/** Internet Header Length, highest bit */
-	VI_IHL_h     = 3,
-	/** Internet Header Length, lowest bit */
-	VI_IHL_l     = 0
-};
-
-/** Bits in ip_header_t.flags_foff */
-enum flags_foff_bits {
-	/** Reserved, must be zero */
-	FF_FLAG_RSVD = 15,
-	/** Don't Fragment */
-	FF_FLAG_DF = 14,
-	/** More Fragments */
-	FF_FLAG_MF = 13,
-	/** Fragment Offset, highest bit */
-	FF_FRAGOFF_h = 12,
-	/** Fragment Offset, lowest bit */
-	FF_FRAGOFF_l = 0
-};
-
-/** Fragment offset is expressed in units of 8 bytes */
-#define FRAG_OFFS_UNIT 8
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/inet_util.c
===================================================================
--- uspace/srv/net/inet/inet_util.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#include <assert.h>
-#include <bitops.h>
-#include <sys/types.h>
-#include "inet_util.h"
-
-uint32_t inet_netmask(int bits)
-{
-	assert(bits >= 0);
-	assert(bits < 32);
-
-	if (bits == 0)
-		return 0;
-	else
-		return BIT_RANGE(uint32_t, 31, 31 - (bits - 1));
-}
-
-/** @}
- */
Index: pace/srv/net/inet/inet_util.h
===================================================================
--- uspace/srv/net/inet/inet_util.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,47 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INET_UTIL_H_
-#define INET_UTIL_H_
-
-#include <sys/types.h>
-
-uint32_t inet_netmask(int bits);
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/inetcfg.c
===================================================================
--- uspace/srv/net/inet/inetcfg.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,631 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#include <async.h>
-#include <errno.h>
-#include <macros.h>
-#include <io/log.h>
-#include <ipc/inet.h>
-#include <loc.h>
-#include <stdlib.h>
-#include <str.h>
-#include <sys/types.h>
-
-#include "addrobj.h"
-#include "inet.h"
-#include "inet_link.h"
-#include "inetcfg.h"
-#include "sroute.h"
-
-static int inetcfg_addr_create_static(char *name, inet_naddr_t *naddr,
-    sysarg_t link_id, sysarg_t *addr_id)
-{
-	inet_link_t *ilink;
-	inet_addrobj_t *addr;
-	iplink_addr_t iaddr;
-	int rc;
-
-	ilink = inet_link_get_by_id(link_id);
-	if (ilink == NULL) {
-		log_msg(LVL_DEBUG, "Link %lu not found.",
-		    (unsigned long) link_id);
-		return ENOENT;
-	}
-
-	addr = inet_addrobj_new();
-	if (addr == NULL) {
-		*addr_id = 0;
-		return ENOMEM;
-	}
-
-	addr->naddr = *naddr;
-	addr->ilink = ilink;
-	addr->name = str_dup(name);
-	inet_addrobj_add(addr);
-
-	iaddr.ipv4 = addr->naddr.ipv4;
-	rc = iplink_addr_add(ilink->iplink, &iaddr);
-	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed setting IP address on internet link.");
-		inet_addrobj_remove(addr);
-		inet_addrobj_delete(addr);
-		return rc;
-	}
-
-	return EOK;
-}
-
-static int inetcfg_addr_delete(sysarg_t addr_id)
-{
-	inet_addrobj_t *addr;
-
-	addr = inet_addrobj_get_by_id(addr_id);
-	if (addr == NULL)
-		return ENOENT;
-
-	inet_addrobj_remove(addr);
-	inet_addrobj_delete(addr);
-
-	return EOK;
-}
-
-static int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
-{
-	inet_addrobj_t *addr;
-
-	addr = inet_addrobj_get_by_id(addr_id);
-	if (addr == NULL)
-		return ENOENT;
-
-	ainfo->naddr = addr->naddr;
-	ainfo->ilink = addr->ilink->svc_id;
-	ainfo->name = str_dup(addr->name);
-
-	return EOK;
-}
-
-static int inetcfg_addr_get_id(char *name, sysarg_t link_id, sysarg_t *addr_id)
-{
-	inet_link_t *ilink;
-	inet_addrobj_t *addr;
-
-	ilink = inet_link_get_by_id(link_id);
-	if (ilink == NULL) {
-		log_msg(LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
-		return ENOENT;
-	}
-
-	addr = inet_addrobj_find_by_name(name, ilink);
-	if (addr == NULL) {
-		log_msg(LVL_DEBUG, "Address '%s' not found.", name);
-		return ENOENT;
-	}
-
-	*addr_id = addr->id;
-	return EOK;
-}
-
-static int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
-{
-	return inet_addrobj_get_id_list(addrs, count);
-}
-
-static int inetcfg_get_link_list(sysarg_t **addrs, size_t *count)
-{
-	return ENOTSUP;
-}
-
-static int inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
-{
-	return inet_sroute_get_id_list(sroutes, count);
-}
-
-static int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
-{
-	inet_link_t *ilink;
-
-	ilink = inet_link_get_by_id(link_id);
-	if (ilink == NULL) {
-		return ENOENT;
-	}
-
-	linfo->name = str_dup(ilink->svc_name);
-	linfo->def_mtu = ilink->def_mtu;
-	return EOK;
-}
-
-static int inetcfg_sroute_create(char *name, inet_naddr_t *dest,
-    inet_addr_t *router, sysarg_t *sroute_id)
-{
-	inet_sroute_t *sroute;
-
-	sroute = inet_sroute_new();
-	if (sroute == NULL) {
-		*sroute_id = 0;
-		return ENOMEM;
-	}
-
-	sroute->dest = *dest;
-	sroute->router = *router;
-	sroute->name = str_dup(name);
-	inet_sroute_add(sroute);
-
-	*sroute_id = sroute->id;
-	return EOK;
-}
-
-static int inetcfg_sroute_delete(sysarg_t sroute_id)
-{
-	inet_sroute_t *sroute;
-
-	sroute = inet_sroute_get_by_id(sroute_id);
-	if (sroute == NULL)
-		return ENOENT;
-
-	inet_sroute_remove(sroute);
-	inet_sroute_delete(sroute);
-
-	return EOK;
-}
-
-static int inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
-{
-	inet_sroute_t *sroute;
-
-	sroute = inet_sroute_get_by_id(sroute_id);
-	if (sroute == NULL)
-		return ENOENT;
-
-	srinfo->dest = sroute->dest;
-	srinfo->router = sroute->router;
-	srinfo->name = str_dup(sroute->name);
-
-	return EOK;
-}
-
-static int inetcfg_sroute_get_id(char *name, sysarg_t *sroute_id)
-{
-	inet_sroute_t *sroute;
-
-	sroute = inet_sroute_find_by_name(name);
-	if (sroute == NULL) {
-		log_msg(LVL_DEBUG, "Static route '%s' not found.", name);
-		return ENOENT;
-	}
-
-	*sroute_id = sroute->id;
-	return EOK;
-}
-
-static void inetcfg_addr_create_static_srv(ipc_callid_t callid,
-    ipc_call_t *call)
-{
-	char *name;
-	inet_naddr_t naddr;
-	sysarg_t link_id;
-	sysarg_t addr_id;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetcfg_addr_create_static_srv()");
-
-	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
-	    0, NULL);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	naddr.ipv4 = IPC_GET_ARG1(*call);
-	naddr.bits = IPC_GET_ARG2(*call);
-	link_id    = IPC_GET_ARG3(*call);
-
-	addr_id = 0;
-	rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id);
-	free(name);
-	async_answer_1(callid, rc, addr_id);
-}
-
-static void inetcfg_addr_delete_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	sysarg_t addr_id;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetcfg_addr_delete_srv()");
-
-	addr_id = IPC_GET_ARG1(*call);
-
-	rc = inetcfg_addr_delete(addr_id);
-	async_answer_0(callid, rc);
-}
-
-static void inetcfg_addr_get_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	ipc_callid_t rcallid;
-	size_t max_size;
-
-	sysarg_t addr_id;
-	inet_addr_info_t ainfo;
-	int rc;
-
-	addr_id = IPC_GET_ARG1(*call);
-	log_msg(LVL_DEBUG, "inetcfg_addr_get_srv()");
-
-	ainfo.naddr.ipv4 = 0;
-	ainfo.naddr.bits = 0;
-	ainfo.ilink = 0;
-	ainfo.name = NULL;
-
-	if (!async_data_read_receive(&rcallid, &max_size)) {
-		async_answer_0(rcallid, EREFUSED);
-		async_answer_0(callid, EREFUSED);
-		return;
-	}
-
-	rc = inetcfg_addr_get(addr_id, &ainfo);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	sysarg_t retval = async_data_read_finalize(rcallid, ainfo.name,
-	    min(max_size, str_size(ainfo.name)));
-	free(ainfo.name);
-
-	async_answer_3(callid, retval, ainfo.naddr.ipv4, ainfo.naddr.bits,
-	    ainfo.ilink);
-}
-
-static void inetcfg_addr_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	char *name;
-	sysarg_t link_id;
-	sysarg_t addr_id;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetcfg_addr_get_id_srv()");
-
-	link_id = IPC_GET_ARG1(*call);
-
-	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
-	    0, NULL);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	addr_id = 0;
-	rc = inetcfg_addr_get_id(name, link_id, &addr_id);
-	free(name);
-	async_answer_1(callid, rc, addr_id);
-}
-
-static void inetcfg_get_addr_list_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	ipc_callid_t rcallid;
-	size_t count;
-	size_t max_size;
-	size_t act_size;
-	size_t size;
-	sysarg_t *id_buf;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetcfg_get_addr_list_srv()");
-
-	if (!async_data_read_receive(&rcallid, &max_size)) {
-		async_answer_0(rcallid, EREFUSED);
-		async_answer_0(callid, EREFUSED);
-		return;
-	}
-
-	rc = inetcfg_get_addr_list(&id_buf, &count);
-	if (rc != EOK) {
-		async_answer_0(rcallid, rc);
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	act_size = count * sizeof(sysarg_t);
-	size = min(act_size, max_size);
-
-	sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
-	free(id_buf);
-
-	async_answer_1(callid, retval, act_size);
-}
-
-
-static void inetcfg_get_link_list_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	ipc_callid_t rcallid;
-	size_t max_size;
-	size_t act_size;
-	size_t size;
-	sysarg_t *id_buf;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetcfg_get_link_list_srv()");
-
-	if (!async_data_read_receive(&rcallid, &max_size)) {
-		async_answer_0(rcallid, EREFUSED);
-		async_answer_0(callid, EREFUSED);
-		return;
-	}
-
-	rc = inetcfg_get_link_list(&id_buf, &act_size);
-	if (rc != EOK) {
-		async_answer_0(rcallid, rc);
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	size = min(act_size, max_size);
-
-	sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
-	free(id_buf);
-
-	async_answer_1(callid, retval, act_size);
-}
-
-static void inetcfg_get_sroute_list_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	ipc_callid_t rcallid;
-	size_t count;
-	size_t max_size;
-	size_t act_size;
-	size_t size;
-	sysarg_t *id_buf;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
-
-	if (!async_data_read_receive(&rcallid, &max_size)) {
-		async_answer_0(rcallid, EREFUSED);
-		async_answer_0(callid, EREFUSED);
-		return;
-	}
-
-	rc = inetcfg_get_sroute_list(&id_buf, &count);
-	if (rc != EOK) {
-		async_answer_0(rcallid, rc);
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	act_size = count * sizeof(sysarg_t);
-	size = min(act_size, max_size);
-
-	sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
-	free(id_buf);
-
-	async_answer_1(callid, retval, act_size);
-}
-
-static void inetcfg_link_get_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	ipc_callid_t rcallid;
-	size_t max_size;
-
-	sysarg_t link_id;
-	inet_link_info_t linfo;
-	int rc;
-
-	link_id = IPC_GET_ARG1(*call);
-	log_msg(LVL_DEBUG, "inetcfg_link_get_srv()");
-
-	linfo.name = NULL;
-
-	if (!async_data_read_receive(&rcallid, &max_size)) {
-		async_answer_0(rcallid, EREFUSED);
-		async_answer_0(callid, EREFUSED);
-		return;
-	}
-
-	rc = inetcfg_link_get(link_id, &linfo);
-	if (rc != EOK) {
-		async_answer_0(rcallid, rc);
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	sysarg_t retval = async_data_read_finalize(rcallid, linfo.name,
-	    min(max_size, str_size(linfo.name)));
-	free(linfo.name);
-
-	async_answer_1(callid, retval, linfo.def_mtu);
-}
-
-static void inetcfg_sroute_create_srv(ipc_callid_t callid,
-    ipc_call_t *call)
-{
-	char *name;
-	inet_naddr_t dest;
-	inet_addr_t router;
-	sysarg_t sroute_id;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetcfg_sroute_create_srv()");
-
-	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
-	    0, NULL);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	dest.ipv4   = IPC_GET_ARG1(*call);
-	dest.bits   = IPC_GET_ARG2(*call);
-	router.ipv4 = IPC_GET_ARG3(*call);
-
-	sroute_id = 0;
-	rc = inetcfg_sroute_create(name, &dest, &router, &sroute_id);
-	free(name);
-	async_answer_1(callid, rc, sroute_id);
-}
-
-static void inetcfg_sroute_delete_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	sysarg_t sroute_id;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetcfg_sroute_delete_srv()");
-
-	sroute_id = IPC_GET_ARG1(*call);
-
-	rc = inetcfg_sroute_delete(sroute_id);
-	async_answer_0(callid, rc);
-}
-
-static void inetcfg_sroute_get_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	ipc_callid_t rcallid;
-	size_t max_size;
-
-	sysarg_t sroute_id;
-	inet_sroute_info_t srinfo;
-	int rc;
-
-	sroute_id = IPC_GET_ARG1(*call);
-	log_msg(LVL_DEBUG, "inetcfg_sroute_get_srv()");
-
-	srinfo.dest.ipv4 = 0;
-	srinfo.dest.bits = 0;
-	srinfo.router.ipv4 = 0;
-	srinfo.name = NULL;
-
-	if (!async_data_read_receive(&rcallid, &max_size)) {
-		async_answer_0(rcallid, EREFUSED);
-		async_answer_0(callid, EREFUSED);
-		return;
-	}
-
-	rc = inetcfg_sroute_get(sroute_id, &srinfo);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	sysarg_t retval = async_data_read_finalize(rcallid, srinfo.name,
-	    min(max_size, str_size(srinfo.name)));
-	free(srinfo.name);
-
-	async_answer_3(callid, retval, srinfo.dest.ipv4, srinfo.dest.bits,
-	    srinfo.router.ipv4);
-}
-
-static void inetcfg_sroute_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	char *name;
-	sysarg_t sroute_id;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
-
-	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
-	    0, NULL);
-	if (rc != EOK) {
-		async_answer_0(callid, rc);
-		return;
-	}
-
-	sroute_id = 0;
-	rc = inetcfg_sroute_get_id(name, &sroute_id);
-	free(name);
-	async_answer_1(callid, rc, sroute_id);
-}
-
-void inet_cfg_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	log_msg(LVL_DEBUG, "inet_cfg_conn()");
-
-	/* Accept the connection */
-	async_answer_0(iid, EOK);
-
-	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);
-			return;
-		}
-
-		switch (method) {
-		case INETCFG_ADDR_CREATE_STATIC:
-			inetcfg_addr_create_static_srv(callid, &call);
-			break;
-		case INETCFG_ADDR_DELETE:
-			inetcfg_addr_delete_srv(callid, &call);
-			break;
-		case INETCFG_ADDR_GET:
-			inetcfg_addr_get_srv(callid, &call);
-			break;
-		case INETCFG_ADDR_GET_ID:
-			inetcfg_addr_get_id_srv(callid, &call);
-			break;
-		case INETCFG_GET_ADDR_LIST:
-			inetcfg_get_addr_list_srv(callid, &call);
-			break;
-		case INETCFG_GET_LINK_LIST:
-			inetcfg_get_link_list_srv(callid, &call);
-			break;
-		case INETCFG_GET_SROUTE_LIST:
-			inetcfg_get_sroute_list_srv(callid, &call);
-			break;
-		case INETCFG_LINK_GET:
-			inetcfg_link_get_srv(callid, &call);
-			break;
-		case INETCFG_SROUTE_CREATE:
-			inetcfg_sroute_create_srv(callid, &call);
-			break;
-		case INETCFG_SROUTE_DELETE:
-			inetcfg_sroute_delete_srv(callid, &call);
-			break;
-		case INETCFG_SROUTE_GET:
-			inetcfg_sroute_get_srv(callid, &call);
-			break;
-		case INETCFG_SROUTE_GET_ID:
-			inetcfg_sroute_get_id_srv(callid, &call);
-			break;
-		default:
-			async_answer_0(callid, EINVAL);
-		}
-	}
-}
-
-/** @}
- */
Index: pace/srv/net/inet/inetcfg.h
===================================================================
--- uspace/srv/net/inet/inetcfg.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INETCFG_H_
-#define INETCFG_H_
-
-extern void inet_cfg_conn(ipc_callid_t, ipc_call_t *, void *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/inetping.c
===================================================================
--- uspace/srv/net/inet/inetping.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,230 +1,0 @@
-/*
- * Copyright (c) 2012 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 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 "icmp.h"
-#include "icmp_std.h"
-#include "inet.h"
-#include "inetping.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 inetping_ident = 0;
-
-static inetping_client_t *inetping_client_find(uint16_t);
-
-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, inet_addr_t *remote,
-    inet_addr_t *local)
-{
-	return inet_get_srcaddr(remote, ICMP_TOS, local);
-}
-
-int inetping_recv(uint16_t ident, inetping_sdu_t *sdu)
-{
-	inetping_client_t *client;
-	async_exch_t *exch;
-	ipc_call_t answer;
-
-	client = inetping_client_find(ident);
-	if (client == NULL) {
-		log_msg(LVL_DEBUG, "Unknown ICMP ident. Dropping.");
-		return ENOENT;
-	}
-
-	exch = async_exchange_begin(client->sess);
-
-	aid_t req = async_send_3(exch, INETPING_EV_RECV, sdu->src.ipv4,
-	    sdu->dest.ipv4, sdu->seq_no, &answer);
-	int 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);
-	if (retval != EOK) {
-		return retval;
-	}
-
-	return EOK;
-}
-
-static void inetping_send_srv(inetping_client_t *client, ipc_callid_t callid,
-    ipc_call_t *call)
-{
-	inetping_sdu_t sdu;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetping_send_srv()");
-
-	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.ipv4 = IPC_GET_ARG1(*call);
-	sdu.dest.ipv4 = IPC_GET_ARG2(*call);
-	sdu.seq_no = IPC_GET_ARG3(*call);
-
-	rc = inetping_send(client, &sdu);
-	free(sdu.data);
-
-	async_answer_0(callid, rc);
-}
-
-static void inetping_get_srcaddr_srv(inetping_client_t *client,
-    ipc_callid_t callid, ipc_call_t *call)
-{
-	inet_addr_t remote;
-	inet_addr_t local;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetping_get_srcaddr_srv()");
-
-	remote.ipv4 = IPC_GET_ARG1(*call);
-	local.ipv4 = 0;
-
-	rc = inetping_get_srcaddr(client, &remote, &local);
-	async_answer_1(callid, rc, local.ipv4);
-}
-
-static int inetping_client_init(inetping_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 = ++inetping_ident;
-	list_append(&client->client_list, &client_list);
-	fibril_mutex_unlock(&client_list_lock);
-
-	return EOK;
-}
-
-static void inetping_client_fini(inetping_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);
-}
-
-static inetping_client_t *inetping_client_find(uint16_t ident)
-{
-	fibril_mutex_lock(&client_list_lock);
-
-	list_foreach(client_list, link) {
-		inetping_client_t *client = list_get_instance(link,
-		    inetping_client_t, client_list);
-
-		if (client->ident == ident) {
-			fibril_mutex_unlock(&client_list_lock);
-			return client;
-		}
-	}
-
-	fibril_mutex_unlock(&client_list_lock);
-	return NULL;
-}
-
-void inetping_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	inetping_client_t client;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inetping_conn()");
-
-	/* Accept the connection */
-	async_answer_0(iid, EOK);
-
-	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 */
-			async_answer_0(callid, EOK);
-			break;
-		}
-
-		switch (method) {
-		case INETPING_SEND:
-			inetping_send_srv(&client, callid, &call);
-			break;
-		case INETPING_GET_SRCADDR:
-			inetping_get_srcaddr_srv(&client, callid, &call);
-			break;
-		default:
-			async_answer_0(callid, EINVAL);
-		}
-	}
-
-	inetping_client_fini(&client);
-}
-
-/** @}
- */
Index: pace/srv/net/inet/inetping.h
===================================================================
--- uspace/srv/net/inet/inetping.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INETPING_H_
-#define INETPING_H_
-
-extern void inetping_conn(ipc_callid_t, ipc_call_t *, void *);
-extern int inetping_recv(uint16_t, inetping_sdu_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/pdu.c
===================================================================
--- uspace/srv/net/inet/pdu.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,268 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#include <align.h>
-#include <bitops.h>
-#include <byteorder.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <io/log.h>
-#include <macros.h>
-#include <mem.h>
-#include <stdlib.h>
-
-#include "inet.h"
-#include "inet_std.h"
-#include "pdu.h"
-
-static FIBRIL_MUTEX_INITIALIZE(ip_ident_lock);
-static uint16_t ip_ident = 0;
-
-/** One's complement addition.
- *
- * Result is a + b + carry.
- */
-static uint16_t inet_ocadd16(uint16_t a, uint16_t b)
-{
-	uint32_t s;
-
-	s = (uint32_t)a + (uint32_t)b;
-	return (s & 0xffff) + (s >> 16);
-}
-
-uint16_t inet_checksum_calc(uint16_t ivalue, void *data, size_t size)
-{
-	uint16_t sum;
-	uint16_t w;
-	size_t words, i;
-	uint8_t *bdata;
-
-	sum = ~ivalue;
-	words = size / 2;
-	bdata = (uint8_t *)data;
-
-	for (i = 0; i < words; i++) {
-		w = ((uint16_t)bdata[2*i] << 8) | bdata[2*i + 1];
-		sum = inet_ocadd16(sum, w);
-	}
-
-	if (size % 2 != 0) {
-		w = ((uint16_t)bdata[2*words] << 8);
-		sum = inet_ocadd16(sum, w);
-	}
-
-	return ~sum;
-}
-
-/** Encode Internet PDU.
- *
- * Encode internet packet into PDU (serialized form). Will encode a
- * fragment of the payload starting at offset @a offs. The resulting
- * PDU will have at most @a mtu bytes. @a *roffs will be set to the offset
- * of remaining payload. If some data is remaining, the MF flag will
- * be set in the header, otherwise the offset will equal @a packet->size.
- *
- * @param packet	Packet to encode
- * @param offs		Offset into packet payload (in bytes)
- * @param mtu		MTU (Maximum Transmission Unit) in bytes
- * @param rdata		Place to store pointer to allocated data buffer
- * @param rsize		Place to store size of allocated data buffer
- * @param roffs		Place to store offset of remaning data
- */
-int inet_pdu_encode(inet_packet_t *packet, size_t offs, size_t mtu,
-    void **rdata, size_t *rsize, size_t *roffs)
-{
-	void *data;
-	size_t size;
-	ip_header_t *hdr;
-	size_t hdr_size;
-	size_t data_offs;
-	uint16_t chksum;
-	uint16_t ident;
-	uint16_t flags_foff;
-	uint16_t foff;
-	size_t fragoff_limit;
-	size_t xfer_size;
-	size_t spc_avail;
-	size_t rem_offs;
-
-	/* Upper bound for fragment offset field */
-	fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
-
-	/* Verify that total size of datagram is within reasonable bounds */
-	if (offs + packet->size > FRAG_OFFS_UNIT * fragoff_limit)
-		return ELIMIT;
-
-	hdr_size = sizeof(ip_header_t);
-	data_offs = ROUND_UP(hdr_size, 4);
-
-	assert(offs % FRAG_OFFS_UNIT == 0);
-	assert(offs / FRAG_OFFS_UNIT < fragoff_limit);
-
-	/* Value for the fragment offset field */
-	foff = offs / FRAG_OFFS_UNIT;
-
-	if (hdr_size >= mtu)
-		return EINVAL;
-
-	/* Amount of space in the PDU available for payload */
-	spc_avail = mtu - hdr_size;
-	spc_avail -= (spc_avail % FRAG_OFFS_UNIT);
-
-	/* Amount of data (payload) to transfer */
-	xfer_size = min(packet->size - offs, spc_avail);
-
-	/* Total PDU size */
-	size = hdr_size + xfer_size;
-
-	/* Offset of remaining payload */
-	rem_offs = offs + xfer_size;
-
-	/* Flags */
-	flags_foff =
-	    (packet->df ? BIT_V(uint16_t, FF_FLAG_DF) : 0) +
-	    (rem_offs < packet->size ? BIT_V(uint16_t, FF_FLAG_MF) : 0) +
-	    (foff << FF_FRAGOFF_l);
-
-	data = calloc(size, 1);
-	if (data == NULL)
-		return ENOMEM;
-
-	/* Allocate identifier */
-	fibril_mutex_lock(&ip_ident_lock);
-	ident = ++ip_ident;
-	fibril_mutex_unlock(&ip_ident_lock);
-
-	/* Encode header fields */
-	hdr = (ip_header_t *)data;
-	hdr->ver_ihl = (4 << VI_VERSION_l) | (hdr_size / sizeof(uint32_t));
-	hdr->tos = packet->tos;
-	hdr->tot_len = host2uint16_t_be(size);
-	hdr->id = host2uint16_t_be(ident);
-	hdr->flags_foff = host2uint16_t_be(flags_foff);
-	hdr->ttl = packet->ttl;
-	hdr->proto = packet->proto;
-	hdr->chksum = 0;
-	hdr->src_addr = host2uint32_t_be(packet->src.ipv4);
-	hdr->dest_addr = host2uint32_t_be(packet->dest.ipv4);
-
-	/* Compute checksum */
-	chksum = inet_checksum_calc(INET_CHECKSUM_INIT, (void *)hdr, hdr_size);
-	hdr->chksum = host2uint16_t_be(chksum);
-
-	/* Copy payload */
-	memcpy((uint8_t *)data + data_offs, packet->data + offs, xfer_size);
-
-	*rdata = data;
-	*rsize = size;
-	*roffs = rem_offs;
-
-	return EOK;
-}
-
-int inet_pdu_decode(void *data, size_t size, inet_packet_t *packet)
-{
-	ip_header_t *hdr;
-	size_t tot_len;
-	size_t data_offs;
-	uint8_t version;
-	uint16_t ident;
-	uint16_t flags_foff;
-	uint16_t foff;
-
-	log_msg(LVL_DEBUG, "inet_pdu_decode()");
-
-	if (size < sizeof(ip_header_t)) {
-		log_msg(LVL_DEBUG, "PDU too short (%zu)", size);
-		return EINVAL;
-	}
-
-	hdr = (ip_header_t *)data;
-
-	version = BIT_RANGE_EXTRACT(uint8_t, VI_VERSION_h, VI_VERSION_l,
-	    hdr->ver_ihl);
-	if (version != 4) {
-		log_msg(LVL_DEBUG, "Version (%d) != 4", version);
-		return EINVAL;
-	}
-
-	tot_len = uint16_t_be2host(hdr->tot_len);
-	if (tot_len < sizeof(ip_header_t)) {
-		log_msg(LVL_DEBUG, "Total Length too small (%zu)", tot_len);
-		return EINVAL;
-	}
-
-	if (tot_len > size) {
-		log_msg(LVL_DEBUG, "Total Length = %zu > PDU size = %zu",
-			tot_len, size);
-		return EINVAL;
-	}
-
-	ident = uint16_t_be2host(hdr->id);
-	flags_foff = uint16_t_be2host(hdr->flags_foff);
-	foff = BIT_RANGE_EXTRACT(uint16_t, FF_FRAGOFF_h, FF_FRAGOFF_l,
-	    flags_foff);
-	/* XXX Checksum */
-
-	packet->src.ipv4 = uint32_t_be2host(hdr->src_addr);
-	packet->dest.ipv4 = uint32_t_be2host(hdr->dest_addr);
-	packet->tos = hdr->tos;
-	packet->proto = hdr->proto;
-	packet->ttl = hdr->ttl;
-	packet->ident = ident;
-
-	packet->df = (flags_foff & BIT_V(uint16_t, FF_FLAG_DF)) != 0;
-	packet->mf = (flags_foff & BIT_V(uint16_t, FF_FLAG_MF)) != 0;
-	packet->offs = foff * FRAG_OFFS_UNIT;
-
-	/* XXX IP options */
-	data_offs = sizeof(uint32_t) * BIT_RANGE_EXTRACT(uint8_t, VI_IHL_h,
-	    VI_IHL_l, hdr->ver_ihl);
-
-	packet->size = tot_len - data_offs;
-	packet->data = calloc(packet->size, 1);
-	if (packet->data == NULL) {
-		log_msg(LVL_WARN, "Out of memory.");
-		return ENOMEM;
-	}
-
-	memcpy(packet->data, (uint8_t *)data + data_offs, packet->size);
-
-	return EOK;
-}
-
-/** @}
- */
Index: pace/srv/net/inet/pdu.h
===================================================================
--- uspace/srv/net/inet/pdu.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INET_PDU_H_
-#define INET_PDU_H_
-
-#include <sys/types.h>
-#include "inet.h"
-
-#define INET_CHECKSUM_INIT 0xffff
-
-extern uint16_t inet_checksum_calc(uint16_t, void *, size_t);
-
-extern int inet_pdu_encode(inet_packet_t *, size_t, size_t, void **,
-    size_t *, size_t *);
-extern int inet_pdu_decode(void *, size_t, inet_packet_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/reass.c
===================================================================
--- uspace/srv/net/inet/reass.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,374 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief Datagram reassembly.
- */
-
-#include <errno.h>
-#include <fibril_synch.h>
-#include <io/log.h>
-#include <macros.h>
-#include <mem.h>
-#include <stdlib.h>
-
-#include "inet.h"
-#include "inet_std.h"
-#include "reass.h"
-
-/** Datagram being reassembled.
- *
- * Uniquely identified by (source address, destination address, protocol,
- * identification) per RFC 791 sec. 2.3 / Fragmentation.
- */
-typedef struct {
-	link_t map_link;
-	/** List of fragments, @c reass_frag_t */
-	list_t frags;
-} reass_dgram_t;
-
-/** One datagram fragment */
-typedef struct {
-	link_t dgram_link;
-	inet_packet_t packet;
-} reass_frag_t;
-
-/** Datagram map, list of reass_dgram_t */
-static LIST_INITIALIZE(reass_dgram_map);
-/** Protects access to @c reass_dgram_map */
-static FIBRIL_MUTEX_INITIALIZE(reass_dgram_map_lock);
-
-static reass_dgram_t *reass_dgram_new(void);
-static reass_dgram_t *reass_dgram_get(inet_packet_t *);
-static int reass_dgram_insert_frag(reass_dgram_t *, inet_packet_t *);
-static bool reass_dgram_complete(reass_dgram_t *);
-static void reass_dgram_remove(reass_dgram_t *);
-static int reass_dgram_deliver(reass_dgram_t *);
-static void reass_dgram_destroy(reass_dgram_t *);
-
-/** Queue packet for datagram reassembly.
- *
- * @param packet	Packet
- * @return		EOK on success or ENOMEM.
- */
-int inet_reass_queue_packet(inet_packet_t *packet)
-{
-	reass_dgram_t *rdg;
-	int rc;
-
-	log_msg(LVL_DEBUG, "inet_reass_queue_packet()");
-
-	fibril_mutex_lock(&reass_dgram_map_lock);
-
-	/* Get existing or new datagram */
-	rdg = reass_dgram_get(packet);
-	if (rdg == NULL) {
-		/* Only happens when we are out of memory */
-		fibril_mutex_unlock(&reass_dgram_map_lock);
-		log_msg(LVL_DEBUG, "Allocation failed, packet dropped.");
-		return ENOMEM;
-	}
-
-	/* Insert fragment into the datagram */
-	rc = reass_dgram_insert_frag(rdg, packet);
-	if (rc != EOK)
-		return ENOMEM;
-
-	/* Check if datagram is complete */
-	if (reass_dgram_complete(rdg)) {
-		/* Remove it from the map */
-		reass_dgram_remove(rdg);
-		fibril_mutex_unlock(&reass_dgram_map_lock);
-
-		/* Deliver complete datagram */
-		rc = reass_dgram_deliver(rdg);
-		reass_dgram_destroy(rdg);
-		return rc;
-	}
-
-	fibril_mutex_unlock(&reass_dgram_map_lock);
-	return EOK;
-}
-
-/** Get datagram reassembly structure for packet.
- *
- * @param packet	Packet
- * @return		Datagram reassembly structure matching @a packet
- */
-static reass_dgram_t *reass_dgram_get(inet_packet_t *packet)
-{
-	assert(fibril_mutex_is_locked(&reass_dgram_map_lock));
-
-	list_foreach(reass_dgram_map, link) {
-		reass_dgram_t *rdg = list_get_instance(link, reass_dgram_t,
-		    map_link);
-
-		link_t *f1_link = list_first(&rdg->frags);
-		assert(f1_link != NULL);
-
-		reass_frag_t *f1 = list_get_instance(f1_link, reass_frag_t,
-		    dgram_link);
-
-		if (f1->packet.src.ipv4 == packet->src.ipv4 &&
-		    f1->packet.dest.ipv4 == packet->dest.ipv4 &&
-		    f1->packet.proto == packet->proto &&
-		    f1->packet.ident == packet->ident) {
-			/* Match */
-			return rdg;
-		}
-	}
-
-	/* No existing reassembly structure. Create a new one. */
-	return reass_dgram_new();
-}
-
-/** Create new datagram reassembly structure.
- *
- * @return New datagram reassembly structure.
- */
-static reass_dgram_t *reass_dgram_new(void)
-{
-	reass_dgram_t *rdg;
-
-	rdg = calloc(1, sizeof(reass_dgram_t));
-	if (rdg == NULL)
-		return NULL;
-
-	link_initialize(&rdg->map_link);
-	list_initialize(&rdg->frags);
-
-	return rdg;
-}
-
-static reass_frag_t *reass_frag_new(void)
-{
-	reass_frag_t *frag;
-
-	frag = calloc(1, sizeof(reass_frag_t));
-	if (frag == NULL)
-		return NULL;
-
-	link_initialize(&frag->dgram_link);
-
-	return frag;
-}
-
-static int reass_dgram_insert_frag(reass_dgram_t *rdg, inet_packet_t *packet)
-{
-	reass_frag_t *frag;
-	void *data_copy;
-	link_t *link;
-
-	assert(fibril_mutex_is_locked(&reass_dgram_map_lock));
-
-	frag = reass_frag_new();
-
-	/* Clone the packet */
-
-	data_copy = malloc(packet->size);
-	if (data_copy == NULL)
-		return ENOMEM;
-
-	frag->packet = *packet;
-	frag->packet.data = data_copy;
-
-	/*
-	 * XXX Make resource-consuming attacks harder, eliminate any duplicate
-	 * data immediately. Possibly eliminate redundant packet headers.
-	 */
-
-	/*
-	 * Insert into the list, which is sorted by offs member ascending.
-	 */
-
-	link = list_first(&rdg->frags);
-	while (link != NULL) {
-		reass_frag_t *qf = list_get_instance(link, reass_frag_t,
-		    dgram_link);
-
-		if (qf->packet.offs >= packet->offs)
-			break;
-
-		link = link->next;
-	}
-
-	if (link != NULL)
-		list_insert_after(&frag->dgram_link, link);
-	else
-		list_append(&frag->dgram_link, &rdg->frags);
-
-	return EOK;
-}
-
-/** Check if datagram is complete.
- *
- * @param rdg		Datagram reassembly structure
- * @return		@c true if complete, @c false if not
- */
-static bool reass_dgram_complete(reass_dgram_t *rdg)
-{
-	reass_frag_t *frag, *prev;
-	link_t *link;
-
-	assert(fibril_mutex_is_locked(&reass_dgram_map_lock));
-	assert(!list_empty(&rdg->frags));
-
-	/* First fragment must be at offset zero */
-	frag = list_get_instance(list_first(&rdg->frags), reass_frag_t,
-	    dgram_link);
-	if (frag->packet.offs != 0)
-		return false;
-
-	prev = frag;
-	while (true) {
-		link = frag->dgram_link.next;
-		if (link == NULL)
-			return false;
-
-		/* Each next fragment must follow immediately or overlap */
-		frag = list_get_instance(link, reass_frag_t, dgram_link);
-		if (frag->packet.offs > prev->packet.offs + prev->packet.size)
-			return false;
-
-		/* No more fragments - datagram is complete */
-		if (!frag->packet.mf)
-			return true;
-
-		prev = frag;
-	}
-
-	return false;
-}
-
-/** Remove datagram from reassembly map.
- *
- * @param rdg		Datagram reassembly structure
- */
-static void reass_dgram_remove(reass_dgram_t *rdg)
-{
-	assert(fibril_mutex_is_locked(&reass_dgram_map_lock));
-	list_remove(&rdg->map_link);
-}
-
-/** Deliver complete datagram.
- *
- * @param rdg		Datagram reassembly structure.
- */
-static int reass_dgram_deliver(reass_dgram_t *rdg)
-{
-	size_t dgram_size;
-	size_t fragoff_limit;
-	inet_dgram_t dgram;
-	reass_frag_t *frag;
-	uint8_t proto;
-
-	/*
-	 * Potentially there could be something beyond the first packet
-	 * that has !MF. Make sure we ignore that.
-	 */
-	frag = NULL;
-	list_foreach(rdg->frags, link) {
-		frag = list_get_instance(link, reass_frag_t, dgram_link);
-
-		if (!frag->packet.mf)
-			break;
-	}
-
-	assert(frag != NULL);
-	assert(!frag->packet.mf);
-
-	dgram_size = frag->packet.offs + frag->packet.size;
-
-	/* Upper bound for fragment offset field */
-	fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
-
-	/* Verify that total size of datagram is within reasonable bounds */
-	if (dgram_size > FRAG_OFFS_UNIT * fragoff_limit)
-		return ELIMIT;
-
-	dgram.data = calloc(dgram_size, 1);
-	if (dgram.data == NULL)
-		return ENOMEM;
-
-	dgram.size = dgram_size;
-	dgram.src = frag->packet.src;
-	dgram.dest = frag->packet.dest;
-	dgram.tos = frag->packet.tos;
-	proto = frag->packet.proto;
-
-	/* Pull together data from individual fragments */
-
-	size_t doffs = 0;
-
-	frag = NULL;
-	list_foreach(rdg->frags, link) {
-		frag = list_get_instance(link, reass_frag_t, dgram_link);
-
-		size_t cb, ce;
-
-		cb = max(doffs, frag->packet.offs);
-		ce = min(dgram_size, frag->packet.offs + frag->packet.size);
-
-		if (ce > cb) {
-			memcpy(dgram.data + cb,
-			    frag->packet.data + cb - frag->packet.offs,
-			    ce - cb);
-		}
-
-		if (!frag->packet.mf)
-			break;
-	}
-
-	return inet_recv_dgram_local(&dgram, proto);
-}
-
-/** Destroy datagram reassembly structure.
- *
- * @param rdg		Datagram reassembly structure.
- */
-static void reass_dgram_destroy(reass_dgram_t *rdg)
-{
-	while (!list_empty(&rdg->frags)) {
-		link_t *flink = list_first(&rdg->frags);
-		reass_frag_t *frag = list_get_instance(flink, reass_frag_t,
-		    dgram_link);
-
-		list_remove(&frag->dgram_link);
-		free(frag->packet.data);
-		free(frag);
-	}
-
-	free(rdg);
-}
-
-/** @}
- */
Index: pace/srv/net/inet/reass.h
===================================================================
--- uspace/srv/net/inet/reass.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INET_REASS_H_
-#define INET_REASS_H_
-
-#include <sys/types.h>
-#include "inet.h"
-
-extern int inet_reass_queue_packet(inet_packet_t *);
-
-#endif
-
-/** @}
- */
Index: pace/srv/net/inet/sroute.c
===================================================================
--- uspace/srv/net/inet/sroute.c	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,219 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#include <bitops.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <io/log.h>
-#include <ipc/loc.h>
-#include <stdlib.h>
-#include <str.h>
-
-#include "sroute.h"
-#include "inet.h"
-#include "inet_link.h"
-#include "inet_util.h"
-
-static FIBRIL_MUTEX_INITIALIZE(sroute_list_lock);
-static LIST_INITIALIZE(sroute_list);
-static sysarg_t sroute_id = 0;
-
-inet_sroute_t *inet_sroute_new(void)
-{
-	inet_sroute_t *sroute = calloc(1, sizeof(inet_sroute_t));
-
-	if (sroute == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating static route object. "
-		    "Out of memory.");
-		return NULL;
-	}
-
-	link_initialize(&sroute->sroute_list);
-	fibril_mutex_lock(&sroute_list_lock);
-	sroute->id = ++sroute_id;
-	fibril_mutex_unlock(&sroute_list_lock);
-
-	return sroute;
-}
-
-void inet_sroute_delete(inet_sroute_t *sroute)
-{
-	if (sroute->name != NULL)
-		free(sroute->name);
-	free(sroute);
-}
-
-void inet_sroute_add(inet_sroute_t *sroute)
-{
-	fibril_mutex_lock(&sroute_list_lock);
-	list_append(&sroute->sroute_list, &sroute_list);
-	fibril_mutex_unlock(&sroute_list_lock);
-}
-
-void inet_sroute_remove(inet_sroute_t *sroute)
-{
-	fibril_mutex_lock(&sroute_list_lock);
-	list_remove(&sroute->sroute_list);
-	fibril_mutex_unlock(&sroute_list_lock);
-}
-
-/** Find address object matching address @a addr.
- *
- * @param addr	Address
- */
-inet_sroute_t *inet_sroute_find(inet_addr_t *addr)
-{
-	uint32_t mask;
-	inet_sroute_t *best;
-
-	log_msg(LVL_DEBUG, "inet_sroute_find(%x)", (unsigned)addr->ipv4);
-
-	fibril_mutex_lock(&sroute_list_lock);
-
-	best = NULL;
-
-	list_foreach(sroute_list, link) {
-		inet_sroute_t *sroute = list_get_instance(link,
-		    inet_sroute_t, sroute_list);
-
-		/* Look for the most specific route */
-		if (best != NULL && best->dest.bits >= sroute->dest.bits)
-			continue;
-
-		mask = inet_netmask(sroute->dest.bits);
-		if ((sroute->dest.ipv4 & mask) == (addr->ipv4 & mask)) {
-			fibril_mutex_unlock(&sroute_list_lock);
-			log_msg(LVL_DEBUG, "inet_sroute_find: found %p",
-			    sroute);
-			return sroute;
-		}
-	}
-
-	log_msg(LVL_DEBUG, "inet_sroute_find: Not found");
-	fibril_mutex_unlock(&sroute_list_lock);
-
-	return NULL;
-}
-
-/** Find static route with a specific name.
- *
- * @param name	Address object name
- * @return	Address object
- */
-inet_sroute_t *inet_sroute_find_by_name(const char *name)
-{
-	log_msg(LVL_DEBUG, "inet_sroute_find_by_name('%s')",
-	    name);
-
-	fibril_mutex_lock(&sroute_list_lock);
-
-	list_foreach(sroute_list, link) {
-		inet_sroute_t *sroute = list_get_instance(link,
-		    inet_sroute_t, sroute_list);
-
-		if (str_cmp(sroute->name, name) == 0) {
-			fibril_mutex_unlock(&sroute_list_lock);
-			log_msg(LVL_DEBUG, "inet_sroute_find_by_name: found %p",
-			    sroute);
-			return sroute;
-		}
-	}
-
-	log_msg(LVL_DEBUG, "inet_sroute_find_by_name: Not found");
-	fibril_mutex_unlock(&sroute_list_lock);
-
-	return NULL;
-}
-
-/** Find static route with the given ID.
- *
- * @param id	Address object ID
- * @return	Address object
- */
-inet_sroute_t *inet_sroute_get_by_id(sysarg_t id)
-{
-	log_msg(LVL_DEBUG, "inet_sroute_get_by_id(%zu)", (size_t)id);
-
-	fibril_mutex_lock(&sroute_list_lock);
-
-	list_foreach(sroute_list, link) {
-		inet_sroute_t *sroute = list_get_instance(link,
-		    inet_sroute_t, sroute_list);
-
-		if (sroute->id == id) {
-			fibril_mutex_unlock(&sroute_list_lock);
-			return sroute;
-		}
-	}
-
-	fibril_mutex_unlock(&sroute_list_lock);
-
-	return NULL;
-}
-
-/** Get IDs of all static routes. */
-int inet_sroute_get_id_list(sysarg_t **rid_list, size_t *rcount)
-{
-	sysarg_t *id_list;
-	size_t count, i;
-
-	fibril_mutex_lock(&sroute_list_lock);
-	count = list_count(&sroute_list);
-
-	id_list = calloc(count, sizeof(sysarg_t));
-	if (id_list == NULL) {
-		fibril_mutex_unlock(&sroute_list_lock);
-		return ENOMEM;
-	}
-
-	i = 0;
-	list_foreach(sroute_list, link) {
-		inet_sroute_t *sroute = list_get_instance(link,
-		    inet_sroute_t, sroute_list);
-
-		id_list[i++] = sroute->id;
-	}
-
-	fibril_mutex_unlock(&sroute_list_lock);
-
-	*rid_list = id_list;
-	*rcount = count;
-
-	return EOK;
-}
-
-/** @}
- */
Index: pace/srv/net/inet/sroute.h
===================================================================
--- uspace/srv/net/inet/sroute.h	(revision 26b678952a97eb76de8a30772239e4a65ccdb937)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * Copyright (c) 2012 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 inet
- * @{
- */
-/**
- * @file
- * @brief
- */
-
-#ifndef INET_SROUTE_H_
-#define INET_SROUTE_H_
-
-#include <sys/types.h>
-#include "inet.h"
-
-extern inet_sroute_t *inet_sroute_new(void);
-extern void inet_sroute_delete(inet_sroute_t *);
-extern void inet_sroute_add(inet_sroute_t *);
-extern void inet_sroute_remove(inet_sroute_t *);
-extern inet_sroute_t *inet_sroute_find(inet_addr_t *);
-extern inet_sroute_t *inet_sroute_find_by_name(const char *);
-extern inet_sroute_t *inet_sroute_get_by_id(sysarg_t);
-extern int inet_sroute_send_dgram(inet_sroute_t *, inet_addr_t *,
-    inet_dgram_t *, uint8_t, uint8_t, int);
-extern int inet_sroute_get_id_list(sysarg_t **, size_t *);
-
-
-#endif
-
-/** @}
- */
Index: uspace/srv/net/inetsrv/Makefile
===================================================================
--- uspace/srv/net/inetsrv/Makefile	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/Makefile	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2012 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.
+#
+
+USPACE_PREFIX = ../../..
+BINARY = inetsrv
+
+SOURCES = \
+	addrobj.c \
+	icmp.c \
+	inetsrv.c \
+	inet_link.c \
+	inet_util.c \
+	inetcfg.c \
+	inetping.c \
+	pdu.c \
+	reass.c \
+	sroute.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/net/inetsrv/addrobj.c
===================================================================
--- uspace/srv/net/inetsrv/addrobj.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/addrobj.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#include <bitops.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <io/log.h>
+#include <ipc/loc.h>
+#include <stdlib.h>
+#include <str.h>
+
+#include "addrobj.h"
+#include "inetsrv.h"
+#include "inet_link.h"
+#include "inet_util.h"
+
+static FIBRIL_MUTEX_INITIALIZE(addr_list_lock);
+static LIST_INITIALIZE(addr_list);
+static sysarg_t addr_id = 0;
+
+inet_addrobj_t *inet_addrobj_new(void)
+{
+	inet_addrobj_t *addr = calloc(1, sizeof(inet_addrobj_t));
+
+	if (addr == NULL) {
+		log_msg(LVL_ERROR, "Failed allocating address object. "
+		    "Out of memory.");
+		return NULL;
+	}
+
+	link_initialize(&addr->addr_list);
+	fibril_mutex_lock(&addr_list_lock);
+	addr->id = ++addr_id;
+	fibril_mutex_unlock(&addr_list_lock);
+
+	return addr;
+}
+
+void inet_addrobj_delete(inet_addrobj_t *addr)
+{
+	if (addr->name != NULL)
+		free(addr->name);
+	free(addr);
+}
+
+void inet_addrobj_add(inet_addrobj_t *addr)
+{
+	fibril_mutex_lock(&addr_list_lock);
+	list_append(&addr->addr_list, &addr_list);
+	fibril_mutex_unlock(&addr_list_lock);
+}
+
+void inet_addrobj_remove(inet_addrobj_t *addr)
+{
+	fibril_mutex_lock(&addr_list_lock);
+	list_remove(&addr->addr_list);
+	fibril_mutex_unlock(&addr_list_lock);
+}
+
+/** Find address object matching address @a addr.
+ *
+ * @param addr	Address
+ * @oaram find	iaf_net to find network (using mask),
+ *		iaf_addr to find local address (exact match)
+ */
+inet_addrobj_t *inet_addrobj_find(inet_addr_t *addr, inet_addrobj_find_t find)
+{
+	uint32_t mask;
+
+	log_msg(LVL_DEBUG, "inet_addrobj_find(%x)", (unsigned)addr->ipv4);
+
+	fibril_mutex_lock(&addr_list_lock);
+
+	list_foreach(addr_list, link) {
+		inet_addrobj_t *naddr = list_get_instance(link,
+		    inet_addrobj_t, addr_list);
+
+		mask = inet_netmask(naddr->naddr.bits);
+		if ((naddr->naddr.ipv4 & mask) == (addr->ipv4 & mask)) {
+			fibril_mutex_unlock(&addr_list_lock);
+			log_msg(LVL_DEBUG, "inet_addrobj_find: found %p",
+			    naddr);
+			return naddr;
+		}
+	}
+
+	log_msg(LVL_DEBUG, "inet_addrobj_find: Not found");
+	fibril_mutex_unlock(&addr_list_lock);
+
+	return NULL;
+}
+
+/** Find address object on a link, with a specific name.
+ *
+ * @param name	Address object name
+ * @param ilink	Inet link
+ * @return	Address object
+ */
+inet_addrobj_t *inet_addrobj_find_by_name(const char *name, inet_link_t *ilink)
+{
+	log_msg(LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')",
+	    name, ilink->svc_name);
+
+	fibril_mutex_lock(&addr_list_lock);
+
+	list_foreach(addr_list, link) {
+		inet_addrobj_t *naddr = list_get_instance(link,
+		    inet_addrobj_t, addr_list);
+
+		if (naddr->ilink == ilink && str_cmp(naddr->name, name) == 0) {
+			fibril_mutex_unlock(&addr_list_lock);
+			log_msg(LVL_DEBUG, "inet_addrobj_find_by_name: found %p",
+			    naddr);
+			return naddr;
+		}
+	}
+
+	log_msg(LVL_DEBUG, "inet_addrobj_find_by_name: Not found");
+	fibril_mutex_unlock(&addr_list_lock);
+
+	return NULL;
+}
+
+/** Find address object with the given ID.
+ *
+ * @param id	Address object ID
+ * @return	Address object
+ */
+inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t id)
+{
+	log_msg(LVL_DEBUG, "inet_addrobj_get_by_id(%zu)", (size_t)id);
+
+	fibril_mutex_lock(&addr_list_lock);
+
+	list_foreach(addr_list, link) {
+		inet_addrobj_t *naddr = list_get_instance(link,
+		    inet_addrobj_t, addr_list);
+
+		if (naddr->id == id) {
+			fibril_mutex_unlock(&addr_list_lock);
+			return naddr;
+		}
+	}
+
+	fibril_mutex_unlock(&addr_list_lock);
+
+	return NULL;
+}
+
+/** Send datagram from address object */
+int inet_addrobj_send_dgram(inet_addrobj_t *addr, inet_addr_t *ldest,
+    inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
+{
+	inet_addr_t lsrc_addr;
+	inet_addr_t *ldest_addr;
+
+	lsrc_addr.ipv4 = addr->naddr.ipv4;
+	ldest_addr = &dgram->dest;
+
+	return inet_link_send_dgram(addr->ilink, &lsrc_addr, ldest_addr, dgram,
+	    proto, ttl, df);
+}
+
+/** Get IDs of all address objects. */
+int inet_addrobj_get_id_list(sysarg_t **rid_list, size_t *rcount)
+{
+	sysarg_t *id_list;
+	size_t count, i;
+
+	fibril_mutex_lock(&addr_list_lock);
+	count = list_count(&addr_list);
+
+	id_list = calloc(count, sizeof(sysarg_t));
+	if (id_list == NULL) {
+		fibril_mutex_unlock(&addr_list_lock);
+		return ENOMEM;
+	}
+
+	i = 0;
+	list_foreach(addr_list, link) {
+		inet_addrobj_t *addr = list_get_instance(link,
+		    inet_addrobj_t, addr_list);
+
+		id_list[i++] = addr->id;
+	}
+
+	fibril_mutex_unlock(&addr_list_lock);
+
+	*rid_list = id_list;
+	*rcount = count;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/addrobj.h
===================================================================
--- uspace/srv/net/inetsrv/addrobj.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/addrobj.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef INET_ADDROBJ_H_
+#define INET_ADDROBJ_H_
+
+#include <sys/types.h>
+#include "inetsrv.h"
+
+typedef enum {
+	/* Find matching network address (using mask) */
+	iaf_net,
+	/* Find exact local address (not using mask) */
+	iaf_addr
+} inet_addrobj_find_t;
+
+extern inet_addrobj_t *inet_addrobj_new(void);
+extern void inet_addrobj_delete(inet_addrobj_t *);
+extern void inet_addrobj_add(inet_addrobj_t *);
+extern void inet_addrobj_remove(inet_addrobj_t *);
+extern inet_addrobj_t *inet_addrobj_find(inet_addr_t *, inet_addrobj_find_t);
+extern inet_addrobj_t *inet_addrobj_find_by_name(const char *, inet_link_t *);
+extern inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t);
+extern int inet_addrobj_send_dgram(inet_addrobj_t *, inet_addr_t *,
+    inet_dgram_t *, uint8_t, uint8_t, int);
+extern int inet_addrobj_get_id_list(sysarg_t **, size_t *);
+
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/icmp.c
===================================================================
--- uspace/srv/net/inetsrv/icmp.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/icmp.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#include <byteorder.h>
+#include <errno.h>
+#include <io/log.h>
+#include <mem.h>
+#include <stdlib.h>
+
+#include "icmp.h"
+#include "icmp_std.h"
+#include "inetsrv.h"
+#include "inetping.h"
+#include "pdu.h"
+
+/* XXX */
+#define INET_TTL_MAX 255
+
+static int icmp_recv_echo_request(inet_dgram_t *);
+static int icmp_recv_echo_reply(inet_dgram_t *);
+
+int icmp_recv(inet_dgram_t *dgram)
+{
+	uint8_t type;
+
+	log_msg(LVL_DEBUG, "icmp_recv()");
+
+	if (dgram->size < 1)
+		return EINVAL;
+
+	type = *(uint8_t *)dgram->data;
+
+	switch (type) {
+	case ICMP_ECHO_REQUEST:
+		return icmp_recv_echo_request(dgram);
+	case ICMP_ECHO_REPLY:
+		return icmp_recv_echo_reply(dgram);
+	default:
+		break;
+	}
+
+	return EINVAL;
+}
+
+static int icmp_recv_echo_request(inet_dgram_t *dgram)
+{
+	icmp_echo_t *request, *reply;
+	uint16_t checksum;
+	size_t size;
+	inet_dgram_t rdgram;
+	int rc;
+
+	log_msg(LVL_DEBUG, "icmp_recv_echo_request()");
+
+	if (dgram->size < sizeof(icmp_echo_t))
+		return EINVAL;
+
+	request = (icmp_echo_t *)dgram->data;
+	size = dgram->size;
+
+	reply = calloc(size, 1);
+	if (reply == NULL)
+		return ENOMEM;
+
+	memcpy(reply, request, size);
+
+	reply->type = ICMP_ECHO_REPLY;
+	reply->code = 0;
+	reply->checksum = 0;
+
+	checksum = inet_checksum_calc(INET_CHECKSUM_INIT, reply, size);
+	reply->checksum = host2uint16_t_be(checksum);
+
+	rdgram.src = dgram->dest;
+	rdgram.dest = dgram->src;
+	rdgram.tos = ICMP_TOS;
+	rdgram.data = reply;
+	rdgram.size = size;
+
+	rc = inet_route_packet(&rdgram, IP_PROTO_ICMP, INET_TTL_MAX, 0);
+
+	free(reply);
+
+	return rc;
+}
+
+static int icmp_recv_echo_reply(inet_dgram_t *dgram)
+{
+	icmp_echo_t *reply;
+	inetping_sdu_t sdu;
+	uint16_t ident;
+
+	log_msg(LVL_DEBUG, "icmp_recv_echo_reply()");
+
+	if (dgram->size < sizeof(icmp_echo_t))
+		return EINVAL;
+
+	reply = (icmp_echo_t *)dgram->data;
+
+	sdu.src = dgram->src;
+	sdu.dest = dgram->dest;
+	sdu.seq_no = uint16_t_be2host(reply->seq_no);
+	sdu.data = reply + sizeof(icmp_echo_t);
+	sdu.size = dgram->size - sizeof(icmp_echo_t);
+	ident = uint16_t_be2host(reply->ident);
+
+	return inetping_recv(ident, &sdu);
+}
+
+int icmp_ping_send(uint16_t ident, inetping_sdu_t *sdu)
+{
+	inet_dgram_t dgram;
+	icmp_echo_t *request;
+	void *rdata;
+	size_t rsize;
+	uint16_t checksum;
+	int rc;
+
+	rsize = sizeof(icmp_echo_t) + sdu->size;
+	rdata = calloc(rsize, 1);
+	if (rdata == NULL)
+		return ENOMEM;
+
+	request = (icmp_echo_t *)rdata;
+
+	request->type = ICMP_ECHO_REQUEST;
+	request->code = 0;
+	request->checksum = 0;
+	request->ident = host2uint16_t_be(ident);
+	request->seq_no = host2uint16_t_be(sdu->seq_no);
+
+	memcpy(rdata + sizeof(icmp_echo_t), sdu->data, sdu->size);
+
+	checksum = inet_checksum_calc(INET_CHECKSUM_INIT, rdata, rsize);
+	request->checksum = host2uint16_t_be(checksum);
+
+	dgram.src = sdu->src;
+	dgram.dest = sdu->dest;
+	dgram.tos = ICMP_TOS;
+	dgram.data = rdata;
+	dgram.size = rsize;
+
+	rc = inet_route_packet(&dgram, IP_PROTO_ICMP, INET_TTL_MAX, 0);
+
+	free(rdata);
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/icmp.h
===================================================================
--- uspace/srv/net/inetsrv/icmp.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/icmp.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef ICMP_H_
+#define ICMP_H_
+
+#include "inetsrv.h"
+
+extern int icmp_recv(inet_dgram_t *);
+extern int icmp_ping_send(uint16_t, inetping_sdu_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/icmp_std.h
===================================================================
--- uspace/srv/net/inetsrv/icmp_std.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/icmp_std.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file ICMP standard definitions
+ *
+ */
+
+#ifndef ICMP_STD_H_
+#define ICMP_STD_H_
+
+#include <sys/types.h>
+
+#define IP_PROTO_ICMP 1
+
+/** Type of service used for ICMP */
+#define ICMP_TOS	0
+
+/** ICMP message type */
+enum icmp_type {
+	ICMP_ECHO_REPLY   = 0,
+	ICMP_ECHO_REQUEST = 8
+};
+
+/** ICMP Echo Request or Reply message header */
+typedef struct {
+	/** ICMP message type */
+	uint8_t type;
+	/** Code (0) */
+	uint8_t code;
+	/** Internet checksum of the ICMP message */
+	uint16_t checksum;
+	/** Indentifier */
+	uint16_t ident;
+	/** Sequence number */
+	uint16_t seq_no;
+} icmp_echo_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#include <bool.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <inet/iplink.h>
+#include <io/log.h>
+#include <loc.h>
+#include <stdlib.h>
+#include <str.h>
+
+#include "addrobj.h"
+#include "inetsrv.h"
+#include "inet_link.h"
+#include "pdu.h"
+
+static int inet_link_open(service_id_t sid);
+static int inet_iplink_recv(iplink_t *ilink, iplink_sdu_t *sdu);
+
+static iplink_ev_ops_t inet_iplink_ev_ops = {
+	.recv = inet_iplink_recv
+};
+
+static LIST_INITIALIZE(inet_link_list);
+static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
+
+static int inet_iplink_recv(iplink_t *iplink, iplink_sdu_t *sdu)
+{
+	inet_packet_t packet;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inet_iplink_recv()");
+	rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
+	if (rc != EOK) {
+		log_msg(LVL_DEBUG, "failed decoding PDU");
+		return rc;
+	}
+
+	log_msg(LVL_DEBUG, "call inet_recv_packet()");
+	rc = inet_recv_packet(&packet);
+	log_msg(LVL_DEBUG, "call inet_recv_packet -> %d", rc);
+	free(packet.data);
+
+	return rc;
+}
+
+static int inet_link_check_new(void)
+{
+	bool already_known;
+	category_id_t iplink_cat;
+	service_id_t *svcs;
+	size_t count, i;
+	int rc;
+
+	fibril_mutex_lock(&inet_discovery_lock);
+
+	rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed resolving category 'iplink'.");
+		fibril_mutex_unlock(&inet_discovery_lock);
+		return ENOENT;
+	}
+
+	rc = loc_category_get_svcs(iplink_cat, &svcs, &count);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed getting list of IP links.");
+		fibril_mutex_unlock(&inet_discovery_lock);
+		return EIO;
+	}
+
+	for (i = 0; i < count; i++) {
+		already_known = false;
+
+		list_foreach(inet_link_list, ilink_link) {
+			inet_link_t *ilink = list_get_instance(ilink_link,
+			    inet_link_t, link_list);
+			if (ilink->svc_id == svcs[i]) {
+				already_known = true;
+				break;
+			}
+		}
+
+		if (!already_known) {
+			log_msg(LVL_DEBUG, "Found IP link '%lu'",
+			    (unsigned long) svcs[i]);
+			rc = inet_link_open(svcs[i]);
+			if (rc != EOK)
+				log_msg(LVL_ERROR, "Could not open IP link.");
+		}
+	}
+
+	fibril_mutex_unlock(&inet_discovery_lock);
+	return EOK;
+}
+
+static inet_link_t *inet_link_new(void)
+{
+	inet_link_t *ilink = calloc(1, sizeof(inet_link_t));
+
+	if (ilink == NULL) {
+		log_msg(LVL_ERROR, "Failed allocating link structure. "
+		    "Out of memory.");
+		return NULL;
+	}
+
+	link_initialize(&ilink->link_list);
+
+	return ilink;
+}
+
+static void inet_link_delete(inet_link_t *ilink)
+{
+	if (ilink->svc_name != NULL)
+		free(ilink->svc_name);
+	free(ilink);
+}
+
+static int inet_link_open(service_id_t sid)
+{
+	inet_link_t *ilink;
+	iplink_addr_t iaddr;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inet_link_open()");
+	ilink = inet_link_new();
+	if (ilink == NULL)
+		return ENOMEM;
+
+	ilink->svc_id = sid;
+	ilink->iplink = NULL;
+
+	rc = loc_service_get_name(sid, &ilink->svc_name);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed getting service name.");
+		goto error;
+	}
+
+	ilink->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid, 0);
+	if (ilink->sess == NULL) {
+		log_msg(LVL_ERROR, "Failed connecting '%s'", ilink->svc_name);
+		goto error;
+	}
+
+	rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, &ilink->iplink);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed opening IP link '%s'",
+		    ilink->svc_name);
+		goto error;
+	}
+
+	rc = iplink_get_mtu(ilink->iplink, &ilink->def_mtu);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed determinning MTU of link '%s'",
+		    ilink->svc_name);
+		goto error;
+	}
+
+	log_msg(LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
+	list_append(&ilink->link_list, &inet_link_list);
+
+	inet_addrobj_t *addr;
+
+	static int first = 1;
+	/* XXX For testing: set static IP address 192.168.0.4/24 */
+	addr = inet_addrobj_new();
+	if (first) {
+		addr->naddr.ipv4 = (127 << 24) + (0 << 16) + (0 << 8) + 1;
+		first = 0;
+	} else {
+		addr->naddr.ipv4 = (192 << 24) + (168 << 16) + (0 << 8) + 4;
+	}
+	addr->naddr.bits = 24;
+	addr->ilink = ilink;
+	addr->name = str_dup("v4a");
+	inet_addrobj_add(addr);
+
+	iaddr.ipv4 = addr->naddr.ipv4;
+	rc = iplink_addr_add(ilink->iplink, &iaddr);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed setting IP address on internet link.");
+		/* XXX Roll back */
+		return rc;
+	}
+
+	return EOK;
+
+error:
+	if (ilink->iplink != NULL)
+		iplink_close(ilink->iplink);
+	inet_link_delete(ilink);
+	return rc;
+}
+
+static void inet_link_cat_change_cb(void)
+{
+	(void) inet_link_check_new();
+}
+
+int inet_link_discovery_start(void)
+{
+	int rc;
+
+	rc = loc_register_cat_change_cb(inet_link_cat_change_cb);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed registering callback for IP link "
+		    "discovery (%d).", rc);
+		return rc;
+	}
+
+	return inet_link_check_new();
+}
+
+/** Send datagram over Internet link */
+int inet_link_send_dgram(inet_link_t *ilink, inet_addr_t *lsrc,
+    inet_addr_t *ldest, inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
+{
+	iplink_sdu_t sdu;
+	inet_packet_t packet;
+	int rc;
+	size_t offs, roffs;
+
+	/*
+	 * Fill packet structure. Fragmentation is performed by
+	 * inet_pdu_encode().
+	 */
+	packet.src = dgram->src;
+	packet.dest = dgram->dest;
+	packet.tos = dgram->tos;
+	packet.proto = proto;
+	packet.ttl = ttl;
+	packet.df = df;
+	packet.data = dgram->data;
+	packet.size = dgram->size;
+
+	sdu.lsrc.ipv4 = lsrc->ipv4;
+	sdu.ldest.ipv4 = ldest->ipv4;
+
+	offs = 0;
+	do {
+		/* Encode one fragment */
+		rc = inet_pdu_encode(&packet, offs, ilink->def_mtu, &sdu.data,
+		    &sdu.size, &roffs);
+		if (rc != EOK)
+			return rc;
+
+		/* Send the PDU */
+		rc = iplink_send(ilink->iplink, &sdu);
+		free(sdu.data);
+
+		offs = roffs;
+	} while (offs < packet.size);
+
+	return rc;
+}
+
+inet_link_t *inet_link_get_by_id(sysarg_t link_id)
+{
+	fibril_mutex_lock(&inet_discovery_lock);
+
+	list_foreach(inet_link_list, elem) {
+		inet_link_t *ilink = list_get_instance(elem, inet_link_t,
+		    link_list);
+
+		if (ilink->svc_id == link_id) {
+			fibril_mutex_unlock(&inet_discovery_lock);
+			return ilink;
+		}
+	}
+
+	fibril_mutex_unlock(&inet_discovery_lock);
+	return NULL;
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inet_link.h
===================================================================
--- uspace/srv/net/inetsrv/inet_link.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inet_link.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef INET_LINK_H_
+#define INET_LINK_H_
+
+#include <sys/types.h>
+#include "inetsrv.h"
+
+extern int inet_link_discovery_start(void);
+extern int inet_link_send_dgram(inet_link_t *, inet_addr_t *,
+    inet_addr_t *, inet_dgram_t *, uint8_t, uint8_t, int);
+extern inet_link_t *inet_link_get_by_id(sysarg_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inet_std.h
===================================================================
--- uspace/srv/net/inetsrv/inet_std.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inet_std.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file IP header definitions
+ *
+ */
+
+#ifndef INET_STD_H_
+#define INET_STD_H_
+
+#include <sys/types.h>
+
+/** Internet Datagram header (fixed part) */
+typedef struct {
+	/** Version, Internet Header Length */
+	uint8_t ver_ihl;
+	/* Type of Service */
+	uint8_t tos;
+	/** Total Length */
+	uint16_t tot_len;
+	/** Identification */
+	uint16_t id;
+	/** Flags, Fragment Offset */
+	uint16_t flags_foff;
+	/** Time to Live */
+	uint8_t ttl;
+	/** Protocol */
+	uint8_t proto;
+	/** Header Checksum */
+	uint16_t chksum;
+	/** Source Address */
+	uint32_t src_addr;
+	/** Destination Address */
+	uint32_t dest_addr;
+} ip_header_t;
+
+/** Bits in ip_header_t.ver_ihl */
+enum ver_ihl_bits {
+	/** Version, highest bit */
+	VI_VERSION_h = 7,
+	/** Version, lowest bit */
+	VI_VERSION_l = 4,
+	/** Internet Header Length, highest bit */
+	VI_IHL_h     = 3,
+	/** Internet Header Length, lowest bit */
+	VI_IHL_l     = 0
+};
+
+/** Bits in ip_header_t.flags_foff */
+enum flags_foff_bits {
+	/** Reserved, must be zero */
+	FF_FLAG_RSVD = 15,
+	/** Don't Fragment */
+	FF_FLAG_DF = 14,
+	/** More Fragments */
+	FF_FLAG_MF = 13,
+	/** Fragment Offset, highest bit */
+	FF_FRAGOFF_h = 12,
+	/** Fragment Offset, lowest bit */
+	FF_FRAGOFF_l = 0
+};
+
+/** Fragment offset is expressed in units of 8 bytes */
+#define FRAG_OFFS_UNIT 8
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inet_util.c
===================================================================
--- uspace/srv/net/inetsrv/inet_util.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inet_util.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#include <assert.h>
+#include <bitops.h>
+#include <sys/types.h>
+#include "inet_util.h"
+
+uint32_t inet_netmask(int bits)
+{
+	assert(bits >= 0);
+	assert(bits < 32);
+
+	if (bits == 0)
+		return 0;
+	else
+		return BIT_RANGE(uint32_t, 31, 31 - (bits - 1));
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inet_util.h
===================================================================
--- uspace/srv/net/inetsrv/inet_util.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inet_util.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef INET_UTIL_H_
+#define INET_UTIL_H_
+
+#include <sys/types.h>
+
+uint32_t inet_netmask(int bits);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inetcfg.c
===================================================================
--- uspace/srv/net/inetsrv/inetcfg.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inetcfg.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,631 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#include <async.h>
+#include <errno.h>
+#include <macros.h>
+#include <io/log.h>
+#include <ipc/inet.h>
+#include <loc.h>
+#include <stdlib.h>
+#include <str.h>
+#include <sys/types.h>
+
+#include "addrobj.h"
+#include "inetsrv.h"
+#include "inet_link.h"
+#include "inetcfg.h"
+#include "sroute.h"
+
+static int inetcfg_addr_create_static(char *name, inet_naddr_t *naddr,
+    sysarg_t link_id, sysarg_t *addr_id)
+{
+	inet_link_t *ilink;
+	inet_addrobj_t *addr;
+	iplink_addr_t iaddr;
+	int rc;
+
+	ilink = inet_link_get_by_id(link_id);
+	if (ilink == NULL) {
+		log_msg(LVL_DEBUG, "Link %lu not found.",
+		    (unsigned long) link_id);
+		return ENOENT;
+	}
+
+	addr = inet_addrobj_new();
+	if (addr == NULL) {
+		*addr_id = 0;
+		return ENOMEM;
+	}
+
+	addr->naddr = *naddr;
+	addr->ilink = ilink;
+	addr->name = str_dup(name);
+	inet_addrobj_add(addr);
+
+	iaddr.ipv4 = addr->naddr.ipv4;
+	rc = iplink_addr_add(ilink->iplink, &iaddr);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed setting IP address on internet link.");
+		inet_addrobj_remove(addr);
+		inet_addrobj_delete(addr);
+		return rc;
+	}
+
+	return EOK;
+}
+
+static int inetcfg_addr_delete(sysarg_t addr_id)
+{
+	inet_addrobj_t *addr;
+
+	addr = inet_addrobj_get_by_id(addr_id);
+	if (addr == NULL)
+		return ENOENT;
+
+	inet_addrobj_remove(addr);
+	inet_addrobj_delete(addr);
+
+	return EOK;
+}
+
+static int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
+{
+	inet_addrobj_t *addr;
+
+	addr = inet_addrobj_get_by_id(addr_id);
+	if (addr == NULL)
+		return ENOENT;
+
+	ainfo->naddr = addr->naddr;
+	ainfo->ilink = addr->ilink->svc_id;
+	ainfo->name = str_dup(addr->name);
+
+	return EOK;
+}
+
+static int inetcfg_addr_get_id(char *name, sysarg_t link_id, sysarg_t *addr_id)
+{
+	inet_link_t *ilink;
+	inet_addrobj_t *addr;
+
+	ilink = inet_link_get_by_id(link_id);
+	if (ilink == NULL) {
+		log_msg(LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
+		return ENOENT;
+	}
+
+	addr = inet_addrobj_find_by_name(name, ilink);
+	if (addr == NULL) {
+		log_msg(LVL_DEBUG, "Address '%s' not found.", name);
+		return ENOENT;
+	}
+
+	*addr_id = addr->id;
+	return EOK;
+}
+
+static int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
+{
+	return inet_addrobj_get_id_list(addrs, count);
+}
+
+static int inetcfg_get_link_list(sysarg_t **addrs, size_t *count)
+{
+	return ENOTSUP;
+}
+
+static int inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
+{
+	return inet_sroute_get_id_list(sroutes, count);
+}
+
+static int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
+{
+	inet_link_t *ilink;
+
+	ilink = inet_link_get_by_id(link_id);
+	if (ilink == NULL) {
+		return ENOENT;
+	}
+
+	linfo->name = str_dup(ilink->svc_name);
+	linfo->def_mtu = ilink->def_mtu;
+	return EOK;
+}
+
+static int inetcfg_sroute_create(char *name, inet_naddr_t *dest,
+    inet_addr_t *router, sysarg_t *sroute_id)
+{
+	inet_sroute_t *sroute;
+
+	sroute = inet_sroute_new();
+	if (sroute == NULL) {
+		*sroute_id = 0;
+		return ENOMEM;
+	}
+
+	sroute->dest = *dest;
+	sroute->router = *router;
+	sroute->name = str_dup(name);
+	inet_sroute_add(sroute);
+
+	*sroute_id = sroute->id;
+	return EOK;
+}
+
+static int inetcfg_sroute_delete(sysarg_t sroute_id)
+{
+	inet_sroute_t *sroute;
+
+	sroute = inet_sroute_get_by_id(sroute_id);
+	if (sroute == NULL)
+		return ENOENT;
+
+	inet_sroute_remove(sroute);
+	inet_sroute_delete(sroute);
+
+	return EOK;
+}
+
+static int inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
+{
+	inet_sroute_t *sroute;
+
+	sroute = inet_sroute_get_by_id(sroute_id);
+	if (sroute == NULL)
+		return ENOENT;
+
+	srinfo->dest = sroute->dest;
+	srinfo->router = sroute->router;
+	srinfo->name = str_dup(sroute->name);
+
+	return EOK;
+}
+
+static int inetcfg_sroute_get_id(char *name, sysarg_t *sroute_id)
+{
+	inet_sroute_t *sroute;
+
+	sroute = inet_sroute_find_by_name(name);
+	if (sroute == NULL) {
+		log_msg(LVL_DEBUG, "Static route '%s' not found.", name);
+		return ENOENT;
+	}
+
+	*sroute_id = sroute->id;
+	return EOK;
+}
+
+static void inetcfg_addr_create_static_srv(ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	char *name;
+	inet_naddr_t naddr;
+	sysarg_t link_id;
+	sysarg_t addr_id;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetcfg_addr_create_static_srv()");
+
+	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
+	    0, NULL);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	naddr.ipv4 = IPC_GET_ARG1(*call);
+	naddr.bits = IPC_GET_ARG2(*call);
+	link_id    = IPC_GET_ARG3(*call);
+
+	addr_id = 0;
+	rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id);
+	free(name);
+	async_answer_1(callid, rc, addr_id);
+}
+
+static void inetcfg_addr_delete_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	sysarg_t addr_id;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetcfg_addr_delete_srv()");
+
+	addr_id = IPC_GET_ARG1(*call);
+
+	rc = inetcfg_addr_delete(addr_id);
+	async_answer_0(callid, rc);
+}
+
+static void inetcfg_addr_get_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	ipc_callid_t rcallid;
+	size_t max_size;
+
+	sysarg_t addr_id;
+	inet_addr_info_t ainfo;
+	int rc;
+
+	addr_id = IPC_GET_ARG1(*call);
+	log_msg(LVL_DEBUG, "inetcfg_addr_get_srv()");
+
+	ainfo.naddr.ipv4 = 0;
+	ainfo.naddr.bits = 0;
+	ainfo.ilink = 0;
+	ainfo.name = NULL;
+
+	if (!async_data_read_receive(&rcallid, &max_size)) {
+		async_answer_0(rcallid, EREFUSED);
+		async_answer_0(callid, EREFUSED);
+		return;
+	}
+
+	rc = inetcfg_addr_get(addr_id, &ainfo);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	sysarg_t retval = async_data_read_finalize(rcallid, ainfo.name,
+	    min(max_size, str_size(ainfo.name)));
+	free(ainfo.name);
+
+	async_answer_3(callid, retval, ainfo.naddr.ipv4, ainfo.naddr.bits,
+	    ainfo.ilink);
+}
+
+static void inetcfg_addr_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	char *name;
+	sysarg_t link_id;
+	sysarg_t addr_id;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetcfg_addr_get_id_srv()");
+
+	link_id = IPC_GET_ARG1(*call);
+
+	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
+	    0, NULL);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	addr_id = 0;
+	rc = inetcfg_addr_get_id(name, link_id, &addr_id);
+	free(name);
+	async_answer_1(callid, rc, addr_id);
+}
+
+static void inetcfg_get_addr_list_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	ipc_callid_t rcallid;
+	size_t count;
+	size_t max_size;
+	size_t act_size;
+	size_t size;
+	sysarg_t *id_buf;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetcfg_get_addr_list_srv()");
+
+	if (!async_data_read_receive(&rcallid, &max_size)) {
+		async_answer_0(rcallid, EREFUSED);
+		async_answer_0(callid, EREFUSED);
+		return;
+	}
+
+	rc = inetcfg_get_addr_list(&id_buf, &count);
+	if (rc != EOK) {
+		async_answer_0(rcallid, rc);
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	act_size = count * sizeof(sysarg_t);
+	size = min(act_size, max_size);
+
+	sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
+	free(id_buf);
+
+	async_answer_1(callid, retval, act_size);
+}
+
+
+static void inetcfg_get_link_list_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	ipc_callid_t rcallid;
+	size_t max_size;
+	size_t act_size;
+	size_t size;
+	sysarg_t *id_buf;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetcfg_get_link_list_srv()");
+
+	if (!async_data_read_receive(&rcallid, &max_size)) {
+		async_answer_0(rcallid, EREFUSED);
+		async_answer_0(callid, EREFUSED);
+		return;
+	}
+
+	rc = inetcfg_get_link_list(&id_buf, &act_size);
+	if (rc != EOK) {
+		async_answer_0(rcallid, rc);
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	size = min(act_size, max_size);
+
+	sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
+	free(id_buf);
+
+	async_answer_1(callid, retval, act_size);
+}
+
+static void inetcfg_get_sroute_list_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	ipc_callid_t rcallid;
+	size_t count;
+	size_t max_size;
+	size_t act_size;
+	size_t size;
+	sysarg_t *id_buf;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
+
+	if (!async_data_read_receive(&rcallid, &max_size)) {
+		async_answer_0(rcallid, EREFUSED);
+		async_answer_0(callid, EREFUSED);
+		return;
+	}
+
+	rc = inetcfg_get_sroute_list(&id_buf, &count);
+	if (rc != EOK) {
+		async_answer_0(rcallid, rc);
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	act_size = count * sizeof(sysarg_t);
+	size = min(act_size, max_size);
+
+	sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
+	free(id_buf);
+
+	async_answer_1(callid, retval, act_size);
+}
+
+static void inetcfg_link_get_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	ipc_callid_t rcallid;
+	size_t max_size;
+
+	sysarg_t link_id;
+	inet_link_info_t linfo;
+	int rc;
+
+	link_id = IPC_GET_ARG1(*call);
+	log_msg(LVL_DEBUG, "inetcfg_link_get_srv()");
+
+	linfo.name = NULL;
+
+	if (!async_data_read_receive(&rcallid, &max_size)) {
+		async_answer_0(rcallid, EREFUSED);
+		async_answer_0(callid, EREFUSED);
+		return;
+	}
+
+	rc = inetcfg_link_get(link_id, &linfo);
+	if (rc != EOK) {
+		async_answer_0(rcallid, rc);
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	sysarg_t retval = async_data_read_finalize(rcallid, linfo.name,
+	    min(max_size, str_size(linfo.name)));
+	free(linfo.name);
+
+	async_answer_1(callid, retval, linfo.def_mtu);
+}
+
+static void inetcfg_sroute_create_srv(ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	char *name;
+	inet_naddr_t dest;
+	inet_addr_t router;
+	sysarg_t sroute_id;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetcfg_sroute_create_srv()");
+
+	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
+	    0, NULL);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	dest.ipv4   = IPC_GET_ARG1(*call);
+	dest.bits   = IPC_GET_ARG2(*call);
+	router.ipv4 = IPC_GET_ARG3(*call);
+
+	sroute_id = 0;
+	rc = inetcfg_sroute_create(name, &dest, &router, &sroute_id);
+	free(name);
+	async_answer_1(callid, rc, sroute_id);
+}
+
+static void inetcfg_sroute_delete_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	sysarg_t sroute_id;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetcfg_sroute_delete_srv()");
+
+	sroute_id = IPC_GET_ARG1(*call);
+
+	rc = inetcfg_sroute_delete(sroute_id);
+	async_answer_0(callid, rc);
+}
+
+static void inetcfg_sroute_get_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	ipc_callid_t rcallid;
+	size_t max_size;
+
+	sysarg_t sroute_id;
+	inet_sroute_info_t srinfo;
+	int rc;
+
+	sroute_id = IPC_GET_ARG1(*call);
+	log_msg(LVL_DEBUG, "inetcfg_sroute_get_srv()");
+
+	srinfo.dest.ipv4 = 0;
+	srinfo.dest.bits = 0;
+	srinfo.router.ipv4 = 0;
+	srinfo.name = NULL;
+
+	if (!async_data_read_receive(&rcallid, &max_size)) {
+		async_answer_0(rcallid, EREFUSED);
+		async_answer_0(callid, EREFUSED);
+		return;
+	}
+
+	rc = inetcfg_sroute_get(sroute_id, &srinfo);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	sysarg_t retval = async_data_read_finalize(rcallid, srinfo.name,
+	    min(max_size, str_size(srinfo.name)));
+	free(srinfo.name);
+
+	async_answer_3(callid, retval, srinfo.dest.ipv4, srinfo.dest.bits,
+	    srinfo.router.ipv4);
+}
+
+static void inetcfg_sroute_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	char *name;
+	sysarg_t sroute_id;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
+
+	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
+	    0, NULL);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	sroute_id = 0;
+	rc = inetcfg_sroute_get_id(name, &sroute_id);
+	free(name);
+	async_answer_1(callid, rc, sroute_id);
+}
+
+void inet_cfg_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	log_msg(LVL_DEBUG, "inet_cfg_conn()");
+
+	/* Accept the connection */
+	async_answer_0(iid, EOK);
+
+	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);
+			return;
+		}
+
+		switch (method) {
+		case INETCFG_ADDR_CREATE_STATIC:
+			inetcfg_addr_create_static_srv(callid, &call);
+			break;
+		case INETCFG_ADDR_DELETE:
+			inetcfg_addr_delete_srv(callid, &call);
+			break;
+		case INETCFG_ADDR_GET:
+			inetcfg_addr_get_srv(callid, &call);
+			break;
+		case INETCFG_ADDR_GET_ID:
+			inetcfg_addr_get_id_srv(callid, &call);
+			break;
+		case INETCFG_GET_ADDR_LIST:
+			inetcfg_get_addr_list_srv(callid, &call);
+			break;
+		case INETCFG_GET_LINK_LIST:
+			inetcfg_get_link_list_srv(callid, &call);
+			break;
+		case INETCFG_GET_SROUTE_LIST:
+			inetcfg_get_sroute_list_srv(callid, &call);
+			break;
+		case INETCFG_LINK_GET:
+			inetcfg_link_get_srv(callid, &call);
+			break;
+		case INETCFG_SROUTE_CREATE:
+			inetcfg_sroute_create_srv(callid, &call);
+			break;
+		case INETCFG_SROUTE_DELETE:
+			inetcfg_sroute_delete_srv(callid, &call);
+			break;
+		case INETCFG_SROUTE_GET:
+			inetcfg_sroute_get_srv(callid, &call);
+			break;
+		case INETCFG_SROUTE_GET_ID:
+			inetcfg_sroute_get_id_srv(callid, &call);
+			break;
+		default:
+			async_answer_0(callid, EINVAL);
+		}
+	}
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inetcfg.h
===================================================================
--- uspace/srv/net/inetsrv/inetcfg.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inetcfg.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef INETCFG_H_
+#define INETCFG_H_
+
+extern void inet_cfg_conn(ipc_callid_t, ipc_call_t *, void *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inetping.c
===================================================================
--- uspace/srv/net/inetsrv/inetping.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inetping.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2012 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 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 "icmp.h"
+#include "icmp_std.h"
+#include "inetsrv.h"
+#include "inetping.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 inetping_ident = 0;
+
+static inetping_client_t *inetping_client_find(uint16_t);
+
+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, inet_addr_t *remote,
+    inet_addr_t *local)
+{
+	return inet_get_srcaddr(remote, ICMP_TOS, local);
+}
+
+int inetping_recv(uint16_t ident, inetping_sdu_t *sdu)
+{
+	inetping_client_t *client;
+	async_exch_t *exch;
+	ipc_call_t answer;
+
+	client = inetping_client_find(ident);
+	if (client == NULL) {
+		log_msg(LVL_DEBUG, "Unknown ICMP ident. Dropping.");
+		return ENOENT;
+	}
+
+	exch = async_exchange_begin(client->sess);
+
+	aid_t req = async_send_3(exch, INETPING_EV_RECV, sdu->src.ipv4,
+	    sdu->dest.ipv4, sdu->seq_no, &answer);
+	int 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);
+	if (retval != EOK) {
+		return retval;
+	}
+
+	return EOK;
+}
+
+static void inetping_send_srv(inetping_client_t *client, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	inetping_sdu_t sdu;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetping_send_srv()");
+
+	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.ipv4 = IPC_GET_ARG1(*call);
+	sdu.dest.ipv4 = IPC_GET_ARG2(*call);
+	sdu.seq_no = IPC_GET_ARG3(*call);
+
+	rc = inetping_send(client, &sdu);
+	free(sdu.data);
+
+	async_answer_0(callid, rc);
+}
+
+static void inetping_get_srcaddr_srv(inetping_client_t *client,
+    ipc_callid_t callid, ipc_call_t *call)
+{
+	inet_addr_t remote;
+	inet_addr_t local;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetping_get_srcaddr_srv()");
+
+	remote.ipv4 = IPC_GET_ARG1(*call);
+	local.ipv4 = 0;
+
+	rc = inetping_get_srcaddr(client, &remote, &local);
+	async_answer_1(callid, rc, local.ipv4);
+}
+
+static int inetping_client_init(inetping_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 = ++inetping_ident;
+	list_append(&client->client_list, &client_list);
+	fibril_mutex_unlock(&client_list_lock);
+
+	return EOK;
+}
+
+static void inetping_client_fini(inetping_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);
+}
+
+static inetping_client_t *inetping_client_find(uint16_t ident)
+{
+	fibril_mutex_lock(&client_list_lock);
+
+	list_foreach(client_list, link) {
+		inetping_client_t *client = list_get_instance(link,
+		    inetping_client_t, client_list);
+
+		if (client->ident == ident) {
+			fibril_mutex_unlock(&client_list_lock);
+			return client;
+		}
+	}
+
+	fibril_mutex_unlock(&client_list_lock);
+	return NULL;
+}
+
+void inetping_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	inetping_client_t client;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inetping_conn()");
+
+	/* Accept the connection */
+	async_answer_0(iid, EOK);
+
+	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 */
+			async_answer_0(callid, EOK);
+			break;
+		}
+
+		switch (method) {
+		case INETPING_SEND:
+			inetping_send_srv(&client, callid, &call);
+			break;
+		case INETPING_GET_SRCADDR:
+			inetping_get_srcaddr_srv(&client, callid, &call);
+			break;
+		default:
+			async_answer_0(callid, EINVAL);
+		}
+	}
+
+	inetping_client_fini(&client);
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inetping.h
===================================================================
--- uspace/srv/net/inetsrv/inetping.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inetping.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef INETPING_H_
+#define INETPING_H_
+
+extern void inetping_conn(ipc_callid_t, ipc_call_t *, void *);
+extern int inetping_recv(uint16_t, inetping_sdu_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief Internet Protocol service
+ */
+
+#include <adt/list.h>
+#include <async.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <io/log.h>
+#include <ipc/inet.h>
+#include <ipc/services.h>
+#include <loc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include "addrobj.h"
+#include "icmp.h"
+#include "icmp_std.h"
+#include "inetsrv.h"
+#include "inetcfg.h"
+#include "inetping.h"
+#include "inet_link.h"
+#include "reass.h"
+#include "sroute.h"
+
+#define NAME "inetsrv"
+
+static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
+
+static FIBRIL_MUTEX_INITIALIZE(client_list_lock);
+static LIST_INITIALIZE(client_list);
+
+static int inet_init(void)
+{
+	service_id_t sid;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inet_init()");
+
+	async_set_client_connection(inet_client_conn);
+
+	rc = loc_server_register(NAME);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed registering server (%d).", rc);
+		return EEXIST;
+	}
+
+	rc = loc_service_register_with_iface(SERVICE_NAME_INET, &sid,
+	    INET_PORT_DEFAULT);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed registering service (%d).", rc);
+		return EEXIST;
+	}
+
+	rc = loc_service_register_with_iface(SERVICE_NAME_INETCFG, &sid,
+	    INET_PORT_CFG);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed registering service (%d).", rc);
+		return EEXIST;
+	}
+
+	rc = loc_service_register_with_iface(SERVICE_NAME_INETPING, &sid,
+	    INET_PORT_PING);
+	if (rc != EOK) {
+		log_msg(LVL_ERROR, "Failed registering service (%d).", rc);
+		return EEXIST;
+	}
+
+	rc = inet_link_discovery_start();
+	if (rc != EOK)
+		return EEXIST;
+
+	return EOK;
+}
+
+static void inet_callback_create_srv(inet_client_t *client, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	log_msg(LVL_DEBUG, "inet_callback_create_srv()");
+
+	async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
+	if (sess == NULL) {
+		async_answer_0(callid, ENOMEM);
+		return;
+	}
+
+	client->sess = sess;
+	async_answer_0(callid, EOK);
+}
+
+static int inet_find_dir(inet_addr_t *src, inet_addr_t *dest, uint8_t tos,
+    inet_dir_t *dir)
+{
+	inet_sroute_t *sr;
+
+	/* XXX Handle case where source address is specified */
+	(void) src;
+
+	dir->aobj = inet_addrobj_find(dest, iaf_net);
+	if (dir->aobj != NULL) {
+		dir->ldest = *dest;
+		dir->dtype = dt_direct;
+	} else {
+		/* No direct path, try using a static route */
+		sr = inet_sroute_find(dest);
+		if (sr != NULL) {
+			dir->aobj = inet_addrobj_find(&sr->router, iaf_net);
+			dir->ldest = sr->router;
+			dir->dtype = dt_router;
+		}
+	}
+
+	if (dir->aobj == NULL) {
+		log_msg(LVL_DEBUG, "inet_send: No route to destination.");
+		return ENOENT;
+	}
+
+	return EOK;
+}
+
+int inet_route_packet(inet_dgram_t *dgram, uint8_t proto, uint8_t ttl,
+    int df)
+{
+	inet_dir_t dir;
+	int rc;
+
+	rc = inet_find_dir(&dgram->src, &dgram->dest, dgram->tos, &dir);
+	if (rc != EOK)
+		return rc;
+
+	return inet_addrobj_send_dgram(dir.aobj, &dir.ldest, dgram,
+	    proto, ttl, df);
+}
+
+static int inet_send(inet_client_t *client, inet_dgram_t *dgram,
+    uint8_t proto, uint8_t ttl, int df)
+{
+	return inet_route_packet(dgram, proto, ttl, df);
+}
+
+int inet_get_srcaddr(inet_addr_t *remote, uint8_t tos, inet_addr_t *local)
+{
+	inet_dir_t dir;
+	int rc;
+
+	rc = inet_find_dir(NULL, remote, tos, &dir);
+	if (rc != EOK)
+		return rc;
+
+	/* XXX dt_local? */
+
+	/* Take source address from the address object */
+	local->ipv4 = dir.aobj->naddr.ipv4;
+	return EOK;
+}
+
+static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	inet_addr_t remote;
+	uint8_t tos;
+	inet_addr_t local;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inet_get_srcaddr_srv()");
+
+	remote.ipv4 = IPC_GET_ARG1(*call);
+	tos = IPC_GET_ARG2(*call);
+	local.ipv4 = 0;
+
+	rc = inet_get_srcaddr(&remote, tos, &local);
+	async_answer_1(callid, rc, local.ipv4);
+}
+
+static void inet_send_srv(inet_client_t *client, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	inet_dgram_t dgram;
+	uint8_t ttl;
+	int df;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inet_send_srv()");
+
+	dgram.src.ipv4 = IPC_GET_ARG1(*call);
+	dgram.dest.ipv4 = IPC_GET_ARG2(*call);
+	dgram.tos = IPC_GET_ARG3(*call);
+	ttl = IPC_GET_ARG4(*call);
+	df = IPC_GET_ARG5(*call);
+
+	rc = async_data_write_accept(&dgram.data, false, 0, 0, 0, &dgram.size);
+	if (rc != EOK) {
+		async_answer_0(callid, rc);
+		return;
+	}
+
+	rc = inet_send(client, &dgram, client->protocol, ttl, df);
+
+	free(dgram.data);
+	async_answer_0(callid, rc);
+}
+
+static void inet_set_proto_srv(inet_client_t *client, ipc_callid_t callid,
+    ipc_call_t *call)
+{
+	sysarg_t proto;
+
+	proto = IPC_GET_ARG1(*call);
+	log_msg(LVL_DEBUG, "inet_set_proto_srv(%lu)", (unsigned long) proto);
+
+	if (proto > UINT8_MAX) {
+		async_answer_0(callid, EINVAL);
+		return;
+	}
+
+	client->protocol = proto;
+	async_answer_0(callid, EOK);
+}
+
+static void inet_client_init(inet_client_t *client)
+{
+	client->sess = NULL;
+
+	fibril_mutex_lock(&client_list_lock);
+	list_append(&client->client_list, &client_list);
+	fibril_mutex_unlock(&client_list_lock);
+}
+
+static void inet_client_fini(inet_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);
+}
+
+static void inet_default_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	inet_client_t client;
+
+	log_msg(LVL_DEBUG, "inet_default_conn()");
+
+	/* Accept the connection */
+	async_answer_0(iid, EOK);
+
+	inet_client_init(&client);
+
+	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);
+			return;
+		}
+
+		switch (method) {
+		case INET_CALLBACK_CREATE:
+			inet_callback_create_srv(&client, callid, &call);
+			break;
+		case INET_GET_SRCADDR:
+			inet_get_srcaddr_srv(&client, callid, &call);
+			break;
+		case INET_SEND:
+			inet_send_srv(&client, callid, &call);
+			break;
+		case INET_SET_PROTO:
+			inet_set_proto_srv(&client, callid, &call);
+			break;
+		default:
+			async_answer_0(callid, EINVAL);
+		}
+	}
+
+	inet_client_fini(&client);
+}
+
+static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	sysarg_t port;
+
+	port = IPC_GET_ARG1(*icall);
+
+	switch (port) {
+	case INET_PORT_DEFAULT:
+		inet_default_conn(iid, icall, arg);
+		break;
+	case INET_PORT_CFG:
+		inet_cfg_conn(iid, icall, arg);
+		break;
+	case INET_PORT_PING:
+		inetping_conn(iid, icall, arg);
+		break;
+	default:
+		async_answer_0(iid, ENOTSUP);
+		break;
+	}
+}
+
+static inet_client_t *inet_client_find(uint8_t proto)
+{
+	fibril_mutex_lock(&client_list_lock);
+
+	list_foreach(client_list, link) {
+		inet_client_t *client = list_get_instance(link, inet_client_t,
+		    client_list);
+
+		if (client->protocol == proto) {
+			fibril_mutex_unlock(&client_list_lock);
+			return client;
+		}
+	}
+
+	fibril_mutex_unlock(&client_list_lock);
+	return NULL;
+}
+
+int inet_ev_recv(inet_client_t *client, inet_dgram_t *dgram)
+{
+	async_exch_t *exch = async_exchange_begin(client->sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_3(exch, INET_EV_RECV, dgram->src.ipv4,
+	    dgram->dest.ipv4, dgram->tos, &answer);
+	int rc = async_data_write_start(exch, dgram->data, dgram->size);
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+	if (retval != EOK)
+		return retval;
+
+	return EOK;
+}
+
+int inet_recv_dgram_local(inet_dgram_t *dgram, uint8_t proto)
+{
+	inet_client_t *client;
+
+	log_msg(LVL_DEBUG, "inet_recv_dgram_local()");
+
+	/* ICMP messages are handled internally */
+	if (proto == IP_PROTO_ICMP)
+		return icmp_recv(dgram);
+
+	client = inet_client_find(proto);
+	if (client == NULL) {
+		log_msg(LVL_DEBUG, "No client found for protocol 0x%" PRIx8,
+		    proto);
+		return ENOENT;
+	}
+
+	return inet_ev_recv(client, dgram);
+}
+
+int inet_recv_packet(inet_packet_t *packet)
+{
+	inet_addrobj_t *addr;
+	inet_dgram_t dgram;
+
+	addr = inet_addrobj_find(&packet->dest, iaf_addr);
+	if (addr != NULL) {
+		/* Destined for one of the local addresses */
+
+		/* Check if packet is a complete datagram */
+		if (packet->offs == 0 && !packet->mf) {
+			/* It is complete deliver it immediately */
+			dgram.src = packet->src;
+			dgram.dest = packet->dest;
+			dgram.tos = packet->tos;
+			dgram.data = packet->data;
+			dgram.size = packet->size;
+
+			return inet_recv_dgram_local(&dgram, packet->proto);
+		} else {
+			/* It is a fragment, queue it for reassembly */
+			inet_reass_queue_packet(packet);
+		}
+	}
+
+	return ENOENT;
+}
+
+int main(int argc, char *argv[])
+{
+	int rc;
+
+	printf(NAME ": HelenOS Internet Protocol service\n");
+
+	if (log_init(NAME, LVL_WARN) != EOK) {
+		printf(NAME ": Failed to initialize logging.\n");
+		return 1;
+	}
+
+	rc = inet_init();
+	if (rc != EOK)
+		return 1;
+
+	printf(NAME ": Accepting connections.\n");
+	task_retval(0);
+	async_manager();
+
+	/* Not reached */
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inetsrv.h
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/inetsrv.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2012 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 inetsrv
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef INETSRV_H_
+#define INETSRV_H_
+
+#include <adt/list.h>
+#include <bool.h>
+#include <inet/iplink.h>
+#include <ipc/loc.h>
+#include <sys/types.h>
+#include <async.h>
+
+/** Inet Client */
+typedef struct {
+	async_sess_t *sess;
+	uint8_t protocol;
+	link_t client_list;
+} inet_client_t;
+
+/** Inetping Client */
+typedef struct {
+	/** Callback session */
+	async_sess_t *sess;
+	/** Session identifier */
+	uint16_t ident;
+	/** Link to client list */
+	link_t client_list;
+} inetping_client_t;
+
+/** Host address */
+typedef struct {
+	uint32_t ipv4;
+} inet_addr_t;
+
+/** Network address */
+typedef struct {
+	/** Address */
+	uint32_t ipv4;
+	/** Number of valid bits in @c ipv4 */
+	int bits;
+} inet_naddr_t;
+
+/** Address object info */
+typedef struct {
+	/** Network address */
+	inet_naddr_t naddr;
+	/** Link service ID */
+	sysarg_t ilink;
+	/** Address object name */
+	char *name;
+} inet_addr_info_t;
+
+/** IP link info */
+typedef struct {
+	/** Link service name */
+	char *name;
+	/** Default MTU */
+	size_t def_mtu;
+} inet_link_info_t;
+
+/** Static route info */
+typedef struct {
+	/** Destination network address */
+	inet_naddr_t dest;
+	/** Router address */
+	inet_addr_t router;
+	/** Static route name */
+	char *name;
+} inet_sroute_info_t;
+
+typedef struct {
+	/** Source address */
+	inet_addr_t src;
+	/** Destination address */
+	inet_addr_t dest;
+	/** Type of service */
+	uint8_t tos;
+	/** Protocol */
+	uint8_t proto;
+	/** Time to live */
+	uint8_t ttl;
+	/** Identifier */
+	uint16_t ident;
+	/** Do not fragment */
+	bool df;
+	/** More fragments */
+	bool mf;
+	/** Offset of fragment into datagram, in bytes */
+	size_t offs;
+	/** Packet data */
+	void *data;
+	/** Packet data size in bytes */
+	size_t size;
+} inet_packet_t;
+
+typedef struct {
+	inet_addr_t src;
+	inet_addr_t dest;
+	uint8_t tos;
+	void *data;
+	size_t size;
+} inet_dgram_t;
+
+typedef struct {
+	link_t link_list;
+	service_id_t svc_id;
+	char *svc_name;
+	async_sess_t *sess;
+	iplink_t *iplink;
+	size_t def_mtu;
+} inet_link_t;
+
+typedef struct {
+	link_t addr_list;
+	sysarg_t id;
+	inet_naddr_t naddr;
+	inet_link_t *ilink;
+	char *name;
+} inet_addrobj_t;
+
+/** Static route configuration */
+typedef struct {
+	link_t sroute_list;
+	sysarg_t id;
+	/** Destination network */
+	inet_naddr_t dest;
+	/** Router via which to route packets */
+	inet_addr_t router;
+	char *name;
+} inet_sroute_t;
+
+typedef enum {
+	/** Destination is on this network node */
+	dt_local,
+	/** Destination is directly reachable */
+	dt_direct,
+	/** Destination is behind a router */
+	dt_router
+} inet_dir_type_t;
+
+/** Direction (next hop) to a destination */
+typedef struct {
+	/** Route type */
+	inet_dir_type_t dtype;
+	/** Address object (direction) */
+	inet_addrobj_t *aobj;
+	/** Local destination address */
+	inet_addr_t ldest;
+} inet_dir_t;
+
+typedef struct {
+	inet_addr_t src;
+	inet_addr_t dest;
+	uint16_t seq_no;
+	void *data;
+	size_t size;
+} inetping_sdu_t;
+
+extern int inet_ev_recv(inet_client_t *, inet_dgram_t *);
+extern int inet_recv_packet(inet_packet_t *);
+extern int inet_route_packet(inet_dgram_t *, uint8_t, uint8_t, int);
+extern int inet_get_srcaddr(inet_addr_t *, uint8_t, inet_addr_t *);
+extern int inet_recv_dgram_local(inet_dgram_t *, uint8_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/pdu.c
===================================================================
--- uspace/srv/net/inetsrv/pdu.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/pdu.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#include <align.h>
+#include <bitops.h>
+#include <byteorder.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <io/log.h>
+#include <macros.h>
+#include <mem.h>
+#include <stdlib.h>
+
+#include "inetsrv.h"
+#include "inet_std.h"
+#include "pdu.h"
+
+static FIBRIL_MUTEX_INITIALIZE(ip_ident_lock);
+static uint16_t ip_ident = 0;
+
+/** One's complement addition.
+ *
+ * Result is a + b + carry.
+ */
+static uint16_t inet_ocadd16(uint16_t a, uint16_t b)
+{
+	uint32_t s;
+
+	s = (uint32_t)a + (uint32_t)b;
+	return (s & 0xffff) + (s >> 16);
+}
+
+uint16_t inet_checksum_calc(uint16_t ivalue, void *data, size_t size)
+{
+	uint16_t sum;
+	uint16_t w;
+	size_t words, i;
+	uint8_t *bdata;
+
+	sum = ~ivalue;
+	words = size / 2;
+	bdata = (uint8_t *)data;
+
+	for (i = 0; i < words; i++) {
+		w = ((uint16_t)bdata[2*i] << 8) | bdata[2*i + 1];
+		sum = inet_ocadd16(sum, w);
+	}
+
+	if (size % 2 != 0) {
+		w = ((uint16_t)bdata[2*words] << 8);
+		sum = inet_ocadd16(sum, w);
+	}
+
+	return ~sum;
+}
+
+/** Encode Internet PDU.
+ *
+ * Encode internet packet into PDU (serialized form). Will encode a
+ * fragment of the payload starting at offset @a offs. The resulting
+ * PDU will have at most @a mtu bytes. @a *roffs will be set to the offset
+ * of remaining payload. If some data is remaining, the MF flag will
+ * be set in the header, otherwise the offset will equal @a packet->size.
+ *
+ * @param packet	Packet to encode
+ * @param offs		Offset into packet payload (in bytes)
+ * @param mtu		MTU (Maximum Transmission Unit) in bytes
+ * @param rdata		Place to store pointer to allocated data buffer
+ * @param rsize		Place to store size of allocated data buffer
+ * @param roffs		Place to store offset of remaning data
+ */
+int inet_pdu_encode(inet_packet_t *packet, size_t offs, size_t mtu,
+    void **rdata, size_t *rsize, size_t *roffs)
+{
+	void *data;
+	size_t size;
+	ip_header_t *hdr;
+	size_t hdr_size;
+	size_t data_offs;
+	uint16_t chksum;
+	uint16_t ident;
+	uint16_t flags_foff;
+	uint16_t foff;
+	size_t fragoff_limit;
+	size_t xfer_size;
+	size_t spc_avail;
+	size_t rem_offs;
+
+	/* Upper bound for fragment offset field */
+	fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
+
+	/* Verify that total size of datagram is within reasonable bounds */
+	if (offs + packet->size > FRAG_OFFS_UNIT * fragoff_limit)
+		return ELIMIT;
+
+	hdr_size = sizeof(ip_header_t);
+	data_offs = ROUND_UP(hdr_size, 4);
+
+	assert(offs % FRAG_OFFS_UNIT == 0);
+	assert(offs / FRAG_OFFS_UNIT < fragoff_limit);
+
+	/* Value for the fragment offset field */
+	foff = offs / FRAG_OFFS_UNIT;
+
+	if (hdr_size >= mtu)
+		return EINVAL;
+
+	/* Amount of space in the PDU available for payload */
+	spc_avail = mtu - hdr_size;
+	spc_avail -= (spc_avail % FRAG_OFFS_UNIT);
+
+	/* Amount of data (payload) to transfer */
+	xfer_size = min(packet->size - offs, spc_avail);
+
+	/* Total PDU size */
+	size = hdr_size + xfer_size;
+
+	/* Offset of remaining payload */
+	rem_offs = offs + xfer_size;
+
+	/* Flags */
+	flags_foff =
+	    (packet->df ? BIT_V(uint16_t, FF_FLAG_DF) : 0) +
+	    (rem_offs < packet->size ? BIT_V(uint16_t, FF_FLAG_MF) : 0) +
+	    (foff << FF_FRAGOFF_l);
+
+	data = calloc(size, 1);
+	if (data == NULL)
+		return ENOMEM;
+
+	/* Allocate identifier */
+	fibril_mutex_lock(&ip_ident_lock);
+	ident = ++ip_ident;
+	fibril_mutex_unlock(&ip_ident_lock);
+
+	/* Encode header fields */
+	hdr = (ip_header_t *)data;
+	hdr->ver_ihl = (4 << VI_VERSION_l) | (hdr_size / sizeof(uint32_t));
+	hdr->tos = packet->tos;
+	hdr->tot_len = host2uint16_t_be(size);
+	hdr->id = host2uint16_t_be(ident);
+	hdr->flags_foff = host2uint16_t_be(flags_foff);
+	hdr->ttl = packet->ttl;
+	hdr->proto = packet->proto;
+	hdr->chksum = 0;
+	hdr->src_addr = host2uint32_t_be(packet->src.ipv4);
+	hdr->dest_addr = host2uint32_t_be(packet->dest.ipv4);
+
+	/* Compute checksum */
+	chksum = inet_checksum_calc(INET_CHECKSUM_INIT, (void *)hdr, hdr_size);
+	hdr->chksum = host2uint16_t_be(chksum);
+
+	/* Copy payload */
+	memcpy((uint8_t *)data + data_offs, packet->data + offs, xfer_size);
+
+	*rdata = data;
+	*rsize = size;
+	*roffs = rem_offs;
+
+	return EOK;
+}
+
+int inet_pdu_decode(void *data, size_t size, inet_packet_t *packet)
+{
+	ip_header_t *hdr;
+	size_t tot_len;
+	size_t data_offs;
+	uint8_t version;
+	uint16_t ident;
+	uint16_t flags_foff;
+	uint16_t foff;
+
+	log_msg(LVL_DEBUG, "inet_pdu_decode()");
+
+	if (size < sizeof(ip_header_t)) {
+		log_msg(LVL_DEBUG, "PDU too short (%zu)", size);
+		return EINVAL;
+	}
+
+	hdr = (ip_header_t *)data;
+
+	version = BIT_RANGE_EXTRACT(uint8_t, VI_VERSION_h, VI_VERSION_l,
+	    hdr->ver_ihl);
+	if (version != 4) {
+		log_msg(LVL_DEBUG, "Version (%d) != 4", version);
+		return EINVAL;
+	}
+
+	tot_len = uint16_t_be2host(hdr->tot_len);
+	if (tot_len < sizeof(ip_header_t)) {
+		log_msg(LVL_DEBUG, "Total Length too small (%zu)", tot_len);
+		return EINVAL;
+	}
+
+	if (tot_len > size) {
+		log_msg(LVL_DEBUG, "Total Length = %zu > PDU size = %zu",
+			tot_len, size);
+		return EINVAL;
+	}
+
+	ident = uint16_t_be2host(hdr->id);
+	flags_foff = uint16_t_be2host(hdr->flags_foff);
+	foff = BIT_RANGE_EXTRACT(uint16_t, FF_FRAGOFF_h, FF_FRAGOFF_l,
+	    flags_foff);
+	/* XXX Checksum */
+
+	packet->src.ipv4 = uint32_t_be2host(hdr->src_addr);
+	packet->dest.ipv4 = uint32_t_be2host(hdr->dest_addr);
+	packet->tos = hdr->tos;
+	packet->proto = hdr->proto;
+	packet->ttl = hdr->ttl;
+	packet->ident = ident;
+
+	packet->df = (flags_foff & BIT_V(uint16_t, FF_FLAG_DF)) != 0;
+	packet->mf = (flags_foff & BIT_V(uint16_t, FF_FLAG_MF)) != 0;
+	packet->offs = foff * FRAG_OFFS_UNIT;
+
+	/* XXX IP options */
+	data_offs = sizeof(uint32_t) * BIT_RANGE_EXTRACT(uint8_t, VI_IHL_h,
+	    VI_IHL_l, hdr->ver_ihl);
+
+	packet->size = tot_len - data_offs;
+	packet->data = calloc(packet->size, 1);
+	if (packet->data == NULL) {
+		log_msg(LVL_WARN, "Out of memory.");
+		return ENOMEM;
+	}
+
+	memcpy(packet->data, (uint8_t *)data + data_offs, packet->size);
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/pdu.h
===================================================================
--- uspace/srv/net/inetsrv/pdu.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/pdu.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef INET_PDU_H_
+#define INET_PDU_H_
+
+#include <sys/types.h>
+#include "inetsrv.h"
+
+#define INET_CHECKSUM_INIT 0xffff
+
+extern uint16_t inet_checksum_calc(uint16_t, void *, size_t);
+
+extern int inet_pdu_encode(inet_packet_t *, size_t, size_t, void **,
+    size_t *, size_t *);
+extern int inet_pdu_decode(void *, size_t, inet_packet_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/reass.c
===================================================================
--- uspace/srv/net/inetsrv/reass.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/reass.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief Datagram reassembly.
+ */
+
+#include <errno.h>
+#include <fibril_synch.h>
+#include <io/log.h>
+#include <macros.h>
+#include <mem.h>
+#include <stdlib.h>
+
+#include "inetsrv.h"
+#include "inet_std.h"
+#include "reass.h"
+
+/** Datagram being reassembled.
+ *
+ * Uniquely identified by (source address, destination address, protocol,
+ * identification) per RFC 791 sec. 2.3 / Fragmentation.
+ */
+typedef struct {
+	link_t map_link;
+	/** List of fragments, @c reass_frag_t */
+	list_t frags;
+} reass_dgram_t;
+
+/** One datagram fragment */
+typedef struct {
+	link_t dgram_link;
+	inet_packet_t packet;
+} reass_frag_t;
+
+/** Datagram map, list of reass_dgram_t */
+static LIST_INITIALIZE(reass_dgram_map);
+/** Protects access to @c reass_dgram_map */
+static FIBRIL_MUTEX_INITIALIZE(reass_dgram_map_lock);
+
+static reass_dgram_t *reass_dgram_new(void);
+static reass_dgram_t *reass_dgram_get(inet_packet_t *);
+static int reass_dgram_insert_frag(reass_dgram_t *, inet_packet_t *);
+static bool reass_dgram_complete(reass_dgram_t *);
+static void reass_dgram_remove(reass_dgram_t *);
+static int reass_dgram_deliver(reass_dgram_t *);
+static void reass_dgram_destroy(reass_dgram_t *);
+
+/** Queue packet for datagram reassembly.
+ *
+ * @param packet	Packet
+ * @return		EOK on success or ENOMEM.
+ */
+int inet_reass_queue_packet(inet_packet_t *packet)
+{
+	reass_dgram_t *rdg;
+	int rc;
+
+	log_msg(LVL_DEBUG, "inet_reass_queue_packet()");
+
+	fibril_mutex_lock(&reass_dgram_map_lock);
+
+	/* Get existing or new datagram */
+	rdg = reass_dgram_get(packet);
+	if (rdg == NULL) {
+		/* Only happens when we are out of memory */
+		fibril_mutex_unlock(&reass_dgram_map_lock);
+		log_msg(LVL_DEBUG, "Allocation failed, packet dropped.");
+		return ENOMEM;
+	}
+
+	/* Insert fragment into the datagram */
+	rc = reass_dgram_insert_frag(rdg, packet);
+	if (rc != EOK)
+		return ENOMEM;
+
+	/* Check if datagram is complete */
+	if (reass_dgram_complete(rdg)) {
+		/* Remove it from the map */
+		reass_dgram_remove(rdg);
+		fibril_mutex_unlock(&reass_dgram_map_lock);
+
+		/* Deliver complete datagram */
+		rc = reass_dgram_deliver(rdg);
+		reass_dgram_destroy(rdg);
+		return rc;
+	}
+
+	fibril_mutex_unlock(&reass_dgram_map_lock);
+	return EOK;
+}
+
+/** Get datagram reassembly structure for packet.
+ *
+ * @param packet	Packet
+ * @return		Datagram reassembly structure matching @a packet
+ */
+static reass_dgram_t *reass_dgram_get(inet_packet_t *packet)
+{
+	assert(fibril_mutex_is_locked(&reass_dgram_map_lock));
+
+	list_foreach(reass_dgram_map, link) {
+		reass_dgram_t *rdg = list_get_instance(link, reass_dgram_t,
+		    map_link);
+
+		link_t *f1_link = list_first(&rdg->frags);
+		assert(f1_link != NULL);
+
+		reass_frag_t *f1 = list_get_instance(f1_link, reass_frag_t,
+		    dgram_link);
+
+		if (f1->packet.src.ipv4 == packet->src.ipv4 &&
+		    f1->packet.dest.ipv4 == packet->dest.ipv4 &&
+		    f1->packet.proto == packet->proto &&
+		    f1->packet.ident == packet->ident) {
+			/* Match */
+			return rdg;
+		}
+	}
+
+	/* No existing reassembly structure. Create a new one. */
+	return reass_dgram_new();
+}
+
+/** Create new datagram reassembly structure.
+ *
+ * @return New datagram reassembly structure.
+ */
+static reass_dgram_t *reass_dgram_new(void)
+{
+	reass_dgram_t *rdg;
+
+	rdg = calloc(1, sizeof(reass_dgram_t));
+	if (rdg == NULL)
+		return NULL;
+
+	link_initialize(&rdg->map_link);
+	list_initialize(&rdg->frags);
+
+	return rdg;
+}
+
+static reass_frag_t *reass_frag_new(void)
+{
+	reass_frag_t *frag;
+
+	frag = calloc(1, sizeof(reass_frag_t));
+	if (frag == NULL)
+		return NULL;
+
+	link_initialize(&frag->dgram_link);
+
+	return frag;
+}
+
+static int reass_dgram_insert_frag(reass_dgram_t *rdg, inet_packet_t *packet)
+{
+	reass_frag_t *frag;
+	void *data_copy;
+	link_t *link;
+
+	assert(fibril_mutex_is_locked(&reass_dgram_map_lock));
+
+	frag = reass_frag_new();
+
+	/* Clone the packet */
+
+	data_copy = malloc(packet->size);
+	if (data_copy == NULL)
+		return ENOMEM;
+
+	frag->packet = *packet;
+	frag->packet.data = data_copy;
+
+	/*
+	 * XXX Make resource-consuming attacks harder, eliminate any duplicate
+	 * data immediately. Possibly eliminate redundant packet headers.
+	 */
+
+	/*
+	 * Insert into the list, which is sorted by offs member ascending.
+	 */
+
+	link = list_first(&rdg->frags);
+	while (link != NULL) {
+		reass_frag_t *qf = list_get_instance(link, reass_frag_t,
+		    dgram_link);
+
+		if (qf->packet.offs >= packet->offs)
+			break;
+
+		link = link->next;
+	}
+
+	if (link != NULL)
+		list_insert_after(&frag->dgram_link, link);
+	else
+		list_append(&frag->dgram_link, &rdg->frags);
+
+	return EOK;
+}
+
+/** Check if datagram is complete.
+ *
+ * @param rdg		Datagram reassembly structure
+ * @return		@c true if complete, @c false if not
+ */
+static bool reass_dgram_complete(reass_dgram_t *rdg)
+{
+	reass_frag_t *frag, *prev;
+	link_t *link;
+
+	assert(fibril_mutex_is_locked(&reass_dgram_map_lock));
+	assert(!list_empty(&rdg->frags));
+
+	/* First fragment must be at offset zero */
+	frag = list_get_instance(list_first(&rdg->frags), reass_frag_t,
+	    dgram_link);
+	if (frag->packet.offs != 0)
+		return false;
+
+	prev = frag;
+	while (true) {
+		link = frag->dgram_link.next;
+		if (link == NULL)
+			return false;
+
+		/* Each next fragment must follow immediately or overlap */
+		frag = list_get_instance(link, reass_frag_t, dgram_link);
+		if (frag->packet.offs > prev->packet.offs + prev->packet.size)
+			return false;
+
+		/* No more fragments - datagram is complete */
+		if (!frag->packet.mf)
+			return true;
+
+		prev = frag;
+	}
+
+	return false;
+}
+
+/** Remove datagram from reassembly map.
+ *
+ * @param rdg		Datagram reassembly structure
+ */
+static void reass_dgram_remove(reass_dgram_t *rdg)
+{
+	assert(fibril_mutex_is_locked(&reass_dgram_map_lock));
+	list_remove(&rdg->map_link);
+}
+
+/** Deliver complete datagram.
+ *
+ * @param rdg		Datagram reassembly structure.
+ */
+static int reass_dgram_deliver(reass_dgram_t *rdg)
+{
+	size_t dgram_size;
+	size_t fragoff_limit;
+	inet_dgram_t dgram;
+	reass_frag_t *frag;
+	uint8_t proto;
+
+	/*
+	 * Potentially there could be something beyond the first packet
+	 * that has !MF. Make sure we ignore that.
+	 */
+	frag = NULL;
+	list_foreach(rdg->frags, link) {
+		frag = list_get_instance(link, reass_frag_t, dgram_link);
+
+		if (!frag->packet.mf)
+			break;
+	}
+
+	assert(frag != NULL);
+	assert(!frag->packet.mf);
+
+	dgram_size = frag->packet.offs + frag->packet.size;
+
+	/* Upper bound for fragment offset field */
+	fragoff_limit = 1 << (FF_FRAGOFF_h - FF_FRAGOFF_l);
+
+	/* Verify that total size of datagram is within reasonable bounds */
+	if (dgram_size > FRAG_OFFS_UNIT * fragoff_limit)
+		return ELIMIT;
+
+	dgram.data = calloc(dgram_size, 1);
+	if (dgram.data == NULL)
+		return ENOMEM;
+
+	dgram.size = dgram_size;
+	dgram.src = frag->packet.src;
+	dgram.dest = frag->packet.dest;
+	dgram.tos = frag->packet.tos;
+	proto = frag->packet.proto;
+
+	/* Pull together data from individual fragments */
+
+	size_t doffs = 0;
+
+	frag = NULL;
+	list_foreach(rdg->frags, link) {
+		frag = list_get_instance(link, reass_frag_t, dgram_link);
+
+		size_t cb, ce;
+
+		cb = max(doffs, frag->packet.offs);
+		ce = min(dgram_size, frag->packet.offs + frag->packet.size);
+
+		if (ce > cb) {
+			memcpy(dgram.data + cb,
+			    frag->packet.data + cb - frag->packet.offs,
+			    ce - cb);
+		}
+
+		if (!frag->packet.mf)
+			break;
+	}
+
+	return inet_recv_dgram_local(&dgram, proto);
+}
+
+/** Destroy datagram reassembly structure.
+ *
+ * @param rdg		Datagram reassembly structure.
+ */
+static void reass_dgram_destroy(reass_dgram_t *rdg)
+{
+	while (!list_empty(&rdg->frags)) {
+		link_t *flink = list_first(&rdg->frags);
+		reass_frag_t *frag = list_get_instance(flink, reass_frag_t,
+		    dgram_link);
+
+		list_remove(&frag->dgram_link);
+		free(frag->packet.data);
+		free(frag);
+	}
+
+	free(rdg);
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/reass.h
===================================================================
--- uspace/srv/net/inetsrv/reass.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/reass.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef INET_REASS_H_
+#define INET_REASS_H_
+
+#include <sys/types.h>
+#include "inetsrv.h"
+
+extern int inet_reass_queue_packet(inet_packet_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/sroute.c
===================================================================
--- uspace/srv/net/inetsrv/sroute.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/sroute.c	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#include <bitops.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <io/log.h>
+#include <ipc/loc.h>
+#include <stdlib.h>
+#include <str.h>
+
+#include "sroute.h"
+#include "inetsrv.h"
+#include "inet_link.h"
+#include "inet_util.h"
+
+static FIBRIL_MUTEX_INITIALIZE(sroute_list_lock);
+static LIST_INITIALIZE(sroute_list);
+static sysarg_t sroute_id = 0;
+
+inet_sroute_t *inet_sroute_new(void)
+{
+	inet_sroute_t *sroute = calloc(1, sizeof(inet_sroute_t));
+
+	if (sroute == NULL) {
+		log_msg(LVL_ERROR, "Failed allocating static route object. "
+		    "Out of memory.");
+		return NULL;
+	}
+
+	link_initialize(&sroute->sroute_list);
+	fibril_mutex_lock(&sroute_list_lock);
+	sroute->id = ++sroute_id;
+	fibril_mutex_unlock(&sroute_list_lock);
+
+	return sroute;
+}
+
+void inet_sroute_delete(inet_sroute_t *sroute)
+{
+	if (sroute->name != NULL)
+		free(sroute->name);
+	free(sroute);
+}
+
+void inet_sroute_add(inet_sroute_t *sroute)
+{
+	fibril_mutex_lock(&sroute_list_lock);
+	list_append(&sroute->sroute_list, &sroute_list);
+	fibril_mutex_unlock(&sroute_list_lock);
+}
+
+void inet_sroute_remove(inet_sroute_t *sroute)
+{
+	fibril_mutex_lock(&sroute_list_lock);
+	list_remove(&sroute->sroute_list);
+	fibril_mutex_unlock(&sroute_list_lock);
+}
+
+/** Find address object matching address @a addr.
+ *
+ * @param addr	Address
+ */
+inet_sroute_t *inet_sroute_find(inet_addr_t *addr)
+{
+	uint32_t mask;
+	inet_sroute_t *best;
+
+	log_msg(LVL_DEBUG, "inet_sroute_find(%x)", (unsigned)addr->ipv4);
+
+	fibril_mutex_lock(&sroute_list_lock);
+
+	best = NULL;
+
+	list_foreach(sroute_list, link) {
+		inet_sroute_t *sroute = list_get_instance(link,
+		    inet_sroute_t, sroute_list);
+
+		/* Look for the most specific route */
+		if (best != NULL && best->dest.bits >= sroute->dest.bits)
+			continue;
+
+		mask = inet_netmask(sroute->dest.bits);
+		if ((sroute->dest.ipv4 & mask) == (addr->ipv4 & mask)) {
+			fibril_mutex_unlock(&sroute_list_lock);
+			log_msg(LVL_DEBUG, "inet_sroute_find: found %p",
+			    sroute);
+			return sroute;
+		}
+	}
+
+	log_msg(LVL_DEBUG, "inet_sroute_find: Not found");
+	fibril_mutex_unlock(&sroute_list_lock);
+
+	return NULL;
+}
+
+/** Find static route with a specific name.
+ *
+ * @param name	Address object name
+ * @return	Address object
+ */
+inet_sroute_t *inet_sroute_find_by_name(const char *name)
+{
+	log_msg(LVL_DEBUG, "inet_sroute_find_by_name('%s')",
+	    name);
+
+	fibril_mutex_lock(&sroute_list_lock);
+
+	list_foreach(sroute_list, link) {
+		inet_sroute_t *sroute = list_get_instance(link,
+		    inet_sroute_t, sroute_list);
+
+		if (str_cmp(sroute->name, name) == 0) {
+			fibril_mutex_unlock(&sroute_list_lock);
+			log_msg(LVL_DEBUG, "inet_sroute_find_by_name: found %p",
+			    sroute);
+			return sroute;
+		}
+	}
+
+	log_msg(LVL_DEBUG, "inet_sroute_find_by_name: Not found");
+	fibril_mutex_unlock(&sroute_list_lock);
+
+	return NULL;
+}
+
+/** Find static route with the given ID.
+ *
+ * @param id	Address object ID
+ * @return	Address object
+ */
+inet_sroute_t *inet_sroute_get_by_id(sysarg_t id)
+{
+	log_msg(LVL_DEBUG, "inet_sroute_get_by_id(%zu)", (size_t)id);
+
+	fibril_mutex_lock(&sroute_list_lock);
+
+	list_foreach(sroute_list, link) {
+		inet_sroute_t *sroute = list_get_instance(link,
+		    inet_sroute_t, sroute_list);
+
+		if (sroute->id == id) {
+			fibril_mutex_unlock(&sroute_list_lock);
+			return sroute;
+		}
+	}
+
+	fibril_mutex_unlock(&sroute_list_lock);
+
+	return NULL;
+}
+
+/** Get IDs of all static routes. */
+int inet_sroute_get_id_list(sysarg_t **rid_list, size_t *rcount)
+{
+	sysarg_t *id_list;
+	size_t count, i;
+
+	fibril_mutex_lock(&sroute_list_lock);
+	count = list_count(&sroute_list);
+
+	id_list = calloc(count, sizeof(sysarg_t));
+	if (id_list == NULL) {
+		fibril_mutex_unlock(&sroute_list_lock);
+		return ENOMEM;
+	}
+
+	i = 0;
+	list_foreach(sroute_list, link) {
+		inet_sroute_t *sroute = list_get_instance(link,
+		    inet_sroute_t, sroute_list);
+
+		id_list[i++] = sroute->id;
+	}
+
+	fibril_mutex_unlock(&sroute_list_lock);
+
+	*rid_list = id_list;
+	*rcount = count;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/sroute.h
===================================================================
--- uspace/srv/net/inetsrv/sroute.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
+++ uspace/srv/net/inetsrv/sroute.h	(revision b4ec1ea0d925eb817dda078a65808347de80c0c4)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 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 inet
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef INET_SROUTE_H_
+#define INET_SROUTE_H_
+
+#include <sys/types.h>
+#include "inetsrv.h"
+
+extern inet_sroute_t *inet_sroute_new(void);
+extern void inet_sroute_delete(inet_sroute_t *);
+extern void inet_sroute_add(inet_sroute_t *);
+extern void inet_sroute_remove(inet_sroute_t *);
+extern inet_sroute_t *inet_sroute_find(inet_addr_t *);
+extern inet_sroute_t *inet_sroute_find_by_name(const char *);
+extern inet_sroute_t *inet_sroute_get_by_id(sysarg_t);
+extern int inet_sroute_send_dgram(inet_sroute_t *, inet_addr_t *,
+    inet_dgram_t *, uint8_t, uint8_t, int);
+extern int inet_sroute_get_id_list(sysarg_t **, size_t *);
+
+
+#endif
+
+/** @}
+ */
