Index: uspace/srv/ethip/ethip.c
===================================================================
--- uspace/srv/ethip/ethip.c	(revision 56792a28217fbe064b9add02d38aa3a08d123212)
+++ uspace/srv/ethip/ethip.c	(revision 1cc8b424862f4775586f9c159c55435151abadac)
@@ -223,5 +223,5 @@
 		break;
 	default:
-		log_msg(LVL_DEBUG, "Unknown ethertype %" PRIu16,
+		log_msg(LVL_DEBUG, "Unknown ethertype 0x%" PRIx16,
 		    frame.etype_len);
 	}
Index: uspace/srv/ethip/pdu.c
===================================================================
--- uspace/srv/ethip/pdu.c	(revision 56792a28217fbe064b9add02d38aa3a08d123212)
+++ uspace/srv/ethip/pdu.c	(revision 1cc8b424862f4775586f9c159c55435151abadac)
@@ -49,4 +49,5 @@
 
 /** Encode Ethernet PDU. */
+#include <stdio.h>
 int eth_pdu_encode(eth_frame_t *frame, void **rdata, size_t *rsize)
 {
@@ -69,4 +70,14 @@
 	    frame->size);
 
+	log_msg(LVL_DEBUG, "Encoding Ethernet frame src=%llx dest=%llx etype=%x",
+	    frame->src, frame->dest, frame->etype_len);
+	log_msg(LVL_DEBUG, "Encoded Ethernet frame (%zu bytes)", size);
+	size_t i;
+	for (i = 0; i < size; i++) {
+		printf("%02x ", ((uint8_t *)(data))[sizeof(eth_header_t) + i]);
+	}
+	printf("\n");
+
+
 	*rdata = data;
 	*rsize = size;
@@ -101,7 +112,7 @@
 	    frame->size);
 
-	log_msg(LVL_DEBUG, "Ethernet frame src=%llx dest=%llx etype=%x",
+	log_msg(LVL_DEBUG, "Decoding Ethernet frame src=%llx dest=%llx etype=%x",
 	    frame->src, frame->dest, frame->etype_len);
-	log_msg(LVL_DEBUG, "Ethernet frame payload (%zu bytes)", frame->size);
+	log_msg(LVL_DEBUG, "Decoded Ethernet frame payload (%zu bytes)", frame->size);
 	size_t i;
 	for (i = 0; i < frame->size; i++) {
@@ -200,5 +211,5 @@
 	}
 
-	if (uint16_t_be2host(pfmt->proto_addr_space) != ETYPE_IP) {
+	if (uint16_t_be2host(pfmt->proto_addr_space) != 0x0800) {
 		log_msg(LVL_DEBUG, "Proto address space != %u (%" PRIu16 ")",
 		    ETYPE_IP, uint16_t_be2host(pfmt->proto_addr_space));
Index: uspace/srv/inet/pdu.c
===================================================================
--- uspace/srv/inet/pdu.c	(revision 56792a28217fbe064b9add02d38aa3a08d123212)
+++ uspace/srv/inet/pdu.c	(revision 1cc8b424862f4775586f9c159c55435151abadac)
@@ -39,4 +39,5 @@
 #include <byteorder.h>
 #include <errno.h>
+#include <fibril_synch.h>
 #include <io/log.h>
 #include <mem.h>
@@ -46,4 +47,45 @@
 #include "inet_std.h"
 #include "pdu.h"
+
+static FIBRIL_MUTEX_INITIALIZE(ip_ident_lock);
+static uint16_t ip_ident = 0;
+
+#define INET_CHECKSUM_INIT 0xffff
+
+/** 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);
+}
+
+static 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.
@@ -56,4 +98,10 @@
 	size_t hdr_size;
 	size_t data_offs;
+	uint16_t chksum;
+	uint16_t ident;
+
+	fibril_mutex_lock(&ip_ident_lock);
+	ident = ++ip_ident;
+	fibril_mutex_unlock(&ip_ident_lock);
 
 	hdr_size = sizeof(ip_header_t);
@@ -69,5 +117,5 @@
 	hdr->tos = packet->tos;
 	hdr->tot_len = host2uint16_t_be(size);
-	hdr->id = host2uint16_t_be(42);
+	hdr->id = host2uint16_t_be(ident);
 	hdr->flags_foff = host2uint16_t_be(packet->df ?
 	    BIT_V(uint16_t, FF_FLAG_DF) : 0);
@@ -78,4 +126,7 @@
 	hdr->dest_addr = host2uint32_t_be(packet->dest.ipv4);
 
+	chksum = inet_checksum_calc(INET_CHECKSUM_INIT, (void *)hdr, hdr_size);
+	hdr->chksum = host2uint16_t_be(chksum);
+
 	memcpy((uint8_t *)data + data_offs, packet->data, packet->size);
 
