diff --git a/Makefile.dep b/Makefile.dep
index 7d78585519295ff88b6522409128e4ebff3262c9..9854b0ee87966673646b9653c8112d31c876da65 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -356,9 +356,14 @@ endif
 
 ifneq (,$(filter lwip,$(USEMODULE)))
   USEPKG += lwip
+  USEMODULE += lwip_contrib
   USEMODULE += lwip_core
 endif
 
+ifneq (,$(filter lwip_contrib,$(USEMODULE)))
+  USEMODULE += sema
+endif
+
 ifneq (,$(filter sema,$(USEMODULE)))
   USEMODULE += xtimer
 endif
diff --git a/pkg/lwip/Makefile.include b/pkg/lwip/Makefile.include
index e944a48255daa7ba67940c4511efd802c5109287..de6a9f0069d2cb156e85a21aa930c79f660f5386 100644
--- a/pkg/lwip/Makefile.include
+++ b/pkg/lwip/Makefile.include
@@ -1,2 +1,6 @@
 INCLUDES += -I$(RIOTBASE)/pkg/lwip/include \
             -I$(BINDIRBASE)/pkg/$(BOARD)/lwip/src/include
+
+ifneq (,$(filter lwip_contrib,$(USEMODULE)))
+  DIRS += $(RIOTBASE)/pkg/lwip/contrib
+endif
\ No newline at end of file
diff --git a/pkg/lwip/contrib/Makefile b/pkg/lwip/contrib/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..048d70b685670b25b968a2f3cb72d18afd234adc
--- /dev/null
+++ b/pkg/lwip/contrib/Makefile
@@ -0,0 +1,3 @@
+MODULE := lwip_contrib
+
+include $(RIOTBASE)/Makefile.base
diff --git a/pkg/lwip/contrib/doc.txt b/pkg/lwip/contrib/doc.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d11a87565bf8bc93487ae368de9a516a6b6c698b
--- /dev/null
+++ b/pkg/lwip/contrib/doc.txt
@@ -0,0 +1,3 @@
+/**
+ * @defgroup lwip_contrib   RIOT lwIP port
+ */
diff --git a/pkg/lwip/contrib/lwip.c b/pkg/lwip/contrib/lwip.c
new file mode 100644
index 0000000000000000000000000000000000000000..83ee33a1baa6272e16dc7369400f9187f43188c8
--- /dev/null
+++ b/pkg/lwip/contrib/lwip.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 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 "lwip/tcpip.h"
+#include "lwip/netif/netdev2.h"
+#include "lwip/netif.h"
+
+#include "netdev2_tap.h"
+
+#include "lwip.h"
+
+#define ENABLE_DEBUG    (0)
+#include "debug.h"
+
+void lwip_bootstrap(void)
+{
+    tcpip_init(NULL, NULL);
+}
+
+/** @} */
diff --git a/pkg/lwip/contrib/sys_arch.c b/pkg/lwip/contrib/sys_arch.c
new file mode 100644
index 0000000000000000000000000000000000000000..767e74d7a2fdaf3fd143ffc0b54125788383b278
--- /dev/null
+++ b/pkg/lwip/contrib/sys_arch.c
@@ -0,0 +1,221 @@
+/*
+ * 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 <stdbool.h>
+#include <string.h>
+
+#include "arch/cc.h"
+#include "arch/sys_arch.h"
+#include "lwip/err.h"
+#include "lwip/mem.h"
+#include "lwip/opt.h"
+#include "lwip/sys.h"
+
+#include "msg.h"
+#include "sema.h"
+#include "thread.h"
+#include "xtimer.h"
+
+void sys_init(void)
+{
+    return;
+}
+
+err_t sys_mutex_new(sys_mutex_t *mutex)
+{
+    mutex_init((mutex_t *)mutex);
+    return ERR_OK;
+}
+
+void sys_mutex_lock(sys_mutex_t *mutex)
+{
+    mutex_lock((mutex_t *)mutex);
+}
+
+void sys_mutex_unlock(sys_mutex_t *mutex)
+{
+    mutex_unlock((mutex_t *)mutex);
+}
+
+void sys_mutex_free(sys_mutex_t *mutex)
+{
+    mem_free(mutex);
+}
+
+err_t sys_sem_new(sys_sem_t *sem, u8_t count)
+{
+    if (sema_create((sema_t *)sem, (unsigned int)count) < 0) {
+        return ERR_VAL;
+    }
+    return ERR_OK;
+}
+
+void sys_sem_free(sys_sem_t *sem)
+{
+    sema_destroy((sema_t *)sem);
+}
+
+void sys_sem_signal(sys_sem_t *sem)
+{
+    LWIP_ASSERT("invalid semaphor", sys_sem_valid(sem));
+    sema_post((sema_t *)sem);
+}
+
+u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t count)
+{
+    LWIP_ASSERT("invalid semaphor", sys_sem_valid(sem));
+    if (count != 0) {
+        uint64_t stop, start;
+        start = xtimer_now64();
+        int res = sema_wait_timed((sema_t *)sem, count * MS_IN_USEC);
+        stop = xtimer_now64() - start;
+        if (res == -ETIMEDOUT) {
+            return SYS_ARCH_TIMEOUT;
+        }
+        return (u32_t)(stop / MS_IN_USEC);
+    }
+    else {
+        sema_wait_timed((sema_t *)sem, 0);
+        return 0;
+    }
+}
+
+err_t sys_mbox_new(sys_mbox_t *mbox, int size)
+{
+    (void)size;
+    mbox->waiting = 0;
+    cib_init(&mbox->cib, SYS_MBOX_SIZE);
+    mutex_init(&mbox->mutex);
+    if (sema_create(&mbox->not_empty, 0) < 0) {
+        return ERR_VAL;
+    }
+    if (sema_create(&mbox->not_full, 0) < 0) {
+        return ERR_VAL;
+    }
+    return ERR_OK;
+}
+
+void sys_mbox_free(sys_mbox_t *mbox)
+{
+    sema_destroy(&mbox->not_empty);
+    sema_destroy(&mbox->not_full);
+}
+
+void sys_mbox_post(sys_mbox_t *mbox, void *msg)
+{
+    int idx;
+
+    LWIP_ASSERT("invalid mbox", sys_mbox_valid(mbox));
+    mutex_lock(&mbox->mutex);
+    while ((idx = cib_put(&mbox->cib)) < 0) {
+        mbox->waiting++;
+        mutex_unlock(&mbox->mutex);
+        sema_wait_timed(&mbox->not_full, 0);
+        mutex_lock(&mbox->mutex);
+        mbox->waiting--;
+    }
+    mbox->msgs[idx] = msg;
+    if (cib_avail(&mbox->cib) == 1) {
+        sema_post(&mbox->not_empty);
+    }
+    mutex_unlock(&mbox->mutex);
+}
+
+err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
+{
+    int idx;
+
+    LWIP_ASSERT("invalid mbox", sys_mbox_valid(mbox));
+    mutex_lock(&mbox->mutex);
+    if ((idx = cib_put(&mbox->cib)) < 0) {
+        mutex_unlock(&mbox->mutex);
+        return ERR_MEM;
+    }
+    mbox->msgs[idx] = msg;
+    if (cib_avail(&mbox->cib) == 1) {
+        sema_post(&mbox->not_empty);
+    }
+    mutex_unlock(&mbox->mutex);
+    return ERR_OK;
+}
+
+u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
+{
+    u32_t time_needed = 0;
+    unsigned int idx;
+
+    LWIP_ASSERT("invalid mbox", sys_mbox_valid(mbox));
+    mutex_lock(&mbox->mutex);
+    while (cib_avail(&mbox->cib) == 0) {
+        sys_sem_t *not_empty = (sys_sem_t *)(&mbox->not_empty);
+        mutex_unlock(&mbox->mutex);
+        if (timeout != 0) {
+            time_needed = sys_arch_sem_wait(not_empty, timeout);
+            if (time_needed == SYS_ARCH_TIMEOUT) {
+                return SYS_ARCH_TIMEOUT;
+            }
+        }
+        else {
+            sys_arch_sem_wait(not_empty, 0);
+        }
+        mutex_lock(&mbox->mutex);
+    }
+    idx = cib_get(&mbox->cib);
+    if (msg != NULL) {
+        *msg = mbox->msgs[idx];
+    }
+    if (mbox->waiting) {
+        sema_post(&mbox->not_full);
+    }
+    mutex_unlock(&mbox->mutex);
+    return time_needed;
+}
+
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
+{
+    int idx;
+
+    LWIP_ASSERT("invalid mbox", sys_mbox_valid(mbox));
+    mutex_lock(&mbox->mutex);
+    if (cib_avail(&mbox->cib) == 0) {
+        mutex_unlock(&mbox->mutex);
+        return SYS_MBOX_EMPTY;
+    }
+    idx = cib_get(&mbox->cib);
+    if (msg != NULL) {
+        *msg = mbox->msgs[idx];
+    }
+    mutex_unlock(&mbox->mutex);
+    return 0;
+}
+
+sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg,
+                            int stacksize, int prio)
+{
+    kernel_pid_t res;
+    char *stack = mem_malloc((size_t)stacksize);
+
+    if (stack == NULL) {
+        return ERR_MEM;
+    }
+    if ((res = thread_create(stack, stacksize, prio, THREAD_CREATE_STACKTEST,
+                             (thread_task_func_t)thread, arg, name)) <= KERNEL_PID_UNDEF) {
+        abort();
+    }
+    sched_switch((char)prio);
+    return res;
+}
+
+/** @} */
diff --git a/pkg/lwip/include/arch/cc.h b/pkg/lwip/include/arch/cc.h
new file mode 100644
index 0000000000000000000000000000000000000000..663efe794a9384d266d2eaded90c6d19e2dfc94e
--- /dev/null
+++ b/pkg/lwip/include/arch/cc.h
@@ -0,0 +1,132 @@
+/*
+ * 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    lwip_arch_cc    Compiler and processor description
+ * @ingroup     lwip
+ * @brief       Describes compiler and processor to lwIP
+ * @{
+ *
+ * @file
+ * @brief   Compiler and processor definitions
+ *
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ */
+#ifndef LWIP_ARCH_CC_H
+#define LWIP_ARCH_CC_H
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "irq.h"
+#include "byteorder.h"
+#include "mutex.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef BYTE_ORDER
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#   define BYTE_ORDER  (LITTLE_ENDIAN)  /**< platform's endianess */
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#   define BYTE_ORDER  (BIG_ENDIAN)     /**< platform's endianess */
+#else
+#   error "Byte order is neither little nor big!"
+#endif
+#endif
+
+/**
+ * @brief   Generic types for lwIP
+ * @{
+ */
+typedef uint8_t u8_t;                   /**< unsigned 8-bit type */
+typedef int8_t  s8_t;                   /**< signed 8-bit type */
+typedef uint16_t u16_t;                 /**< unsigned 16-bit type */
+typedef int16_t  s16_t;                 /**< signed 16-bit type */
+typedef uint32_t u32_t;                 /**< unsigned 32-bit type */
+typedef int32_t  s32_t;                 /**< signed 32-bit type */
+
+typedef unsigned long mem_ptr_t;        /**< A generic pointer type. It has to be an integer type
+                                         *   (not void*, due to some pointer arithmetics). */
+/**
+ * @}
+ */
+
+/**
+ * @brief   (sn)printf formatters for the generic lwIP types
+ * @{
+ */
+#define X8_F    "02" PRIx8
+#define U16_F   PRIu16
+#define S16_F   PRId16
+#define X16_F   PRIx16
+#define U32_F   PRIu32
+#define S32_F   PRId32
+#define X32_F   PRIx32
+
+#define SZT_F   "lu"
+/**
+ * @}
+ */
+
+/**
+ * @brief   Compiler hints for packing structures
+ * @{
+ */
+#define PACK_STRUCT_FIELD(x)    x
+#define PACK_STRUCT_STRUCT      __attribute__((packed))
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_END
+/**
+ * @}
+ */
+
+/**
+ * @todo check for best value
+ */
+#define LWIP_CHKSUM_ALGORITHM   (3)
+
+#ifdef MODULE_LOG
+#  define LWIP_PLATFORM_DIAG(x)   LOG_INFO x
+#  ifdef NDEBUG
+#    define LWIP_PLATFORM_ASSERT(x)
+#  else
+#    define LWIP_PLATFORM_ASSERT(x)     \
+        do { \
+            LOG_ERROR("Assertion \"%s\" failed at %s:%d\n", x, __FILE__, __LINE__); \
+            fflush(NULL); \
+            abort(); \
+        } while (0)
+#  endif
+#else
+#  define LWIP_PLATFORM_DIAG(x)   printf x
+#  ifdef NDEBUG
+#    define LWIP_PLATFORM_ASSERT(x)
+#  else
+#    define LWIP_PLATFORM_ASSERT(x)     \
+        do { \
+            printf("Assertion \"%s\" failed at %s:%d\n", x, __FILE__, __LINE__); \
+            fflush(NULL); \
+            abort(); \
+        } while (0)
+#  endif
+#endif
+
+#define SYS_ARCH_PROTECT(x)         mutex_lock(&x)
+#define SYS_ARCH_UNPROTECT(x)       mutex_unlock(&x)
+#define SYS_ARCH_DECL_PROTECT(x)    mutex_t x = MUTEX_INIT
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_ARCH_CC_H */
+/** @} */
diff --git a/pkg/lwip/include/arch/sys_arch.h b/pkg/lwip/include/arch/sys_arch.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b02458e2cfacec57e904b44a84fe15e89e7c98c
--- /dev/null
+++ b/pkg/lwip/include/arch/sys_arch.h
@@ -0,0 +1,91 @@
+/*
+ * 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    lwip_arch_sys_arch Architecture depentent definitions
+ * @ingroup     lwip
+ * @brief       Semaphores and mailboxes.
+ * @{
+ *
+ * @file
+ * @brief   Semaphore and mailboxes definitions.
+ *
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ */
+#ifndef LWIP_ARCH_SYS_ARCH_H
+#define LWIP_ARCH_SYS_ARCH_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "cib.h"
+#include "kernel_types.h"
+#include "mutex.h"
+#include "random.h"
+#include "sema.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LWIP_COMPAT_MUTEX   (0)
+#define SYS_SEM_NULL        { 0, PRIORITY_QUEUE_INIT }
+#define SYS_MBOX_SIZE       (8)
+
+typedef struct {
+    cib_t cib;
+    void *msgs[SYS_MBOX_SIZE];
+    mutex_t mutex;
+    sema_t not_empty;
+    sema_t not_full;
+    volatile int waiting;
+} sys_mbox_t;
+
+typedef mutex_t sys_mutex_t;
+typedef sema_t sys_sem_t;
+typedef kernel_pid_t sys_thread_t;
+
+static inline bool sys_mutex_valid(sys_mutex_t *mutex)
+{
+    return mutex != NULL;
+}
+
+static inline bool sys_sem_valid(sys_sem_t *sem)
+{
+    return sem != NULL;
+}
+
+static inline bool sys_mbox_valid(sys_mbox_t *mbox)
+{
+    return (mbox != NULL) && (mbox->cib.mask != 0);
+}
+
+static inline void sys_mbox_set_invalid(sys_mbox_t *mbox)
+{
+    if (mbox != NULL) {
+        mbox->cib.mask = 0;
+    }
+}
+
+#define sys_mutex_valid(mutex)          (sys_mutex_valid(mutex))
+#define sys_mutex_set_invalid(mutex)
+#define sys_sem_valid(sem)              (sys_sem_valid(sem))
+#define sys_sem_set_invalid(sem)
+#define sys_mbox_valid(mbox)            (sys_mbox_valid(mbox))
+#define sys_mbox_set_invalid(mbox)      (sys_mbox_set_invalid(mbox))
+
+#ifdef MODULE_RANDOM
+#define LWIP_RAND()                     (random_uint32())
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_ARCH_SYS_ARCH_H */
+/** @} */
diff --git a/pkg/lwip/include/lwip.h b/pkg/lwip/include/lwip.h
new file mode 100644
index 0000000000000000000000000000000000000000..999d07bca092ca938523a0ecdc14cd37e857f7fa
--- /dev/null
+++ b/pkg/lwip/include/lwip.h
@@ -0,0 +1,45 @@
+/*
+ * 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    pkg_lwip    lwIP
+ * @ingroup     pkg
+ * @brief       A lightweight TCP/IP stack
+ * @see         http://savannah.nongnu.org/projects/lwip/
+ *
+ * lwIP is a lightweight TCP/IP stack primarily for usage with Ethernet.
+ * It can be used with the the @ref conn.
+ *
+ * @{
+ *
+ * @file
+ * @brief   lwIP bootstrap definitions
+ *
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ */
+#ifndef LWIP_H_
+#define LWIP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Initializes lwIP stack.
+ *
+ * This initializes lwIP, i.e. all netdevs are added to as interfaces to the
+ * stack and the stack's thread is started.
+ */
+void lwip_bootstrap(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_H_ */
+/** @} */
diff --git a/pkg/lwip/include/lwipopts.h b/pkg/lwip/include/lwipopts.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d9d9dfac1ecc548ccc68a3003049cf7d12a694b
--- /dev/null
+++ b/pkg/lwip/include/lwipopts.h
@@ -0,0 +1,54 @@
+/*
+ * 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    lwip_opts   lwIP options
+ * @ingroup     lwip
+ * @brief       Options for the lwIP stack
+ * @{
+ *
+ * @file
+ * @brief   Option definitions
+ *
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ */
+#ifndef LWIP_LWIPOPTS_H_
+#define LWIP_LWIPOPTS_H_
+
+#include "thread.h"
+#include "net/gnrc/netif/hdr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   lwIP configuration macros.
+ * @see     lwIP documentation
+ * @{
+ */
+#define LWIP_SOCKET             (0)
+#define MEMP_MEM_MALLOC         (1)
+#define NETIF_MAX_HWADDR_LEN    (GNRC_NETIF_HDR_L2ADDR_MAX_LEN)
+
+#define TCPIP_THREAD_STACKSIZE  (THREAD_STACKSIZE_DEFAULT)
+
+#define MEM_ALIGNMENT           (4)
+#ifndef MEM_SIZE
+/* packet buffer size of GNRC + stack for TCP/IP */
+#define MEM_SIZE                (TCPIP_THREAD_STACKSIZE + 6144)
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LWIP_LWIPOPTS_H_ */
+/** @} */
diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c
index 1d1f43d00a582ec02d9f7723da89af06bb5238fa..ff98b4a8f9e4cc8319b7a0a2d230848ae2280bbf 100644
--- a/sys/auto_init/auto_init.c
+++ b/sys/auto_init/auto_init.c
@@ -76,6 +76,10 @@
 #include "net/gnrc/udp.h"
 #endif
 
+#ifdef MODULE_LWIP
+#include "lwip.h"
+#endif
+
 #ifdef MODULE_FIB
 #include "net/fib.h"
 #endif
@@ -150,7 +154,10 @@ void auto_init(void)
     extern void dht_auto_init(void);
     dht_auto_init();
 #endif
-
+#ifdef MODULE_LWIP
+    DEBUG("Bootstraping lwIP.\n");
+    lwip_bootstrap();
+#endif
 
 /* initialize network devices */
 #ifdef MODULE_AUTO_INIT_GNRC_NETIF