diff --git a/sys/Makefile b/sys/Makefile
index 9f26e4a4e28252caac3d073e4137ffc208588468..1f85bbf815bdf7b8a0e3b340b6f8b198be59f9cf 100644
--- a/sys/Makefile
+++ b/sys/Makefile
@@ -13,6 +13,9 @@ endif
 ifneq (,$(filter net_if,$(USEMODULE)))
     DIRS += net/link_layer/net_if
 endif
+ifneq (,$(filter l2_ping,$(USEMODULE)))
+    DIRS += net/link_layer/ping
+endif
 ifneq (,$(filter transport_layer,$(USEMODULE)))
 	USEMODULE += udp
 	USEMODULE += tcp
diff --git a/sys/Makefile.include b/sys/Makefile.include
index 31f4f1bb41dc5384316880e0c077253b0e38c3ee..45986e0f8bd0a20ff47c5041033a23b060fdb359 100644
--- a/sys/Makefile.include
+++ b/sys/Makefile.include
@@ -37,6 +37,9 @@ endif
 ifneq (,$(filter ieee802154,$(USEMODULE)))
     USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
 endif
+ifneq (,$(filter l2_ping,$(USEMODULE)))
+    USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
+endif
 ifneq (,$(filter ccn_lite,$(USEMODULE)))
     USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
     USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/ccn_lite
diff --git a/sys/include/ping.h b/sys/include/ping.h
deleted file mode 100644
index a6ec62319c45427d617d3cd2d29c264247a2fdea..0000000000000000000000000000000000000000
--- a/sys/include/ping.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2010 Freie Universität Berlin
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- */
-
-
-/**
- * @defgroup    sys_ping Ping
- * @ingroup     sys
- * @brief       Ping
- */
-
-#include "radio/radio.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void init_payload(void);
-void ping_init(protocol_t protocol, uint8_t channr, radio_address_t addr);
-void ping(radio_address_t addr, uint8_t channr);
-void calc_rtt(void);
-void print_success(void);
-void print_failed(void);
-void gpio_n_timer_init(void);
-void adjust_timer(void);
-static void ping_handler(void *payload, int payload_size,
-                         packet_info_t *packet_info);
-static void pong_handler(void *payload, int payload_size,
-                         packet_info_t *packet_info);
-void pong(uint16_t src);
-
-typedef struct pong {
-    int hopcount;
-    int ttl;
-    radio_address_t radio_address;
-} ping_r;
-
-typedef struct ping_payload {
-    char *payload;
-} ping_payload;
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/sys/net/include/ping.h b/sys/net/include/ping.h
new file mode 100644
index 0000000000000000000000000000000000000000..2ca378de33bbc99785c3bea13954fad57d3598fa
--- /dev/null
+++ b/sys/net/include/ping.h
@@ -0,0 +1,31 @@
+
+/**
+ * @defgroup    sys_ping Ping
+ * @ingroup     sys
+ * @brief       Ping
+ */
+
+#include "radio/radio.h"
+
+#define RCV_BUFFER_SIZE     (64)
+#define RADIO_STACK_SIZE    (KERNEL_CONF_STACKSIZE_DEFAULT)
+#define PING_PAYLOAD    (8)
+
+typedef enum {
+    L2_PING,
+    L2_PONG
+} l2_ping_type_t;
+
+void ping_init(void);
+void ping(radio_address_t addr);
+
+typedef struct pong {
+    int hopcount;
+    int ttl;
+    radio_address_t radio_address;
+} ping_r;
+
+typedef struct ping_payload {
+    uint8_t type;
+    char payload[PING_PAYLOAD];
+} ping_payload;
diff --git a/sys/ping/Makefile b/sys/net/link_layer/ping/Makefile
similarity index 64%
rename from sys/ping/Makefile
rename to sys/net/link_layer/ping/Makefile
index 48422e909a47d7cd428d10fa73825060ccc8d8c2..9e5ec0eaca273289cd9128b9adc24dd7982f775c 100644
--- a/sys/ping/Makefile
+++ b/sys/net/link_layer/ping/Makefile
@@ -1 +1,3 @@
+MODULE := l2_ping
+
 include $(RIOTBASE)/Makefile.base
diff --git a/sys/net/link_layer/ping/ping.c b/sys/net/link_layer/ping/ping.c
new file mode 100644
index 0000000000000000000000000000000000000000..37523385b2a77f979deddddb3eeb47ab82e2a670
--- /dev/null
+++ b/sys/net/link_layer/ping/ping.c
@@ -0,0 +1,154 @@
+/**
+ * Ping: low level ping pong
+ *
+ * Copyright (C) 2013, Igor Merkulow <igor.merkulow@gmail.com>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser General
+ * Public License. See the file LICENSE in the top level directory for more
+ * details.
+ */
+
+/**
+ * @file
+ * @author Igor Merkulow <igor.merkulow@gmail.com>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "thread.h"
+#include "msg.h"
+
+#include "transceiver.h"
+#include "radio/types.h"
+#include "vtimer.h"
+#include "timex.h"
+#include "ping.h"
+
+static void send_l2_packet(radio_address_t dst, l2_ping_type_t type);
+static void pong(radio_address_t src);
+static void *pkt_handler(void *unused);
+static void ping_handler(packet_info_t *packet_info);
+static void pong_handler(void);
+static void print_success(void);
+static void print_failed(void);
+static void calc_rtt(void);
+
+char radio_stack_buffer[RADIO_STACK_SIZE];
+msg_t msg_q[RCV_BUFFER_SIZE];
+
+ping_payload pipa;
+timex_t start;
+float rtt = 0;
+
+void ping_handler(packet_info_t *packet_info)
+{
+    pong(packet_info->phy_src);
+}
+
+void ping_init(void)
+{
+    kernel_pid_t radio_pid = thread_create(radio_stack_buffer,
+                                           RADIO_STACK_SIZE, PRIORITY_MAIN - 2,
+                                           CREATE_STACKTEST, pkt_handler, NULL,
+                                           "l2_ping_handler");
+    uint16_t transceivers = TRANSCEIVER_DEFAULT;
+
+    transceiver_init(transceivers);
+    (void) transceiver_start();
+    transceiver_register(transceivers, radio_pid);
+}
+
+void ping(radio_address_t addr)
+{
+    while (1) {
+        vtimer_now(&start);
+
+        send_l2_packet(addr, L2_PING);
+        vtimer_usleep(500 * 1000);
+    }
+}
+
+static void pkt_handler(void)
+{
+    (void) unused;
+
+    msg_t m;
+    radio_packet_t *p;
+
+    msg_init_queue(msg_q, sizeof(msg_q));
+
+    while (1) {
+        msg_receive(&m);
+
+        if (m.type == PKT_PENDING) {
+            p = (radio_packet_t *) m.content.ptr;
+
+            p->processing--;
+        }
+        else if (m.type == ENOBUFFER) {
+            puts("Transceiver buffer full");
+        }
+        else {
+            puts("Unknown packet received");
+        }
+    }
+
+    return NULL;
+}
+
+static void calc_rtt(void)
+{
+    timex_t end;
+    vtimer_now(&end);
+    timex_t result = timex_sub(end, start);
+
+    rtt = result.seconds + (float)result.microseconds / (1000.0 * 1000.0);
+}
+
+static void print_success(void)
+{
+    printf("%s%f%s\n", "time=", rtt, "ms");
+}
+
+static void print_failed(void)
+{
+    printf("%s\n", "ping failed");
+}
+
+static void pong(radio_address_t src)
+{
+    send_l2_packet(src, L2_PONG);
+}
+
+static void send_l2_packet(radio_address_t dst, l2_ping_type_t type)
+{
+    radio_packet_t p;
+
+    transceiver_command_t tcmd;
+    tcmd.transceivers = TRANSCEIVER_DEFAULT;
+    tcmd.data = &p;
+
+    pipa.type = type;
+
+    p.data = (uint8_t*) &pipa;
+    p.length = sizeof(pipa);
+    p.dst = dst;
+
+    msg_t mesg;
+    mesg.type = SND_PKT;
+    mesg.content.ptr = (char *) &tcmd;
+
+    msg_send_receive(&mesg, &mesg, transceiver_pid);
+    int8_t response = mesg.content.value;
+
+    if (response <= 0) {
+        print_failed();
+    }
+}
+
+static void pong_handler(void)
+{
+    calc_rtt();
+    print_success();
+}
diff --git a/sys/ping/ping.c b/sys/ping/ping.c
deleted file mode 100644
index 8c486a0c753dd0b7cd7f8908a0c8408eea26bc9c..0000000000000000000000000000000000000000
--- a/sys/ping/ping.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Ping: low level ping pong
- *
- * Copyright (C) 2013, Igor Merkulow <igor.merkulow@gmail.com>
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- */
-
-/**
- * @file
- * @author Igor Merkulow <igor.merkulow@gmail.com>
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "thread.h"
-#include "msg.h"
-
-#include "cc110x_legacy_csma/cc1100.h"
-#include "lpc2387.h"
-
-#include "vtimer.h"
-#include "timex.h"
-#include "gpioint.h"
-#include "ping.h"
-
-ping_payload *pipa;
-protocol_t protocol_id = 0;
-radio_address_t r_address = 0;
-timex_t start = 0;
-float rtt = 0;
-
-void ping_handler(void *payload, int payload_size,
-                  packet_info_t *packet_info)
-{
-    pong(packet_info->phy_src);
-}
-
-void pong_handler(void *payload, int payload_size,
-                  packet_info_t *packet_info)
-{
-    calc_rtt();
-    print_success();
-}
-
-void pong(uint16_t src)
-{
-    int trans_ok = cc1100_send_csmaca(src, protocol_id, 2, pipa->payload,
-                                      sizeof(pipa->payload));
-
-    if (trans_ok < 0) {
-        print_failed();
-    }
-}
-
-void ping_init(protocol_t protocol, uint8_t channr, radio_address_t addr)
-{
-    protocol_id = protocol;
-    r_address = addr;
-    cc1100_set_packet_handler(protocol, ping_handler);
-    cc1100_set_channel(channr);
-    cc1100_set_address(r_address);
-    init_payload();
-}
-
-void ping(radio_address_t addr, uint8_t channr)
-{
-    cc1100_set_packet_handler(protocol_id, pong_handler);
-    cc1100_set_channel(channr);
-    cc1100_set_address(r_address);
-
-    while (1) {
-        vtimer_now(&start);
-        int trans_ok = cc1100_send_csmaca(addr,
-                                          protocol_id, 2, pipa->payload, sizeof(pipa->payload));
-
-        if (trans_ok < 0) {
-            print_failed();
-        }
-
-        hwtimer_wait(HWTIMER_TICKS(500 * 1000));
-    }
-}
-
-void calc_rtt(void)
-{
-    timex_t end;
-    vtimer_now(&end);
-    timex_t result = timex_sub(end, start);
-
-    rtt = result.seconds + (float)result.microseconds / (1000.0 * 1000.0);
-}
-
-void print_success(void)
-{
-    printf("%s%f%s\n", "time=", rtt, "ms");
-}
-
-void print_failed(void)
-{
-    printf("%s\n", "ping failed");
-}
-
-void init_payload(void)
-{
-    pipa = malloc(sizeof(*pipa));
-    pipa->payload = NULL;
-}