diff --git a/Makefile.dep b/Makefile.dep
index 9aa67841c8edfae6159bd6bd4306222b1ea688c2..90c3ec01eb96b202667062a9fe9f980fc8f1c900 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -357,6 +357,10 @@ ifneq (,$(filter posix_semaphore,$(USEMODULE)))
   USEMODULE += xtimer
 endif
 
+ifneq (,$(filter emb6_conn_udp,$(USEMODULE)))
+  USEMODULE += emb6_sock
+endif
+
 ifneq (,$(filter emb6_%,$(USEMODULE)))
   USEMODULE += emb6
 endif
@@ -430,6 +434,25 @@ ifneq (,$(filter lwip_contrib,$(USEMODULE)))
   USEMODULE += sema
 endif
 
+ifneq (,$(filter emb6_%,$(USEMODULE)))
+  USEMODULE += emb6
+endif
+
+ifneq (,$(filter emb6,$(USEMODULE)))
+  USEPKG += emb6
+  USEMODULE += emb6_bsp
+  USEMODULE += emb6_common
+  USEMODULE += emb6_contrib
+  USEMODULE += emb6_ipv6
+  USEMODULE += emb6_ipv6_multicast
+  USEMODULE += emb6_llsec
+  USEMODULE += emb6_mac
+  USEMODULE += emb6_netdev2
+  USEMODULE += emb6_rpl
+  USEMODULE += emb6_sicslowpan
+  USEMODULE += emb6_utils
+endif
+
 ifneq (,$(filter sema,$(USEMODULE)))
   USEMODULE += xtimer
 endif
diff --git a/pkg/emb6/Makefile.include b/pkg/emb6/Makefile.include
index e1236c8b8d127b46378b07784a114ff77ec1d364..090cebac9c0a716af82dfd90b684e2629bef15af 100644
--- a/pkg/emb6/Makefile.include
+++ b/pkg/emb6/Makefile.include
@@ -22,6 +22,10 @@ ifneq (,$(filter emb6_contrib,$(USEMODULE)))
   DIRS += $(EMB6_CONTRIB)
 endif
 
+ifneq (,$(filter emb6_conn_udp,$(USEMODULE)))
+  DIRS += $(EMB6_CONTRIB)/conn/udp
+endif
+
 ifneq (,$(filter emb6_ipv6,$(USEMODULE)))
   DIRS += $(EMB6_DIR)/emb6/src/net/ipv6
   INCLUDES += -I$(EMB6_DIR)/emb6/inc/net/ipv6
diff --git a/pkg/emb6/contrib/conn/udp/Makefile b/pkg/emb6/contrib/conn/udp/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..e5dbafaedd9b426abbbf7df36189fb6c0895d9fe
--- /dev/null
+++ b/pkg/emb6/contrib/conn/udp/Makefile
@@ -0,0 +1,3 @@
+MODULE = emb6_conn_udp
+
+include $(RIOTBASE)/Makefile.base
diff --git a/pkg/emb6/contrib/conn/udp/emb6_conn_udp.c b/pkg/emb6/contrib/conn/udp/emb6_conn_udp.c
new file mode 100644
index 0000000000000000000000000000000000000000..bbd488edfe3f9ddb346037d8e52189883cac6eab
--- /dev/null
+++ b/pkg/emb6/contrib/conn/udp/emb6_conn_udp.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+/**
+ * @{
+ *
+ * @file
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include "evproc.h"
+#include "msg.h"
+#include "mutex.h"
+#include "net/af.h"
+#include "net/conn/udp.h"
+#include "net/ipv6/hdr.h"
+#include "sched.h"
+#include "uip.h"
+
+#define _MSG_TYPE_CLOSE     (0x4123)
+#define _MSG_TYPE_RCV       (0x4124)
+
+/* struct to describe a sendto command for emb6 thread */
+typedef struct {
+    struct udp_socket sock;
+    mutex_t mutex;
+    const void *data;
+    int res;
+    uint16_t data_len;
+} _send_cmd_t;
+
+extern uint16_t uip_slen;
+
+static bool send_registered = false;
+
+static void _input_callback(struct udp_socket *c, void *ptr,
+                            const uip_ipaddr_t *src_addr, uint16_t src_port,
+                            const uip_ipaddr_t *dst_addr, uint16_t dst_port,
+                            const uint8_t *data, uint16_t datalen);
+static void _output_callback(c_event_t c_event, p_data_t p_data);
+
+static int _reg_and_bind(struct udp_socket *c, void *ptr,
+                         udp_socket_input_callback_t cb, uint16_t port)
+{
+    if (udp_socket_register(c, ptr, cb) < 0) {
+        return -EMFILE;
+    }
+    if (udp_socket_bind(c, port) < 0) {
+        udp_socket_close(c);
+        return -EALREADY;
+    }
+    return 0;
+}
+
+int conn_udp_create(conn_udp_t *conn, const void *addr, size_t addr_len,
+                    int family, uint16_t port)
+{
+    int res;
+
+    (void)addr;
+    (void)addr_len;
+    if (family != AF_INET6) {
+        return -EAFNOSUPPORT;
+    }
+    if (conn->sock.input_callback != NULL) {
+        return -EINVAL;
+    }
+    mutex_init(&conn->mutex);
+    mutex_lock(&conn->mutex);
+    if ((res = _reg_and_bind(&conn->sock, conn, _input_callback, port)) < 0) {
+        conn->sock.input_callback = NULL;
+        mutex_unlock(&conn->mutex);
+        return res;
+    }
+    conn->waiting_thread = KERNEL_PID_UNDEF;
+    mutex_unlock(&conn->mutex);
+    return 0;
+}
+
+void conn_udp_close(conn_udp_t *conn)
+{
+    if (conn->sock.input_callback != NULL) {
+        mutex_lock(&conn->mutex);
+        if (conn->waiting_thread != KERNEL_PID_UNDEF) {
+            msg_t msg;
+            msg.type = _MSG_TYPE_CLOSE;
+            msg.content.ptr = (char *)conn;
+            mutex_unlock(&conn->mutex);
+            msg_send(&msg, conn->waiting_thread);
+            mutex_lock(&conn->mutex);
+        }
+        udp_socket_close(&conn->sock);
+        conn->sock.input_callback = NULL;
+        mutex_unlock(&conn->mutex);
+    }
+}
+
+int conn_udp_getlocaladdr(conn_udp_t *conn, void *addr, uint16_t *port)
+{
+    if (conn->sock.input_callback != NULL) {
+        mutex_lock(&conn->mutex);
+        memset(addr, 0, sizeof(ipv6_addr_t));
+        *port = NTOHS(conn->sock.udp_conn->lport);
+        mutex_unlock(&conn->mutex);
+        return sizeof(ipv6_addr_t);
+    }
+    return -EBADF;
+}
+
+int conn_udp_recvfrom(conn_udp_t *conn, void *data, size_t max_len, void *addr,
+                      size_t *addr_len, uint16_t *port)
+{
+    int res = -EIO;
+    msg_t msg;
+
+    if (conn->sock.input_callback == NULL) {
+        return -ENOTSOCK;
+    }
+    mutex_lock(&conn->mutex);
+    if (conn->waiting_thread != KERNEL_PID_UNDEF) {
+        mutex_unlock(&conn->mutex);
+        return -EALREADY;
+    }
+    conn->waiting_thread = sched_active_pid;
+    mutex_unlock(&conn->mutex);
+    msg_receive(&msg);
+    if (msg.type == _MSG_TYPE_CLOSE) {
+        conn->waiting_thread = KERNEL_PID_UNDEF;
+        return -EINTR;
+    }
+    else if (msg.type == _MSG_TYPE_RCV) {
+        mutex_lock(&conn->mutex);
+        if (msg.content.ptr == (char *)conn) {
+            if (max_len < conn->recv_info.datalen) {
+                conn->waiting_thread = KERNEL_PID_UNDEF;
+                mutex_unlock(&conn->mutex);
+                return -ENOBUFS;
+            }
+            memcpy(data, conn->recv_info.data, conn->recv_info.datalen);
+            memcpy(addr, conn->recv_info.src, sizeof(ipv6_addr_t));
+            *addr_len = sizeof(ipv6_addr_t);
+            *port = conn->recv_info.src_port;
+            res = (int)conn->recv_info.datalen;
+        }
+        conn->waiting_thread = KERNEL_PID_UNDEF;
+        mutex_unlock(&conn->mutex);
+    }
+    return res;
+}
+
+int conn_udp_sendto(const void *data, size_t len, const void *src, size_t src_len,
+                    const void *dst, size_t dst_len, int family, uint16_t sport,
+                    uint16_t dport)
+{
+    int res;
+    _send_cmd_t send_cmd;
+
+    if (!send_registered) {
+        if (evproc_regCallback(EVENT_TYPE_CONN_SEND, _output_callback) != E_SUCCESS) {
+            return -EIO;
+        }
+        else {
+            send_registered = true;
+        }
+    }
+    mutex_init(&send_cmd.mutex);
+    if ((len > (UIP_BUFSIZE - (UIP_LLH_LEN + UIP_IPUDPH_LEN))) ||
+        (len > UINT16_MAX)) {
+        return -EMSGSIZE;
+    }
+    if ((dst_len > sizeof(ipv6_addr_t)) || (family != AF_INET6)) {
+        return -EAFNOSUPPORT;
+    }
+    mutex_lock(&send_cmd.mutex);
+    send_cmd.data = data;
+    send_cmd.data_len = (uint16_t)len;
+    if ((res = _reg_and_bind(&send_cmd.sock, NULL, NULL, sport)) < 0) {
+        mutex_unlock(&send_cmd.mutex);
+        return res;
+    }
+    udp_socket_connect(&send_cmd.sock, (uip_ipaddr_t *)dst, dport); /* can't fail at this point */
+    /* change to emb6 thread context */
+    if (evproc_putEvent(E_EVPROC_TAIL, EVENT_TYPE_CONN_SEND, &send_cmd) != E_SUCCESS) {
+        udp_socket_close(&send_cmd.sock);
+        mutex_unlock(&send_cmd.mutex);
+        return -EIO;
+    }
+    /* block thread until data was send */
+    mutex_lock(&send_cmd.mutex);
+    udp_socket_close(&send_cmd.sock);
+    mutex_unlock(&send_cmd.mutex);
+
+    return send_cmd.res;
+}
+
+static void _input_callback(struct udp_socket *c, void *ptr,
+                            const uip_ipaddr_t *src_addr, uint16_t src_port,
+                            const uip_ipaddr_t *dst_addr, uint16_t dst_port,
+                            const uint8_t *data, uint16_t datalen)
+{
+    conn_udp_t *conn = ptr;
+
+    (void)dst_addr;
+    (void)dst_port;
+    mutex_lock(&conn->mutex);
+    if (conn->waiting_thread != KERNEL_PID_UNDEF) {
+        msg_t msg;
+        conn->recv_info.src_port = src_port;
+        conn->recv_info.src = (const ipv6_addr_t *)src_addr;
+        conn->recv_info.data = data;
+        conn->recv_info.datalen = datalen - sizeof(ipv6_hdr_t);
+        msg.type = _MSG_TYPE_RCV;
+        msg.content.ptr = (char *)conn;
+        mutex_unlock(&conn->mutex);
+        msg_send(&msg, conn->waiting_thread);
+    }
+    else {
+        mutex_unlock(&conn->mutex);
+    }
+}
+
+static void _output_callback(c_event_t c_event, p_data_t p_data)
+{
+    _send_cmd_t *send_cmd = (_send_cmd_t *)p_data;
+
+    if ((c_event != EVENT_TYPE_CONN_SEND) || (p_data == NULL)) {
+        return;
+    }
+    if ((send_cmd->res = udp_socket_send(&send_cmd->sock, send_cmd->data, send_cmd->data_len)) < 0) {
+        send_cmd->res = -EHOSTUNREACH;
+    }
+    mutex_unlock(&send_cmd->mutex);
+}
+
+/** @} */
diff --git a/pkg/emb6/include/emb6/conn/udp.h b/pkg/emb6/include/emb6/conn/udp.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc835ca06bd0e7cd6e9467e4deca5628ec9c4962
--- /dev/null
+++ b/pkg/emb6/include/emb6/conn/udp.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 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    emb6_conn_udp   udp_conn wrapper for emb6
+ * @ingroup     emb6
+ * @brief       UDP conn for emb6
+ *
+ * For this implementation to receive with an open connection only with one
+ * thread at once. If you use @ref conn_udp_recvfrom() with more than one thread
+ * simultaneously, it will return `-EALREADY`.
+ *
+ * @{
+ *
+ * @file
+ * @brief   UDP conn definitions
+ *
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ */
+#ifndef EMB6_CONN_UDP_H_
+#define EMB6_CONN_UDP_H_
+
+#include <stdint.h>
+
+#include "kernel_types.h"
+#include "mutex.h"
+#include "net/ipv6/addr.h"
+
+#include "uip.h"
+#include "udp-socket.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief @ref net_conn_udp definition for emb6
+ */
+struct conn_udp {
+    struct udp_socket sock;         /**< emb6 internal socket */
+    mutex_t mutex;                  /**< mutex for the connection */
+    kernel_pid_t waiting_thread;    /**< thread waiting for an incoming packet
+                                     *   on this connection */
+    struct {
+        uint16_t src_port;          /**< source port */
+        const ipv6_addr_t *src;     /**< source address */
+        const void *data;           /**< data of received packet */
+        size_t datalen;             /**< length of received packet data */
+    } recv_info;                    /**< info on received packet */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EMB6_CONN_UDP_H_ */
+/** @} */
diff --git a/sys/include/net/conn/udp.h b/sys/include/net/conn/udp.h
index 2e400a0cf7a269ed9997413d550d8913d327458f..b59ac07ce49d2066851641eeea1af06306611e13 100644
--- a/sys/include/net/conn/udp.h
+++ b/sys/include/net/conn/udp.h
@@ -31,6 +31,10 @@
 #include "lwip/conn.h"
 #endif
 
+#ifdef MODULE_EMB6_CONN_UDP
+#include "emb6/conn/udp.h"
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif