Index: uspace/srv/net/dnsres/dns_msg.c
===================================================================
--- uspace/srv/net/dnsres/dns_msg.c	(revision f1dcf6dc78256466b2546940d33f3fea01b85904)
+++ uspace/srv/net/dnsres/dns_msg.c	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
@@ -49,4 +49,31 @@
 static uint16_t dns_uint16_t_decode(uint8_t *, size_t);
 
+static int dns_dstr_ext(char **dstr, const char *suff)
+{
+	size_t s1, s2;
+	size_t nsize;
+	char *nstr;
+
+	if (*dstr == NULL) {
+		*dstr = str_dup(suff);
+		if (*dstr == NULL)
+			return ENOMEM;
+		return EOK;
+	}
+
+	s1 = str_size(*dstr);
+	s2 = str_size(suff);
+	nsize = s1 + s2 + 1;
+
+	nstr = realloc(*dstr, nsize);
+	if (nstr == NULL)
+		return ENOMEM;
+
+	str_cpy((*dstr) + s1, nsize - s1, suff);
+
+	*dstr = nstr;
+	return EOK;
+}
+
 #include <stdio.h>
 static int dns_name_encode(char *name, uint8_t *buf, size_t buf_size,
@@ -69,5 +96,5 @@
 		c = str_decode(name, &off, STR_NO_LIMIT);
 		printf("c=%d\n", (int)c);
-		if (c > 127) {
+		if (c >= 127) {
 			/* Non-ASCII character */
 			printf("non-ascii character\n");
@@ -121,4 +148,10 @@
 	size_t ptr;
 	size_t eptr;
+	char *name;
+	char dbuf[2];
+	int rc;
+	bool first;
+
+	name = NULL;
 
 	if (boff > size)
@@ -127,8 +160,11 @@
 	bp = buf + boff;
 	bsize = min(size - boff, DNS_NAME_MAX_SIZE);
+	first = true;
+	*eoff = 0;
 
 	while (true) {
 		if (bsize == 0) {
-			return EINVAL;
+			rc = EINVAL;
+			goto error;
 		}
 
@@ -140,6 +176,12 @@
 			break;
 
-		if (bp != buf + boff + 1)
+		if (!first) {
 			printf(".");
+			rc = dns_dstr_ext(&name, ".");
+			if (rc != EOK) {
+				rc = ENOMEM;
+				goto error;
+			}
+		}
 
 		if ((lsize & 0xc0) == 0xc0) {
@@ -148,13 +190,18 @@
 			if (bsize < 1) {
 				printf("Pointer- bsize < 1\n");
-				return EINVAL;
+				rc = EINVAL;
+				goto error;
 			}
 
 			ptr = dns_uint16_t_decode(bp - 1, bsize) & 0x3fff;
+			++bp;
+			--bsize;
+
 			if (ptr >= (size_t)(bp - buf)) {
 				printf("Pointer- forward ref %u, pos=%u\n",
 				    ptr, bp - buf);
 				/* Forward reference */
-				return EINVAL;
+				rc = EINVAL;
+				goto error;
 			}
 
@@ -163,5 +210,10 @@
 			 * XXX Is assumption correct?
 			 */
-			eptr = buf - bp;
+			eptr = bp - buf;
+			/*
+			 * This is where encoded name ends in terms where
+			 * the message continues
+			 */
+			*eoff = eptr;
 
 			printf("ptr=%u, eptr=%u\n", ptr, eptr);
@@ -172,18 +224,40 @@
 
 		if (lsize > bsize) {
-			return EINVAL;
+			rc = EINVAL;
+			goto error;
 		}
 
 		for (i = 0; i < lsize; i++) {
 			printf("%c", *bp);
+
+			if (*bp < 32 || *bp >= 127) {
+				rc = EINVAL;
+				goto error;
+			}
+
+			dbuf[0] = *bp;
+			dbuf[1] = '\0';
+
+			rc = dns_dstr_ext(&name, dbuf);
+			if (rc != EOK) {
+				rc = ENOMEM;
+				goto error;
+			}
 			++bp;
 			--bsize;
 		}
+
+		first = false;
 	}
 
 	printf("\n");
 
-	*eoff = bp - buf;
-	return EOK;
+	*rname = name;
+	if (*eoff == 0)
+		*eoff = bp - buf;
+	return EOK;
+error:
+	free(name);
+	return rc;
 }
 
@@ -207,12 +281,17 @@
 
 /** Decode unaligned big-endian 32-bit integer */
-static uint16_t dns_uint32_t_decode(uint8_t *buf, size_t buf_size)
-{
+uint32_t dns_uint32_t_decode(uint8_t *buf, size_t buf_size)
+{
+	uint32_t w;
 	assert(buf_size >= 4);
 
-	return ((uint32_t)buf[0] << 24) +
+	w = ((uint32_t)buf[0] << 24) +
 	    ((uint32_t)buf[1] << 16) +
 	    ((uint32_t)buf[2] << 8) +
-	    buf[0];
+	    buf[3];
+
+	printf("dns_uint32_t_decode: %x, %x, %x, %x -> %x\n",
+	    buf[0], buf[1], buf[2], buf[3], w);
+	return w;
 }
 
@@ -304,5 +383,5 @@
 	}
 
-	printf("ok decoding name..\n");
+	printf("ok decoding name.. '%s'\n", rr->name);
 	if (name_eoff + 2 * sizeof(uint16_t) > buf_size) {
 		printf("name_eoff + 2 * 2 = %d >  buf_size = %d\n",
@@ -324,13 +403,17 @@
 	rr->rtype = dns_uint16_t_decode(bp, bsz);
 	bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
+	printf("rtype=%u\n", rr->rtype);
 
 	rr->rclass = dns_uint16_t_decode(bp, bsz);
 	bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
+	printf("rclass=%u\n", rr->rclass);
 
 	rr->ttl = dns_uint32_t_decode(bp, bsz);
 	bp += sizeof(uint32_t); bsz -= sizeof(uint32_t);
+	printf("ttl=%u\n", rr->ttl);
 
 	rdlength = dns_uint16_t_decode(bp, bsz);
 	bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
+	printf("rdlength=%u\n", rdlength);
 
 	if (rdlength > bsz) {
@@ -469,4 +552,5 @@
 		printf("ok decoding question\n");
 
+		list_append(&question->msg, &msg->question);
 		doff = field_eoff;
 	}
@@ -484,4 +568,5 @@
 		printf("ok decoding answer\n");
 
+		list_append(&rr->msg, &msg->answer);
 		doff = field_eoff;
 	}
Index: uspace/srv/net/dnsres/dns_msg.h
===================================================================
--- uspace/srv/net/dnsres/dns_msg.h	(revision f1dcf6dc78256466b2546940d33f3fea01b85904)
+++ uspace/srv/net/dnsres/dns_msg.h	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
@@ -45,4 +45,5 @@
 extern int dns_message_encode(dns_message_t *, void **, size_t *);
 extern int dns_message_decode(void *, size_t, dns_message_t **);
+extern uint32_t dns_uint32_t_decode(uint8_t *, size_t);
 
 #endif
Index: uspace/srv/net/dnsres/dns_type.h
===================================================================
--- uspace/srv/net/dnsres/dns_type.h	(revision f1dcf6dc78256466b2546940d33f3fea01b85904)
+++ uspace/srv/net/dnsres/dns_type.h	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
@@ -38,4 +38,5 @@
 
 #include <adt/list.h>
+#include <inet/inet.h>
 #include <stdbool.h>
 #include <stdint.h>
@@ -80,4 +81,5 @@
 /** Unencoded DNS resource record */
 typedef struct {
+	link_t msg;
 	/** Domain name */
 	char *name;
@@ -97,4 +99,8 @@
 /** Host information */
 typedef struct {
+	/** Host name */
+	char *name;
+	/** Host address */
+	inet_addr_t addr;
 } dns_host_info_t;
 
Index: uspace/srv/net/dnsres/dnsres.c
===================================================================
--- uspace/srv/net/dnsres/dnsres.c	(revision f1dcf6dc78256466b2546940d33f3fea01b85904)
+++ uspace/srv/net/dnsres/dnsres.c	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
@@ -35,4 +35,5 @@
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <errno.h>
 
@@ -43,12 +44,39 @@
 #define NAME  "dnsres"
 
+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;
+}
+
 int main(int argc, char *argv[])
 {
 	dns_host_info_t hinfo;
+	char *astr;
 	int rc;
 
 	printf("%s: DNS Resolution Service\n", NAME);
-	rc = dns_name2host("helenos.org", &hinfo);
+	rc = dns_name2host(argc < 2 ? "helenos.org" : argv[1], &hinfo);
 	printf("dns_name2host() -> rc = %d\n", rc);
+
+	if (rc == EOK) {
+		rc = addr_format(&hinfo.addr, &astr);
+		if (rc != EOK) {
+			printf("Out of memory\n");
+			return ENOMEM;
+		}
+
+		printf("hostname: %s\n", hinfo.name);
+		printf("IPv4 address: %s\n", astr);
+		free(astr);
+	}
 
 	return 0;
Index: uspace/srv/net/dnsres/query.c
===================================================================
--- uspace/srv/net/dnsres/query.c	(revision f1dcf6dc78256466b2546940d33f3fea01b85904)
+++ uspace/srv/net/dnsres/query.c	(revision 7262f89f382dcb4ff1d35a91b1432f6c669f70a5)
@@ -36,5 +36,7 @@
 #include <errno.h>
 #include <mem.h>
+#include <str.h>
 
+#include "dns_msg.h"
 #include "dns_std.h"
 #include "dns_type.h"
@@ -44,4 +46,5 @@
 static uint16_t msg_id;
 
+#include <stdio.h>
 int dns_name2host(const char *name, dns_host_info_t *info)
 {
@@ -72,5 +75,26 @@
 		return rc;
 
-	return EOK;
+	list_foreach(amsg->answer, link) {
+		dns_rr_t *rr = list_get_instance(link, dns_rr_t, msg);
+
+		printf(" - '%s' %u/%u, dsize %u\n",
+			rr->name, rr->rtype, rr->rclass, rr->rdata_size);
+
+		if (rr->rtype == DTYPE_A && rr->rclass == DC_IN) {
+			if (rr->rdata_size != sizeof(uint32_t)) {
+				printf("rdata_size = %u - fail\n", rr->rdata_size);
+				return EIO;
+			}
+
+			info->name = str_dup(rr->name);
+			info->addr.ipv4 = dns_uint32_t_decode(rr->rdata, rr->rdata_size);
+			printf("info->addr = %x\n", info->addr.ipv4);
+			return EOK;
+		}
+	}
+
+	printf("no A/IN found, fail\n");
+
+	return EIO;
 }
 
