Index: uspace/app/inetcfg/inetcfg.c
===================================================================
--- uspace/app/inetcfg/inetcfg.c	(revision a88a6eac286c731241e6249e900167e43e7d64d9)
+++ uspace/app/inetcfg/inetcfg.c	(revision 0e94b97998379f74e0e2e1d0a6b52341fabcaf09)
@@ -40,4 +40,5 @@
 #include <loc.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <str_error.h>
 #include <sys/types.h>
@@ -86,4 +87,18 @@
 }
 
+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_create_static(int argc, char *argv[])
 {
@@ -129,6 +144,57 @@
 		printf(NAME ": Failed creating static address '%s' (%d)\n",
 		    "v4s", rc);
-		return 1;
-	}
+		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;
+	}
+
+	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]);
+			continue;
+		}
+
+		rc = inetcfg_link_get(ainfo.ilink, &linfo);
+		if (rc != EOK) {
+			printf("Failed getting properties of link %zu.\n",
+			    (size_t)ainfo.ilink);
+			continue;
+		}
+
+		rc = naddr_format(&ainfo.naddr, &astr);
+		if (rc != EOK) {
+			printf("Memory allocation failed.\n");
+			goto out;
+		}
+
+		printf("%s %s %s\n", astr, linfo.name,
+		    ainfo.name);
+
+		free(astr);
+		free(ainfo.name);
+		free(linfo.name);
+	}
+out:
+	free(addr_list);
 
 	return EOK;
@@ -138,10 +204,4 @@
 {
 	int rc;
-
-	if (argc < 2) {
-		printf(NAME ": Missing argument.\n");
-		print_syntax();
-		return 1;
-	}
 
 	rc = inetcfg_init();
@@ -150,4 +210,11 @@
 		    rc);
 		return 1;
+	}
+
+	if (argc < 2) {
+		rc = addr_list();
+		if (rc != EOK)
+			return 1;
+		return 0;
 	}
 
Index: uspace/lib/c/generic/inetcfg.c
===================================================================
--- uspace/lib/c/generic/inetcfg.c	(revision a88a6eac286c731241e6249e900167e43e7d64d9)
+++ uspace/lib/c/generic/inetcfg.c	(revision 0e94b97998379f74e0e2e1d0a6b52341fabcaf09)
@@ -35,4 +35,5 @@
 #include <loc.h>
 #include <stdlib.h>
+#include <str.h>
 
 static async_sess_t *inetcfg_sess = NULL;
@@ -156,16 +157,38 @@
 int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
 {
-	sysarg_t ipv4, bits;
-	async_exch_t *exch = async_exchange_begin(inetcfg_sess);
-
-	int rc = async_req_1_2(exch, INETCFG_ADDR_GET, addr_id,
-	    &ipv4, &bits);
-	async_exchange_end(exch);
-
-	if (rc != EOK)
-		return rc;
-
-	ainfo->naddr.ipv4 = ipv4;
-	ainfo->naddr.bits = bits;
+	ipc_call_t dreply;
+	sysarg_t dretval;
+	size_t act_size;
+	char name_buf[LOC_NAME_MAXLEN + 1];
+
+	async_exch_t *exch = async_exchange_begin(inetcfg_sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, INETCFG_ADDR_GET, addr_id, &answer);
+	aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
+	async_wait_for(dreq, &dretval);
+
+	async_exchange_end(exch);
+
+	if (dretval != EOK) {
+		async_wait_for(req, NULL);
+		return dretval;
+	}
+
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+
+	if (retval != EOK)
+		return retval;
+
+	act_size = IPC_GET_ARG2(dreply);
+	assert(act_size <= LOC_NAME_MAXLEN);
+	name_buf[act_size] = '\0';
+
+	ainfo->naddr.ipv4 = IPC_GET_ARG1(answer);
+	ainfo->naddr.bits = IPC_GET_ARG2(answer);
+	ainfo->ilink = IPC_GET_ARG3(answer);
+	ainfo->name = str_dup(name_buf);
+
 	return EOK;
 }
@@ -185,13 +208,35 @@
 int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
 {
-	async_exch_t *exch = async_exchange_begin(inetcfg_sess);
-
-	int rc = async_req_1_0(exch, INETCFG_LINK_GET, link_id);
-	async_exchange_end(exch);
-
-	if (rc != EOK)
-		return rc;
-
-	linfo->dummy = 0;
+	ipc_call_t dreply;
+	sysarg_t dretval;
+	size_t act_size;
+	char name_buf[LOC_NAME_MAXLEN + 1];
+
+	async_exch_t *exch = async_exchange_begin(inetcfg_sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, INETCFG_LINK_GET, link_id, &answer);
+	aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
+	async_wait_for(dreq, &dretval);
+
+	async_exchange_end(exch);
+
+	if (dretval != EOK) {
+		async_wait_for(req, NULL);
+		return dretval;
+	}
+
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+
+	if (retval != EOK)
+		return retval;
+
+	act_size = IPC_GET_ARG2(dreply);
+	assert(act_size <= LOC_NAME_MAXLEN);
+	name_buf[act_size] = '\0';
+
+	linfo->name = str_dup(name_buf);
+
 	return EOK;
 }
Index: uspace/lib/c/include/inet/inetcfg.h
===================================================================
--- uspace/lib/c/include/inet/inetcfg.h	(revision a88a6eac286c731241e6249e900167e43e7d64d9)
+++ uspace/lib/c/include/inet/inetcfg.h	(revision 0e94b97998379f74e0e2e1d0a6b52341fabcaf09)
@@ -51,9 +51,14 @@
 	/** 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 {
-	int dummy;
+	/** Link service name */
+	char *name;
 } inet_link_info_t;
 
Index: uspace/srv/inet/addrobj.c
===================================================================
--- uspace/srv/inet/addrobj.c	(revision a88a6eac286c731241e6249e900167e43e7d64d9)
+++ uspace/srv/inet/addrobj.c	(revision 0e94b97998379f74e0e2e1d0a6b52341fabcaf09)
@@ -36,4 +36,5 @@
 
 #include <bitops.h>
+#include <errno.h>
 #include <fibril_synch.h>
 #include <io/log.h>
@@ -47,4 +48,5 @@
 static FIBRIL_MUTEX_INITIALIZE(addr_list_lock);
 static LIST_INITIALIZE(addr_list);
+static sysarg_t addr_id = 0;
 
 static uint32_t inet_netmask(int bits)
@@ -67,4 +69,7 @@
 
 	link_initialize(&addr->addr_list);
+	fibril_mutex_lock(&addr_list_lock);
+	addr->id = ++addr_id;
+	fibril_mutex_unlock(&addr_list_lock);
 
 	return addr;
@@ -73,4 +78,6 @@
 void inet_addrobj_delete(inet_addrobj_t *addr)
 {
+	if (addr->name != NULL)
+		free(addr->name);
 	free(addr);
 }
@@ -123,4 +130,30 @@
 }
 
+/** Find address object matching address @a addr.
+ *
+ * @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 to directly reachable destination */
 int inet_addrobj_send_dgram(inet_addrobj_t *addr, inet_dgram_t *dgram,
@@ -137,4 +170,35 @@
 }
 
+/** 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/inet/addrobj.h
===================================================================
--- uspace/srv/inet/addrobj.h	(revision a88a6eac286c731241e6249e900167e43e7d64d9)
+++ uspace/srv/inet/addrobj.h	(revision 0e94b97998379f74e0e2e1d0a6b52341fabcaf09)
@@ -38,4 +38,5 @@
 #define INET_ADDROBJ_H_
 
+#include <sys/types.h>
 #include "inet.h"
 
@@ -52,6 +53,9 @@
 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_get_by_id(sysarg_t);
 extern int inet_addrobj_send_dgram(inet_addrobj_t *, inet_dgram_t *,
     uint8_t, uint8_t, int);
+extern int inet_addrobj_get_id_list(sysarg_t **, size_t *);
+
 
 #endif
Index: uspace/srv/inet/inet.h
===================================================================
--- uspace/srv/inet/inet.h	(revision a88a6eac286c731241e6249e900167e43e7d64d9)
+++ uspace/srv/inet/inet.h	(revision 0e94b97998379f74e0e2e1d0a6b52341fabcaf09)
@@ -68,9 +68,14 @@
 	/** 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 {
-	int dummy;
+	/** Link service name */
+	char *name;
 } inet_link_info_t;
 
@@ -104,6 +109,8 @@
 typedef struct {
 	link_t addr_list;
+	sysarg_t id;
 	inet_naddr_t naddr;
 	inet_link_t *ilink;
+	char *name;
 } inet_addrobj_t;
 
Index: uspace/srv/inet/inet_link.c
===================================================================
--- uspace/srv/inet/inet_link.c	(revision a88a6eac286c731241e6249e900167e43e7d64d9)
+++ uspace/srv/inet/inet_link.c	(revision 0e94b97998379f74e0e2e1d0a6b52341fabcaf09)
@@ -42,4 +42,5 @@
 #include <loc.h>
 #include <stdlib.h>
+#include <str.h>
 
 #include "addrobj.h"
@@ -196,4 +197,5 @@
 	addr->naddr.bits = 24;
 	addr->ilink = ilink;
+	addr->name = str_dup("v4a");
 	inet_addrobj_add(addr);
 
Index: uspace/srv/inet/inetcfg.c
===================================================================
--- uspace/srv/inet/inetcfg.c	(revision a88a6eac286c731241e6249e900167e43e7d64d9)
+++ uspace/srv/inet/inetcfg.c	(revision 0e94b97998379f74e0e2e1d0a6b52341fabcaf09)
@@ -42,4 +42,5 @@
 #include <loc.h>
 #include <stdlib.h>
+#include <str.h>
 #include <sys/types.h>
 
@@ -67,4 +68,5 @@
 	addr->naddr = *naddr;
 	addr->ilink = ilink;
+	addr->name = str_dup("foo");
 	inet_addrobj_add(addr);
 
@@ -88,20 +90,38 @@
 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_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_addr_list(sysarg_t **addrs, size_t *count)
-{
-	return ENOTSUP;
-}
-
-static int inetcfg_get_link_list(sysarg_t **addrs, size_t *count)
-{
-	return ENOTSUP;
-}
-
-static int inetcfg_link_get(sysarg_t addr_id, inet_link_info_t *ainfo)
-{
-	return ENOTSUP;
+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);
+	return EOK;
 }
 
@@ -140,4 +160,7 @@
 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;
@@ -147,10 +170,99 @@
 	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);
-	async_answer_2(callid, rc, ainfo.naddr.ipv4, ainfo.naddr.bits);
+	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_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_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_0(callid, retval);
+}
+
+static void inetcfg_get_link_list_srv(ipc_callid_t callid, ipc_call_t *call)
 {
 	ipc_callid_t rcallid;
@@ -161,49 +273,4 @@
 	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, &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_link_get_srv(ipc_callid_t callid, ipc_call_t *call)
-{
-	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()");
-
-	rc = inetcfg_link_get(link_id, &linfo);
-	async_answer_0(callid, rc);
-}
-
-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()");
 
