diff --git a/libports/run/test-ping_client.run b/libports/run/test-ping_client.run
new file mode 100644
index 000000000..ae3f711eb
--- /dev/null
+++ b/libports/run/test-ping_client.run
@@ -0,0 +1,117 @@
+#
+# \brief Test ping
+# \author Josef Soentgen
+# \date 2013-01-06
+#
+
+#
+# Build
+#
+
+set build_components {
+ core init
+ drivers/pci drivers/timer drivers/nic
+ test/lwip/pingpong/client
+}
+
+lappend_if [have_spec omap4] build_components drivers/usb
+
+build $build_components
+
+create_boot_directory
+
+#
+# Generate config
+#
+
+set config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append_if [have_spec omap4] config {
+
+
+
+
+
+
+
+
+ }
+
+append_if [expr ![have_spec omap4]] config {
+
+
+
+ }
+
+append_if [have_spec pci] config {
+
+
+
+ }
+
+append config {
+
+}
+
+install_config $config
+
+#
+# Boot modules
+#
+
+# generic modules
+set boot_modules {
+ core init timer
+ ld.lib.so libc.lib.so lwip.lib.so
+ test-ping_client
+}
+
+# platform-specific modules
+lappend_if [have_spec pci] boot_modules pci_drv
+lappend_if [have_spec omap4] boot_modules usb_drv
+lappend_if [expr ![have_spec omap4]] boot_modules nic_drv
+
+build_boot_image $boot_modules
+
+#
+# Execute test case
+#
+
+# qemu config
+append qemu_args " -m 128 -nographic "
+
+append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
+append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
+
+append qemu_args " -net user "
+
+run_genode_until forever
+
+# vi: set ft=tcl :
diff --git a/libports/run/test-ping_server.run b/libports/run/test-ping_server.run
new file mode 100644
index 000000000..df71ada43
--- /dev/null
+++ b/libports/run/test-ping_server.run
@@ -0,0 +1,117 @@
+#
+# \brief Test pong
+# \author Josef Soentgen
+# \date 2013-01-06
+#
+
+#
+# Build
+#
+
+set build_components {
+ core init
+ drivers/pci drivers/timer drivers/nic
+ test/lwip/pingpong/server
+}
+
+lappend_if [have_spec omap4] build_components drivers/usb
+
+build $build_components
+
+create_boot_directory
+
+#
+# Generate config
+#
+
+set config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append_if [have_spec omap4] config {
+
+
+
+
+
+
+
+
+ }
+
+append_if [expr ![have_spec omap4]] config {
+
+
+
+ }
+
+append_if [have_spec pci] config {
+
+
+
+ }
+
+append config {
+
+}
+
+install_config $config
+
+#
+# Boot modules
+#
+
+# generic modules
+set boot_modules {
+ core init timer
+ ld.lib.so libc.lib.so lwip.lib.so
+ test-ping_server
+}
+
+# platform-specific modules
+lappend_if [have_spec pci] boot_modules pci_drv
+lappend_if [have_spec omap4] boot_modules usb_drv
+lappend_if [expr ![have_spec omap4]] boot_modules nic_drv
+
+build_boot_image $boot_modules
+
+#
+# Execute test case
+#
+
+# qemu config
+append qemu_args " -m 128 -nographic "
+
+append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
+append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
+
+append qemu_args " -net user "
+
+run_genode_until forever
+
+# vi: set ft=tcl :
diff --git a/libports/src/test/lwip/pingpong/README b/libports/src/test/lwip/pingpong/README
new file mode 100644
index 000000000..f87ae0c8a
--- /dev/null
+++ b/libports/src/test/lwip/pingpong/README
@@ -0,0 +1,13 @@
+Pingpong is a simple test where a client sends ping packets with different
+sizes to a server. The client has to specify the serverip in its config
+as well as the start and end of the ping packet sizes in bytes.
+
+!
+!
+!
+!
+!
+!
+
+If verbose is set 1 the client and the server will print the id and the
+size of each packet (packet header + payload size).
diff --git a/libports/src/test/lwip/pingpong/client/main.cc b/libports/src/test/lwip/pingpong/client/main.cc
new file mode 100644
index 000000000..bab82c5bc
--- /dev/null
+++ b/libports/src/test/lwip/pingpong/client/main.cc
@@ -0,0 +1,155 @@
+/*
+ * \brief Ping-client
+ * \author Josef Soentgen
+ * \date 2013-01-24
+ *
+ */
+
+/*
+ * Copyright (C) 2013 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+/* Genode includes */
+#include
+#include
+#include
+
+#include
+
+/* libc includes */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "../pingpong.h"
+
+unsigned int verbose;
+
+int
+dial(const char *addr)
+{
+ int s;
+ struct sockaddr_in in_addr;
+
+ PLOG("Create new socket...");
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (s == -1) {
+ PERR("Could not create socket!");
+ return -1;
+ }
+
+ PLOG("Connect to server %s:%d...", addr, Sport);
+ in_addr.sin_port = htons(Sport);
+ in_addr.sin_family = AF_INET;
+ in_addr.sin_addr.s_addr = inet_addr(addr);
+ if (connect(s, (struct sockaddr *)&in_addr, sizeof (in_addr)) == -1) {
+ PERR("Could not connect to server!");
+ close(s);
+ return -1;
+ }
+
+ PLOG("Sucessful connected to server.");
+
+ return s;
+}
+
+int
+sendping(const char *addr, size_t dsize)
+{
+ Packet p;
+ int s;
+ size_t i;
+ ssize_t n;
+
+ s = dial(addr);
+ if (s == -1)
+ return -1;
+
+ p.h.type = Tping;
+ p.h.dsize = dsize;
+ p.d = (char *)malloc(p.h.dsize);
+ if (p.d == NULL) {
+ PERR("Out of memory!");
+ return -1;
+ }
+
+ PINF("Try to send %d packets...", Numpackets);
+ for (i = 0; i < Numpackets; i++) {
+ forgepacket(&p, i + 1);
+
+ n = sendpacket(s, &p);
+ if (n <= 0)
+ break;
+ if (n != (sizeof (Packetheader) + p.h.dsize)) {
+ PERR("size mismatch: %ld != %lu", n, sizeof (Packetheader) + p.h.dsize);
+ break;
+ }
+
+ if (verbose)
+ PINF("%lu %ld", p.h.id, n);
+ }
+
+ close(s);
+ free(p.d);
+
+ switch (n) {
+ case 0:
+ PERR("Disconnect, sent packets: %lu", i);
+ return 0;
+ break;
+ case -1:
+ PERR("Error, sent packets: %lu", i);
+ return 1;
+ break;
+ default:
+ PINF("Sucessful, sent packets: %lu", i);
+ return 0;
+ break;
+ }
+
+ /* never reached */
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ char serverip[16];
+ unsigned int i;
+ unsigned int startsize, endsize;
+
+ /* DHCP */
+ if (lwip_nic_init(0, 0, 0)) {
+ PERR("We got no IP address!");
+ return 1;
+ }
+
+ /* default settings */
+ startsize = 1;
+ endsize = 32768;
+ verbose = 0;
+
+ Genode::Xml_node argv_node = Genode::config()->xml_node().sub_node("argv");
+ try {
+ argv_node.attribute("serverip" ).value(serverip, sizeof(serverip));
+ argv_node.attribute("startsize").value( &startsize );
+ argv_node.attribute("endsize").value( &endsize );
+ argv_node.attribute("verbose").value( &verbose );
+ } catch(...) { }
+
+ if ((endsize + sizeof (Packetheader)) > Databuf) {
+ PERR("endsize is greater than the servers' data buffer");
+ return 1;
+ }
+
+ for (i = startsize; i <= endsize; i <<= 1)
+ sendping(serverip, i);
+
+ return 0;
+}
diff --git a/libports/src/test/lwip/pingpong/client/target.mk b/libports/src/test/lwip/pingpong/client/target.mk
new file mode 100644
index 000000000..466331b17
--- /dev/null
+++ b/libports/src/test/lwip/pingpong/client/target.mk
@@ -0,0 +1,7 @@
+TARGET = test-ping_client
+LIBS = cxx env libc libc_lwip lwip
+SRC_CC = main.cc ../pingpong.cc
+
+CC_OPT_main += -fpermissive
+
+INC_DIR += $(REP_DIR)/src/lib/lwip/include
diff --git a/libports/src/test/lwip/pingpong/pingpong.cc b/libports/src/test/lwip/pingpong/pingpong.cc
new file mode 100644
index 000000000..49311526f
--- /dev/null
+++ b/libports/src/test/lwip/pingpong/pingpong.cc
@@ -0,0 +1,165 @@
+/*
+ * \brief PingPong
+ * \author Josef Soentgen
+ * \date 2013-01-24
+ *
+ */
+
+/*
+ * Copyright (C) 2013 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+/* Genode includes */
+#include
+
+/* libc includes */
+#include
+#include
+#include
+
+#include "pingpong.h"
+
+void
+forgepacket(Packet *p, uint32_t id)
+{
+ p->h.id = id;
+ p->d[p->h.dsize - 1] = (id % 128);
+
+ //PLOG("payload for %u = %u", id, (id % 128));
+}
+
+int
+checkpacket(size_t n, Packet *p)
+{
+ /* check size of received packet */
+ if (n != (sizeof (Packetheader) + p->h.dsize)) {
+ PERR("packetsize mismatch!");
+ return -1;
+ }
+
+ //PLOG("header: %u, data: %u", n - p->h.dsize, n - sizeof (Packetheader));
+
+ /* check packet type */
+ if (p->h.type != Tping) {
+ PERR("wrong packet type!");
+ return -1;
+ }
+
+ /* check payload */
+ if (p->d[p->h.dsize - 1] != (p->h.id % 128)) {
+ PERR("packet payload corrupt, expected: %d got: %d", (p->h.id % 128),
+ p->d[p->h.dsize - 1]);
+ return -1;
+ }
+
+ return 0;
+}
+
+ssize_t
+sendpacket(int s, Packet *p)
+{
+ char *b;
+ ssize_t sent, nd, nh;
+ size_t dsize;
+
+ /* send packet header */
+ b = (char *)&p->h;
+ nh = 0;
+ while (nh < sizeof (Packetheader)) {
+ sent = send(s, b + nh, sizeof (Packetheader) - nh, 0);
+ switch (sent) {
+ case -1:
+ PERR("send(Packetheader) == -1");
+ return nh;
+ break;
+ case 0:
+ PERR("send(Packetheader) == 0, connection closed");
+ return nh;
+ break;
+ default:
+ nh += sent;
+ }
+ }
+
+ /* sent packet data */
+ b = (char *)p->d;
+ dsize = p->h.dsize; // save data length
+ nd = 0;
+ while (nd < dsize) {
+ sent = send(s, b + nd, dsize - nd, 0);
+ switch (sent) {
+ case -1:
+ PERR("send(data) == -1");
+ return nd;
+ break;
+ case 0:
+ PERR("send(data) == 0, connection closed");
+ return nd;
+ break;
+ default:
+ nd += sent;
+ }
+ }
+
+ return nh + nd;
+}
+
+ssize_t
+recvpacket(int s, Packet *p, char *dbuf, size_t ldbuf)
+{
+ char *b;
+ ssize_t r, nd, nh;
+ size_t dsize;
+
+ /* recv packet header */
+ b = (char *)&p->h;
+ nh = 0;
+ while (nh < sizeof (Packetheader)) {
+ r = recv(s, b + nh, sizeof (Packetheader) - nh, 0);
+ switch (r) {
+ case -1:
+ PERR("recv(Packetheader) == -1");
+ return nh;
+ break;
+ case 0:
+ /* disconnect */
+ PERR("recv(Packetheader) == 0, connection closed");
+ return nh;
+ break;
+ default:
+ nh += r;
+ break;
+ }
+ }
+
+ if (p->h.dsize > ldbuf) {
+ PERR("packet payload is too large for dbuf!");
+ return -1;
+ }
+
+ /* receive packet data */
+ dsize = p->h.dsize;
+ nd = 0;
+ while (nd < dsize) {
+ r = recv(s, dbuf + nd, dsize - nd, 0);
+ switch (r) {
+ case -1:
+ PERR("recv(data) == -1");
+ return nh + nd;
+ break;
+ case 0:
+ /* disconnect */
+ PERR("recv(data) == 0, connection closed");
+ return nh + nd;
+ break;
+ default:
+ nd += r;
+ break;
+ }
+ }
+
+ return nh + nd;
+}
diff --git a/libports/src/test/lwip/pingpong/pingpong.h b/libports/src/test/lwip/pingpong/pingpong.h
new file mode 100644
index 000000000..708aa3ee7
--- /dev/null
+++ b/libports/src/test/lwip/pingpong/pingpong.h
@@ -0,0 +1,48 @@
+/*
+ * \brief PingPong
+ * \author Josef Soentgen
+ * \date 2013-01-24
+ *
+ */
+
+/*
+ * Copyright (C) 2013 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+#ifndef _PINGPONG_H_
+#define _PINGPONG_H_
+
+enum {
+ Databuf = 1024 * 1024, // data buffer for server
+ Numpackets = 1024,
+ Pdata = 16384,
+ Sport = 10000,
+ Tping = 1,
+ Tpong = 2
+};
+
+typedef struct Packetheader Packetheader;
+struct Packetheader
+{
+ uint32_t type; // packet type
+ uint32_t id; // packet id
+ uint32_t dsize; // data size
+};
+
+typedef struct Packet Packet;
+struct Packet
+{
+ Packetheader h;
+ char *d;
+};
+
+void forgepacket(Packet *, uint32_t);
+int checkpacket(size_t, Packet *);
+
+ssize_t sendpacket(int, Packet *);
+ssize_t recvpacket(int, Packet *, char *, size_t);
+
+#endif /* _PINGPONG_H_ */
diff --git a/libports/src/test/lwip/pingpong/server/main.cc b/libports/src/test/lwip/pingpong/server/main.cc
new file mode 100644
index 000000000..072b13911
--- /dev/null
+++ b/libports/src/test/lwip/pingpong/server/main.cc
@@ -0,0 +1,160 @@
+/*
+ * \brief Ping-server
+ * \author Josef Soentgen
+ * \date 2013-01-24
+ *
+ */
+
+/*
+ * Copyright (C) 2013 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+/* Genode includes */
+#include
+#include
+#include
+
+#include
+
+/* libc includes */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "../pingpong.h"
+
+unsigned int verbose;
+
+int
+announce(const char *addr)
+{
+ int s;
+ struct sockaddr_in in_addr;
+
+ PLOG("Create new socket...");
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (s == -1) {
+ PERR("Could not create socket!");
+ return -1;
+ }
+
+ PLOG("Bind socket to %d", Sport);
+ in_addr.sin_port = htons(Sport);
+ in_addr.sin_family = AF_INET;
+ in_addr.sin_addr.s_addr = inet_addr(addr);
+ if ( bind(s, (struct sockaddr *)&in_addr, sizeof (in_addr)) == -1) {
+ PERR("Could not bind!");
+ close(s);
+ return -1;
+ }
+
+ return s;
+}
+
+int
+recvping(const char *addr)
+{
+ int s, c;
+
+ struct sockaddr caddr;
+ socklen_t lcaddr = sizeof (caddr);
+
+ s = announce(addr);
+ if (s == -1)
+ return -1;
+
+ PLOG("Listen on %s:%d...", addr, Sport);
+ if (listen(s, 5) == -1) {
+ PERR("Could not listen!");
+ close(s);
+ return -1;
+ }
+
+ while (1) {
+ Packet p;
+ int act;
+ size_t packets;
+ ssize_t n;
+
+ PINF("wait...");
+ c = accept(s, &caddr, &lcaddr);
+ if (c == -1) {
+ PERR("Invalid socket from accept()!");
+ continue;
+ }
+ PLOG("client %d connected...", c);
+
+ p.d = (char *)malloc(Databuf);
+ if (p.d == NULL) {
+ PERR("Out of memeory!");
+ close(c);
+ break;
+ }
+
+ /* receive packets from client */
+ act = 1; packets = 0;
+ while (act) {
+ n = recvpacket(c, &p, p.d, Databuf);
+ switch (n) {
+ case -1:
+ /* error */
+ PERR("recvpacket() == -1");
+ case 0:
+ /* disconnect */
+ PERR("disconnect");
+ close(c);
+ act = 0;
+ break;
+ default:
+ /* check if packet is vaid */
+ if (checkpacket(n, &p)) {
+ act = 0;
+ }
+ break;
+ }
+
+ if (verbose)
+ PINF("%u %d", p.h.id, n);
+ }
+ PINF("received packets: %u", packets);
+
+ free(p.d);
+ }
+
+ close(s);
+
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ char listenip[16];
+
+ /* DHCP */
+ if (lwip_nic_init(0, 0, 0)) {
+ PERR("We got no IP address!");
+ return 1;
+ }
+
+ verbose = 0;
+
+ Genode::Xml_node argv_node = Genode::config()->xml_node().sub_node("argv");
+ try {
+ argv_node.attribute("listenip" ).value(listenip, sizeof(listenip));
+ argv_node.attribute("verbose").value( &verbose );
+ } catch(...) {
+ PERR("listenip was not specified!");
+ return 1;
+ }
+
+ recvping(listenip);
+
+ return 0;
+}
diff --git a/libports/src/test/lwip/pingpong/server/target.mk b/libports/src/test/lwip/pingpong/server/target.mk
new file mode 100644
index 000000000..97b11e46c
--- /dev/null
+++ b/libports/src/test/lwip/pingpong/server/target.mk
@@ -0,0 +1,7 @@
+TARGET = test-ping_server
+LIBS = cxx env libc libc_lwip lwip
+SRC_CC = main.cc ../pingpong.cc
+
+CC_OPT_main += -fpermissive
+
+INC_DIR += $(REP_DIR)/src/lib/lwip/include