diff --git a/Makefile.dep b/Makefile.dep
index 48fa8002dd36943544aae314277bcfd9552098be..a7531a3231f852f5c356c92edaad7ed9a6d0ccaf 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -184,6 +184,13 @@ ifneq (,$(filter ng_udp,$(USEMODULE)))
   USEMODULE += ng_inet_csum
 endif
 
+ifneq (,$(filter ng_nettest,$(USEMODULE)))
+  USEMODULE += ng_netapi
+  USEMODULE += ng_netreg
+  USEMODULE += ng_netif
+  USEMODULE += ng_pktbuf
+endif
+
 ifneq (,$(filter ng_netbase,$(USEMODULE)))
   USEMODULE += ng_netapi
   USEMODULE += ng_netreg
diff --git a/sys/Makefile b/sys/Makefile
index e815e4cb87fcfb78b75d1d85346c25ad0f587f5b..35fb3f01680bf919623bab56b3be726132cd16f7 100644
--- a/sys/Makefile
+++ b/sys/Makefile
@@ -107,6 +107,9 @@ endif
 ifneq (,$(filter ng_netreg,$(USEMODULE)))
     DIRS += net/crosslayer/ng_netreg
 endif
+ifneq (,$(filter ng_nettest,$(USEMODULE)))
+    DIRS += net/crosslayer/ng_nettest
+endif
 ifneq (,$(filter ng_nomac,$(USEMODULE)))
     DIRS += net/link_layer/ng_nomac
 endif
diff --git a/sys/include/net/ng_nettest.h b/sys/include/net/ng_nettest.h
new file mode 100644
index 0000000000000000000000000000000000000000..05f837066b5a8f4e404a200d2426bc5870c27592
--- /dev/null
+++ b/sys/include/net/ng_nettest.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
+ *
+ * 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    net_ng_nettest  NETAPI test framework
+ * @ingroup     net_ng_netapi
+ * @brief       This provides a framework to test the @ref net_ng_netapi IPC
+ *              calls.
+ * @{
+ *
+ * @file
+ * @brief   Definitions for the @ref net_ng_netapi test framework
+ *
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ */
+#ifndef NG_NETTEST_H_
+#define NG_NETTEST_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "kernel_types.h"
+#include "net/ng_netapi.h"
+#include "net/ng_netconf.h"
+#include "net/ng_nettype.h"
+#include "net/ng_pkt.h"
+#include "thread.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Timeout for tests in microseconds
+ */
+#ifndef NG_NETTEST_TIMEOUT
+#define NG_NETTEST_TIMEOUT          (1000)
+#endif
+
+/**
+ * @brief   Default stack size to use for the nettest thread
+ */
+#ifndef NG_NETTEST_STACK_SIZE
+#define NG_NETTEST_STACK_SIZE       (THREAD_STACKSIZE_DEFAULT)
+#endif
+
+/**
+ * @brief   Default priority for the nettest thread
+ */
+#ifndef NG_NETTEST_PRIO
+#define NG_NETTEST_PRIO             (THREAD_PRIORITY_MAIN)
+#endif
+
+/**
+ * @brief   Default message queue size to use for the nettest thread.
+ */
+#ifndef NG_NETTEST_MSG_QUEUE_SIZE
+#define NG_NETTEST_MSG_QUEUE_SIZE   (8U)
+#endif
+
+
+/**
+ * @brief   Type for get/set callbacks.
+ *
+ * @param[in] context   (Optional) context for the option.
+ *                      Compare ng_netapi_opt_t::context.
+ * @param[in,out] data  Data to set or buffer to read into.
+ *                      Compare ng_netapi_opt_t::data.
+ * @param[in] data_len  Size of the data / the buffer.
+ *                      Compare ng_netapi_opt_t::data_len
+ *
+ * @return  The value for the @ref NG_NETAPI_MSG_TYPE_ACK message.
+ */
+typedef int (*ng_nettest_opt_cb_t)(uint16_t context, void *data, uint16_t data_len);
+
+/**
+ * @brief   Option callback list element.
+ */
+typedef struct {
+    ng_nettest_opt_cb_t get;    /**< getter for an option */
+    ng_nettest_opt_cb_t set;    /**< setter for an option */
+} ng_nettest_opt_cbs_t;
+
+/**
+ * @brief   Result type for tests.
+ */
+typedef enum {
+    NG_NETTEST_SUCCESS = 0,     /**< test was successful */
+    NG_NETTEST_FAIL,            /**< test failed */
+    NG_NETTEST_TIMED_OUT,       /**< test timed out */
+    NG_NETTEST_WRONG_MSG,       /**< wrong message type received */
+    NG_NETTEST_WRONG_SENDER,    /**< wrong message type received */
+} ng_nettest_res_t;
+
+/**
+ * @brief   Registers a getter for an option.
+ *
+ * @details Overrides previous registrations.
+ *
+ * @param[in] opt   The option to register the getter for.
+ * @param[in] cb    An option getter. NULL to delete.
+ */
+void ng_nettest_register_get(ng_netconf_opt_t opt, ng_nettest_opt_cb_t cb);
+
+/**
+ * @brief   Registers a setter for an option.
+ *
+ * @details Overrides previous registrations.
+ *
+ * @param[in] opt   The option to register the setter for.
+ * @param[in] cb    An option setter. NULL to delete.
+ */
+void ng_nettest_register_set(ng_netconf_opt_t opt, ng_nettest_opt_cb_t cb);
+
+/**
+ * @brief   Test @ref NG_NETAPI_MSG_TYPE_SND command to @p pid.
+ *
+ * @details This registered the nettest thread to (@p exp_type, @p exp_demux_ctx)
+ * and checks if @p exp_pkts of @p exp_out were received from @p exp_senders.
+ * If no message was received after @ref NG_NETTEST_TIMEOUT microseconds, while
+ * there are still packets expected, the function will return NG_NETTEST_TIMED_OUT.
+ *
+ * @param[in] pid           The thread you want to test the
+ *                          @ref NG_NETAPI_MSG_TYPE_SND command for.
+ * @param[in] in            The packet you want to send through @p pid.
+ * @param[in] exp_pkts      The number of packets expected to be received.
+ * @param[in] exp_senders   The PID the resulting packet should be coming from.
+ *                          Must be of dimension @p exp_pkts.
+ * @param[in] exp_out       The expected packet from @p exp_sender.
+ *                          Must be of dimension @p exp_pkts.
+ * @param[in] exp_type      The expected receiver type for the
+ *                          @ref NG_NETAPI_MSG_TYPE_SND command.
+ * @param[in] exp_demux_ctx The expected receiver demux type for the
+ *                          @ref NG_NETAPI_MSG_TYPE_SND command.
+ *
+ * @return  @see ng_nettest_res_t
+ */
+ng_nettest_res_t ng_nettest_send(kernel_pid_t pid, ng_pktsnip_t *in,
+                                 unsigned int exp_pkts, kernel_pid_t exp_senders[],
+                                 ng_pktsnip_t *exp_out[], ng_nettype_t exp_type,
+                                 uint32_t exp_demux_ctx);
+
+/**
+ * @brief   Test @ref NG_NETAPI_MSG_TYPE_SND command to @p pid with the receiving
+ *          thread being an interface.
+ *
+ * @details This registered the nettest thread as an interface and checks ifx
+ * @p exp_pkts of @p exp_out were received from @p exp_senders. If no message
+ * was received after @ref NG_NETTEST_TIMEOUT microseconds, while there are
+ * still packets expected, the function will return NG_NETTEST_TIMED_OUT.
+ *
+ * @param[in] pid           The thread you want to test the
+ *                          @ref NG_NETAPI_MSG_TYPE_SND command for.
+ * @param[in] in            The packet you want to send through @p pid.
+ * @param[in] exp_pkts      The number of packets expected to be received.
+ * @param[in] exp_senders   The PID the resulting packet should be coming from.
+ *                          Must be of dimension @p exp_pkts.
+ * @param[in] exp_out       The expected packet from @p exp_sender.
+ *                          Must be of dimension @p exp_pkts.
+ *
+ * @return  @see ng_nettest_res_t
+ */
+ng_nettest_res_t ng_nettest_send_iface(kernel_pid_t pid, ng_pktsnip_t *in,
+                                       unsigned int exp_pkts,
+                                       kernel_pid_t exp_senders[],
+                                       ng_pktsnip_t *exp_out[]);
+
+/**
+ * @brief   Test @ref NG_NETAPI_MSG_TYPE_RCV command to @p pid.
+ *
+ * @details This registered the nettest thread to (@p exp_type, @p exp_demux_ctx)
+ * and checks if @p exp_pkts of @p exp_out were received from @p exp_senders.
+ * If no message was received after @ref NG_NETTEST_TIMEOUT microseconds, while
+ * there are still packets expected, the function will return NG_NETTEST_TIMED_OUT.
+ *
+ * @param[in] pid           The thread you want to test the
+ *                          @ref NG_NETAPI_MSG_TYPE_RCV command for.
+ * @param[in] in            The packet you want to send through @p pid.
+ * @param[in] exp_pkts      The number of packets expected to be received.
+ * @param[in] exp_senders   The PID the resulting packet should be coming from.
+ *                          Must be of dimension @p exp_pkts.
+ * @param[in] exp_out       The expected packet from @p exp_sender.
+ *                          Must be of dimension @p exp_pkts.
+ * @param[in] exp_type      The expected receiver type for the
+ *                          @ref NG_NETAPI_MSG_TYPE_RCV command.
+ * @param[in] exp_demux_ctx The expected receiver demux type for the
+ *                          @ref NG_NETAPI_MSG_TYPE_RCV command.
+ *
+ * @return  @see ng_nettest_res_t
+ */
+ng_nettest_res_t ng_nettest_receive(kernel_pid_t pid, ng_pktsnip_t *in,
+                                    unsigned int exp_pkts, kernel_pid_t exp_senders[],
+                                    ng_pktsnip_t *exp_out[], ng_nettype_t exp_type,
+                                    uint32_t exp_demux_ctx);
+
+/**
+ * @brief   Test @ref NG_NETAPI_MSG_TYPE_GET command to @p pid.
+ *
+ * @param[in] pid           The thread you want to test the
+ *                          @ref NG_NETAPI_MSG_TYPE_GET command for.
+ * @param[in] opt           The option you want to test.
+ * @param[in] context       The context for the option.
+ * @param[in] data          The data pointer for the @ref NG_NETAPI_MSG_TYPE_GET
+ *                          command.
+ * @param[in] data_len      The maximum length for @p data.
+ * @param[in] exp_data      The expected value for the returned data. May be
+ *                          NULL if @p exp_res < 0
+ * @param[in] exp_res       The expected return value for the
+ *                          @ref NG_NETAPI_MSG_TYPE_GET command.
+ *
+ * @return  @see ng_nettest_res_t
+ */
+ng_nettest_res_t ng_nettest_get(kernel_pid_t pid, ng_netconf_opt_t opt,
+                                uint16_t context, void *data, size_t data_len,
+                                void *exp_data, int exp_res);
+
+/**
+ * @brief   Test @ref NG_NETAPI_MSG_TYPE_SET command to @p pid.
+ *
+ * @param[in] pid           The thread you want to test the
+ *                          @ref NG_NETAPI_MSG_TYPE_SET command for.
+ * @param[in] opt           The option you want to test.
+ * @param[in] context       The context for the option.
+ * @param[in] data          The data pointer for the @ref NG_NETAPI_MSG_TYPE_SET
+ *                          command.
+ * @param[in] data_len      The maximum length for @p data.
+ * @param[in] exp_res       The expected return value for the
+ *                          @ref NG_NETAPI_MSG_TYPE_SET command.
+ *
+ * @return  @see ng_nettest_res_t
+ */
+ng_nettest_res_t ng_nettest_set(kernel_pid_t pid, ng_netconf_opt_t opt,
+                                uint16_t context, void *data, size_t data_len,
+                                int exp_res);
+
+/**
+ * @brief   Initializes the @ref net_ng_nettest module.
+ *
+ * @return  The PID to the nettest thread, on success.
+ * @return  a negative errno on error.
+ * @return  -EOVERFLOW, if there are too many threads running already
+ */
+int ng_nettest_init(void);
+
+/**
+ * @brief   Resets ng_nettest_opt_cbs_t list.
+ */
+void ng_nettest_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NG_NETTEST_H_ */
+/** @} */
diff --git a/sys/net/crosslayer/ng_nettest/Makefile b/sys/net/crosslayer/ng_nettest/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..48422e909a47d7cd428d10fa73825060ccc8d8c2
--- /dev/null
+++ b/sys/net/crosslayer/ng_nettest/Makefile
@@ -0,0 +1 @@
+include $(RIOTBASE)/Makefile.base
diff --git a/sys/net/crosslayer/ng_nettest/ng_nettest.c b/sys/net/crosslayer/ng_nettest/ng_nettest.c
new file mode 100644
index 0000000000000000000000000000000000000000..2fcf19fb6d3ede79a55f839adc1ec523cf07c4b3
--- /dev/null
+++ b/sys/net/crosslayer/ng_nettest/ng_nettest.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
+ *
+ * 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
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include "msg.h"
+#include "mutex.h"
+#include "net/ng_netapi.h"
+#include "net/ng_netif.h"
+#include "net/ng_netconf.h"
+#include "net/ng_netreg.h"
+#include "net/ng_pktbuf.h"
+#include "timex.h"
+#include "thread.h"
+#include "vtimer.h"
+
+#include "net/ng_nettest.h"
+
+static ng_nettest_opt_cbs_t _opt_cbs[NETCONF_OPT_NUMOF];
+static mutex_t _mutex = MUTEX_INIT;
+static kernel_pid_t _pid = KERNEL_PID_UNDEF;
+static char _stack[NG_NETTEST_STACK_SIZE];
+
+static void *_event_loop(void *arg);
+
+void ng_nettest_register_get(ng_netconf_opt_t opt, ng_nettest_opt_cb_t cb)
+{
+    mutex_lock(&_mutex);
+    _opt_cbs[opt].get = cb;
+    mutex_unlock(&_mutex);
+}
+
+void ng_nettest_register_set(ng_netconf_opt_t opt, ng_nettest_opt_cb_t cb)
+{
+    mutex_lock(&_mutex);
+    _opt_cbs[opt].set = cb;
+    mutex_unlock(&_mutex);
+}
+
+static ng_nettest_res_t _pkt_test(uint16_t cmd_type, kernel_pid_t pid, ng_pktsnip_t *in,
+                                  unsigned int exp_pkts, kernel_pid_t exp_senders[],
+                                  ng_pktsnip_t *exp_out[])
+{
+    msg_t msg;
+    timex_t t = { 0, NG_NETTEST_TIMEOUT };
+    ng_nettest_res_t res = NG_NETTEST_SUCCESS;
+
+    msg.type = cmd_type;
+    msg.content.ptr = (char *)in;
+
+    msg_send(&msg, pid);
+
+    for (unsigned int i = 0; i < exp_pkts; i++) {
+        ng_pktsnip_t *out;
+
+        if ((vtimer_msg_receive_timeout(&msg, t) < 0) && res == NG_NETTEST_SUCCESS) {
+            res = NG_NETTEST_TIMED_OUT;
+        }
+
+        if (msg.type != NG_NETAPI_MSG_TYPE_SND && (res == NG_NETTEST_SUCCESS)) {
+            res = NG_NETTEST_WRONG_MSG;
+        }
+
+        if (msg.sender_pid != exp_senders[i] && (res == NG_NETTEST_SUCCESS)) {
+            res = NG_NETTEST_WRONG_SENDER;
+        }
+
+        out = (ng_pktsnip_t *)msg.content.ptr;
+
+        if ((out == NULL) && (res == NG_NETTEST_SUCCESS)) {
+            res = NG_NETTEST_FAIL;
+        }
+
+        while (out) {
+            if ((res == NG_NETTEST_SUCCESS) &&
+                ((out->users != exp_out[i]->users) ||
+                 (out->size != exp_out[i]->size) ||
+                 (out->type != exp_out[i]->type) ||
+                 (memcmp(out->data, exp_out[i]->data, out->size) != 0))) {
+                res = NG_NETTEST_FAIL;
+            }
+
+            out = out->next;
+        }
+
+        ng_pktbuf_release((ng_pktsnip_t *)msg.content.ptr);
+    }
+
+    return res;
+}
+
+ng_nettest_res_t ng_nettest_send(kernel_pid_t pid, ng_pktsnip_t *in,
+                                 unsigned int exp_pkts, kernel_pid_t exp_senders[],
+                                 ng_pktsnip_t *exp_out[], ng_nettype_t exp_type,
+                                 uint32_t exp_demux_ctx)
+{
+    ng_netreg_entry_t reg_entry = { NULL, exp_demux_ctx, thread_getpid() };
+    ng_nettest_res_t res;
+
+    ng_netreg_register(exp_type, &reg_entry);
+
+    res = _pkt_test(NG_NETAPI_MSG_TYPE_SND, pid, in, exp_pkts, exp_senders,
+                    exp_out);
+
+    ng_netreg_unregister(exp_type, &reg_entry);
+
+    return res;
+}
+
+ng_nettest_res_t ng_nettest_send_iface(kernel_pid_t pid, ng_pktsnip_t *in,
+                                       unsigned int exp_pkts,
+                                       kernel_pid_t exp_senders[],
+                                       ng_pktsnip_t *exp_out[])
+{
+    ng_nettest_res_t res;
+
+    ng_netif_add(thread_getpid());
+
+    res = _pkt_test(NG_NETAPI_MSG_TYPE_SND, pid, in, exp_pkts, exp_senders,
+                    exp_out);
+
+    ng_netif_remove(thread_getpid());
+
+    return res;
+}
+
+ng_nettest_res_t ng_nettest_receive(kernel_pid_t pid, ng_pktsnip_t *in,
+                                    unsigned int exp_pkts, kernel_pid_t exp_senders[],
+                                    ng_pktsnip_t *exp_out[], ng_nettype_t exp_type,
+                                    uint32_t exp_demux_ctx)
+{
+    ng_netreg_entry_t reg_entry = { NULL, exp_demux_ctx, thread_getpid() };
+    ng_nettest_res_t res;
+
+    ng_netreg_register(exp_type, &reg_entry);
+
+    res = _pkt_test(NG_NETAPI_MSG_TYPE_RCV, pid, in, exp_pkts, exp_senders,
+                    exp_out);
+
+    ng_netreg_unregister(exp_type, &reg_entry);
+
+    return res;
+}
+
+ng_nettest_res_t ng_nettest_get(kernel_pid_t pid, ng_netconf_opt_t opt,
+                                uint16_t context, void *data, size_t data_len,
+                                void *exp_data, int exp_res)
+{
+    if ((exp_res != ng_netapi_get(pid, opt, context, data, data_len)) ||
+        ((exp_res > 0) && (memcpy(exp_data, data, exp_res)))) {
+        return NG_NETTEST_FAIL;
+    }
+
+    return NG_NETTEST_SUCCESS;
+}
+
+ng_nettest_res_t ng_nettest_set(kernel_pid_t pid, ng_netconf_opt_t opt,
+                                uint16_t context, void *data, size_t data_len,
+                                int exp_res)
+{
+    if (exp_res != ng_netapi_get(pid, opt, context, data, data_len)) {
+        return NG_NETTEST_FAIL;
+    }
+
+    return NG_NETTEST_SUCCESS;
+}
+
+int ng_nettest_init(void)
+{
+    if (_pid <= KERNEL_PID_UNDEF) {
+        _pid = thread_create(_stack, sizeof(_stack), NG_NETTEST_PRIO,
+                             CREATE_STACKTEST, _event_loop, NULL, "nettest");
+    }
+
+    return _pid;
+}
+
+void ng_nettest_reset(void)
+{
+    for (int i = 0; i < NETCONF_OPT_NUMOF; i++) {
+        _opt_cbs[i].get = NULL;
+        _opt_cbs[i].set = NULL;
+    }
+}
+
+static inline uint32_t _get_set_opt(ng_nettest_opt_cb_t cb, uint16_t context,
+                                    void *data, uint16_t data_len)
+{
+    int res;
+
+    mutex_lock(&_mutex);
+    if (cb != NULL) {
+        res = cb(context, data, data_len);
+    }
+    else {
+        res = -ENOTSUP;
+    }
+    mutex_unlock(&_mutex);
+    return (uint32_t)res;
+}
+
+static void *_event_loop(void *arg)
+{
+    msg_t reply, msg_queue[NG_NETTEST_MSG_QUEUE_SIZE];
+
+    (void)arg;
+    msg_init_queue(msg_queue, NG_NETTEST_MSG_QUEUE_SIZE);
+    reply.type = NG_NETAPI_MSG_TYPE_ACK;
+
+    while (1) {
+        msg_t msg;
+        ng_netapi_opt_t *opt;
+
+        msg_receive(&msg);
+
+        switch (msg.type) {
+            case NG_NETAPI_MSG_TYPE_GET:
+                opt = (ng_netapi_opt_t *)msg.content.ptr;
+                reply.content.value = _get_set_opt(_opt_cbs[opt->opt].get,
+                                                   opt->context, opt->data,
+                                                   opt->data_len);
+                break;
+
+            case NG_NETAPI_MSG_TYPE_SET:
+                opt = (ng_netapi_opt_t *)msg.content.ptr;
+                reply.content.value = _get_set_opt(_opt_cbs[opt->opt].set,
+                                                   opt->context, opt->data,
+                                                   opt->data_len);
+                break;
+        }
+
+        msg_reply(&msg, &reply);
+    }
+
+    return NULL;
+}
+
+/** @} */