diff --git a/examples/posix_sockets/main.c b/examples/posix_sockets/main.c
index 995019ad8c932232ca7ef521210a5cff3a10d4ea..de60a3bb139fd82a0073362262d38d9baafa53ab 100644
--- a/examples/posix_sockets/main.c
+++ b/examples/posix_sockets/main.c
@@ -20,9 +20,11 @@
 
 #include <stdio.h>
 
+#include "msg.h"
 #include "shell.h"
 
-#define MAIN_MSG_QUEUE_SIZE (1)
+#define MAIN_MSG_QUEUE_SIZE (4)
+static msg_t main_msg_queue[MAIN_MSG_QUEUE_SIZE];
 
 extern int udp_cmd(int argc, char **argv);
 
@@ -33,6 +35,9 @@ static const shell_command_t shell_commands[] = {
 
 int main(void)
 {
+    /* a sendto() call performs an implicit bind(), hence, a message queue is
+     * required for the thread executing the shell */
+    msg_init_queue(main_msg_queue, MAIN_MSG_QUEUE_SIZE);
     puts("RIOT socket example application");
     /* start shell */
     puts("All up, running the shell now");
diff --git a/sys/posix/sockets/posix_sockets.c b/sys/posix/sockets/posix_sockets.c
index 5da5795872aebd96daebf4e813231cfedf3e512e..623283e6364740938fc68852326908483e8f47aa 100644
--- a/sys/posix/sockets/posix_sockets.c
+++ b/sys/posix/sockets/posix_sockets.c
@@ -56,6 +56,7 @@ typedef struct {
     int protocol;
     bool bound;
     socket_conn_t conn;
+    uint16_t src_port;
 } socket_t;
 
 socket_t _pool[SOCKET_POOL_SIZE];
@@ -119,11 +120,6 @@ static inline int _choose_ipproto(int type, int protocol)
     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);
@@ -153,7 +149,7 @@ static inline socklen_t _addr_truncate(struct sockaddr *out, socklen_t 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)
+                                          void **addr, size_t *addr_len, network_uint16_t *port)
 {
     switch (address->sa_family) {
         case AF_INET:
@@ -164,8 +160,7 @@ static inline int _get_data_from_sockaddr(const struct sockaddr *address, size_t
             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);
+            port->u16 = in_addr->sin_port;
             break;
         case AF_INET6:
             if (address_len < sizeof(struct sockaddr_in6)) {
@@ -175,8 +170,7 @@ static inline int _get_data_from_sockaddr(const struct sockaddr *address, size_t
             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);
+            port->u16 = in6_addr->sin6_port;
             break;
         default:
             errno = EAFNOSUPPORT;
@@ -225,6 +219,7 @@ static int socket_close(int socket)
         }
     }
     s->domain = AF_UNSPEC;
+    s->src_port = 0;
     mutex_unlock(&_pool_mutex);
     return res;
 }
@@ -278,6 +273,7 @@ int socket(int domain, int type, int protocol)
         }
     }
     s->bound = false;
+    s->src_port = 0;
     mutex_unlock(&_pool_mutex);
     return res;
 }
@@ -363,8 +359,8 @@ int accept(int socket, struct sockaddr *restrict address,
                     res = -1;
                     break;
                 }
-                _htons_port(port);  /* XXX: sin(6)_port is supposed to be network byte
-                                     *      order */
+                *port = htons(*port); /* XXX: sin(6)_port is supposed to be
+                                         network byte order */
                 *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
             }
             break;
@@ -384,7 +380,7 @@ int bind(int socket, const struct sockaddr *address, socklen_t address_len)
     int res = 0;
     void *addr;
     size_t addr_len;
-    uint16_t port;
+    network_uint16_t port = { 0 };
     mutex_lock(&_pool_mutex);
     s = _get_socket(socket);
     mutex_unlock(&_pool_mutex);
@@ -411,7 +407,8 @@ int bind(int socket, const struct sockaddr *address, socklen_t address_len)
 #endif
 #ifdef MODULE_CONN_TCP
         case SOCK_STREAM:
-            if ((res = conn_tcp_create(&s->conn.tcp, addr, addr_len, s->domain, port)) < 0) {
+            if ((res = conn_tcp_create(&s->conn.tcp, addr, addr_len, s->domain,
+                                       byteorder_ntohs(port))) < 0) {
                 errno = -res;
                 return -1;
             }
@@ -419,7 +416,9 @@ int bind(int socket, const struct sockaddr *address, socklen_t address_len)
 #endif
 #ifdef MODULE_CONN_UDP
         case SOCK_DGRAM:
-            if ((res = conn_udp_create(&s->conn.udp, addr, addr_len, s->domain, port)) < 0) {
+            if ((res = conn_udp_create(&s->conn.udp, addr, addr_len, s->domain,
+                                       byteorder_ntohs(port))) < 0) {
+
                 errno = -res;
                 return -1;
             }
@@ -433,6 +432,7 @@ int bind(int socket, const struct sockaddr *address, socklen_t address_len)
             errno = EOPNOTSUPP;
             return -1;
     }
+    s->src_port = byteorder_ntohs(port);
     s->bound = true;
     return 0;
 }
@@ -443,7 +443,7 @@ int connect(int socket, const struct sockaddr *address, socklen_t address_len)
     int res = 0;
     void *addr;
     size_t addr_len;
-    uint16_t port;
+    network_uint16_t port;
     mutex_lock(&_pool_mutex);
     s = _get_socket(socket);
     mutex_unlock(&_pool_mutex);
@@ -465,8 +465,9 @@ int connect(int socket, const struct sockaddr *address, socklen_t address_len)
     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) {
+            if ((res = conn_tcp_connect(&s->conn.tcp, addr, addr_len,
+                                        byteorder_ntohs(port))) < 0) {
+
                 errno = -res;
                 return -1;
             }
@@ -538,8 +539,8 @@ int getpeername(int socket, struct sockaddr *__restrict address,
             return -1;
     }
     tmp.ss_family = s->domain;
-    _htons_port(port);  /* XXX: sin(6)_port is supposed to be network byte
-                         *      order */
+    *port = htons(*port); /* XXX: sin(6)_port is supposed to be network byte
+                             order */
     *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
     return 0;
 }
@@ -622,8 +623,8 @@ int getsockname(int socket, struct sockaddr *__restrict address,
             return -1;
     }
     tmp.ss_family = AF_INET;
-    _htons_port(port);  /* XXX: sin(6)_port is supposed to be network byte
-                         *      order */
+    *port = htons(*port); /* XXX: sin(6)_port is supposed to be network byte
+                             order */
     *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
     return 0;
 }
@@ -724,8 +725,8 @@ ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
     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) {
+            if ((res = conn_udp_recvfrom(&s->conn.udp, buffer, length, addr,
+                                         &addr_len, port)) < 0) {
                 errno = -res;
                 return -1;
             }
@@ -758,8 +759,8 @@ ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
     }
     if ((address != NULL) && (address_len != NULL)) {
         tmp.ss_family = s->domain;
-        _htons_port(port);  /* XXX: sin_port is supposed to be network byte
-                             *      order */
+        *port = htons(*port); /* XXX: sin(6)_port is supposed to be network
+                                 byte order */
         *address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
     }
     return res;
@@ -777,7 +778,8 @@ ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
     int res = 0;
     void *addr = NULL;
     size_t addr_len = 0;
-    uint16_t port = 0;
+    network_uint16_t port;
+    port.u16 = 0;
     (void)flags;
     mutex_lock(&_pool_mutex);
     s = _get_socket(socket);
@@ -857,12 +859,21 @@ ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
                 /* 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);
+                                      sport, byteorder_ntohs(port));
             }
             else if (address != NULL) {
-                uint16_t sport = (uint16_t)genrand_uint32_range(1LU << 10U, 1LU << 16U);
+                ipv6_addr_t local;
+                s->src_port = (uint16_t)genrand_uint32_range(1LU << 10U, 1LU << 16U);
+                /* implicitly bind the socket here */
+                ipv6_addr_set_unspecified(&local);
+                if ((res = conn_udp_create(&s->conn.udp, &local, sizeof(local),
+                                           s->domain, s->src_port)) < 0) {
+                    errno = -res;
+                    return -1;
+                }
+                s->bound = true;
                 res = conn_udp_sendto(buffer, length, NULL, 0, addr, addr_len, s->domain,
-                                      sport, port);
+                                      s->src_port, byteorder_ntohs(port));
             }
             else {
                 errno = ENOTCONN;