diff --git a/os/run/network_test_nic.inc b/os/run/network_test_nic.inc
new file mode 100644
index 0000000000..0f0ec6e019
--- /dev/null
+++ b/os/run/network_test_nic.inc
@@ -0,0 +1,262 @@
+#
+# \brief Nic performance test
+# \author Alexander Boettcher
+# \date 2013-03-26
+#
+
+if {[have_spec linux]} {
+ puts "Run script does not support Linux."; exit 0 }
+
+#
+# Build
+#
+
+set build_components {
+ core init
+ drivers/pci drivers/timer drivers/nic
+}
+
+lappend_if [expr [have_spec omap4] || [have_spec exynos5]] build_components drivers/usb
+lappend_if [expr [have_spec omap4] || [have_spec exynos5]] build_components drivers/usb_net_stat
+lappend_if [have_spec acpi] build_components drivers/acpi
+lappend_if [have_spec pci] build_components drivers/pci/device_pd
+lappend_if [have_spec x86] build_components drivers/nic_stat
+
+lappend_if $use_nic_client build_components test/nic_raw
+lappend_if $use_nic_bridge build_components server/nic_bridge
+
+#
+# Choose network driver
+#
+if {[expr $use_nic_client && ([have_spec omap4] || [have_spec exynos5])]} {
+ set network_driver "usb_drv" }
+if {[expr !$use_nic_client && ([have_spec omap4] || [have_spec exynos5])]} {
+ set network_driver "usb_drv_net_stat" }
+if {[expr $use_nic_client && ![have_spec omap4] && ![have_spec exynos5]]} {
+ set network_driver "nic_drv" }
+if {[expr !$use_nic_client && ![have_spec omap4] && ![have_spec exynos5]]} {
+ set network_driver "nic_drv_stat" }
+
+build $build_components
+
+create_boot_directory
+
+#
+# Generate config
+#
+
+set config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append_if [expr [have_spec omap4] || [have_spec exynos5]] config "
+
+
+
+
+
+
+
+
+ "
+
+append_if [expr ![have_spec omap4] && ![have_spec exynos5]] config "
+
+
+
+ "
+
+append_if $use_nic_bridge config {
+
+
+
+
+ }
+append_if $use_nic_bridge config "
+ "
+append_if $use_nic_bridge config {
+
+
+
+ }
+
+append_if $use_nic_client config {
+
+
+ }
+append_if [expr $use_nic_client && $use_nic_bridge] config {
+ }
+append_if $use_nic_client config {
+
+
+ }
+
+append_if [have_spec acpi] config {
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append_if [expr ![have_spec acpi] && [have_spec pci]] config {
+
+
+
+ }
+
+append config {
+
+}
+
+install_config $config
+
+#
+# Boot modules
+#
+
+# generic modules
+set boot_modules {
+ core init timer
+}
+
+lappend_if $use_nic_client boot_modules test-nic_raw
+lappend_if $use_nic_bridge boot_modules nic_bridge
+
+# platform-specific modules
+lappend_if [have_spec acpi] boot_modules acpi_drv
+lappend_if [have_spec pci] boot_modules pci_drv
+lappend_if [expr [have_spec omap4] || [have_spec exynos5]] boot_modules usb_drv
+lappend_if [expr [have_spec omap4] || [have_spec exynos5]] boot_modules usb_drv_net_stat
+lappend_if [expr ![have_spec omap4] && ![have_spec exynos5]] boot_modules nic_drv
+lappend_if [expr ![have_spec omap4] && ![have_spec exynos5]] boot_modules nic_drv_stat
+lappend_if [have_spec nova] boot_modules pci_device_pd
+
+build_boot_image $boot_modules
+
+# build the test client
+set test_client_dir $genode_dir/os/src/lib/net
+if {![file exists bin/nic_drv_test_client]} {
+ exec g++ -Wall -o bin/nic_drv_test_client $test_client_dir/stat-client.cc
+}
+# set appropriate rights to create raw sockets
+set cap_rights [exec getcap bin/nic_drv_test_client]
+if {![regexp cap_net_raw $cap_rights]} {
+ set sudo_command "sudo setcap cap_net_raw=ep bin/nic_drv_test_client"
+ puts "For sending raw packets cap_net_raw permission are required."
+ puts "Trying to execute: '$sudo_command'"
+ eval "exec $sudo_command"
+}
+
+#
+# Execute test case
+#
+
+if {[expr [have_spec omap4] || [have_spec exynos5]]} {
+ run_genode_until {announces service "Nic"} 30
+ set serial_id $spawn_id
+
+ set match_string "Using configured mac: "
+
+ sleep 10
+} else {
+ set match_string {--- get MAC address }
+ run_genode_until "$match_string.*\n" 30
+ set serial_id $spawn_id
+
+ sleep 2
+
+}
+
+# remember output string, will be overwritten by next run_genode_until
+set mac_string $output
+
+if {$use_nic_client} {
+ # wait until client become ready
+ if {![regexp {ready to receive packets} $output]} {
+ run_genode_until {ready to receive packets} 10 $serial_id
+ }
+}
+
+if {$use_nic_bridge} {
+ set match_string "mac: "
+ if {![regexp "$match_string.*\n" $output]} {
+ run_genode_until "$match_string.*\n" 10 $serial_id
+ }
+}
+
+grep_output $match_string
+unify_output {[\r\n\t]+} ""
+unify_output {[\033]\[0m} ""
+
+set pos [string first $match_string $mac_string]
+set mac_addr [string replace $mac_string 0 [expr $pos + [string length $match_string] - 1]]
+
+#
+# Start test with different packet size
+#
+set test_result ""
+set packet_size_list [list 64 128 256 512 1024 1500]
+foreach packet_size $packet_size_list {
+ set packet_count [expr 200 * 1024 * 1024 / $packet_size]
+
+ set time_start [clock milliseconds]
+ spawn bin/nic_drv_test_client eth0 $mac_addr $packet_size $packet_count
+ set test_app_id $spawn_id
+ interact $test_app_id
+
+ run_genode_until "packets dropped.*\n" 15 $serial_id
+ run_genode_until "packets dropped.*\n" 70 $serial_id
+ set time_end [clock milliseconds]
+
+ set target_data [regexp -inline {[0-9]+ kiBytes} $output]
+ set target_data [regexp -inline {[0-9]+} $target_data]
+
+ set match_string {[0-9]+ kBit/s \(raw [0-9]+ kBit/s\), runtime [0-9]+ ms}
+ set target_perf [regexp -inline $match_string $output]
+ set target_perf [regexp -all -inline {[0-9]+} $target_perf]
+ set target_runtime [lindex $target_perf 2]
+ set target_perf [lindex $target_perf 0]
+
+ set host_data [expr $packet_count * $packet_size / 1024 ]
+# set host_perf [expr $host_data * 1024 * 8 / ($time_end - $time_start)]
+ set host_perf [expr $target_data * 1024 * 8 / ($time_end - $time_start)]
+
+ puts "host : data send - $host_data kiBytes"
+ puts "target: data received - $target_data kiBytes"
+ puts "host : runtime [expr $time_end - $time_start] ms $host_perf kBit/s"
+ puts "target: runtime $target_runtime ms $target_perf kBit/s"
+ puts "! PERF: rx_$packet_size [expr $host_perf / 1000] MBit/s ok"
+ set test_result "$test_result rx_$packet_size:$host_perf"
+}
+close -i $serial_id
+
+puts ""
+puts "Test succeeded"
+
+# vi: set ft=tcl :
diff --git a/os/run/network_test_nic.run b/os/run/network_test_nic.run
new file mode 100644
index 0000000000..a32bbfdbf1
--- /dev/null
+++ b/os/run/network_test_nic.run
@@ -0,0 +1,14 @@
+source ${genode_dir}/os/run/network_test_nic_raw.run
+set test_result_raw $test_result
+
+source ${genode_dir}/os/run/network_test_nic_raw_client.run
+set test_result_raw_client $test_result
+
+source ${genode_dir}/os/run/network_test_nic_raw_bridge_client.run
+set test_result_raw_bridge_client $test_result
+
+puts "\nTest results:\n"
+puts "nic : $test_result_raw"
+puts "nic+client : $test_result_raw_client"
+puts "nic+bridge+client: $test_result_raw_bridge_client"
+puts ""
diff --git a/os/run/network_test_nic_raw.run b/os/run/network_test_nic_raw.run
new file mode 100644
index 0000000000..72a6a83841
--- /dev/null
+++ b/os/run/network_test_nic_raw.run
@@ -0,0 +1,4 @@
+set use_nic_client 0
+set use_nic_bridge 0
+
+source ${genode_dir}/os/run/network_test_nic.inc
diff --git a/os/run/network_test_nic_raw_bridge_client.run b/os/run/network_test_nic_raw_bridge_client.run
new file mode 100644
index 0000000000..53173d1b3b
--- /dev/null
+++ b/os/run/network_test_nic_raw_bridge_client.run
@@ -0,0 +1,4 @@
+set use_nic_client 1
+set use_nic_bridge 1
+
+source ${genode_dir}/os/run/network_test_nic.inc
diff --git a/os/run/network_test_nic_raw_client.run b/os/run/network_test_nic_raw_client.run
new file mode 100644
index 0000000000..6be00f6753
--- /dev/null
+++ b/os/run/network_test_nic_raw_client.run
@@ -0,0 +1,4 @@
+set use_nic_client 1
+set use_nic_bridge 0
+
+source ${genode_dir}/os/run/network_test_nic.inc
diff --git a/os/src/lib/net/stat-client.cc b/os/src/lib/net/stat-client.cc
new file mode 100644
index 0000000000..5d6483b98f
--- /dev/null
+++ b/os/src/lib/net/stat-client.cc
@@ -0,0 +1,190 @@
+/*
+ * \brief Send a raw Ethernet frame
+ * \author Alexander Boettcher
+ * \date 2013-04-02
+ *
+ */
+
+/*
+ * Copyright (C) 2013-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.
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+enum {
+ FRAG_DONT = 0x40,
+
+ IP_VERSION = 4,
+ IP_HEADER_LENGTH = 5, /* 5 * 4Bytes */
+
+ PROTOCOL_IP_UDP = 17,
+
+ PACKET_BUFFER = 4096,
+ };
+
+static unsigned short checksum(unsigned short * data, unsigned short count) {
+ unsigned short result = 0;
+
+ for (unsigned i=0; i < count; i++) {
+ result += htons(data[i]);
+ }
+
+ return ~result;
+}
+
+int main(int argc, char **argv)
+{
+ const char * net_if_name = argv[1];
+ const char * net_mac_dst = argv[2];
+ struct ifreq net_if, net_mac_src;
+
+ if (argc < 5 || strlen(net_mac_dst) < 17) {
+ printf("argument missing\n");
+ printf("usage: ' '"
+ " - e.g. 'eth0 2e:60:90:0c:4e:01 256 65536'\n");
+ return 1;
+ }
+
+ unsigned long const packet_size = atol(argv[3]);
+ unsigned long const packet_count = atol(argv[4]);
+
+ char packet[PACKET_BUFFER];
+ memset(packet, 0, sizeof(packet));
+
+ if (packet_size < 64 || packet_size > sizeof(packet)) {
+ printf("packet size must be in the range of 64 - %lu\n",
+ sizeof(packet));
+ return 1;
+ }
+ printf("sending %lu packets a %lu Bytes via %s network interface\n",
+ packet_count, packet_size, net_if_name);
+
+ int const sock_fd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
+ if (sock_fd < 0) {
+ perror("socket d");
+ return 2;
+ }
+
+ /* get network interface */
+ memset(&net_if, 0, sizeof(net_if));
+ strncpy(net_if.ifr_name, net_if_name, strlen(net_if_name));
+ if (ioctl(sock_fd, SIOCGIFINDEX, &net_if)) {
+ perror("ioctl SIOCGIFINDEX");
+ return 3;
+ }
+
+ /* get mac of network interface */
+ memset(&net_mac_src, 0, sizeof(net_mac_src));
+ strncpy(net_mac_src.ifr_name, net_if_name, strlen(net_if_name));
+ if (ioctl(sock_fd, SIOCGIFHWADDR, &net_mac_src)) {
+ perror("ioctl SIOCGIFHWADDR");
+ return 4;
+ }
+
+ struct ether_header *eh = (struct ether_header *) packet;
+
+ /* create ethernet frame */
+ memcpy(eh->ether_shost, net_mac_src.ifr_hwaddr.sa_data, ETH_ALEN);
+ for (unsigned i=0; i < ETH_ALEN; i++)
+ eh->ether_dhost[i] = strtoul(&net_mac_dst[i*3], 0, 16);
+ eh->ether_type = htons(ETH_P_IP);
+
+ /* debugging */
+ if (true) {
+ printf("%02x", eh->ether_shost[0]);
+ for (unsigned i=1; i < ETH_ALEN; i++)
+ printf(":%02x", eh->ether_shost[i]);
+
+ printf(" -> %02x", eh->ether_dhost[0]);
+ for (unsigned i=1; i < ETH_ALEN; i++)
+ printf(":%02x", eh->ether_dhost[i]);
+ printf("\n");
+ }
+
+ /* create IP frame */
+ struct iphdr *ip = (struct iphdr *) (packet + sizeof(struct ether_header));
+
+ ip->version = IP_VERSION;
+ ip->ihl = IP_HEADER_LENGTH;
+ ip->protocol = PROTOCOL_IP_UDP;
+/*
+ ip->daddr = (10U) | (65U << 24);
+ ip->saddr = (10U) | (22U << 24);
+*/
+ ip->tot_len = htons(packet_size - ((char *)ip - packet));
+ ip->ttl = 10;
+ ip->frag_off = FRAG_DONT;
+
+ ip->check = htons(checksum((unsigned short *)ip,
+ sizeof(*ip) / sizeof(unsigned short)));
+
+ /* setup UDP header */
+ struct udphdr *udp = (struct udphdr *) (ip + 1);
+ udp->source = htons(7321);
+ udp->dest = htons(7323);
+
+ /* add UDP data */
+ char * data = (char *) (udp + 1);
+ char txt_magic[] = "Hello world! Genode is greeting.";
+ memcpy(data, txt_magic, sizeof(txt_magic));
+
+ int len = data + sizeof(txt_magic) - packet;
+ udp->len = htons(len - ((char *)udp - packet));
+
+ if ((len + 0UL) > sizeof(packet)) {
+ printf("packet size larger then buffer %d > %lu\n", len, sizeof(packet));
+ return 5;
+ }
+
+ /* send packet */
+ struct sockaddr_ll socket_address;
+ socket_address.sll_ifindex = net_if.ifr_ifindex;
+ socket_address.sll_halen = ETH_ALEN;
+ memcpy(socket_address.sll_addr, net_mac_dst, ETH_ALEN);
+
+ int res = sendto(sock_fd, packet, len, 0, (struct sockaddr*)&socket_address,
+ sizeof(struct sockaddr_ll));
+ if (res != len) {
+ perror("sending packet - start");
+ return 6;
+ }
+ memset(data, 0, sizeof(txt_magic));
+
+ for (unsigned long j=0; j < packet_count;j++)
+ {
+ res = sendto(sock_fd, packet, packet_size, 0,
+ (struct sockaddr*)&socket_address,
+ sizeof(struct sockaddr_ll));
+ }
+
+ memcpy(data, txt_magic, sizeof(txt_magic));
+
+ usleep (5000);
+ res = sendto(sock_fd, packet, len, 0, (struct sockaddr*)&socket_address,
+ sizeof(struct sockaddr_ll));
+ if (res != len) {
+ perror("sending packet - end");
+ return 6;
+ }
+
+ printf("send %lu packets a %lu Bytes = %lu kiBytes\n",
+ packet_count, packet_size,
+ packet_count / 1024 * packet_size);
+}