Index: uspace/lib/c/generic/dnsr.c
===================================================================
--- uspace/lib/c/generic/dnsr.c	(revision b49d8725cc1c4a58c2affddebe1cffcc4caa6c90)
+++ uspace/lib/c/generic/dnsr.c	(revision 3e664287e034298711db95506e3d6e3f1a348b8a)
@@ -44,20 +44,19 @@
 static async_exch_t *dnsr_exchange_begin(void)
 {
-	async_sess_t *sess;
-	service_id_t dnsr_svc;
-
 	fibril_mutex_lock(&dnsr_sess_mutex);
-
+	
 	if (dnsr_sess == NULL) {
+		service_id_t dnsr_svc;
+		
 		(void) loc_service_get_id(SERVICE_NAME_DNSR, &dnsr_svc,
 		    IPC_FLAG_BLOCKING);
-
+		
 		dnsr_sess = loc_service_connect(EXCHANGE_SERIALIZE, dnsr_svc,
 		    IPC_FLAG_BLOCKING);
 	}
-
-	sess = dnsr_sess;
+	
+	async_sess_t *sess = dnsr_sess;
 	fibril_mutex_unlock(&dnsr_sess_mutex);
-
+	
 	return async_exchange_begin(sess);
 }
@@ -109,5 +108,5 @@
 
 	info->cname = str_dup(cname_buf);
-	info->addr.ipv4 = IPC_GET_ARG1(answer);
+	inet2_addr_unpack(IPC_GET_ARG1(answer), &info->addr);
 
 	*rinfo = info;
@@ -119,35 +118,49 @@
 	if (info == NULL)
 		return;
-
+	
 	free(info->cname);
 	free(info);
 }
 
-int dnsr_get_srvaddr(inet_addr_t *srvaddr)
+int dnsr_get_srvaddr(inet2_addr_t *srvaddr)
 {
-	sysarg_t addr;
 	async_exch_t *exch = dnsr_exchange_begin();
-
-	int rc = async_req_0_1(exch, DNSR_GET_SRVADDR, &addr);
-	dnsr_exchange_end(exch);
-
-	if (rc != EOK)
+	
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, DNSR_GET_SRVADDR, &answer);
+	int rc = async_data_read_start(exch, srvaddr, sizeof(inet2_addr_t));
+	
+	loc_exchange_end(exch);
+	
+	if (rc != EOK) {
+		async_forget(req);
 		return rc;
-
-	srvaddr->ipv4 = addr;
-	return EOK;
+	}
+	
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+	
+	return (int) retval;
 }
 
-int dnsr_set_srvaddr(inet_addr_t *srvaddr)
+int dnsr_set_srvaddr(inet2_addr_t *srvaddr)
 {
 	async_exch_t *exch = dnsr_exchange_begin();
-
-	int rc = async_req_1_0(exch, DNSR_SET_SRVADDR, srvaddr->ipv4);
-	dnsr_exchange_end(exch);
-
-	if (rc != EOK)
+	
+	ipc_call_t answer;
+	aid_t req = async_send_0(exch, DNSR_SET_SRVADDR, &answer);
+	int rc = async_data_write_start(exch, srvaddr, sizeof(inet2_addr_t));
+	
+	loc_exchange_end(exch);
+	
+	if (rc != EOK) {
+		async_forget(req);
 		return rc;
-
-	return EOK;
+	}
+	
+	sysarg_t retval;
+	async_wait_for(req, &retval);
+	
+	return (int) retval;
 }
 
Index: uspace/lib/c/generic/inet/addr2.c
===================================================================
--- uspace/lib/c/generic/inet/addr2.c	(revision 3e664287e034298711db95506e3d6e3f1a348b8a)
+++ uspace/lib/c/generic/inet/addr2.c	(revision 3e664287e034298711db95506e3d6e3f1a348b8a)
@@ -0,0 +1,344 @@
+/*
+ * 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 Internet address parsing and formatting.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <inet/addr2.h>
+#include <net/socket_codes.h>
+#include <net/inet.h>
+#include <stdio.h>
+
+/** Parse network address family.
+ *
+ * @param text Network address in common notation.
+ * @param af   Place to store network address family.
+ *
+ * @return EOK on success, EINVAL if input is not in valid format.
+ *
+ */
+int inet2_addr_family(const char *text, uint16_t *af)
+{
+	char *dot = str_chr(text, '.');
+	if (dot != NULL) {
+		*af = AF_INET;
+		return EOK;
+	}
+	
+	char *collon = str_chr(text, ':');
+	if (collon != NULL) {
+		*af = AF_INET6;
+		return EOK;
+	}
+	
+	*af = AF_NONE;
+	return EINVAL;
+}
+
+/** Parse node address.
+ *
+ * @param text Network address in common notation.
+ * @param addr Place to store node address.
+ *
+ * @return EOK on success, EINVAL if input is not in valid format.
+ *
+ */
+int inet2_addr_parse(const char *text, inet2_addr_t *addr)
+{
+	int rc = inet2_addr_family(text, &addr->family);
+	if (rc != EOK)
+		return rc;
+	
+	rc = inet_pton(addr->family, text, addr->addr);
+	if (rc != EOK)
+		return rc;
+	
+	return EOK;
+}
+
+/** Parse network address.
+ *
+ * @param text  Network address in common notation.
+ * @param naddr Place to store network address.
+ *
+ * @return EOK on success, EINVAL if input is not in valid format.
+ *
+ */
+int inet2_naddr_parse(const char *text, inet2_naddr_t *naddr)
+{
+	char *slash = str_chr(text, '/');
+	if (slash == NULL)
+		return EINVAL;
+	
+	*slash = 0;
+	
+	int rc = inet2_addr_family(text, &naddr->family);
+	if (rc != EOK)
+		return rc;
+	
+	rc = inet_pton(naddr->family, text, naddr->addr);
+	*slash = '/';
+	
+	if (rc != EOK)
+		return rc;
+	
+	slash++;
+	
+	switch (naddr->family) {
+	case AF_INET:
+		naddr->prefix = strtoul(slash, &slash, 10);
+		if (naddr->prefix > 32)
+			return EINVAL;
+		break;
+	case AF_INET6:
+		naddr->prefix = strtoul(slash, &slash, 10);
+		if (naddr->prefix > 128)
+			return EINVAL;
+		break;
+	default:
+		return ENOTSUP;
+	}
+	
+	return EOK;
+}
+
+/** Format node address.
+ *
+ * @param addr Node address.
+ * @param bufp Place to store pointer to formatted string.
+ *
+ * @return EOK on success.
+ * @return ENOMEM if out of memory.
+ * @return ENOTSUP on unsupported address family.
+ *
+ */
+int inet2_addr_format(inet2_addr_t *addr, char **bufp)
+{
+	int rc;
+	
+	switch (addr->family) {
+	case AF_NONE:
+		rc = asprintf(bufp, "none");
+		break;
+	case AF_INET:
+		rc = asprintf(bufp, "%u.%u.%u.%u", addr->addr[0],
+		    addr->addr[1], addr->addr[2], addr->addr[3]);
+		break;
+	case AF_INET6:
+		// FIXME TODO
+		break;
+	default:
+		return ENOTSUP;
+	}
+	
+	if (rc < 0)
+		return ENOMEM;
+	
+	return EOK;
+}
+
+/** Format network address.
+ *
+ * @param naddr Network address.
+ * @param bufp  Place to store pointer to formatted string.
+ *
+ * @return EOK on success.
+ * @return ENOMEM if out of memory.
+ * @return ENOTSUP on unsupported address family.
+ *
+ */
+int inet2_naddr_format(inet2_naddr_t *naddr, char **bufp)
+{
+	int rc;
+	
+	switch (naddr->family) {
+	case AF_NONE:
+		rc = asprintf(bufp, "none");
+		break;
+	case AF_INET:
+		rc = asprintf(bufp, "%u.%u.%u.%u/%u", naddr->addr[0],
+		    naddr->addr[1], naddr->addr[2], naddr->addr[3],
+		    naddr->prefix);
+		break;
+	case AF_INET6:
+		// FIXME TODO
+		break;
+	default:
+		return ENOTSUP;
+	}
+	
+	if (rc < 0)
+		return ENOMEM;
+	
+	return EOK;
+}
+
+/** Create packed IPv4 address
+ *
+ * Convert an IPv4 address to a packed 32 bit representation.
+ *
+ * @param addr   Source address.
+ * @param packed Place to store the packed 32 bit representation.
+ *
+ * @return EOK on success.
+ * @return EINVAL if addr is not an IPv4 address.
+ *
+ */
+int inet2_addr_pack(inet2_addr_t *addr, uint32_t *packed)
+{
+	if (addr->family != AF_INET)
+		return EINVAL;
+	
+	*packed = (addr->addr[0] << 24) | (addr->addr[1] << 16) |
+	    (addr->addr[2] << 8) | addr->addr[3];
+	return EOK;
+}
+
+/** Create packed IPv4 address
+ *
+ * Convert an IPv4 address to a packed 32 bit representation.
+ *
+ * @param naddr  Source address.
+ * @param packed Place to store the packed 32 bit representation.
+ * @param prefix Place to store the number of valid bits.
+ *
+ * @return EOK on success.
+ * @return EINVAL if addr is not an IPv4 address.
+ *
+ */
+int inet2_naddr_pack(inet2_naddr_t *naddr, uint32_t *packed, uint8_t *prefix)
+{
+	if (naddr->family != AF_INET)
+		return EINVAL;
+	
+	*packed = (naddr->addr[0] << 24) | (naddr->addr[1] << 16) |
+	    (naddr->addr[2] << 8) | naddr->addr[3];
+	*prefix = naddr->prefix;
+	
+	return EOK;
+}
+
+void inet2_addr_unpack(uint32_t packed, inet2_addr_t *addr)
+{
+	addr->family = AF_INET;
+	addr->addr[0] = (packed >> 24) & 0xff;
+	addr->addr[1] = (packed >> 16) & 0xff;
+	addr->addr[2] = (packed >> 8) & 0xff;
+	addr->addr[3] = packed & 0xff;
+}
+
+void inet2_naddr_unpack(uint32_t packed, uint8_t prefix, inet2_naddr_t *naddr)
+{
+	naddr->family = AF_INET;
+	naddr->addr[0] = (packed >> 24) & 0xff;
+	naddr->addr[1] = (packed >> 16) & 0xff;
+	naddr->addr[2] = (packed >> 8) & 0xff;
+	naddr->addr[3] = packed & 0xff;
+	naddr->prefix = prefix;
+}
+
+int inet2_addr_sockaddr_in(inet2_addr_t *addr, sockaddr_in_t *sockaddr_in)
+{
+	uint32_t packed;
+	int rc = inet2_addr_pack(addr, &packed);
+	if (rc != EOK)
+		return rc;
+	
+	sockaddr_in->sin_family = AF_INET;
+	sockaddr_in->sin_addr.s_addr = host2uint32_t_be(packed);
+	return EOK;
+}
+
+void inet2_naddr_addr(inet2_naddr_t *naddr, inet2_addr_t *addr)
+{
+	addr->family = naddr->family;
+	memcpy(addr->addr, naddr->addr, INET2_ADDR_SIZE);
+}
+
+void inet2_addr(inet2_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
+{
+	addr->family = AF_INET;
+	addr->addr[0] = a;
+	addr->addr[1] = b;
+	addr->addr[2] = c;
+	addr->addr[3] = d;
+}
+
+void inet2_naddr(inet2_naddr_t *naddr, uint8_t a, uint8_t b, uint8_t c, uint8_t d,
+    uint8_t prefix)
+{
+	naddr->family = AF_INET;
+	naddr->addr[0] = a;
+	naddr->addr[1] = b;
+	naddr->addr[2] = c;
+	naddr->addr[3] = d;
+	naddr->prefix = prefix;
+}
+
+void inet2_addr_empty(inet2_addr_t *addr)
+{
+	addr->family = 0;
+	memset(addr->addr, 0, INET2_ADDR_SIZE);
+}
+
+void inet2_naddr_empty(inet2_naddr_t *naddr)
+{
+	naddr->family = 0;
+	memset(naddr->addr, 0, INET2_ADDR_SIZE);
+	naddr->prefix = 0;
+}
+
+int inet2_addr_compare(inet2_addr_t *a, inet2_addr_t *b)
+{
+	if (a->family != b->family)
+		return 0;
+	
+	switch (a->family) {
+	case AF_INET:
+		return ((a->addr[0] == b->addr[0]) && (a->addr[1] == b->addr[1]) &&
+		    (a->addr[2] == b->addr[2]) && (a->addr[3] == b->addr[3]));
+	case AF_INET6:
+		// FIXME TODO
+		return 0;
+	default:
+		return 0;
+	}
+}
+
+int inet2_addr_is_empty(inet2_addr_t *addr)
+{
+	return (addr->family == 0);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/inetping.c
===================================================================
--- uspace/lib/c/generic/inetping.c	(revision b49d8725cc1c4a58c2affddebe1cffcc4caa6c90)
+++ uspace/lib/c/generic/inetping.c	(revision 3e664287e034298711db95506e3d6e3f1a348b8a)
@@ -79,34 +79,35 @@
 {
 	async_exch_t *exch = async_exchange_begin(inetping_sess);
-
+	
 	ipc_call_t answer;
-	aid_t req = async_send_3(exch, INETPING_SEND, sdu->src.ipv4,
-	    sdu->dest.ipv4, sdu->seq_no, &answer);
+	aid_t req = async_send_3(exch, INETPING_SEND, (sysarg_t) sdu->src,
+	    (sysarg_t) sdu->dest, sdu->seq_no, &answer);
 	sysarg_t retval = async_data_write_start(exch, sdu->data, sdu->size);
-
+	
 	async_exchange_end(exch);
-
+	
 	if (retval != EOK) {
 		async_forget(req);
 		return retval;
 	}
-
+	
 	async_wait_for(req, &retval);
 	return retval;
 }
 
-int inetping_get_srcaddr(inet_addr_t *remote, inet_addr_t *local)
+int inetping_get_srcaddr(uint32_t remote, uint32_t *local)
 {
+	async_exch_t *exch = async_exchange_begin(inetping_sess);
+	
 	sysarg_t local_addr;
-	async_exch_t *exch = async_exchange_begin(inetping_sess);
-
-	int rc = async_req_1_1(exch, INETPING_GET_SRCADDR, remote->ipv4,
+	int rc = async_req_1_1(exch, INETPING_GET_SRCADDR, (sysarg_t) remote,
 	    &local_addr);
+	
 	async_exchange_end(exch);
-
+	
 	if (rc != EOK)
 		return rc;
-
-	local->ipv4 = local_addr;
+	
+	*local = (uint32_t) local_addr;
 	return EOK;
 }
@@ -114,17 +115,16 @@
 static void inetping_ev_recv(ipc_callid_t callid, ipc_call_t *call)
 {
-	int rc;
 	inetping_sdu_t sdu;
-
-	sdu.src.ipv4 = IPC_GET_ARG1(*call);
-	sdu.dest.ipv4 = IPC_GET_ARG2(*call);
+	
+	sdu.src = IPC_GET_ARG1(*call);
+	sdu.dest = IPC_GET_ARG2(*call);
 	sdu.seq_no = IPC_GET_ARG3(*call);
-
-	rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
+	
+	int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
 		return;
 	}
-
+	
 	rc = inetping_ev_ops->recv(&sdu);
 	free(sdu.data);
Index: uspace/lib/c/generic/net/inet.c
===================================================================
--- uspace/lib/c/generic/net/inet.c	(revision b49d8725cc1c4a58c2affddebe1cffcc4caa6c90)
+++ uspace/lib/c/generic/net/inet.c	(revision 3e664287e034298711db95506e3d6e3f1a348b8a)
@@ -94,97 +94,63 @@
 }
 
+static int inet_pton4(const char *address, uint8_t *data)
+{
+	memset(data, 0, 4);
+	
+	const char *cur = address;
+	size_t i = 0;
+	
+	while (i < 4) {
+		int rc = str_uint8_t(cur, &cur, 10, false, &data[i]);
+		if (rc != EOK)
+			return rc;
+		
+		i++;
+		
+		if (*cur == 0)
+			break;
+		
+		if (*cur != '.')
+			return EINVAL;
+		
+		if (i < 4)
+			cur++;
+	}
+	
+	if ((i == 4) && (*cur != 0))
+		return EINVAL;
+	
+	return EOK;
+}
+
+static int inet_pton6(const char *address, uint8_t *data)
+{
+	// FIXME TODO
+	return ENOTSUP;
+}
+
 /** Parses the character string into the address.
  *
- *  If the string is shorter than the full address, zero bytes are added.
+ * @param[in]  family  The address family.
+ * @param[in]  address The character buffer to be parsed.
+ * @param[out] data    The address data to be filled.
  *
- *  @param[in] family	The address family.
- *  @param[in] address	The character buffer to be parsed.
- *  @param[out] data	The address data to be filled.
- *  @return		EOK on success.
- *  @return		EINVAL if the data parameter is NULL.
- *  @return		ENOENT if the address parameter is NULL.
- *  @return		ENOTSUP if the address family is not supported.
+ * @return EOK on success.
+ * @return EINVAL if the data parameter is NULL.
+ * @return ENOENT if the address parameter is NULL.
+ * @return ENOTSUP if the address family is not supported.
+ *
  */
 int inet_pton(uint16_t family, const char *address, uint8_t *data)
 {
-	/** The base number of the values. */
-	int base;
-	/** The number of bytes per a section. */
-	size_t bytes;
-	/** The number of bytes of the address data. */
-	int count;
-
-	const char *next;
-	char *last;
-	int index;
-	size_t shift;
-	unsigned long value;
-
-	if (!data)
-		return EINVAL;
-
-	/* Set processing parameters */
 	switch (family) {
 	case AF_INET:
-		count = 4;
-		base = 10;
-		bytes = 1;
-		break;
-
+		return inet_pton4(address, data);
 	case AF_INET6:
-		count = 16;
-		base = 16;
-		bytes = 4;
-		break;
-
+		return inet_pton6(address, data);
 	default:
+		/** Unknown address family */
 		return ENOTSUP;
 	}
-
-	/* Erase if no address */
-	if (!address) {
-		memset(data, 0, count);
-		return ENOENT;
-	}
-
-	/* Process string from the beginning */
-	next = address;
-	index = 0;
-	do {
-		/* If the actual character is set */
-		if (next && *next) {
-
-			/* If not on the first character */
-			if (index) {
-				/* Move to the next character */
-				++next;
-			}
-
-			/* Parse the actual integral value */
-			value = strtoul(next, &last, base);
-			/*
-			 * Remember the last problematic character
-			 * should be either '.' or ':' but is ignored to be
-			 * more generic
-			 */
-			next = last;
-
-			/* Fill the address data byte by byte */
-			shift = bytes - 1;
-			do {
-				/* like little endian */
-				data[index + shift] = value;
-				value >>= 8;
-			} while(shift --);
-
-			index += bytes;
-		} else {
-			/* Erase the rest of the address */
-			memset(data + index, 0, count - index);
-			return EOK;
-		}
-	} while (index < count);
-
-	return EOK;
 }
 
