Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 7af0cc5a018d0110bf2c694b3d163d45aa8b2725)
+++ uspace/app/init/init.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -360,4 +360,6 @@
 	srv_start("/srv/udp");
 	srv_start("/srv/dnsrsrv");
+	srv_start("/srv/dhcp");
+	srv_start("/srv/nconfsrv");
 	
 	srv_start("/srv/clipboard");
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 7af0cc5a018d0110bf2c694b3d163d45aa8b2725)
+++ uspace/lib/c/Makefile	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -77,4 +77,5 @@
 	generic/device/pci.c \
 	generic/device/ahci.c \
+	generic/dhcp.c \
 	generic/dnsr.c \
 	generic/dlfcn.c \
Index: uspace/lib/c/generic/dhcp.c
===================================================================
--- uspace/lib/c/generic/dhcp.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
+++ uspace/lib/c/generic/dhcp.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2013 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <async.h>
+#include <assert.h>
+#include <errno.h>
+#include <inet/dhcp.h>
+#include <ipc/dhcp.h>
+#include <ipc/services.h>
+#include <loc.h>
+#include <stdlib.h>
+
+static async_sess_t *dhcp_sess = NULL;
+
+int dhcp_init(void)
+{
+	service_id_t dhcp_svc;
+	int rc;
+
+	assert(dhcp_sess == NULL);
+
+	rc = loc_service_get_id(SERVICE_NAME_DHCP, &dhcp_svc,
+	    IPC_FLAG_BLOCKING);
+	if (rc != EOK)
+		return ENOENT;
+
+	dhcp_sess = loc_service_connect(EXCHANGE_SERIALIZE, dhcp_svc,
+	    IPC_FLAG_BLOCKING);
+	if (dhcp_sess == NULL)
+		return ENOENT;
+
+	return EOK;
+}
+
+int dhcp_link_add(sysarg_t link_id)
+{
+	async_exch_t *exch = async_exchange_begin(dhcp_sess);
+
+	int rc = async_req_1_0(exch, DHCP_LINK_ADD, link_id);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+int dhcp_link_remove(sysarg_t link_id)
+{
+	async_exch_t *exch = async_exchange_begin(dhcp_sess);
+
+	int rc = async_req_1_0(exch, DHCP_LINK_REMOVE, link_id);
+	async_exchange_end(exch);
+
+	return rc;
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/inet/dhcp.h
===================================================================
--- uspace/lib/c/include/inet/dhcp.h	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
+++ uspace/lib/c/include/inet/dhcp.h	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_INET_DHCP_H_
+#define LIBC_INET_DHCP_H_
+
+#include <sys/types.h>
+
+extern int dhcp_init(void);
+extern int dhcp_link_add(sysarg_t);
+extern int dhcp_link_remove(sysarg_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/dhcp.h
===================================================================
--- uspace/lib/c/include/ipc/dhcp.h	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
+++ uspace/lib/c/include/ipc/dhcp.h	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_IPC_DHCP_H_
+#define LIBC_IPC_DHCP_H_
+
+#include <ipc/common.h>
+
+/** DHCP service requests */
+typedef enum {
+	DHCP_LINK_ADD = IPC_FIRST_USER_METHOD,
+	DHCP_LINK_REMOVE
+} dhcp_request_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision 7af0cc5a018d0110bf2c694b3d163d45aa8b2725)
+++ uspace/lib/c/include/ipc/services.h	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -54,4 +54,5 @@
 
 #define SERVICE_NAME_CORECFG	"corecfg"
+#define SERVICE_NAME_DHCP       "net/dhcp"
 #define SERVICE_NAME_DNSR       "net/dnsr"
 #define SERVICE_NAME_INET       "net/inet"
Index: uspace/srv/net/dhcp/Makefile
===================================================================
--- uspace/srv/net/dhcp/Makefile	(revision 7af0cc5a018d0110bf2c694b3d163d45aa8b2725)
+++ uspace/srv/net/dhcp/Makefile	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -31,5 +31,6 @@
 
 SOURCES = \
-	dhcp.c 
+	dhcp.c \
+	main.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/net/dhcp/dhcp.c
===================================================================
--- uspace/srv/net/dhcp/dhcp.c	(revision 7af0cc5a018d0110bf2c694b3d163d45aa8b2725)
+++ uspace/srv/net/dhcp/dhcp.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -39,4 +39,5 @@
 #include <inet/dnsr.h>
 #include <inet/inetcfg.h>
+#include <io/log.h>
 #include <loc.h>
 #include <net/in.h>
@@ -46,4 +47,5 @@
 #include <stdlib.h>
 
+#include "dhcp.h"
 #include "dhcp_std.h"
 
@@ -113,5 +115,5 @@
 	    (struct sockaddr *)&addr, sizeof(addr));
 	if (rc != EOK) {
-		printf("Sending failed\n");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Sending failed");
 		return rc;
 	}
@@ -154,5 +156,5 @@
 	    (struct sockaddr *)&src_addr, &src_addr_size);
 	if (rc < 0) {
-		printf("recvfrom failed (%d)\n", rc);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "recvfrom failed (%d)", rc);
 		return rc;
 	}
@@ -222,5 +224,5 @@
 	size_t i;
 
-	printf("Receive reply\n");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Receive reply");
 	memset(offer, 0, sizeof(*offer));
 
@@ -231,5 +233,5 @@
 		return rc;
 
-	printf("Your IP address: %s\n", saddr);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Your IP address: %s", saddr);
 	free(saddr);
 
@@ -240,5 +242,5 @@
 		return rc;
 
-	printf("Next server IP address: %s\n", saddr);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Next server IP address: %s", saddr);
 	free(saddr);
 
@@ -249,5 +251,5 @@
 		return rc;
 
-	printf("Relay agent IP address: %s\n", saddr);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Relay agent IP address: %s", saddr);
 	free(saddr);
 
@@ -320,10 +322,10 @@
 
 	if (!have_server_id) {
-		printf("Missing server ID option.\n");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Missing server ID option.");
 		return rc;
 	}
 
 	if (!have_subnet_mask) {
-		printf("Missing subnet mask option.\n");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Missing subnet mask option.");
 		return rc;
 	}
@@ -333,5 +335,5 @@
 		return rc;
 
-	printf("Offered network address: %s\n", saddr);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Offered network address: %s", saddr);
 	free(saddr);
 
@@ -341,5 +343,5 @@
 			return rc;
 
-		printf("Router address: %s\n", saddr);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Router address: %s", saddr);
 		free(saddr);
 	}
@@ -350,5 +352,5 @@
 			return rc;
 
-		printf("DNS server: %s\n", saddr);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "DNS server: %s", saddr);
 		free(saddr);
 	}
@@ -367,5 +369,6 @@
 	    &addr_id);
 	if (rc != EOK) {
-		printf("Error creating IP address %s (%d)\n", "dhcp4a", rc);
+		log_msg(LOG_DEFAULT, LVL_ERROR,
+		    "Error creating IP address %s (%d)", "dhcp4a", rc);
 		return rc;
 	}
@@ -378,6 +381,6 @@
 		rc = inetcfg_sroute_create("dhcpdef", &defr, &offer->router, &sroute_id);
 		if (rc != EOK) {
-			printf("Error creating default route %s (%d).\n", "dhcpdef",
-			    rc);
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Error creating "
+			    "default route %s (%d).", "dhcpdef", rc);
 			return rc;
 		}
@@ -387,6 +390,6 @@
 		rc = dnsr_set_srvaddr(&offer->dns_server);
 		if (rc != EOK) {
-			printf("%s: Error setting nameserver address (%d))\n",
-			    NAME, rc);
+			log_msg(LOG_DEFAULT, LVL_ERROR, "%s: Error setting "
+			    "nameserver address (%d))", NAME, rc);
 			return rc;
 		}
@@ -396,36 +399,21 @@
 }
 
-int main(int argc, char *argv[])
+int dhcpsrv_link_add(service_id_t link_id)
 {
 	int fd;
 	struct sockaddr_in laddr;
 	void *msg;
-	service_id_t iplink;
 	size_t msg_size;
 	dhcp_offer_t offer;
 	int rc;
 
-	if (argc < 2) {
-		printf("syntax: %s <ip-link>\n", NAME);
-		return 1;
-	}
-
-	rc = inetcfg_init();
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcpsrv_link_add(%zu)", link_id);
+
+	/* Get link hardware address */
+	rc = inetcfg_link_get(link_id, &link_info);
 	if (rc != EOK) {
-		printf("Error contacting inet configuration service.\n");
-		return 1;
-	}
-
-	rc = loc_service_get_id(argv[1], &iplink, 0);
-	if (rc != EOK) {
-		printf("Error resolving service '%s'.\n", argv[1]);
-		return 1;
-	}
-
-	/* Get link hardware address */
-	rc = inetcfg_link_get(iplink, &link_info);
-	if (rc != EOK) {
-		printf("Error getting properties for link '%s'.\n", argv[1]);
-		return 1;
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting properties "
+		    "for link %zu.", link_id);
+		return EIO;
 	}
 
@@ -436,54 +424,60 @@
 	fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
 	if (fd < 0)
-		return 1;
-
-	printf("Bind socket.\n");
+		return EIO;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Bind socket.");
 	rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
 	if (rc != EOK)
-		return 1;
-
-	printf("Set socket options\n");
-	rc = setsockopt(fd, SOL_SOCKET, SO_IPLINK, &iplink, sizeof(iplink));
-	if (rc != EOK)
-		return 1;
+		return EIO;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Set socket options");
+	rc = setsockopt(fd, SOL_SOCKET, SO_IPLINK, &link_id, sizeof(link_id));
+	if (rc != EOK)
+		return EIO;
 
 	transport_fd = fd;
 
-	printf("Send DHCPDISCOVER\n");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Send DHCPDISCOVER");
 	rc = dhcp_send_discover();
 	if (rc != EOK)
-		return 1;
+		return EIO;
 
 	rc = dhcp_recv_msg(&msg, &msg_size);
 	if (rc != EOK)
-		return 1;
-
-	printf("Received %zu bytes\n", msg_size);
+		return EIO;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Received %zu bytes", msg_size);
 
 	rc = dhcp_recv_reply(msg, msg_size, &offer);
 	if (rc != EOK)
-		return 1;
+		return EIO;
 
 	rc = dhcp_send_request(&offer);
 	if (rc != EOK)
-		return 1;
+		return EIO;
 
 	rc = dhcp_recv_msg(&msg, &msg_size);
 	if (rc != EOK)
-		return 1;
-
-	printf("Received %zu bytes\n", msg_size);
+		return EIO;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Received %zu bytes", msg_size);
 
 	rc = dhcp_recv_reply(msg, msg_size, &offer);
 	if (rc != EOK)
-		return 1;
-
-	rc = dhcp_cfg_create(iplink, &offer);
-	if (rc != EOK)
-		return 1;
+		return EIO;
+
+	rc = dhcp_cfg_create(link_id, &offer);
+	if (rc != EOK)
+		return EIO;
 
 	closesocket(fd);
-	return 0;
-}
+	return EOK;
+}
+
+int dhcpsrv_link_remove(service_id_t link_id)
+{
+	return ENOTSUP;
+}
+
 
 /** @}
Index: uspace/srv/net/dhcp/dhcp.h
===================================================================
--- uspace/srv/net/dhcp/dhcp.h	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
+++ uspace/srv/net/dhcp/dhcp.h	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup dhcp
+ * @{
+ */
+/**
+ * @file
+ * @brief
+ */
+
+#ifndef DHCP_H
+#define DHCP_H
+
+#include <ipc/loc.h>
+
+extern int dhcpsrv_link_add(service_id_t);
+extern int dhcpsrv_link_remove(service_id_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/dhcp/main.c
===================================================================
--- uspace/srv/net/dhcp/main.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
+++ uspace/srv/net/dhcp/main.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2013 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup dhcp
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <async.h>
+#include <errno.h>
+#include <io/log.h>
+#include <inet/inetcfg.h>
+#include <ipc/dhcp.h>
+#include <ipc/services.h>
+#include <loc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <task.h>
+
+#include "dhcp.h"
+
+#define NAME  "dhcp"
+
+static void dhcp_client_conn(ipc_callid_t, ipc_call_t *, void *);
+
+static int dhcp_init(void)
+{
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_init()");
+
+	rc = inetcfg_init();
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error contacting inet configuration service.\n");
+		return EIO;
+	}
+
+	async_set_client_connection(dhcp_client_conn);
+
+	rc = loc_server_register(NAME);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server (%d).", rc);
+		return EEXIST;
+	}
+
+	service_id_t sid;
+	rc = loc_service_register(SERVICE_NAME_DHCP, &sid);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
+		return EEXIST;
+	}
+
+	return EOK;
+}
+
+static void dhcp_link_add_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	sysarg_t link_id;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_link_add_srv()");
+
+	link_id = IPC_GET_ARG1(*call);
+
+	rc = dhcpsrv_link_add(link_id);
+	async_answer_0(callid, rc);
+}
+
+static void dhcp_link_remove_srv(ipc_callid_t callid, ipc_call_t *call)
+{
+	sysarg_t link_id;
+	int rc;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_link_remove_srv()");
+
+	link_id = IPC_GET_ARG1(*call);
+
+	rc = dhcpsrv_link_remove(link_id);
+	async_answer_0(callid, rc);
+}
+
+static void dhcp_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_client_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 DHCP_LINK_ADD:
+			dhcp_link_add_srv(callid, &call);
+			break;
+		case DHCP_LINK_REMOVE:
+			dhcp_link_remove_srv(callid, &call);
+			break;
+		default:
+			async_answer_0(callid, EINVAL);
+		}
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	int rc;
+
+	printf("%s: DHCP Service\n", NAME);
+
+	if (log_init(NAME) != EOK) {
+		printf(NAME ": Failed to initialize logging.\n");
+		return 1;
+	}
+
+	rc = dhcp_init();
+	if (rc != EOK)
+		return 1;
+
+	printf(NAME ": Accepting connections.\n");
+	task_retval(0);
+	async_manager();
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision 7af0cc5a018d0110bf2c694b3d163d45aa8b2725)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -251,4 +251,5 @@
 	}
 	
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Configured link '%s'.", ilink->svc_name);
 	return EOK;
 	
Index: uspace/srv/net/inetsrv/inetcfg.c
===================================================================
--- uspace/srv/net/inetsrv/inetcfg.c	(revision 7af0cc5a018d0110bf2c694b3d163d45aa8b2725)
+++ uspace/srv/net/inetsrv/inetcfg.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -750,4 +750,5 @@
 		sysarg_t method = IPC_GET_IMETHOD(call);
 
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "method %d", (int)method);
 		if (!method) {
 			/* The other side has hung up */
Index: uspace/srv/net/nconfsrv/iplink.c
===================================================================
--- uspace/srv/net/nconfsrv/iplink.c	(revision 7af0cc5a018d0110bf2c694b3d163d45aa8b2725)
+++ uspace/srv/net/nconfsrv/iplink.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -38,8 +38,10 @@
 #include <errno.h>
 #include <fibril_synch.h>
+#include <inet/dhcp.h>
 #include <inet/inetcfg.h>
 #include <io/log.h>
 #include <loc.h>
 #include <stdlib.h>
+#include <str.h>
 
 #include "iplink.h"
@@ -139,4 +141,5 @@
 	}
 
+	log_msg(LOG_DEFAULT, LVL_NOTE, "Configure link %s", nlink->svc_name);
 	rc = inetcfg_link_add(sid);
 	if (rc != EOK) {
@@ -144,4 +147,13 @@
 		    "'%s'.\n", nlink->svc_name);
 		goto error;
+	}
+
+	if (str_lcmp(nlink->svc_name, "net/eth", str_length("net/eth")) == 0) {
+		rc = dhcp_link_add(sid);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed configuring DHCP on "
+			    " link '%s'.\n", nlink->svc_name);
+			goto error;
+		}
 	}
 
Index: uspace/srv/net/nconfsrv/nconfsrv.c
===================================================================
--- uspace/srv/net/nconfsrv/nconfsrv.c	(revision 7af0cc5a018d0110bf2c694b3d163d45aa8b2725)
+++ uspace/srv/net/nconfsrv/nconfsrv.c	(revision bd88bee745abe1948dac683975e4b015ecdfaf39)
@@ -39,4 +39,5 @@
 #include <errno.h>
 #include <fibril_synch.h>
+#include <inet/dhcp.h>
 #include <inet/inetcfg.h>
 #include <io/log.h>
@@ -65,4 +66,11 @@
 	if (rc != EOK) {
 		log_msg(LOG_DEFAULT, LVL_ERROR, "Error contacting inet "
+		    "configuration service.");
+		return EIO;
+	}
+
+	rc = dhcp_init();
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error contacting dhcp "
 		    "configuration service.");
 		return EIO;
