diff --git a/Makefile.dep b/Makefile.dep
index 3f6ef658a8428c28689771dc7d3cf970e63855ec..e0f3d7892689408a84f88788446dcd5e0a25bb17 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -1,9 +1,5 @@
 ifneq (,$(filter libcoap,$(USEPKG)))
-    USEMODULE += pnet
-endif
-
-ifneq (,$(filter pnet,$(USEMODULE)))
-    USEMODULE += vtimer
+    USEMODULE += posix_sockets
 endif
 
 ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pktbuf,$(USEMODULE))))
@@ -276,6 +272,11 @@ ifneq (,$(filter newlib,$(USEMODULE)))
   USEMODULE += uart_stdio
 endif
 
+ifneq (,$(filter posix_sockets,$(USEMODULE)))
+  USEMODULE += posix
+  USEMODULE += random
+endif
+
 ifneq (,$(filter posix,$(USEMODULE)))
   USEMODULE += timex
   USEMODULE += vtimer
diff --git a/sys/Makefile b/sys/Makefile
index 2d4a659303f3295acb7f977ecd6cd8d7ac187ec8..efb6384dadf17aa24bb879fa44753af6ab7461e1 100644
--- a/sys/Makefile
+++ b/sys/Makefile
@@ -1,5 +1,5 @@
-ifneq (,$(filter pnet,$(USEMODULE)))
-    DIRS += posix/pnet
+ifneq (,$(filter posix_sockets,$(USEMODULE)))
+    DIRS += posix/sockets
 endif
 ifneq (,$(filter pthread,$(USEMODULE)))
     DIRS += posix/pthread
diff --git a/sys/Makefile.include b/sys/Makefile.include
index 91ebcbdda0ededcf7759551938334814a5d23738..1c4d405dee44b8b031c431af1b8dc73be549b5b7 100644
--- a/sys/Makefile.include
+++ b/sys/Makefile.include
@@ -18,7 +18,7 @@ ifneq (,$(filter posix,$(USEMODULE)))
     USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
     USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
 endif
-ifneq (,$(filter pnet,$(USEMODULE)))
+ifneq (,$(filter posix_sockets,$(USEMODULE)))
     USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
 endif
 ifneq (,$(filter pthread,$(USEMODULE)))
diff --git a/sys/posix/include/arpa/inet.h b/sys/posix/include/arpa/inet.h
index 1b2d5f51c404cc2f50c7c5692900ea71e4831fe9..98646b9f04d117faf7a85e75587ec94efd5374b7 100644
--- a/sys/posix/include/arpa/inet.h
+++ b/sys/posix/include/arpa/inet.h
@@ -31,29 +31,13 @@
 #include "net/af.h"
 #include "net/ipv4/addr.h"
 #include "net/ipv6/addr.h"
-#include "socket_base/socket.h"
+#include "sys/bytes.h"
+#include "netinet/in.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef uint16_t in_port_t;         /**< Internet port type */
-typedef uint32_t in_addr_t;         /**< IPv4 address type */
-
-/**
- * @brief   Alias to @ref IPV4_ADDR_MAX_STR_LEN
- */
-#ifndef INET_ADDRSTRLEN
-#define INET_ADDRSTRLEN     (IPV4_ADDR_MAX_STR_LEN)
-#endif
-
-/**
- * @brief   Alias to @ref IPV6_ADDR_MAX_STR_LEN
- */
-#ifndef INET6_ADDRSTRLEN
-#define INET6_ADDRSTRLEN    (IPV6_ADDR_MAX_STR_LEN)
-#endif
-
 /**
  * @brief   Size in byte of an IPv4 address
  */
@@ -68,66 +52,6 @@ typedef uint32_t in_addr_t;         /**< IPv4 address type */
 #define IN6ADDRSZ           (sizeof(ipv6_addr_t))
 #endif
 
-
-/**
- * @brief   IPv4 address structure type.
- */
-struct in_addr {
-    in_addr_t s_addr;       ///< an IPv4 address
-};
-
-/**
- * @brief   Convert values between host and network byte order.
- *
- * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htonl.html">
- *          The Open Group Base Specification Issue 7, htonl
- *      </a>
- *
- * @param[in] hostlong  A 32 bit number.
- * @return              The argument value converted from host to network byte
- *                      order.
- */
-#define htonl(hostlong)     HTONL(hostlong)
-
-/**
- * @brief   Convert values between host and network byte order.
- *
- * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htons.html">
- *          The Open Group Base Specification Issue 7, htons
- *      </a>
- *
- * @param[in] hostshort A 16 bit number.
- * @return              The argument value converted from host to network byte
- *                      order.
- */
-#define htons(hostshort)    HTONS(hostshort)
-
-/**
- * @brief   Convert values between host and network byte order.
- *
- * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohl.html">
- *          The Open Group Base Specification Issue 7, ntohl
- *      </a>
- *
- * @param[in] netlong   A 32-bit integer number.
- * @return              The argument value converted from network to host byte
- *                      order.
- */
-#define ntohl(netlong)      NTOHL(netlong)
-
-/**
- * @brief   Convert values between host and network byte order.
- *
- * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohs.html">
- *          The Open Group Base Specification Issue 7, ntohs
- *      </a>
- *
- * @param[in] netshort  A 16-bit integer number.
- * @return              The argument value converted from network to host byte
- *                      order.
- */
-#define ntohs(netshort)     NTOHS(netshort)
-
 /**
  * @brief   Converts an IP address to its string representation
  *
diff --git a/sys/posix/include/netinet/in.h b/sys/posix/include/netinet/in.h
index 4767182d15f06af6f2a5ebaa7a9544946bc0487b..5d3ccb0148c44fe4d3a8c532a46d1ec2b97009cc 100644
--- a/sys/posix/include/netinet/in.h
+++ b/sys/posix/include/netinet/in.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Freie Universität Berlin
+ * Copyright (C) 2013-15 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
@@ -7,7 +7,7 @@
  */
 
 /**
- * @addtogroup  pnet
+ * @addtogroup  posix_sockets
  * @{
  */
 
@@ -25,135 +25,244 @@
 
 #include <inttypes.h>
 #include <sys/socket.h>
-#include <arpa/inet.h>
-#include "net/gnrc/ipv6.h"
-#include "socket_base/socket.h"
+
+#include "net/protnum.h"
+#include "net/ipv6/addr.h"
+#include "sys/bytes.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define INET_ADDRSTRLEN     (16)    /**< Length of the string form for IPv4. */
+#define INET6_ADDRSTRLEN    (46)    /**< Length of the string form for IPv6. */
+
 /**
- * IPv4 socket address type.
+ * IPv4 local host address.
  */
-struct sockaddr_in {
-    sa_family_t     sin_family; ///< Protocol family, always AF_INET.
-    in_port_t       sin_port;   ///< Port number
-    struct in_addr  sin_addr;   ///< IPv4 address
-};
+#define INADDR_ANY          ((in_addr_t)0x00000000)
 
 /**
- * IPv6 address structure type.
+ * IPv4 broadcast address.
  */
-struct in6_addr {
-    /**
-     * Private RIOT-internal data, needs not to be touched by the user.
-     */
-    ipv6_addr_t     __in6_u;
+#define INADDR_BROADCAST    ((in_addr_t)0xffffffff)
 
-    /**
-     * IPv6 Address represented as sequence of 8-bit numbers. Member of
-     * struct in6_addr.
-     */
-#define s6_addr     __in6_u.uint8
+/**
+ * IPv6 wildcard address.
+ */
+#define IN6ADDR_ANY_INIT        IPV6_ADDR_UNSPECIFIED
 
-    /**
-     * IPv6 Address represented as sequence of 16-bit numbers. Member of
-     * struct in6_addr.
-     */
-#define s6_addr16   __in6_u.uint16
+/**
+ * IPv6 loopback address.
+ */
+#define IN6ADDR_LOOPBACK_INIT   IPV6_ADDR_LOOPBACK
 
-    /**
-     * IPv6 Address represented as sequence of 32-bit numbers. Member of
-     * struct in6_addr.
-     */
-#define s6_addr32   __in6_u.uint32
-};
+/**
+ * @name    IPv6 address macros
+ * @{
+ */
+/**
+ * @brief Check if address is the unspecified address (`::`).
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not the unspecified address.
+ * @return any other value otherwise.
+ */
+#define IN6_IS_ADDR_UNSPECIFIED(addr)   ((int)(ipv6_addr_is_unspecified((const ipv6_addr_t *)(addr))))
 
 /**
- * IPv6 socket address type.
+ * @brief Check if address is the loopback address (`::1`).
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not the loopback address.
+ * @return any other value otherwise.
  */
-struct sockaddr_in6 {
-    /**
-     * Private RIOT-internal data, needs not to be touched by the user.
-     */
-    sockaddr6_t __in6_a;
+#define IN6_IS_ADDR_LOOPBACK(addr)      ((int)(ipv6_addr_is_loopback((const ipv6_addr_t *)(addr))))
 
-    /**
-     * Protocol family, always AF_INET6. Member of struct sockaddr_in6
-     */
-#define         sin6_family     __in6_a.sin6_family
+/**
+ * @brief Check if address is a multicast address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not a multicast address.
+ * @return any other value otherwise.
+ */
+#define IN6_IS_ADDR_MULTICAST(addr)     ((int)(ipv6_addr_is_multicast((const ipv6_addr_t *)(addr))))
 
-    /**
-     * Port number. Member of struct sockaddr_in6
-     */
-#define         sin6_port       __in6_a.sin6_port
+/**
+ * @brief Check if address is a link-local address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not a link-local address.
+ * @return any other value otherwise.
+ */
+#define IN6_IS_ADDR_LINKLOCAL(addr)     ((int)(ipv6_addr_is_link_local((const ipv6_addr_t *)addr)))
 
-    /**
-     * IPv6 traffic class and flow information. Member of struct sockaddr_in6
-     */
-#define         sin6_flowinfo   __in6_a.sin6_flowinfo
+/**
+ * @brief Check if address is a site-local address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not a site-local address.
+ * @return any other value otherwise.
+ */
+#define IN6_IS_ADDR_SITELOCAL(addr)     ((int)(ipv6_addr_is_site_local((const ipv6_addr_t *)addr)))
 
-    /**
-     * IPv6 address. Member of struct sockaddr_in6
-     */
-#define         sin6_addr       __in6_a.sin6_addr
+/**
+ * @brief Check if address is an IPv4 mapped address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not an IPv4 mapped address.
+ * @return any other value otherwise.
+ */
+#define IN6_IS_ADDR_V4MAPPED(addr)      ((int)(ipv6_addr_is_ipv4_mapped((const ipv6_addr_t *)addr)))
 
-    /**
-     * Set of interfaces for a scope.
-     */
-    uint32_t    sin6_scope_id;
-};
+/**
+ * @brief Check if address is an IPv4-compatible address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not an IPv4-compatible address.
+ * @return any other value otherwise.
+ */
+#define IN6_IS_ADDR_V4COMPAT(addr)      ((int)(ipv6_addr_is_ipv4_compat((const ipv6_addr_t *)addr)))
 
 /**
- * IPv6 wildcard address.
+ * @brief Check if address is a multicast node-local address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not a multicast node-local address.
+ * @return any other value otherwise.
  */
-#define IN6ADDR_ANY_INIT        {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
+#define IN6_IS_ADDR_MC_NODELOCAL(addr)  (IN6_IS_ADDR_MULTICAST(addr) && \
+        (int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_IF_LOCAL))
 
 /**
- * IPv6 loopback address.
+ * @brief Check if address is a multicast link-local address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not a multicast link-local address.
+ * @return any other value otherwise.
  */
-#define IN6ADDR_LOOPBACK_INIT   {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}
+#define IN6_IS_ADDR_MC_LINKLOCAL(addr)  (IN6_IS_ADDR_MULTICAST(addr) && \
+        (int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_LINK_LOCAL))
 
 /**
- * IPv6 socket address for the wildcard address.
+ * @brief Check if address is a multicast site-local address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not a multicast site-local address.
+ * @return any other value otherwise.
  */
-extern const struct sockaddr_in6 in6addr_any;
+#define IN6_IS_ADDR_MC_SITELOCAL(addr)  (IN6_IS_ADDR_MULTICAST(addr) && \
+        (int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_SITE_LOCAL))
 
 /**
- * IPv6 socket address for the loopback address.
+ * @brief Check if address is a multicast organization-local address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not a multicast organization-local address.
+ * @return any other value otherwise.
  */
-extern const struct sockaddr_in6 in6addr_loopback;
+#define IN6_IS_ADDR_MC_ORGLOCAL(addr)   (IN6_IS_ADDR_MULTICAST(addr) && \
+        (int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_ORG_LOCAL))
 
 /**
- * IPv4 local host address.
+ * @brief Check if address is a multicast global address.
+ *
+ * @param[in] addr  address of type `const struct in6_addr *`
+ *
+ * @return 0, when an address is not a multicast global address.
+ * @return any other value otherwise.
  */
-#define INADDR_ANY          ((in_addr_t)0x00000000)
+#define IN6_IS_ADDR_MC_GLOBAL(addr)     (IN6_IS_ADDR_MULTICAST(addr) && \
+        (int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_GLOBAL))
+/** @} */
 
 /**
- * IPv4 broadcast address.
+ * @name    Protocol numbers for option
+ * @{
  */
-#define INADDR_BROADCAST    ((in_addr_t)0xffffffff)
+#define IPPROTO_IP      (PROTNUM_IPV4)          /**< Internet Protocol version 4 */
+#define IPPROTO_IPV6    (PROTNUM_IPV6)          /**< Internet Protocol version 6 */
+#define IPPROTO_ICMP    (PROTNUM_ICMP)          /**< Internet Control Message Protocol */
+#define IPPROTO_ICMPV6  (PROTNUM_ICMPV6)        /**< ICMP for IPv6 */
+#define IPPROTO_RAW     (PROTNUM_RESERVED)      /**< Raw IP packets protocol */
+#define IPPROTO_TCP     (PROTNUM_TCP)           /**< Transmission control protocol */
+#define IPPROTO_UDP     (PROTNUM_UDP)           /**< User datagram protocol */
+/** @} */
 
 /**
- * Multicast hop limit option name for getsockopt() or setsockopt()
- *
- * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html">
- *          The Open Group Base Specification Issue 7, getsockopt
- *      </a>
- * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">
- *          The Open Group Base Specification Issue 7, setsockopt
- *      </a>
+ * @todo IPv6 option names
  */
-#define IPV6_MULTICAST_HOPS 0x12
+
+typedef uint16_t in_port_t;         /**< Internet port type */
+typedef uint32_t in_addr_t;         /**< IPv4 address type */
 
 /**
- * Test for IPv6 multicast address.
- *
- * @param[in] a An IPv6 address.
- * @return  1 if *a* is an multicast address, 0 if not.
+ * IPv4 address structure type.
  */
-#define IN6_IS_ADDR_MULTICAST(a) (((const uint8_t *) (a))[0] == 0xff)
+struct in_addr {
+    in_addr_t s_addr;           /**< an IPv4 address */
+};
+
+/**
+ * @brief   IPv6 address structure type.
+ */
+struct in6_addr {
+    uint8_t s6_addr[16];        /**< unsigned 8-bit integer array */
+};
+
+/**
+ * @brief   IPv4 socket address type.
+ * @extends struct sockaddr
+ */
+struct sockaddr_in {
+    sa_family_t     sin_family; /**< Protocol family, always AF_INET */
+    in_port_t       sin_port;   /**< Port number */
+    struct in_addr  sin_addr;   /**< IPv4 address */
+};
+
+/**
+ * IPv6 socket address type.
+ * @extends struct sockaddr
+ */
+struct sockaddr_in6 {
+    /**
+     * Protocol family, always AF_INET6. Member of struct sockaddr_in6
+     */
+    int             sin6_family;    /**< Protocol family, always AF_INET6 */
+    in_port_t       sin6_port;      /**< Port number */
+    uint32_t        sin6_flowinfo;  /**< IPv6 traffic class and flow information */
+    struct in6_addr sin6_addr;      /**< IPv6 address */
+    uint32_t        sin6_scope_id;  /**< Set of interfaces for a scope */
+};
+
+/**
+ * @brief   IPv6 multicast request.
+ */
+struct ipv6_mreq {
+    struct in6_addr ipv6mr_multiaddr;   /**< an IPv6 multicast address */
+    unsigned        ipv6mr_interface;   /**< interface index, leave 0 for default */
+};
+
+/**
+ * IPv6 socket address for the wildcard address.
+ */
+extern const struct sockaddr_in6 in6addr_any;
+
+/**
+ * IPv6 socket address for the loopback address.
+ */
+extern const struct sockaddr_in6 in6addr_loopback;
 
 #ifdef __cplusplus
 }
diff --git a/sys/posix/include/sys/bytes.h b/sys/posix/include/sys/bytes.h
new file mode 100644
index 0000000000000000000000000000000000000000..86d4872f6211d4c3e3eee85a83017e1eda55320b
--- /dev/null
+++ b/sys/posix/include/sys/bytes.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+/**
+ * @addtogroup  posix_sockets
+ */
+/**
+ * @{
+ *
+ * @file
+ * @brief   System-internal byte operations.
+ *
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ */
+#ifndef BYTES_H_
+#define BYTES_H_
+
+#include "byteorder.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief   Convert values between host and network byte order.
+ *
+ * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htonl.html">
+ *          The Open Group Base Specification Issue 7, htonl
+ *      </a>
+ *
+ * @param[in] hostlong  A 32 bit number.
+ * @return              The argument value converted from host to network byte
+ *                      order.
+ */
+#ifndef htonl
+#define htonl(hostlong)     HTONL(hostlong)
+#endif
+
+/**
+ * @brief   Convert values between host and network byte order.
+ *
+ * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htons.html">
+ *          The Open Group Base Specification Issue 7, htons
+ *      </a>
+ *
+ * @param[in] hostshort A 16 bit number.
+ * @return              The argument value converted from host to network byte
+ *                      order.
+ */
+#ifndef htons
+#define htons(hostshort)    HTONS(hostshort)
+#endif
+
+/**
+ * @brief   Convert values between host and network byte order.
+ *
+ * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohl.html">
+ *          The Open Group Base Specification Issue 7, ntohl
+ *      </a>
+ *
+ * @param[in] netlong   A 32-bit integer number.
+ * @return              The argument value converted from network to host byte
+ *                      order.
+ */
+#ifndef ntohl
+#define ntohl(netlong)      NTOHL(netlong)
+#endif
+
+/**
+ * @brief   Convert values between host and network byte order.
+ *
+ * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohs.html">
+ *          The Open Group Base Specification Issue 7, ntohs
+ *      </a>
+ *
+ * @param[in] netshort  A 16-bit integer number.
+ * @return              The argument value converted from network to host byte
+ *                      order.
+ */
+#ifndef ntohs
+#define ntohs(netshort)     NTOHS(netshort)
+#endif
+
+typedef size_t socklen_t;           /**< socket address length */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BYTES_H_ */
+/** @} */
diff --git a/sys/posix/include/sys/socket.h b/sys/posix/include/sys/socket.h
index e0db357b186e552421fdb37d71d264fc5a073e8d..52fcd6d4bb68510f036178a216c496311cfa2335 100644
--- a/sys/posix/include/sys/socket.h
+++ b/sys/posix/include/sys/socket.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Freie Universität Berlin
+ * Copyright (C) 2013-15 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
@@ -7,7 +7,7 @@
  */
 
 /**
- * @addtogroup  pnet
+ * @addtogroup  posix_sockets
  * @{
  */
 
@@ -18,6 +18,12 @@
  *              The Open Group Base Specifications Issue 7, <sys/socket.h>
  *          </a>
  *
+ * @todo Omitted from original specification for now:
+ * * struct msghdr, struct cmesghdr, and struct linger and all related defines
+ * * getsockopt()/setsockopt() and all related defines.
+ * * shutdown() and all related defines.
+ * * sockatmark()
+ *
  * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
  */
 #ifndef _SYS_SOCKET_H
@@ -32,135 +38,81 @@
 #define __SOCKADDR_COMMON_SIZE  (sizeof (unsigned short int))
 #endif
 
+#include <stdlib.h>
 #include <sys/types.h>
+#include <sys/uio.h>
 
-#include "cpu.h"
+#include "kernel_types.h"
 #include "net/af.h"
-
-#include "socket_base/socket.h"
+#include "sys/bytes.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /**
- * @brief   Used to define the socket address.
- */
-struct __attribute__((packed)) sockaddr {
-    sa_family_t sa_family;  ///< Address family
-    char sa_data[14];       ///< Socket address (variable length data)
-};
-
-/**
- * @brief   Implementation based socket address table.
- */
-struct __attribute__((packed)) sockaddr_storage {
-    sa_family_t ss_family;  ///< Address family
-    char ss_data[14];       ///< address data
-};
-
-/*
- * Omitted from original specification for now are struct msghdr,
- * struct cmesghdr, and struct linger and all related defines
- */
-
-/**
- * @brief  *level* value for getsockopt() or setsockopt().
- */
-#define SOL_SOCKET 1    ///< Options to be accessed at socket level, not
-                        ///< protocol level.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_ACCEPTCONN   1   ///< Socket is accepting connections.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_BROADCAST    2   ///< Transmission of broadcast messages is supported.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_DEBUG        3   ///< Debugging information is being recorded.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_DONTROUTE    4   ///< Bypass normal routing.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_ERROR        5   ///< Socket error status.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_KEEPALIVE    6   ///< Connections are kept alive with periodic messages.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_OOBINLINE    7   ///< Out-of-band data is transmitted in line.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_RCVBUF       8   ///< Receive buffer size.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_RCVLOWAT     9   ///< Receive "low water mark".
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_RCVTIMEO    10   ///< Receive timeout.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_REUSEADDR   11   ///< Reuse of local addresses is supported.
-
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
+ * @brief   Maximum data length for a socket address.
+ *
+ * It is assumed that struct sockaddr_in6 is currently the longest socket address struct.
+ * As such it's data length is taken consisting of the IPv6 address (16 byte), the port (2 byte),
+ * the flow information (4 byte) and the scope ID (4 byte)
  */
-#define SO_SNDBUF      12   ///< Send buffer size.
+#define SOCKADDR_MAX_DATA_LEN   (26)
 
 /**
- * @brief   *option_name* value for getsockopt() or setsockopt()
+ * @name    Socket types
+ * @{
  */
-#define SO_SNDLOWAT    13   ///< Send "low water mark".
+#define SOCK_DGRAM      (1)     /**< Datagram socket */
+#define SOCK_RAW        (2)     /**< Raw socket */
+#define SOCK_SEQPACKET  (3)     /**< Sequenced-packet socket */
+#define SOCK_STREAM     (4)     /**< Stream socket */
+/** @} */
 
-/**
- * @brief   *option_name* value for getsockopt() or setsockopt()
- */
-#define SO_SNDTIMEO    14   ///< Send timeout.
+#define SOL_SOCKET      (-1)    /**< Options to be accessed at socket level, not protocol level */
 
 /**
- * @brief   *option_name* value for getsockopt() or setsockopt()
+ * @name    Option names
+ * @brief   Option names for getsockopt() and setsockopt()
+ * @{
  */
-#define SO_TYPE        15   ///< Socket type.
-
-#define SOMAXCONN       16  ///< Maximum *backlog* size for listen()
+#define SO_ACCEPTCONN   (0)     /**< Socket is accepting connections. */
+#define SO_BROADCAST    (1)     /**< Transmission of broadcast messages is supported. */
+#define SO_DEBUG        (2)     /**< Debugging information is being recorded. */
+#define SO_DONTROUTE    (3)     /**< Bypass normal routing. */
+#define SO_ERROR        (4)     /**< Socket error status. */
+#define SO_KEEPALIVE    (5)     /**< Connections are kept alive with periodic messages. */
+#define SO_LINGER       (6)     /**< Socket lingers on close. */
+#define SO_OOBINLINE    (7)     /**< Out-of-band data is transmitted in line. */
+#define SO_RCVBUF       (8)     /**< Receive buffer size. */
+#define SO_RCVLOWAT     (9)     /**< Receive "low water mark". */
+#define SO_RCVTIMEO     (10)    /**< Receive timeout. */
+#define SO_REUSEADDR    (11)    /**< Reuse of local addresses is supported. */
+#define SO_SNDBUF       (12)    /**< Send buffer size. */
+#define SO_SNDLOWAT     (13)    /**< Send "low water mark". */
+#define SO_SNDTIMEO     (14)    /**< Send timeout. */
+#define SO_TYPE         (15)    /**< Socket type. */
+/** @} */
+
+typedef unsigned int sa_family_t;   /**< address family type */
 
 /**
- * @brief   *how* value for shutdown()
+ * @brief   Used to define the socket address.
  */
-#define SHUT_WR     1   ///< Disables further send operations.
+struct sockaddr {
+    sa_family_t sa_family;                  /**< Address family */
+    char sa_data[SOCKADDR_MAX_DATA_LEN];    /**< Socket address (variable length data) */
+};
 
 /**
- * @brief   *how* value for shutdown()
+ * @brief   Implementation based socket address table.
+ * @extends struct sockaddr
  */
-#define SHUT_RD     2   ///< Disables further receive operations.
+struct sockaddr_storage {
+    sa_family_t ss_family;                  /**< Address family */
+    uint8_t ss_data[SOCKADDR_MAX_DATA_LEN]; /**< Socket address */
+};
 
-/**
- * @brief   *how* value for shutdown()
- */
-#define SHUT_RDWR   3   ///< Disables further send and receive operations.
 
 /**
  * @brief   Accept a new connection on a socket
@@ -260,27 +212,56 @@ int bind(int socket, const struct sockaddr *address,
 int connect(int socket, const struct sockaddr *address, socklen_t address_len);
 
 /**
- * @brief   Get the socket options.
+ * @brief   Get the name of the peer socket.
+ * @details The getpeername() function shall retrieve the peer address of the specified socket,
+ *          store this address in the sockaddr structure pointed to by the @p address argument,
+ *          and store the length of this address in the object pointed to by the @p address_len
+ *          argument.
  *
- * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html">
- *          The Open Group Base Specification Issue 7, getsockopt
+ * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html">
+ *          The Open Group Base Specification Issue 7, getpeername
  *      </a>
  *
- * @param[in] socket        Specifies the file descriptor associated with the socket.
- * @param[in] level         Protocol level this option applies to. Valid values
- *                          are defined in <sys/socket.h>, prefixed with
- *                          ``SOL_``.
- * @param[in] option_name   Defines the option to get. Valid values are defined
- *                          in <sys/socket.h>, prefixed with ``SO_``.
- * @param[out] option_value Buffer to write the current value of the socket
- *                          option into.
- * @param[out] option_len   Length of the option value in byte.
+ * @param[in] socket            Specifies the file descriptor associated with the
+ *                              socket.
+ * @param[out] address          Points to a sockaddr structure containing the peer
+ *                              address. The length and format of the address depend
+ *                              on the address family of the socket.
+ * @param[in,out] address_len   Specifies the length of the sockaddr structure on input and the
+ *                              length of the stored address on output. If the address is greater
+ *                              than the length of the supplied sockaddr structure, the stored
+ *                              address shal be truncated.
+ * @return  Upon successful completion, getpeername() shall return 0; otherwise,
+ *          -1 shall be returned and errno set to indicate the error.
+ */
+int getpeername(int socket, struct sockaddr *__restrict address,
+                socklen_t *__restrict address_len);
+
+/**
+ * @brief   Get the socket name.
+ * @details The getsockname() function shall retrieve the locally-bound name of the specified
+ *          socket, store this address in the sockaddr structure pointed to by the @p address
+ *          argument, and store the length of this address in the object pointed to by the
+ *          @p address_len argument.
  *
- * @return  Upon successful completion, getsockopt() shall return 0; otherwise,
+ * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html">
+ *          The Open Group Base Specification Issue 7, getsockname
+ *      </a>
+ *
+ * @param[in] socket            Specifies the file descriptor associated with the
+ *                              socket.
+ * @param[out] address          Points to a sockaddr structure containing the peer
+ *                              address. The length and format of the address depend
+ *                              on the address family of the socket.
+ * @param[in,out] address_len   Specifies the length of the sockaddr structure on input and the
+ *                              length of the stored address on output. If the address is greater
+ *                              than the length of the supplied sockaddr structure, the stored
+ *                              address shal be truncated.
+ * @return  Upon successful completion, getsockname() shall return 0; otherwise,
  *          -1 shall be returned and errno set to indicate the error.
  */
-int getsockopt(int socket, int level, int option_name,
-               void *__restrict option_value, socklen_t *__restrict option_len);
+int getsockname(int socket, struct sockaddr *__restrict address,
+                socklen_t *__restrict address_len);
 
 /**
  * @brief   Listen for socket connections and limit the queue of incoming
@@ -396,9 +377,9 @@ ssize_t send(int socket, const void *buffer, size_t length, int flags);
  * @details Shall send a message through a connection-mode or
  *          connectionless-mode socket. If the socket is a connectionless-mode
  *          socket, the message shall be sent to the address specified by
- *          *dest_addr* if no pre-specified peer address has been set. If a
+ *          @p address if no pre-specified peer address has been set. If a
  *          peer address has been pre-specified, either the message shall be
- *          sent to the address specified by *dest_addr* (overriding the
+ *          sent to the address specified by @p address (overriding the
  *          pre-specified peer address), or the function shall return -1 and
  *          set errno to EISCONN.
  *
@@ -406,45 +387,23 @@ ssize_t send(int socket, const void *buffer, size_t length, int flags);
  *          The Open Group Base Specification Issue 7, sendto
  *      </a>
  *
- * @param[in] socket    Specifies the socket file descriptor.
- * @param[in] message   Points to the buffer containing the message to send.
- * @param[in] length    Specifies the length of the message in bytes.
- * @param[in] flags     Specifies the type of message reception. Support
- *                      for values other than 0 is not implemented yet.
- * @param[in] dest_addr Points to a sockaddr structure containing the
- *                      destination address. The length and format of the
- *                      address depend on the address family of the socket.
- * @param[in] dest_len  Specifies the length of the sockaddr structure pointed
- *                      to by the *dest_addr* argument.
+ * @param[in] socket        Specifies the socket file descriptor.
+ * @param[in] buffer        Points to the buffer containing the message to send.
+ * @param[in] length        Specifies the length of the message in bytes.
+ * @param[in] flags         Specifies the type of message reception. Support
+ *                          for values other than 0 is not implemented yet.
+ * @param[in] address       Points to a sockaddr structure containing the
+ *                          destination address. The length and format of the
+ *                          address depend on the address family of the socket.
+ * @param[in] address_len   Specifies the length of the sockaddr structure pointed
+ *                          to by the @p address argument.
  *
  * @return  Upon successful completion, send() shall return the number of bytes
  *          sent. Otherwise, -1 shall be returned and errno set to indicate the
  *          error.
  */
-ssize_t sendto(int socket, const void *message, size_t length, int flags,
-               const struct sockaddr *dest_addr, socklen_t dest_len);
-
-/**
- * @brief   Set the socket options.
- *
- * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">
- *          The Open Group Base Specification Issue 7, setsockopt
- *      </a>
- *
- * @param[in] socket        Specifies the file descriptor associated with the socket.
- * @param[in] level         Protocol level this option applies to. Valid values
- *                          are defined in <sys/socket.h>, prefixed with
- *                          ``SOL_``.
- * @param[in] option_name   Defines the option to set. Valid values are defined
- *                          in <sys/socket.h>, prefixed with ``SO_``.
- * @param[in] option_value  Value for the option to set.
- * @param[in] option_len    Length of the option value in byte.
- *
- * @return  Upon successful completion, setsockopt() shall return 0; otherwise,
- *          -1 shall be returned and errno set to indicate the error.
- */
-int setsockopt(int socket, int level, int option_name, const void *option_value,
-               socklen_t option_len);
+ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
+               const struct sockaddr *address, socklen_t address_len);
 
 /**
  * @brief   Create an endpoint for communication.
@@ -469,6 +428,34 @@ int setsockopt(int socket, int level, int option_name, const void *option_value,
  */
 int socket(int domain, int type, int protocol);
 
+/**
+ * @todo implement out these functions
+ * @{
+ */
+static inline int getsockopt(int socket, int level, int option_name, void *option_value,
+                             socklen_t *option_len)
+{
+    (void)socket;
+    (void)level;
+    (void)option_name;
+    (void)option_value;
+    (void)option_len;
+    return -1;
+}
+
+static inline int setsockopt(int socket, int level, int option_name, const void *option_value,
+                             socklen_t option_len)
+{
+    (void)socket;
+    (void)level;
+    (void)option_name;
+    (void)option_value;
+    (void)option_len;
+    return -1;
+}
+
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/sys/posix/pnet/netinet_in.c b/sys/posix/pnet/netinet_in.c
deleted file mode 100644
index 7ef06230c3cecdfbaca4fb1f13fa94fdf126a671..0000000000000000000000000000000000000000
--- a/sys/posix/pnet/netinet_in.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2013 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
- * @brief   Providing values for in6addr_any and in6addr_loopback.
- * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
- */
-#include <netinet/in.h>
-
-const struct sockaddr_in6 in6addr_any = {{AF_INET6, 0, 0, IN6ADDR_ANY_INIT}, 0};
-const struct sockaddr_in6 in6addr_loopback = {{
-        AF_INET6, 0, 0, IN6ADDR_LOOPBACK_INIT
-    }, 0
-};
-
-/**
- * @}
- */
diff --git a/sys/posix/pnet/sys_socket.c b/sys/posix/pnet/sys_socket.c
deleted file mode 100644
index bc870a9f69de9cfbe94a2549c8e83a7a51eb9f2e..0000000000000000000000000000000000000000
--- a/sys/posix/pnet/sys_socket.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2013 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
- * @brief   Providing implementation for POSIX socket wrapper.
- * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
- * @todo
- */
-
-#include "sys/socket.h"
-
-int flagless_send(int fd, const void *buf, size_t len)
-{
-    (void)fd;
-    (void)buf;
-    (void)len;
-
-    return -1;
-}
-
-int flagless_recv(int fd, void *buf, size_t len)
-{
-    return (int)socket_base_recv(fd, buf, (uint32_t)len, 0);
-}
-
-int socket(int domain, int type, int protocol)
-{
-    (void)domain;
-    (void)type;
-    (void)protocol;
-
-    return -1;
-}
-
-
-int accept(int socket, struct sockaddr *restrict address,
-           socklen_t *restrict address_len)
-{
-    (void)socket;
-    (void)address;
-    (void)address_len;
-
-    return -1;
-}
-
-int bind(int socket, const struct sockaddr *address, socklen_t address_len)
-{
-    (void)socket;
-    (void)address;
-    (void)address_len;
-
-    return -1;
-}
-
-int connect(int socket, const struct sockaddr *address, socklen_t address_len)
-{
-    (void)socket;
-    (void)address;
-    (void)address_len;
-
-    return -1;
-}
-
-int getsockopt(int socket, int level, int option_name,
-               void *restrict option_value, socklen_t *restrict option_len)
-{
-    // TODO
-    (void) socket;
-    (void) level;
-    (void) option_name;
-    (void) option_value;
-    (void) option_len;
-
-    return -1;
-}
-
-int listen(int socket, int backlog)
-{
-    (void)socket;
-    (void)backlog;
-
-    return -1;
-}
-
-ssize_t recv(int socket, void *buffer, size_t length, int flags)
-{
-    (void)socket;
-    (void)buffer;
-    (void)length;
-    (void)flags;
-
-    return -1;
-}
-
-ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
-                 struct sockaddr *restrict address,
-                 socklen_t *restrict address_len)
-{
-    (void)socket;
-    (void)buffer;
-    (void)length;
-    (void)flags;
-    (void)address;
-    (void)address_len;
-
-    return -1;
-}
-
-ssize_t send(int socket, const void *buffer, size_t length, int flags)
-{
-    (void)socket;
-    (void)buffer;
-    (void)length;
-    (void)flags;
-    return -1;
-}
-
-ssize_t sendto(int socket, const void *message, size_t length, int flags,
-               const struct sockaddr *dest_addr, socklen_t dest_len)
-{
-    // TODO
-    (void)socket;
-    (void)message;
-    (void)length;
-    (void)flags;
-    (void)dest_addr;
-    (void)dest_len;
-
-    return -1;
-}
-
-int setsockopt(int socket, int level, int option_name, const void *option_value,
-               socklen_t option_len)
-{
-    // TODO
-    (void) socket;
-    (void) level;
-    (void) option_name;
-    (void) option_value;
-    (void) option_len;
-
-    return -1;
-}
-
-/**
- * @}
- */
diff --git a/sys/posix/pnet/Makefile b/sys/posix/sockets/Makefile
similarity index 58%
rename from sys/posix/pnet/Makefile
rename to sys/posix/sockets/Makefile
index 48422e909a47d7cd428d10fa73825060ccc8d8c2..7f84cdea31b2faa152b1425ffcdc5125160f2c33 100644
--- a/sys/posix/pnet/Makefile
+++ b/sys/posix/sockets/Makefile
@@ -1 +1,3 @@
+MODULE = posix_sockets
+
 include $(RIOTBASE)/Makefile.base
diff --git a/sys/posix/pnet/doc.txt b/sys/posix/sockets/doc.txt
similarity index 78%
rename from sys/posix/pnet/doc.txt
rename to sys/posix/sockets/doc.txt
index cb5bdbaa22db37eb92d4b87c1660983fc03a9f27..c02bd2f6fbff0def890f5b9aa61324efd59d307c 100644
--- a/sys/posix/pnet/doc.txt
+++ b/sys/posix/sockets/doc.txt
@@ -7,8 +7,8 @@
  */
 
 /**
- * @defgroup pnet  Network related POSIX wrapper of RIOT
- * @brief   Network related POSIX header files
+ * @defgroup posix_sockets  POSIX sockets
+ * @brief   POSIX socket wrapper of RIOT's @ref net_conn
  * @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/">
  *          The Open Group Specifications Issue 7
  *      </a>
diff --git a/sys/posix/sockets/posix_sockets.c b/sys/posix/sockets/posix_sockets.c
new file mode 100644
index 0000000000000000000000000000000000000000..e1c2015981dba2941505b73f2f1629c03bc3ca6d
--- /dev/null
+++ b/sys/posix/sockets/posix_sockets.c
@@ -0,0 +1,890 @@
+/*
+ * Copyright (C) 2015 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
+ * @brief   Providing implementation for POSIX socket wrapper.
+ * @author  Martine Lenders <mlenders@inf.fu-berlin.de>
+ * @todo
+ */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "fd.h"
+#include "mutex.h"
+#include "net/conn.h"
+#include "net/ipv4/addr.h"
+#include "net/ipv6/addr.h"
+#include "random.h"
+
+#include "sys/socket.h"
+#include "netinet/in.h"
+
+#define SOCKET_POOL_SIZE    (4)
+
+/**
+ * @brief   Unitfied connection type.
+ */
+typedef union {
+    /* is not supposed to be used */
+    /* cppcheck-suppress unusedStructMember */
+    int undef;                  /**< for case that no connection module is present */
+#ifdef  MODULE_CONN_IP
+    conn_ip_t raw;              /**< raw IP connection */
+#endif  /* MODULE_CONN_IP */
+#ifdef  MODULE_CONN_TCP
+    conn_tcp_t tcp;             /**< TCP connection */
+#endif  /* MODULE_CONN_TCP */
+#ifdef  MODULE_CONN_UDP
+    conn_udp_t udp;             /**< UDP connection */
+#endif  /* MODULE_CONN_UDP */
+} socket_conn_t;
+
+typedef struct {
+    int fd;
+    sa_family_t domain;
+    int type;
+    int protocol;
+    bool bound;
+    socket_conn_t conn;
+} socket_t;
+
+socket_t _pool[SOCKET_POOL_SIZE];
+mutex_t _pool_mutex = MUTEX_INIT;
+
+const struct sockaddr_in6 in6addr_any = {AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0};
+const struct sockaddr_in6 in6addr_loopback = {
+    AF_INET6, 0, 0, IN6ADDR_LOOPBACK_INIT, 0
+};
+
+static socket_t *_get_free_socket(void)
+{
+    for (int i = 0; i < SOCKET_POOL_SIZE; i++) {
+        if (_pool[i].domain == AF_UNSPEC) {
+            return &_pool[i];
+        }
+    }
+    return NULL;
+}
+
+static socket_t *_get_socket(int fd)
+{
+    for (int i = 0; i < SOCKET_POOL_SIZE; i++) {
+        if (_pool[i].fd == fd) {
+            return &_pool[i];
+        }
+    }
+    return NULL;
+}
+
+static inline int _choose_ipproto(int type, int protocol)
+{
+    switch (type) {
+#ifdef MODULE_CONN_TCP
+        case SOCK_STREAM:
+            if ((protocol == 0) || (protocol == IPPROTO_TCP)) {
+                return protocol;
+            }
+            else {
+                errno = EPROTOTYPE;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_UDP
+        case SOCK_DGRAM:
+            if ((protocol == 0) || (protocol == IPPROTO_UDP)) {
+                return protocol;
+            }
+            else {
+                errno = EPROTOTYPE;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_IP
+        case SOCK_RAW:
+            return protocol;
+#endif
+        default:
+            (void)protocol;
+            break;
+    }
+    errno = EPROTONOSUPPORT;
+    return -1;
+}
+
+static inline void _htons_port(uint16_t *port)
+{
+    *port = htons(*port);
+}
+
+static inline ipv4_addr_t *_in_addr_ptr(struct sockaddr_storage *addr)
+{
+    return (ipv4_addr_t *)(&((struct sockaddr_in *)addr)->sin_addr);
+}
+
+static inline uint16_t *_in_port_ptr(struct sockaddr_storage *addr)
+{
+    return &((struct sockaddr_in *)addr)->sin_port;
+}
+
+static inline ipv6_addr_t *_in6_addr_ptr(struct sockaddr_storage *addr)
+{
+    return (ipv6_addr_t *)(&((struct sockaddr_in6 *)addr)->sin6_addr);
+}
+
+static inline uint16_t *_in6_port_ptr(struct sockaddr_storage *addr)
+{
+    return &((struct sockaddr_in6 *)addr)->sin6_port;
+}
+
+static inline socklen_t _addr_truncate(struct sockaddr *out, socklen_t out_len,
+                                       struct sockaddr_storage *in, socklen_t target_size)
+{
+    out_len = (out_len < target_size) ? out_len : target_size;
+    memcpy(out, in, out_len);
+    return out_len;
+}
+
+static inline int _get_data_from_sockaddr(const struct sockaddr *address, size_t address_len,
+                                          void **addr, size_t *addr_len, uint16_t *port)
+{
+    switch (address->sa_family) {
+        case AF_INET:
+            if (address_len < sizeof(struct sockaddr_in)) {
+                errno = EINVAL;
+                return -1;
+            }
+            struct sockaddr_in *in_addr = (struct sockaddr_in *)address;
+            *addr = &in_addr->sin_addr;
+            *addr_len = sizeof(ipv4_addr_t);
+            /* XXX sin_port is in network byteorder */
+            *port = ntohs(in_addr->sin_port);
+            break;
+        case AF_INET6:
+            if (address_len < sizeof(struct sockaddr_in6)) {
+                errno = EINVAL;
+                return -1;
+            }
+            struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)address;
+            *addr = &in6_addr->sin6_addr;
+            *addr_len = sizeof(ipv6_addr_t);
+            /* XXX sin6_port is in network byteorder */
+            *port = ntohs(in6_addr->sin6_port);
+            break;
+        default:
+            errno = EAFNOSUPPORT;
+            return -1;
+    }
+    return 0;
+}
+
+static int socket_close(int socket)
+{
+    socket_t *s;
+    int res = 0;
+    if ((unsigned)(socket - 1) > (SOCKET_POOL_SIZE - 1)) {
+        return -1;
+    }
+    mutex_lock(&_pool_mutex);
+    s = &_pool[socket];
+    if (s->bound) {
+        switch (s->domain) {
+            case AF_INET:
+            case AF_INET6:
+                switch (s->type) {
+#ifdef MODULE_CONN_UDP
+                    case SOCK_DGRAM:
+                        conn_udp_close(&s->conn.udp);
+                        break;
+#endif
+#ifdef MODULE_CONN_IP
+                    case SOCK_RAW:
+                        conn_ip_close(&s->conn.raw);
+                        break;
+#endif
+#ifdef MODULE_CONN_TCP
+                    case SOCK_STREAM:
+                        conn_tcp_close(&s->conn.tcp);
+                        break;
+#endif
+                    default:
+                        errno = EOPNOTSUPP;
+                        res = -1;
+                        break;
+                }
+            default:
+                res = -1;
+                break;
+        }
+    }
+    s->domain = AF_UNSPEC;
+    mutex_unlock(&_pool_mutex);
+    return res;
+}
+
+static ssize_t socket_read(int socket, void *buf, size_t n)
+{
+    return recv(socket, buf, n, 0);
+}
+
+static ssize_t socket_write(int socket, const void *buf, size_t n)
+{
+    return send(socket, buf, n, 0);
+}
+
+int socket(int domain, int type, int protocol)
+{
+    int res = 0;
+    socket_t *s;
+    mutex_lock(&_pool_mutex);
+    s = _get_free_socket();
+    if (s == NULL) {
+        errno = ENFILE;
+        mutex_unlock(&_pool_mutex);
+        return -1;
+    }
+    switch (domain) {
+        case AF_INET:
+        case AF_INET6:
+            s->domain = domain;
+            s->type = type;
+            if ((s->protocol = _choose_ipproto(type, protocol)) < 0) {
+                res = -1;
+            }
+            break;
+
+        default:
+            (void)type;
+            (void)protocol;
+            errno = EAFNOSUPPORT;
+            res = -1;
+    }
+    if (res == 0) {
+        /* TODO: add read and write */
+        int fd = fd_new(s - _pool, socket_read, socket_write, socket_close);
+        if (fd < 0) {
+            errno = ENFILE;
+            res = -1;
+        }
+        else {
+            s->fd = res = fd;
+        }
+    }
+    s->bound = false;
+    mutex_unlock(&_pool_mutex);
+    return res;
+}
+
+
+int accept(int socket, struct sockaddr *restrict address,
+           socklen_t *restrict address_len)
+{
+    socket_t *s, *new_s = NULL;
+    int res = 0;
+    /* May be kept unassigned if no conn module is available */
+    /* cppcheck-suppress unassignedVariable */
+    struct sockaddr_storage tmp;
+    void *addr;
+    uint16_t *port;
+    socklen_t tmp_len;
+    mutex_lock(&_pool_mutex);
+    s = _get_socket(socket);
+    if (s == NULL) {
+        mutex_unlock(&_pool_mutex);
+        errno = ENOTSOCK;
+        return -1;
+    }
+    if (!s->bound) {
+        mutex_unlock(&_pool_mutex);
+        errno = EINVAL;
+        return -1;
+    }
+    switch (s->domain) {
+        case AF_INET:
+            addr = _in_addr_ptr(&tmp);
+            port = _in_port_ptr(&tmp);
+            tmp_len = sizeof(struct sockaddr_in);
+            break;
+        case AF_INET6:
+            addr = _in6_addr_ptr(&tmp);
+            port = _in6_port_ptr(&tmp);
+            tmp_len = sizeof(struct sockaddr_in6);
+            break;
+        default:
+            (void)address;
+            (void)address_len;
+            (void)new_s;
+            (void)tmp;
+            (void)addr;
+            (void)port;
+            (void)tmp_len;
+            errno = EPROTO;
+            res = -1;
+            break;
+    }
+    switch (s->type) {
+#ifdef MODULE_CONN_TCP
+        case SOCK_STREAM:
+            new_s = _get_free_socket();
+            if (new_s == NULL) {
+                errno = ENFILE;
+                res = -1;
+                break;
+            }
+            if ((res = conn_tcp_accept(&s->conn.tcp, &new_s->conn.tcp)) < 0) {
+                errno = -res;
+                res = -1;
+                break;
+            }
+            else if ((address != NULL) && (address_len != NULL)) {
+                /* TODO: add read and write */
+                int fd = fd_new(new_s - _pool, NULL, NULL, socket_close);
+                if (fd < 0) {
+                    errno = ENFILE;
+                    res = -1;
+                    break;
+                }
+                else {
+                    new_s->fd = res = fd;
+                }
+                new_s->domain = s->domain;
+                new_s->type = s->type;
+                new_s->protocol = s->protocol;
+                tmp.ss_family = s->domain;
+                if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
+                    errno = -res;
+                    res = -1;
+                    break;
+                }
+                _htons_port(port);  /* XXX: sin(6)_port is supposed to be network byte
+                                     *      order */
+                *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
+            }
+            break;
+#endif
+        default:
+            errno = EOPNOTSUPP;
+            res = -1;
+            break;
+    }
+    mutex_unlock(&_pool_mutex);
+    return res;
+}
+
+int bind(int socket, const struct sockaddr *address, socklen_t address_len)
+{
+    socket_t *s;
+    int res = 0;
+    void *addr;
+    size_t addr_len;
+    uint16_t port;
+    mutex_lock(&_pool_mutex);
+    s = _get_socket(socket);
+    mutex_unlock(&_pool_mutex);
+    if (s == NULL) {
+        errno = ENOTSOCK;
+        return -1;
+    }
+    if (address->sa_family != s->domain) {
+        errno = EAFNOSUPPORT;
+        return -1;
+    }
+    if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
+        return -1;
+    }
+    switch (s->type) {
+#ifdef MODULE_CONN_IP
+        case SOCK_RAW:
+            (void)port;
+            if ((res = conn_ip_create(&s->conn.raw, addr, addr_len, s->domain, s->protocol)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_TCP
+        case SOCK_STREAM:
+            if ((res = conn_tcp_create(&s->conn.tcp, addr, addr_len, s->domain, port)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_UDP
+        case SOCK_DGRAM:
+            if ((res = conn_udp_create(&s->conn.udp, addr, addr_len, s->domain, port)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+        default:
+            (void)addr;
+            (void)addr_len;
+            (void)port;
+            (void)res;
+            errno = EOPNOTSUPP;
+            return -1;
+    }
+    s->bound = true;
+    return 0;
+}
+
+int connect(int socket, const struct sockaddr *address, socklen_t address_len)
+{
+    socket_t *s;
+    int res = 0;
+    void *addr;
+    size_t addr_len;
+    uint16_t port;
+    mutex_lock(&_pool_mutex);
+    s = _get_socket(socket);
+    mutex_unlock(&_pool_mutex);
+    if (s == NULL) {
+        errno = ENOTSOCK;
+        return -1;
+    }
+    if (!s->bound) {
+        errno = EINVAL;
+        return -1;
+    }
+    if (address->sa_family != s->domain) {
+        errno = EAFNOSUPPORT;
+        return -1;
+    }
+    if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
+        return -1;
+    }
+    switch (s->type) {
+#ifdef MODULE_CONN_TCP
+        case SOCK_STREAM:
+            /* XXX sin_port is in network byteorder */
+            if ((res = conn_tcp_connect(&s->conn.tcp, addr, addr_len, port)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+        default:
+            (void)res;
+            errno = EPROTOTYPE;
+            return -1;
+    }
+    return 0;
+}
+
+int getpeername(int socket, struct sockaddr *__restrict address,
+                socklen_t *__restrict address_len)
+{
+    socket_t *s;
+    int res = 0;
+    /* May be kept unassigned if no conn module is available */
+    /* cppcheck-suppress unassignedVariable */
+    struct sockaddr_storage tmp;
+    void *addr;
+    uint16_t *port;
+    socklen_t tmp_len;
+    mutex_lock(&_pool_mutex);
+    s = _get_socket(socket);
+    mutex_unlock(&_pool_mutex);
+    if (s == NULL) {
+        errno = ENOTSOCK;
+        return -1;
+    }
+    switch (s->domain) {
+        case AF_INET:
+            addr = _in_addr_ptr(&tmp);
+            port = _in_port_ptr(&tmp);
+            tmp_len = sizeof(struct sockaddr_in);
+            break;
+        case AF_INET6:
+            addr = _in6_addr_ptr(&tmp);
+            port = _in6_port_ptr(&tmp);
+            tmp_len = sizeof(struct sockaddr_in6);
+            break;
+        default:
+            (void)address;
+            (void)address_len;
+            (void)tmp;
+            (void)addr;
+            (void)port;
+            (void)tmp_len;
+            (void)res;
+            errno = EBADF;
+            return -1;
+    }
+    if (*address_len != tmp_len) {
+        errno = EINVAL;
+        return -1;
+    }
+    switch (s->type) {
+#ifdef MODULE_CONN_TCP
+        case SOCK_STREAM:
+            if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+        default:
+            errno = ENOTCONN;
+            return -1;
+    }
+    tmp.ss_family = s->domain;
+    _htons_port(port);  /* XXX: sin(6)_port is supposed to be network byte
+                         *      order */
+    *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
+    return 0;
+}
+
+int getsockname(int socket, struct sockaddr *__restrict address,
+                socklen_t *__restrict address_len)
+{
+    socket_t *s;
+    int res = 0;
+    /* May be kept unassigned if no conn module is available */
+    /* cppcheck-suppress unassignedVariable */
+    struct sockaddr_storage tmp;
+    void *addr;
+    uint16_t *port;
+    socklen_t tmp_len;
+    mutex_lock(&_pool_mutex);
+    s = _get_socket(socket);
+    mutex_unlock(&_pool_mutex);
+    if (s == NULL) {
+        errno = ENOTSOCK;
+        return -1;
+    }
+    if (!s->bound) {
+        memset(address, 0, *address_len);
+        return 0;
+    }
+    switch (s->domain) {
+        case AF_INET:
+            addr = _in_addr_ptr(&tmp);
+            port = _in_port_ptr(&tmp);
+            tmp_len = sizeof(struct sockaddr_in);
+            break;
+        case AF_INET6:
+            addr = _in6_addr_ptr(&tmp);
+            port = _in6_port_ptr(&tmp);
+            tmp_len = sizeof(struct sockaddr_in6);
+            break;
+        default:
+            (void)address;
+            (void)address_len;
+            (void)tmp;
+            (void)addr;
+            (void)port;
+            (void)tmp_len;
+            (void)res;
+            errno = EBADF;
+            return -1;
+    }
+    if (*address_len != tmp_len) {
+        errno = EINVAL;
+        return -1;
+    }
+    switch (s->type) {
+#ifdef MODULE_CONN_UDP
+        case SOCK_DGRAM:
+            if ((res = conn_udp_getlocaladdr(&s->conn.udp, addr, port)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_IP
+        case SOCK_RAW:
+            if ((res = conn_ip_getlocaladdr(&s->conn.raw, addr)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_TCP
+        case SOCK_STREAM:
+            if ((res = conn_tcp_getlocaladdr(&s->conn.tcp, addr, port)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+        default:
+            errno = EOPNOTSUPP;
+            return -1;
+    }
+    tmp.ss_family = AF_INET;
+    _htons_port(port);  /* XXX: sin(6)_port is supposed to be network byte
+                         *      order */
+    *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
+    return 0;
+}
+
+int listen(int socket, int backlog)
+{
+    socket_t *s;
+    int res = 0;
+    mutex_lock(&_pool_mutex);
+    s = _get_socket(socket);
+    mutex_unlock(&_pool_mutex);
+    if (!s->bound) {
+        errno = EINVAL;
+        return -1;
+    }
+    switch (s->domain) {
+        case AF_INET:
+        case AF_INET6:
+            switch (s->type) {
+#ifdef MODULE_CONN_TCP
+                case SOCK_STREAM:
+                    if ((res = conn_tcp_listen(&s->conn.tcp, backlog)) < 0) {
+                        errno = -res;
+                        return -1;
+                    }
+                    break;
+#endif
+                default:
+                    errno = EOPNOTSUPP;
+                    return -1;
+            }
+            break;
+        default:
+            (void)backlog;
+            (void)res;
+            errno = EAFNOSUPPORT;
+            return -1;
+    }
+    return 0;
+}
+
+ssize_t recv(int socket, void *buffer, size_t length, int flags)
+{
+    return recvfrom(socket, buffer, length, flags, NULL, NULL);
+}
+
+ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
+                 struct sockaddr *restrict address,
+                 socklen_t *restrict address_len)
+{
+    socket_t *s;
+    int res = 0;
+    /* May be kept unassigned if no conn module is available */
+    /* cppcheck-suppress unassignedVariable */
+    struct sockaddr_storage tmp;
+    void *addr;
+    size_t addr_len;
+    uint16_t *port;
+    socklen_t tmp_len;
+    (void)flags;
+    mutex_lock(&_pool_mutex);
+    s = _get_socket(socket);
+    mutex_unlock(&_pool_mutex);
+    if (s == NULL) {
+        errno = ENOTSOCK;
+        return -1;
+    }
+    if (!s->bound) {
+        errno = EINVAL;
+        return -1;
+    }
+    switch (s->domain) {
+        case AF_INET:
+            addr = _in_addr_ptr(&tmp);
+            port = _in_port_ptr(&tmp);
+            addr_len = sizeof(ipv4_addr_t);
+            tmp_len = sizeof(struct sockaddr_in);
+            break;
+        case AF_INET6:
+            addr = _in6_addr_ptr(&tmp);
+            port = _in6_port_ptr(&tmp);
+            addr_len = sizeof(ipv6_addr_t);
+            tmp_len = sizeof(struct sockaddr_in6);
+            break;
+        default:
+            (void)buffer;
+            (void)length;
+            (void)address;
+            (void)address_len;
+            (void)tmp;
+            (void)addr;
+            (void)port;
+            (void)tmp_len;
+            errno = EAFNOSUPPORT;
+            return -1;
+    }
+    switch (s->type) {
+#ifdef MODULE_CONN_UDP
+        case SOCK_DGRAM:
+            if ((res = conn_udp_recvfrom(&s->conn.udp, buffer, length, addr, &addr_len,
+                                         port)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_IP
+        case SOCK_RAW:
+            if ((res = conn_ip_recvfrom(&s->conn.raw, buffer, length, addr, &addr_len)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_TCP
+        case SOCK_STREAM:
+            if ((res = conn_tcp_recv(&s->conn.tcp, buffer, length)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+        default:
+            (void)addr_len;
+            errno = EOPNOTSUPP;
+            return -1;
+    }
+    if ((address != NULL) && (address_len != NULL)) {
+        tmp.ss_family = s->domain;
+        _htons_port(port);  /* XXX: sin_port is supposed to be network byte
+                             *      order */
+        *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
+    }
+    return res;
+}
+
+ssize_t send(int socket, const void *buffer, size_t length, int flags)
+{
+    return sendto(socket, buffer, length, flags, NULL, 0);
+}
+
+ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
+               const struct sockaddr *address, socklen_t address_len)
+{
+    socket_t *s;
+    int res = 0;
+    void *addr = NULL;
+    size_t addr_len = 0;
+    uint16_t port = 0;
+    (void)flags;
+    mutex_lock(&_pool_mutex);
+    s = _get_socket(socket);
+    mutex_unlock(&_pool_mutex);
+    if (s == NULL) {
+        errno = ENOTSOCK;
+        return -1;
+    }
+    if (address != NULL) {
+        if (address->sa_family != s->domain) {
+            errno = EAFNOSUPPORT;
+            return -1;
+        }
+        if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
+            return -1;
+        }
+    }
+    switch (s->type) {
+#ifdef MODULE_CONN_IP
+        case SOCK_RAW:
+            if ((address != NULL) && (s->bound)) {
+                uint8_t src_addr[sizeof(ipv6_addr_t)];
+                size_t src_len;
+                int res = conn_ip_getlocaladdr(&s->conn.raw, src_addr);
+                if (res < 0) {
+                    errno = ENOTSOCK;   /* Something seems to be wrong with the socket */
+                    return -1;
+                }
+                src_len = (size_t)res;
+                /* cppcheck bug? res is read below in l824 */
+                /* cppcheck-suppress unreadVariable */
+                res = conn_ip_sendto(buffer, length, src_addr, src_len, addr, addr_len, s->domain,
+                                     s->protocol);
+            }
+            else if (address != NULL) {
+                res = conn_ip_sendto(buffer, length, NULL, 0, addr, addr_len, s->domain,
+                                     s->protocol);
+            }
+            else {
+                errno = ENOTCONN;
+                return -1;
+            }
+            if (res < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_TCP
+        case SOCK_STREAM:
+            if (!s->bound) {
+                errno = ENOTCONN;
+                return -1;
+            }
+            if (address != NULL) {
+                errno = EISCONN;
+                return -1;
+            }
+            if ((res = conn_tcp_send(&s->conn.tcp, buffer, length)) < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+#ifdef MODULE_CONN_UDP
+        case SOCK_DGRAM:
+            if ((address != NULL) && (s->bound)) {
+                uint8_t src_addr[sizeof(ipv6_addr_t)];
+                size_t src_len;
+                uint16_t sport;
+                int res = conn_udp_getlocaladdr(&s->conn.udp, src_addr, &sport);
+                if (res < 0) {
+                    errno = ENOTSOCK;   /* Something seems to be wrong with the socket */
+                    return -1;
+                }
+                src_len = (size_t)res;
+                /* cppcheck bug? res is read below in l824 */
+                /* cppcheck-suppress unreadVariable */
+                res = conn_udp_sendto(buffer, length, src_addr, src_len, addr, addr_len, s->domain,
+                                      sport, port);
+            }
+            else if (address != NULL) {
+                uint16_t sport = (uint16_t)genrand_uint32_range(1LU << 10U, 1LU << 16U);
+                res = conn_udp_sendto(buffer, length, NULL, 0, addr, addr_len, s->domain,
+                                      sport, port);
+            }
+            else {
+                errno = ENOTCONN;
+                return -1;
+            }
+            if (res < 0) {
+                errno = -res;
+                return -1;
+            }
+            break;
+#endif
+        default:
+            (void)buffer;
+            (void)length;
+            errno = EOPNOTSUPP;
+            return -1;
+    }
+    return res;
+}
+
+
+/**
+ * @}
+ */